Kaynağa Gözat

完善农机故障告警、农机作业记录;新增农机监控汇总

yawuga 10 ay önce
ebeveyn
işleme
480b224b28

+ 3 - 1
public/index.html

@@ -8,11 +8,13 @@
     <link rel="icon" href="<%= BASE_URL %>favicon.ico">
     <title><%= webpackConfig.name %></title>
     <!--[if lt IE 11]><script>window.location.href='/html/ie.html';</script><![endif]-->
+    <!-- 高德地图API配置 -->
     <script type="text/javascript">
       window._AMapSecurityConfig = {
-        securityJsCode: "YOUR_SECURITY_CODE", // 如果使用安全密钥
+        securityJsCode: "YOUR_SECURITY_CODE", // 请替换为真实的安全密钥(可选)
       };
     </script>
+    <!-- 请将YOUR_AMAP_KEY替换为您的高德地图API密钥 -->
     <script type="text/javascript" src="https://webapi.amap.com/maps?v=2.0&key=YOUR_AMAP_KEY&plugin=AMap.Scale,AMap.OverView,AMap.ToolBar,AMap.MapType"></script>
 	  <style>
     html,

+ 19 - 0
src/router/index.js

@@ -100,6 +100,25 @@ export const constantRoutes = [
         meta: { title: '管理信息', activeMenu: '/base/field' }
       }
     ]
+  },
+  {
+    path: '/base',
+    component: Layout,
+    hidden: true,
+    children: [
+      {
+        path: 'machines/monitor',
+        component: () => import('@/views/base/machines/monitor'),
+        name: 'MachineMonitor',
+        meta: { title: '农机监控', activeMenu: '/base/machines' }
+      },
+      {
+        path: 'machines/machines-monitor',
+        component: () => import('@/views/base/machines/machines-monitor'),
+        name: 'MachinesMonitor',
+        meta: { title: '农机监控汇总', activeMenu: '/base/machines' }
+      }
+    ]
   }
 ]
 

+ 1100 - 134
src/views/base/machineAlarmRecords/index.vue

@@ -1,91 +1,65 @@
 <template>
   <div class="app-container">
     <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
-      <el-form-item label="农机ID" prop="machineId">
+      <el-form-item label="农机编号" prop="machineId">
         <el-input
           v-model="queryParams.machineId"
-          placeholder="请输入农机ID"
+          placeholder="请输入农机编号关键词"
           clearable
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
-      <el-form-item label="报警类型" prop="alarmType">
-        <el-select v-model="queryParams.alarmType" placeholder="请选择报警类型" clearable>
-          <el-option
-            v-for="dict in dict.type.machine_alarm_type"
-            :key="dict.value"
-            :label="dict.label"
-            :value="dict.value"
-          />
-        </el-select>
-      </el-form-item>
-      <el-form-item label="报警级别" prop="alarmLevel">
-        <el-select v-model="queryParams.alarmLevel" placeholder="请选择报警级别" clearable>
-          <el-option
-            v-for="dict in dict.type.machine_alarm_level"
-            :key="dict.value"
-            :label="dict.label"
-            :value="dict.value"
-          />
-        </el-select>
-      </el-form-item>
-      <el-form-item label="报警时间" prop="alarmTime">
-        <el-date-picker clearable
-          v-model="queryParams.alarmTime"
-          type="date"
-          value-format="yyyy-MM-dd"
-          placeholder="请选择报警时间">
-        </el-date-picker>
-      </el-form-item>
-      <el-form-item label="报警位置信息" prop="locationInfo">
+      <el-form-item label="农机名称" prop="machineName">
         <el-input
-          v-model="queryParams.locationInfo"
-          placeholder="请输入报警位置信息"
+          v-model="queryParams.machineName"
+          placeholder="请输入农机名称关键词"
           clearable
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
-      <el-form-item label="处理状态" prop="handledStatus">
-        <el-select v-model="queryParams.handledStatus" placeholder="请选择处理状态" clearable>
-          <el-option
-            v-for="dict in dict.type.machine_handled_status"
-            :key="dict.value"
-            :label="dict.label"
-            :value="dict.value"
-          />
+      <el-form-item label="告警等级" prop="alarmLevel">
+        <el-select v-model="queryParams.alarmLevel" placeholder="所有告警等级" clearable>
+          <el-option label="提示" value="3" />
+          <el-option label="告警" value="2" />
+          <el-option label="紧急" value="1" />
         </el-select>
       </el-form-item>
-      <el-form-item label="处理人ID" prop="handlerId">
-        <el-input
-          v-model="queryParams.handlerId"
-          placeholder="请输入处理人ID"
-          clearable
-          @keyup.enter.native="handleQuery"
-        />
+      <el-form-item label="农机类型" prop="machineType">
+        <el-select v-model="queryParams.machineType" placeholder="所有农机类型" clearable>
+          <el-option label="拖拉机" value="tractor" />
+          <el-option label="收割机" value="harvester" />
+          <el-option label="播种机" value="seeder" />
+          <el-option label="喷药机" value="sprayer" />
+          <el-option label="耕地机" value="cultivator" />
+        </el-select>
       </el-form-item>
-      <el-form-item label="处理人姓名" prop="handlerName">
-        <el-input
-          v-model="queryParams.handlerName"
-          placeholder="请输入处理人姓名"
-          clearable
-          @keyup.enter.native="handleQuery"
-        />
+      <el-form-item label="所属农场" prop="farmId">
+        <el-select v-model="queryParams.farmId" placeholder="所有农场" clearable>
+          <el-option label="绿野农场" value="1" />
+          <el-option label="丰收农场" value="2" />
+          <el-option label="田园农场" value="3" />
+          <el-option label="生态农场" value="4" />
+          <el-option label="科技农场" value="5" />
+        </el-select>
       </el-form-item>
-      <el-form-item label="处理时间" prop="handleTime">
-        <el-date-picker clearable
-          v-model="queryParams.handleTime"
-          type="date"
+      <el-form-item label="告警时间">
+        <el-date-picker
+          v-model="daterangeAlarmTime"
+          style="width: 240px"
           value-format="yyyy-MM-dd"
-          placeholder="请选择处理时间">
-        </el-date-picker>
+          type="daterange"
+          range-separator="至"
+          start-placeholder="年/月/日"
+          end-placeholder="年/月/日"
+        ></el-date-picker>
       </el-form-item>
-      <el-form-item label="解决时间" prop="resolvedTime">
-        <el-date-picker clearable
-          v-model="queryParams.resolvedTime"
-          type="date"
-          value-format="yyyy-MM-dd"
-          placeholder="请选择解决时间">
-        </el-date-picker>
+      <el-form-item label="处理状态" prop="handledStatus">
+        <el-select v-model="queryParams.handledStatus" placeholder="所有状态" clearable>
+          <el-option label="未处理" value="0" />
+          <el-option label="已处理" value="1" />
+          <el-option label="处理中" value="2" />
+          <el-option label="忽略" value="3" />
+        </el-select>
       </el-form-item>
       <el-form-item>
         <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
@@ -93,39 +67,65 @@
       </el-form-item>
     </el-form>
 
-    <el-row :gutter="10" class="mb8">
-      <el-col :span="1.5">
-        <el-button
-          type="primary"
-          plain
-          icon="el-icon-plus"
-          size="mini"
-          @click="handleAdd"
-          v-hasPermi="['base:machineAlarmRecords:add']"
-        >新增</el-button>
+    <!-- 告警统计面板 -->
+    <div class="statistics-panel">
+      <el-row :gutter="20">
+        <el-col :span="6">
+          <div class="stat-card total">
+            <div class="stat-header">
+              <span class="stat-title">今日告警总数</span>
+            </div>
+            <div class="stat-content">
+              <div class="stat-number">{{ todayStatistics.total }}</div>
+              <div class="stat-change" :class="todayStatistics.change >= 0 ? 'increase' : 'decrease'">
+                <span>较昨日 {{ todayStatistics.change >= 0 ? '+' : '' }}{{ todayStatistics.change }}</span>
+              </div>
+            </div>
+          </div>
       </el-col>
-      <el-col :span="1.5">
-        <el-button
-          type="success"
-          plain
-          icon="el-icon-edit"
-          size="mini"
-          :disabled="single"
-          @click="handleUpdate"
-          v-hasPermi="['base:machineAlarmRecords:edit']"
-        >修改</el-button>
+        <el-col :span="6">
+          <div class="stat-card emergency">
+            <div class="stat-header">
+              <span class="stat-title">紧急告警</span>
+            </div>
+            <div class="stat-content">
+              <div class="stat-number">{{ levelStatistics.emergency.total }}</div>
+              <div class="stat-detail">
+                <span>未处理: {{ levelStatistics.emergency.unprocessed }}</span>
+              </div>
+            </div>
+          </div>
       </el-col>
-      <el-col :span="1.5">
-        <el-button
-          type="danger"
-          plain
-          icon="el-icon-delete"
-          size="mini"
-          :disabled="multiple"
-          @click="handleDelete"
-          v-hasPermi="['base:machineAlarmRecords:remove']"
-        >删除</el-button>
+        <el-col :span="6">
+          <div class="stat-card warning">
+            <div class="stat-header">
+              <span class="stat-title">警告</span>
+            </div>
+            <div class="stat-content">
+              <div class="stat-number">{{ levelStatistics.warning.total }}</div>
+              <div class="stat-detail">
+                <span>未处理: {{ levelStatistics.warning.unprocessed }}</span>
+              </div>
+            </div>
+          </div>
       </el-col>
+        <el-col :span="6">
+          <div class="stat-card info">
+            <div class="stat-header">
+              <span class="stat-title">提示信息</span>
+            </div>
+            <div class="stat-content">
+              <div class="stat-number">{{ levelStatistics.info.total }}</div>
+              <div class="stat-detail">
+                <span>未处理: {{ levelStatistics.info.unprocessed }}</span>
+              </div>
+            </div>
+          </div>
+        </el-col>
+      </el-row>
+    </div>
+
+    <el-row :gutter="10" class="mb8">
       <el-col :span="1.5">
         <el-button
           type="warning"
@@ -141,60 +141,70 @@
 
     <el-table v-loading="loading" :data="machineAlarmRecordsList" @selection-change="handleSelectionChange">
       <el-table-column type="selection" width="55" align="center" />
-      <el-table-column label="报警记录ID" align="center" prop="id" />
-      <el-table-column label="农机ID" align="center" prop="machineId" />
-      <el-table-column label="报警类型" align="center" prop="alarmType">
+      <el-table-column label="告警ID" align="center" prop="id" />
+      <el-table-column label="告警等级" align="center" prop="alarmLevel">
         <template slot-scope="scope">
-          <dict-tag :options="dict.type.machine_alarm_type" :value="scope.row.alarmType"/>
+          <span :class="['custom-tag', 'level-tag', getAlertLevelClass(scope.row.alarmLevel)]">
+            {{ getAlertLevelText(scope.row.alarmLevel) }}
+          </span>
+        </template>
+      </el-table-column>
+      <el-table-column label="农机名称" align="center" prop="machineName">
+        <template slot-scope="scope">
+          <span>{{ getMachineName(scope.row.machineId) }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="农机编号" align="center" prop="machineId" />
+      <el-table-column label="农机类型" align="center" prop="machineType">
+        <template slot-scope="scope">
+          <span>{{ getMachineType(scope.row.machineId) }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="所属农场" align="center" prop="farmName">
+        <template slot-scope="scope">
+          <span>{{ getFarmName(scope.row.machineId) }}</span>
         </template>
       </el-table-column>
-      <el-table-column label="报警级别" align="center" prop="alarmLevel">
+      <el-table-column label="告警类型" align="center" prop="alarmType">
         <template slot-scope="scope">
-          <dict-tag :options="dict.type.machine_alarm_level" :value="scope.row.alarmLevel"/>
+          <dict-tag :options="dict.type.machine_alarm_type" :value="scope.row.alarmType"/>
         </template>
       </el-table-column>
-      <el-table-column label="报警描述" align="center" prop="alarmDesc" />
-      <el-table-column label="报警时间" align="center" prop="alarmTime" width="180">
+      <el-table-column label="告警内容" align="center" prop="alarmDesc" />
+      <el-table-column label="警时间" align="center" prop="alarmTime" width="180">
         <template slot-scope="scope">
           <span>{{ parseTime(scope.row.alarmTime, '{y}-{m}-{d}') }}</span>
         </template>
       </el-table-column>
-      <el-table-column label="报警位置信息" align="center" prop="locationInfo" />
       <el-table-column label="处理状态" align="center" prop="handledStatus">
         <template slot-scope="scope">
-          <dict-tag :options="dict.type.machine_handled_status" :value="scope.row.handledStatus"/>
+          <span :class="['custom-tag', 'status-tag', getProcessStatusClass(scope.row.handledStatus)]">
+            {{ getProcessStatusText(scope.row.handledStatus) }}
+          </span>
         </template>
       </el-table-column>
-      <el-table-column label="处理人ID" align="center" prop="handlerId" />
-      <el-table-column label="处理人姓名" align="center" prop="handlerName" />
+      <el-table-column label="处理人" align="center" prop="handlerName" />
       <el-table-column label="处理时间" align="center" prop="handleTime" width="180">
         <template slot-scope="scope">
           <span>{{ parseTime(scope.row.handleTime, '{y}-{m}-{d}') }}</span>
         </template>
       </el-table-column>
-      <el-table-column label="处理描述" align="center" prop="handleDesc" />
-      <el-table-column label="解决时间" align="center" prop="resolvedTime" width="180">
-        <template slot-scope="scope">
-          <span>{{ parseTime(scope.row.resolvedTime, '{y}-{m}-{d}') }}</span>
-        </template>
-      </el-table-column>
-      <el-table-column label="备注" align="center" prop="remark" />
       <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
         <template slot-scope="scope">
           <el-button
             size="mini"
             type="text"
-            icon="el-icon-edit"
-            @click="handleUpdate(scope.row)"
-            v-hasPermi="['base:machineAlarmRecords:edit']"
-          >修改</el-button>
+            icon="el-icon-view"
+            @click="handleDetail(scope.row)"
+          >查看</el-button>
           <el-button
+            v-if="scope.row.handledStatus == 0 || scope.row.handledStatus == '0' || scope.row.handledStatus == 2 || scope.row.handledStatus == '2'"
             size="mini"
             type="text"
-            icon="el-icon-delete"
-            @click="handleDelete(scope.row)"
-            v-hasPermi="['base:machineAlarmRecords:remove']"
-          >删除</el-button>
+            icon="el-icon-edit"
+            @click="handleProcess(scope.row)"
+            v-hasPermi="['base:machineAlarmRecords:edit']"
+          >处理</el-button>
         </template>
       </el-table-column>
     </el-table>
@@ -207,6 +217,160 @@
       @pagination="getList"
     />
 
+    <!-- 告警详情对话框 -->
+    <el-dialog title="告警详情" :visible.sync="detailOpen" width="600px" append-to-body>
+      <div class="alert-detail">
+        <!-- 主要告警信息卡片 -->
+        <div class="alert-card">
+          <!-- 头部信息 -->
+          <div class="alert-header">
+            <div class="alert-level-tag">
+              <span :class="['custom-tag', 'level-tag', getAlertLevelClass(currentRecord.alarmLevel)]">
+                {{ getAlertLevelText(currentRecord.alarmLevel) }}
+              </span>
+            </div>
+            <div class="alert-time">{{ parseTime(currentRecord.alarmTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</div>
+          </div>
+          
+          <!-- 告警内容 -->
+          <div class="alert-content">
+            {{ getAlertContent(currentRecord) }}
+          </div>
+        </div>
+        
+        <!-- 设备信息 -->
+        <div class="section">
+          <div class="section-title">设备信息</div>
+          <div class="device-info">
+            <div class="info-grid">
+              <div class="info-item">
+                <span class="label">农机名称</span>
+                <span class="value">{{ getMachineName(currentRecord.machineId) }}</span>
+              </div>
+              <div class="info-item">
+                <span class="label">农机编号</span>
+                <span class="value">{{ currentRecord.machineId }}</span>
+              </div>
+              <div class="info-item">
+                <span class="label">农机类型</span>
+                <span class="value">{{ getMachineType(currentRecord.machineId) }}</span>
+              </div>
+                             <div class="info-item">
+                 <span class="label">所属农场</span>
+                 <span class="value">{{ getFarmName(currentRecord.machineId) }}</span>
+               </div>
+            </div>
+          </div>
+        </div>
+        
+        <!-- 处理状态 -->
+        <div class="section">
+          <div class="section-title">处理状态</div>
+          <div class="status-info">
+            <div class="status-item">
+              <span class="label">当前状态</span>
+              <span class="value status">
+                <span :class="['custom-tag', 'status-tag', getProcessStatusClass(currentRecord.handledStatus)]">
+                  {{ getProcessStatusText(currentRecord.handledStatus) }}
+                </span>
+              </span>
+            </div>
+            <div class="status-item">
+              <span class="label">处理人</span>
+              <span class="value">{{ currentRecord.handlerName || '-' }}</span>
+            </div>
+                         <div class="status-item">
+               <span class="label">处理时间</span>
+               <span class="value">{{ currentRecord.handleTime ? parseTime(currentRecord.handleTime, '{y}-{m}-{d} {h}:{i}:{s}') : '-' }}</span>
+             </div>
+            <div class="status-item full-width">
+              <span class="label">处理记录</span>
+              <div class="process-record">
+                {{ currentRecord.handleDesc || '暂无处理记录' }}
+              </div>
+            </div>
+          </div>
+        </div>
+        
+        <!-- 附件信息 -->
+        <div class="section">
+          <div class="section-title">附件信息</div>
+          <div class="attachment-info">
+            <div v-if="currentRecord.attachments && currentRecord.attachments.length > 0" class="attachment-list">
+              <div v-for="(attachment, index) in getAttachmentList(currentRecord.attachments)" :key="index" class="attachment-item">
+                <div class="attachment-preview">
+                  <i v-if="isImage(attachment.name)" class="el-icon-picture-outline"></i>
+                  <i v-else class="el-icon-document"></i>
+                </div>
+                <div class="attachment-details">
+                  <div class="attachment-name" :title="attachment.name">{{ attachment.name }}</div>
+                  <div class="attachment-size">{{ formatFileSize(attachment.size) }}</div>
+                </div>
+                <div class="attachment-actions">
+                  <el-button size="mini" type="text" @click="downloadAttachment(attachment)">下载</el-button>
+                  <el-button v-if="isImage(attachment.name)" size="mini" type="text" @click="previewImage(attachment)">预览</el-button>
+                </div>
+              </div>
+            </div>
+            <div v-else class="no-attachment">
+              <i class="el-icon-folder-opened"></i>
+              <span>暂无附件</span>
+            </div>
+          </div>
+        </div>
+      </div>
+      
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="detailOpen = false">关闭</el-button>
+      </div>
+    </el-dialog>
+
+    <!-- 处理告警对话框 -->
+    <el-dialog title="处理告警" :visible.sync="processOpen" width="500px" append-to-body>
+      <el-form ref="processForm" :model="processForm" :rules="processRules" label-width="80px">
+        <el-form-item label="告警信息">
+                     <div class="process-alert-info">
+             <div class="info-item-row">
+               <span class="label">农机编号:</span>
+               <span class="value">{{ processForm.machineId }}</span>
+             </div>
+             <div class="info-item-row">
+               <span class="label">农机名称:</span>
+               <span class="value">{{ getMachineName(processForm.machineId) }}</span>
+             </div>
+             <div class="alert-content-preview">
+               {{ getAlertContent(processForm) }}
+             </div>
+           </div>
+        </el-form-item>
+        <el-form-item label="处理结果" prop="handledStatus">
+          <el-select v-model="processForm.handledStatus" placeholder="请选择处理结果">
+            <el-option label="未处理" :value="0"></el-option>
+            <el-option label="已处理" :value="1"></el-option>
+            <el-option label="处理中" :value="2"></el-option>
+            <el-option label="忽略" :value="3"></el-option>
+          </el-select>
+        </el-form-item>
+                 <el-form-item label="处理备注" prop="handleDesc">
+           <el-input 
+             v-model="processForm.handleDesc" 
+             type="textarea" 
+             :rows="4"
+             placeholder="请输入处理备注..."
+             maxlength="500"
+             show-word-limit
+           />
+         </el-form-item>
+         <el-form-item label="附件上传">
+           <file-upload v-model="processForm.attachments" :limit="5" />
+         </el-form-item>
+       </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitProcess" :loading="processLoading">确 定</el-button>
+        <el-button @click="cancelProcess">取 消</el-button>
+      </div>
+    </el-dialog>
+
     <!-- 添加或修改农机故障告警记录对话框 -->
     <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
       <el-form ref="form" :model="form" :rules="rules" label-width="80px">
@@ -298,7 +462,7 @@ import { listMachineAlarmRecords, getMachineAlarmRecords, delMachineAlarmRecords
 
 export default {
   name: "MachineAlarmRecords",
-  dicts: ['machine_alarm_level', 'machine_alarm_type', 'machine_handled_status'],
+  dicts: ['machine_alarm_level', 'machine_alarm_type', 'machine_handled_status', 'machine_type', 'farm_list'],
   data() {
     return {
       // 遮罩层
@@ -319,22 +483,34 @@ export default {
       title: "",
       // 是否显示弹出层
       open: false,
+      // 告警详情对话框
+      detailOpen: false,
+      // 当前记录
+      currentRecord: {},
+      // 处理告警对话框
+      processOpen: false,
+      // 处理表单
+      processForm: {},
+      // 处理规则
+      processRules: {
+        handledStatus: [{ required: true, message: '请选择处理结果', trigger: 'change' }],
+        handleDesc: [{ required: true, message: '请输入处理备注', trigger: 'blur' }],
+      },
+      // 处理按钮加载中
+      processLoading: false,
+      // 告警时间范围
+      daterangeAlarmTime: [],
       // 查询参数
       queryParams: {
         pageNum: 1,
         pageSize: 10,
         machineId: null,
-        alarmType: null,
+        machineName: null,
         alarmLevel: null,
-        alarmDesc: null,
+        machineType: null,
+        farmId: null,
         alarmTime: null,
-        locationInfo: null,
         handledStatus: null,
-        handlerId: null,
-        handlerName: null,
-        handleTime: null,
-        handleDesc: null,
-        resolvedTime: null,
       },
       // 表单参数
       form: {},
@@ -349,21 +525,118 @@ export default {
         alarmDesc: [
           { required: true, message: "报警描述不能为空", trigger: "blur" }
         ],
+      },
+      // 今日统计数据
+      todayStatistics: {
+        total: 0,
+        change: 0
+      },
+      // 各等级统计数据
+      levelStatistics: {
+        emergency: {
+          total: 0,
+          unprocessed: 0
+        },
+        warning: {
+          total: 0,
+          unprocessed: 0
+        },
+        info: {
+          total: 0,
+          unprocessed: 0
+        }
       }
     }
   },
   created() {
     this.getList()
+    this.getStatistics()
   },
   methods: {
     /** 查询农机故障告警记录列表 */
     getList() {
       this.loading = true
+      this.queryParams.params = {}
+      if (null != this.daterangeAlarmTime && '' != this.daterangeAlarmTime) {
+        this.queryParams.params["beginAlarmTime"] = this.daterangeAlarmTime[0]
+        this.queryParams.params["endAlarmTime"] = this.daterangeAlarmTime[1]
+      }
       listMachineAlarmRecords(this.queryParams).then(response => {
         this.machineAlarmRecordsList = response.rows
         this.total = response.total
         this.loading = false
+        // 获取列表后更新统计数据
+        this.updateStatisticsFromList()
+      })
+    },
+    /** 获取统计数据 */
+    getStatistics() {
+      // 这里可以调用专门的统计API
+      // 暂时使用模拟数据
+      this.todayStatistics = {
+        total: 24,
+        change: 8
+      }
+      this.levelStatistics = {
+        emergency: {
+          total: 2,
+          unprocessed: 1
+        },
+        warning: {
+          total: 3,
+          unprocessed: 2
+        },
+        info: {
+          total: 1,
+          unprocessed: 0
+        }
+      }
+    },
+    /** 从列表数据更新统计 */
+    updateStatisticsFromList() {
+      if (!this.machineAlarmRecordsList || this.machineAlarmRecordsList.length === 0) {
+        return
+      }
+      
+      // 重置统计数据
+      this.levelStatistics = {
+        emergency: { total: 0, unprocessed: 0 },
+        warning: { total: 0, unprocessed: 0 },
+        info: { total: 0, unprocessed: 0 }
+      }
+      
+      // 今日日期
+      const today = new Date().toISOString().slice(0, 10)
+      let todayCount = 0
+      
+      // 遍历记录统计
+      this.machineAlarmRecordsList.forEach(record => {
+        // 统计今日告警
+        if (record.alarmTime && record.alarmTime.includes(today)) {
+          todayCount++
+        }
+        
+        // 统计各等级告警
+        const level = record.alarmLevel
+        const isUnprocessed = record.handledStatus == 0 || record.handledStatus == '0' || record.handledStatus == 2 || record.handledStatus == '2'
+        
+        // 根据告警等级统计 (1-紧急, 2-告警, 3-提示)
+        if (level == 1 || level == '1') {
+          this.levelStatistics.emergency.total++
+          if (isUnprocessed) this.levelStatistics.emergency.unprocessed++
+        } else if (level == 2 || level == '2') {
+          this.levelStatistics.warning.total++
+          if (isUnprocessed) this.levelStatistics.warning.unprocessed++
+        } else if (level == 3 || level == '3') {
+          this.levelStatistics.info.total++
+          if (isUnprocessed) this.levelStatistics.info.unprocessed++
+        }
       })
+      
+      // 更新今日统计 (这里只是示例,实际应该从后端获取完整统计)
+      if (todayCount > 0) {
+        this.todayStatistics.total = todayCount
+      }
     },
     // 取消按钮
     cancel() {
@@ -401,6 +674,7 @@ export default {
     },
     /** 重置按钮操作 */
     resetQuery() {
+      this.daterangeAlarmTime = []
       this.resetForm("queryForm")
       this.handleQuery()
     },
@@ -461,7 +735,699 @@ export default {
       this.download('base/machineAlarmRecords/export', {
         ...this.queryParams
       }, `machineAlarmRecords_${new Date().getTime()}.xlsx`)
+    },
+    /** 根据农机ID获取农机名称 */
+    getMachineName(machineId) {
+      const machineNames = {
+        1: '约翰迪尔拖拉机',
+        2: '久保田收割机',
+        3: '雷沃旋耕机',
+        4: '东方红播种机',
+        5: '福田插秧机'
+      }
+      return machineNames[machineId] || '未知农机'
+    },
+    /** 根据农机ID获取农机类型 */
+    getMachineType(machineId) {
+      const machineTypes = {
+        1: '拖拉机',
+        2: '收割机',
+        3: '旋耕机',
+        4: '播种机',
+        5: '插秧机'
+      }
+      return machineTypes[machineId] || '未知类型'
+    },
+    /** 根据农机ID获取所属农场 */
+    getFarmName(machineId) {
+      const farmNames = {
+        1: '绿野农场',
+        2: '丰收农场',
+        3: '田园农场',
+        4: '生态农场',
+        5: '科技农场'
+      }
+      return farmNames[machineId] || '未知农场'
+    },
+    /** 获取处理状态文本 */
+    getProcessStatusText(status) {
+      const statusMap = {
+        '0': '未处理',
+        '1': '已处理',
+        '2': '处理中',
+        '3': '忽略',
+        0: '未处理',
+        1: '已处理',
+        2: '处理中',
+        3: '忽略'
+      }
+      return statusMap[status] || '未知状态'
+    },
+    /** 获取处理状态样式类 */
+    getProcessStatusClass(status) {
+      const statusMap = {
+        '0': 'pending',
+        '1': 'processed',
+        '2': 'processing',
+        '3': 'ignored',
+        0: 'pending',
+        1: 'processed',
+        2: 'processing',
+        3: 'ignored'
+      }
+      return statusMap[status] || 'pending'
+    },
+    /** 获取告警等级样式类 */
+    getAlertLevelClass(level) {
+      const levelMap = {
+        '1': 'emergency',
+        '2': 'warning', 
+        '3': 'info',
+        1: 'emergency',
+        2: 'warning',
+        3: 'info'
+      }
+      return levelMap[level] || 'info'
+    },
+    /** 获取告警等级文本 */
+    getAlertLevelText(level) {
+      const levelMap = {
+        '1': '紧急',
+        '2': '告警',
+        '3': '提示',
+        1: '紧急',
+        2: '告警', 
+        3: '提示'
+      }
+      return levelMap[level] || '未知'
+    },
+    /** 查看告警详情 */
+    handleDetail(record) {
+      // 可以根据需要调用API获取更详细的信息
+      // getMachineAlarmRecords(record.id).then(response => {
+      //   this.currentRecord = response.data
+      //   this.detailOpen = true
+      // })
+      
+      // 当前直接使用列表数据显示
+      this.currentRecord = { ...record }
+      this.detailOpen = true
+    },
+    /** 获取告警内容 */
+    getAlertContent(record) {
+      if (!record.alarmDesc) {
+        return '暂无告警内容'
+      }
+      
+      let content = record.alarmDesc
+      
+      // 尝试去掉设备名称前缀
+      // 匹配模式:设备XXX + 告警内容
+      const devicePatterns = [
+        // 匹配"设备D1001温度异常"格式
+        /^设备[A-Za-z0-9]+(.+)$/,
+        // 匹配"D1001温度异常"格式  
+        /^[A-Za-z0-9]+(.+)$/,
+        // 匹配设备名称开头的格式
+        /^.+?号(.+)$/,
+        /^.+?站(.+)$/
+      ]
+      
+      // 如果告警内容包含设备信息,尝试去掉设备前缀
+      if (record.machineId && content.includes(record.machineId)) {
+        // 去掉设备编号前缀
+        content = content.replace(new RegExp(`^.*?${record.machineId}`, ''), '')
+      } else {
+        // 使用通用模式尝试去掉设备前缀
+        for (let pattern of devicePatterns) {
+          const match = content.match(pattern)
+          if (match && match[1]) {
+            content = match[1]
+            break
+          }
+        }
+      }
+      
+      // 清理开头的标点符号
+      content = content.replace(/^[::,,\s]+/, '')
+      
+      return content || record.alarmDesc
+    },
+    /** 处理告警 */
+    handleProcess(record) {
+      this.resetProcessForm()
+      this.currentRecord = { ...record }
+             this.processForm = {
+         id: record.id,
+         machineId: record.machineId,
+         alarmType: record.alarmType,
+         alarmLevel: record.alarmLevel,
+         alarmDesc: record.alarmDesc,
+         alarmTime: record.alarmTime,
+         locationInfo: record.locationInfo,
+         handledStatus: 0, // 默认设为未处理,用户可以修改
+         handleDesc: '',
+         handlerName: '',
+         attachments: ''
+       }
+      this.processOpen = true
+    },
+    /** 提交处理 */
+    submitProcess() {
+      this.$refs.processForm.validate((valid) => {
+        if (valid) {
+          this.processLoading = true
+          
+                     // 准备要更新的数据
+           const updateData = {
+             id: this.processForm.id,
+             handledStatus: this.processForm.handledStatus,
+             handleDesc: this.processForm.handleDesc,
+             handlerName: this.processForm.handlerName || '当前用户',
+             attachments: this.processForm.attachments
+           }
+          
+          updateMachineAlarmRecords(updateData).then(response => {
+            this.$modal.msgSuccess("处理成功")
+            this.processOpen = false
+            this.processLoading = false
+            this.resetProcessForm()
+            // 刷新列表
+            this.getList()
+          }).catch(() => {
+            this.processLoading = false
+          })
+        }
+      })
+    },
+    /** 取消处理 */
+    cancelProcess() {
+      this.processOpen = false
+      this.resetProcessForm()
+    },
+    /** 重置处理表单 */
+    resetProcessForm() {
+             this.processForm = {
+         id: null,
+         machineId: null,
+         alarmType: null,
+         alarmLevel: null,
+         alarmDesc: null,
+         alarmTime: null,
+         locationInfo: null,
+         handledStatus: 0,
+         handleDesc: null,
+         handlerName: null,
+         attachments: null
+       }
+      if (this.$refs.processForm) {
+        this.$refs.processForm.resetFields()
+      }
+    },
+    /** 获取附件列表 */
+    getAttachmentList(attachments) {
+      if (!attachments) return []
+      // 如果attachments是字符串,尝试解析为JSON
+      if (typeof attachments === 'string') {
+        try {
+          return JSON.parse(attachments)
+        } catch (e) {
+          // 如果解析失败,按逗号分割处理
+          return attachments.split(',').map(url => ({
+            name: this.getFileNameFromUrl(url),
+            url: url,
+            size: 0
+          }))
+        }
+      }
+      // 如果是数组直接返回
+      return Array.isArray(attachments) ? attachments : []
+    },
+    /** 从URL中提取文件名 */
+    getFileNameFromUrl(url) {
+      if (!url) return '未知文件'
+      const parts = url.split('/')
+      return parts[parts.length - 1] || '未知文件'
+    },
+    /** 判断是否为图片 */
+    isImage(fileName) {
+      if (!fileName) return false
+      const imageExts = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp']
+      const ext = fileName.toLowerCase().substring(fileName.lastIndexOf('.'))
+      return imageExts.includes(ext)
+    },
+    /** 格式化文件大小 */
+    formatFileSize(size) {
+      if (!size || size === 0) return '未知大小'
+      if (size < 1024) return size + ' B'
+      if (size < 1024 * 1024) return (size / 1024).toFixed(1) + ' KB'
+      return (size / (1024 * 1024)).toFixed(1) + ' MB'
+    },
+    /** 下载附件 */
+    downloadAttachment(attachment) {
+      if (attachment.url) {
+        window.open(attachment.url, '_blank')
+      } else {
+        this.$modal.msgError('附件链接无效')
+      }
+    },
+    /** 预览图片 */
+    previewImage(attachment) {
+      if (attachment.url) {
+        this.$modal.msgInfo('图片预览功能暂未实现,请点击下载查看')
+        // 这里可以集成图片预览组件
+        // this.$imagePreview([attachment.url])
+      }
     }
   }
 }
 </script>
+
+<style scoped>
+/* 自定义标签样式 */
+.custom-tag {
+  display: inline-block;
+  padding: 4px 12px;
+  border-radius: 12px;
+  font-size: 12px;
+  font-weight: 500;
+  text-align: center;
+  min-width: 50px;
+  line-height: 1.2;
+}
+
+/* 告警等级标签 */
+.level-tag.emergency {
+  background-color: #fef2f2;
+  color: #dc2626;
+  border: 1px solid #fecaca;
+}
+
+.level-tag.warning {
+  background-color: #fffbeb;
+  color: #d97706;
+  border: 1px solid #fed7aa;
+}
+
+.level-tag.info {
+  background-color: #eff6ff;
+  color: #2563eb;
+  border: 1px solid #bfdbfe;
+}
+
+/* 处理状态标签 */
+.status-tag.pending {
+  background-color: #fef2f2;
+  color: #dc2626;
+  border: 1px solid #fecaca;
+}
+
+.status-tag.processing {
+  background-color: #fffbeb;
+  color: #d97706;
+  border: 1px solid #fed7aa;
+}
+
+.status-tag.processed {
+  background-color: #f0fdf4;
+  color: #16a34a;
+  border: 1px solid #bbf7d0;
+}
+
+.status-tag.ignored {
+  background-color: #f9fafb;
+  color: #6b7280;
+  border: 1px solid #d1d5db;
+}
+
+/* 统计面板样式 */
+.statistics-panel {
+  margin-bottom: 16px;
+  padding: 20px;
+  background: #fff;
+  border-radius: 12px;
+  box-shadow: 0 1px 3px rgba(0,0,0,0.08);
+}
+
+/* 统一各部分间距 */
+.app-container .el-form {
+  margin-bottom: 16px;
+}
+
+.app-container .mb8 {
+  margin-bottom: 16px !important;
+}
+
+.app-container .el-table {
+  margin-top: 0;
+}
+
+.stat-card {
+  border-radius: 12px;
+  padding: 20px;
+  height: 140px;
+  display: flex;
+  flex-direction: column;
+  justify-content: space-between;
+  transition: all 0.3s ease;
+  cursor: pointer;
+  box-shadow: 0 4px 15px rgba(0,0,0,0.1), 0 2px 6px rgba(0,0,0,0.05);
+  position: relative;
+  overflow: hidden;
+  color: #fff;
+}
+
+.stat-card:hover {
+  transform: translateY(-3px);
+  box-shadow: 0 8px 25px rgba(0,0,0,0.15), 0 4px 10px rgba(0,0,0,0.1);
+}
+
+.stat-card.total {
+  background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);
+}
+
+.stat-card.emergency {
+  background: linear-gradient(135deg, #ef4444 0%, #f97316 100%);
+}
+
+.stat-card.warning {
+  background: linear-gradient(135deg, #f59e0b 0%, #eab308 100%);
+}
+
+.stat-card.info {
+  background: linear-gradient(135deg, #06b6d4 0%, #3b82f6 100%);
+}
+
+.stat-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 10px;
+}
+
+.stat-title {
+  font-size: 14px;
+  font-weight: 600;
+  color: rgba(255, 255, 255, 0.9);
+  margin-bottom: 0;
+  line-height: 1.2;
+}
+
+.stat-content {
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: flex-start;
+}
+
+.stat-number {
+  font-size: 36px;
+  font-weight: 700;
+  line-height: 1.0;
+  margin: 8px 0;
+  color: #fff;
+}
+
+.stat-change {
+  font-size: 12px;
+  font-weight: 500;
+  color: rgba(255, 255, 255, 0.8);
+  line-height: 1.2;
+  margin: 0;
+}
+
+.stat-change.increase {
+  color: rgba(255, 255, 255, 0.9);
+}
+
+.stat-change.decrease {
+  color: rgba(255, 255, 255, 0.9);
+}
+
+.stat-detail {
+  font-size: 12px;
+  font-weight: 500;
+  color: rgba(255, 255, 255, 0.85);
+  line-height: 1.2;
+  margin: 0;
+}
+
+/* 告警详情对话框样式 */
+.alert-detail {
+  padding: 10px;
+}
+
+.alert-card {
+  background-color: #f8f9fa;
+  border-radius: 8px;
+  padding: 20px;
+  margin-bottom: 20px;
+  border: 1px solid #e9ecef;
+  box-shadow: 0 2px 4px rgba(0,0,0,0.05);
+  border-left: 4px solid #f56c6c;
+}
+
+.alert-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 15px;
+  padding-bottom: 12px;
+  border-bottom: 1px solid #e9ecef;
+}
+
+.alert-level-tag {
+  font-weight: bold;
+}
+
+.alert-time {
+  color: #909399;
+  font-size: 14px;
+}
+
+.alert-content {
+  color: #606266;
+  line-height: 1.6;
+  font-size: 14px;
+}
+
+.section {
+  margin-bottom: 20px;
+}
+
+.section-title {
+  font-size: 16px;
+  font-weight: bold;
+  color: #303133;
+  margin-bottom: 15px;
+  padding-bottom: 8px;
+  border-bottom: 1px solid #ebeef5;
+}
+
+.device-info .info-grid {
+  display: grid;
+  grid-template-columns: 1fr 1fr;
+  gap: 15px;
+}
+
+.info-item {
+  display: flex;
+  flex-direction: column;
+}
+
+.info-item .label {
+  color: #909399;
+  font-size: 14px;
+  margin-bottom: 5px;
+}
+
+.info-item .value {
+  color: #303133;
+  font-weight: 500;
+  font-size: 15px;
+}
+
+.status-info {
+  display: grid;
+  grid-template-columns: 1fr 1fr;
+  gap: 15px;
+}
+
+.status-item {
+  display: flex;
+  align-items: center;
+  gap: 10px;
+}
+
+.status-item.full-width {
+  grid-column: 1 / -1;
+  flex-direction: column;
+  align-items: flex-start;
+  gap: 8px;
+}
+
+.status-item .label {
+  color: #606266;
+  font-size: 14px;
+  font-weight: 500;
+  min-width: 80px;
+  flex-shrink: 0;
+}
+
+.status-item .value {
+  color: #303133;
+  font-weight: 600;
+  flex: 1;
+}
+
+.status-item .value.status {
+  display: flex;
+  align-items: center;
+}
+
+.process-record {
+  color: #606266;
+  font-size: 14px;
+  padding: 12px;
+  background-color: #f8f9fa;
+  border-radius: 4px;
+  border: 1px solid #e9ecef;
+  width: 100%;
+  min-height: 50px;
+  display: flex;
+  align-items: center;
+}
+
+.dialog-footer {
+  text-align: right;
+}
+
+.process-alert-info {
+  background-color: #f8f9fa;
+  border-radius: 4px;
+  padding: 15px;
+  margin-bottom: 10px;
+  border: 1px solid #e9ecef;
+}
+
+.process-alert-info .info-item {
+  display: inline-block;
+  margin-right: 20px;
+  margin-bottom: 8px;
+}
+
+.process-alert-info .info-item-row {
+  display: block;
+  margin-bottom: 8px;
+}
+
+.process-alert-info .label {
+  color: #606266;
+  font-size: 14px;
+  margin-right: 5px;
+}
+
+.process-alert-info .value {
+  color: #303133;
+  font-weight: 500;
+}
+
+.alert-content-preview {
+  color: #606266;
+  font-size: 14px;
+  line-height: 1.5;
+  margin-top: 10px;
+  padding-top: 10px;
+  border-top: 1px solid #e9ecef;
+}
+
+/* 附件信息样式 */
+.attachment-info {
+  margin-top: 10px;
+}
+
+.attachment-list {
+  background-color: #f8f9fa;
+  border-radius: 4px;
+  padding: 10px;
+  border: 1px solid #e9ecef;
+}
+
+.attachment-item {
+  display: flex;
+  align-items: center;
+  padding: 8px;
+  background-color: #fff;
+  border-radius: 4px;
+  margin-bottom: 8px;
+  border: 1px solid #e9ecef;
+  transition: all 0.3s;
+}
+
+.attachment-item:hover {
+  background-color: #f5f7fa;
+  border-color: #409eff;
+}
+
+.attachment-item:last-child {
+  margin-bottom: 0;
+}
+
+.attachment-preview {
+  width: 32px;
+  height: 32px;
+  margin-right: 12px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  background-color: #f0f2f5;
+  border-radius: 4px;
+  color: #606266;
+  font-size: 16px;
+}
+
+.attachment-details {
+  flex: 1;
+  min-width: 0;
+}
+
+.attachment-name {
+  font-size: 14px;
+  font-weight: 500;
+  color: #303133;
+  margin-bottom: 4px;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+
+.attachment-size {
+  font-size: 12px;
+  color: #909399;
+}
+
+.attachment-actions {
+  margin-left: 12px;
+  flex-shrink: 0;
+}
+
+.no-attachment {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  color: #909399;
+  font-size: 14px;
+  padding: 40px 20px;
+  background-color: #f8f9fa;
+  border-radius: 4px;
+  border: 1px dashed #e9ecef;
+}
+
+.no-attachment i {
+  font-size: 32px;
+  margin-bottom: 8px;
+  color: #c0c4cc;
+}
+</style>

+ 748 - 141
src/views/base/machineWorkRecords/index.vue

@@ -1,34 +1,64 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
-      <el-form-item label="农机ID" prop="machineId">
+    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="80px">
+      <el-form-item label="农机编号" prop="machineCode">
         <el-input
-          v-model="queryParams.machineId"
-          placeholder="请输入农机ID"
+          v-model="queryParams.machineCode"
+          placeholder="请输入农机编号"
           clearable
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
-      <el-form-item label="作业地块ID" prop="fieldId">
+      <el-form-item label="农机名称" prop="machineName">
         <el-input
-          v-model="queryParams.fieldId"
-          placeholder="请输入作业地块ID"
+          v-model="queryParams.machineName"
+          placeholder="请输入农机名称"
           clearable
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
-      <el-form-item label="任务名称" prop="taskName">
+      <el-form-item label="所属农场" prop="farmName">
+        <el-select v-model="queryParams.farmName" placeholder="请选择所属农场" clearable>
+          <el-option
+            v-for="farm in farmOptions"
+            :key="farm.value"
+            :label="farm.label"
+            :value="farm.value"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="作业地块" prop="fieldName">
+        <el-select v-model="queryParams.fieldName" placeholder="请选择作业地块" clearable>
+          <el-option
+            v-for="field in fieldOptions"
+            :key="field.value"
+            :label="field.label"
+            :value="field.value"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="作业名称" prop="taskName">
         <el-input
           v-model="queryParams.taskName"
-          placeholder="请输入任务名称"
+          placeholder="请输入作业名称"
           clearable
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
-      <el-form-item label="任务类型" prop="taskType">
-        <el-select v-model="queryParams.taskType" placeholder="请选择任务类型" clearable>
+      <el-form-item label="作业类型" prop="taskType">
+        <el-select v-model="queryParams.taskType" placeholder="请选择作业类型" clearable>
           <el-option
-            v-for="dict in dict.type.machine_work_task_type"
+            v-for="dict in taskTypeOptions"
+            :key="dict.value"
+            :label="dict.label"
+            :value="dict.value"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="作业状态" prop="status">
+        <el-select v-model="queryParams.status" placeholder="请选择作业状态" clearable>
+          <el-option
+            v-for="dict in statusOptions"
             :key="dict.value"
             :label="dict.label"
             :value="dict.value"
@@ -36,55 +66,35 @@
         </el-select>
       </el-form-item>
       <el-form-item label="开始时间" prop="startTime">
-        <el-date-picker clearable
-          v-model="queryParams.startTime"
-          type="date"
+        <el-date-picker
+          v-model="daterangeStartTime"
+          style="width: 240px"
           value-format="yyyy-MM-dd"
-          placeholder="请选择开始时间">
+          type="daterange"
+          range-separator="至"
+          start-placeholder="开始日期"
+          end-placeholder="结束日期">
         </el-date-picker>
       </el-form-item>
       <el-form-item label="结束时间" prop="endTime">
-        <el-date-picker clearable
-          v-model="queryParams.endTime"
-          type="date"
+        <el-date-picker
+          v-model="daterangeEndTime"
+          style="width: 240px"
           value-format="yyyy-MM-dd"
-          placeholder="请选择结束时间">
+          type="daterange"
+          range-separator="至"
+          start-placeholder="开始日期"
+          end-placeholder="结束日期">
         </el-date-picker>
       </el-form-item>
-      <el-form-item label="作业面积(亩)" prop="workArea">
+      <el-form-item label="操作员" prop="operatorName">
         <el-input
-          v-model="queryParams.workArea"
-          placeholder="请输入作业面积(亩)"
+          v-model="queryParams.operatorName"
+          placeholder="请输入操作员"
           clearable
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
-      <el-form-item label="油耗(升)" prop="fuelConsumption">
-        <el-input
-          v-model="queryParams.fuelConsumption"
-          placeholder="请输入油耗(升)"
-          clearable
-          @keyup.enter.native="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="操作员ID" prop="operatorId">
-        <el-input
-          v-model="queryParams.operatorId"
-          placeholder="请输入操作员ID"
-          clearable
-          @keyup.enter.native="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="记录状态" prop="status">
-        <el-select v-model="queryParams.status" placeholder="请选择记录状态" clearable>
-          <el-option
-            v-for="dict in dict.type.machine_work_status"
-            :key="dict.value"
-            :label="dict.label"
-            :value="dict.value"
-          />
-        </el-select>
-      </el-form-item>
       <el-form-item>
         <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
         <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
@@ -138,35 +148,57 @@
     </el-row>
 
     <el-table v-loading="loading" :data="machineWorkRecordsList" @selection-change="handleSelectionChange">
-      <el-table-column type="selection" width="55" align="center" />
-      <el-table-column label="工作记录ID" align="center" prop="id" />
-      <el-table-column label="农机ID" align="center" prop="machineId" />
-      <el-table-column label="作业地块ID" align="center" prop="fieldId" />
-      <el-table-column label="任务名称" align="center" prop="taskName" />
-      <el-table-column label="任务类型" align="center" prop="taskType">
+      <el-table-column type="selection" width="55" align="center" :fixed="false" />
+      <el-table-column label="作业单号" align="center" prop="workOrderId" width="200">
+        <template slot-scope="scope">
+          <span>{{ scope.row.workOrderId || '—' }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="农机编号" align="center" prop="machineCode" />
+      <el-table-column label="农机名称" align="center" prop="machineName" />
+      <el-table-column label="农机类型" align="center" prop="machineType">
+        <template slot-scope="scope">
+          <span>{{ getMachineTypeLabel(scope.row.machineType) }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="所属农场" align="center" prop="farmName" />
+      <el-table-column label="作业地块" align="center" prop="fieldName" />
+      <el-table-column label="作业名称" align="center" prop="taskName" />
+      <el-table-column label="作业类型" align="center" prop="taskType">
+        <template slot-scope="scope">
+          <span>{{ getTaskTypeLabel(scope.row.taskType) }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="作业状态" align="center" prop="status" :show-overflow-tooltip="false" width="100">
         <template slot-scope="scope">
-          <dict-tag :options="dict.type.machine_work_task_type" :value="scope.row.taskType"/>
+          <div style="overflow: visible !important; text-overflow: clip !important; white-space: nowrap !important;">
+            <span 
+              :class="['work-status-tag', getStatusClass(scope.row.status)]"
+            >{{ getStatusLabel(scope.row.status) }}</span>
+          </div>
         </template>
       </el-table-column>
       <el-table-column label="开始时间" align="center" prop="startTime" width="180">
         <template slot-scope="scope">
-          <span>{{ parseTime(scope.row.startTime, '{y}-{m}-{d}') }}</span>
+          <span>{{ parseTime(scope.row.startTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
         </template>
       </el-table-column>
       <el-table-column label="结束时间" align="center" prop="endTime" width="180">
         <template slot-scope="scope">
-          <span>{{ parseTime(scope.row.endTime, '{y}-{m}-{d}') }}</span>
+          <span>{{ parseTime(scope.row.endTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
         </template>
       </el-table-column>
+      <el-table-column label="作业时长(小时)" align="center" prop="workDuration" />
       <el-table-column label="作业面积(亩)" align="center" prop="workArea" />
       <el-table-column label="油耗(升)" align="center" prop="fuelConsumption" />
-      <el-table-column label="操作员ID" align="center" prop="operatorId" />
-      <el-table-column label="记录状态" align="center" prop="status">
+      <el-table-column label="操作员" align="center" prop="operatorName" />
+      <el-table-column label="备注" align="center" prop="remark">
         <template slot-scope="scope">
-          <dict-tag :options="dict.type.machine_work_status" :value="scope.row.status"/>
+          <el-tooltip class="item" effect="dark" :content="scope.row.remark" placement="top" :disabled="!scope.row.remark">
+            <span class="remark-text">{{ scope.row.remark }}</span>
+          </el-tooltip>
         </template>
       </el-table-column>
-      <el-table-column label="备注" align="center" prop="remark" />
       <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
         <template slot-scope="scope">
           <el-button
@@ -196,64 +228,158 @@
     />
 
     <!-- 添加或修改农机作业记录对话框 -->
-    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
-      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
-        <el-form-item label="农机ID" prop="machineId">
-          <el-input v-model="form.machineId" placeholder="请输入农机ID" />
-        </el-form-item>
-        <el-form-item label="作业地块ID" prop="fieldId">
-          <el-input v-model="form.fieldId" placeholder="请输入作业地块ID" />
-        </el-form-item>
-        <el-form-item label="任务名称" prop="taskName">
-          <el-input v-model="form.taskName" placeholder="请输入任务名称" />
-        </el-form-item>
-        <el-form-item label="任务类型" prop="taskType">
-          <el-select v-model="form.taskType" placeholder="请选择任务类型">
-            <el-option
-              v-for="dict in dict.type.machine_work_task_type"
-              :key="dict.value"
-              :label="dict.label"
-              :value="dict.value"
-            ></el-option>
-          </el-select>
-        </el-form-item>
-        <el-form-item label="开始时间" prop="startTime">
-          <el-date-picker clearable
-            v-model="form.startTime"
-            type="date"
-            value-format="yyyy-MM-dd"
-            placeholder="请选择开始时间">
-          </el-date-picker>
-        </el-form-item>
-        <el-form-item label="结束时间" prop="endTime">
-          <el-date-picker clearable
-            v-model="form.endTime"
-            type="date"
-            value-format="yyyy-MM-dd"
-            placeholder="请选择结束时间">
-          </el-date-picker>
-        </el-form-item>
-        <el-form-item label="作业面积(亩)" prop="workArea">
-          <el-input v-model="form.workArea" placeholder="请输入作业面积(亩)" />
-        </el-form-item>
-        <el-form-item label="油耗(升)" prop="fuelConsumption">
-          <el-input v-model="form.fuelConsumption" placeholder="请输入油耗(升)" />
-        </el-form-item>
-        <el-form-item label="操作员ID" prop="operatorId">
-          <el-input v-model="form.operatorId" placeholder="请输入操作员ID" />
-        </el-form-item>
-        <el-form-item label="记录状态" prop="status">
-          <el-radio-group v-model="form.status">
-            <el-radio
-              v-for="dict in dict.type.machine_work_status"
-              :key="dict.value"
-              :label="dict.value"
-            >{{dict.label}}</el-radio>
-          </el-radio-group>
-        </el-form-item>
-        <el-form-item label="备注" prop="remark">
-          <el-input v-model="form.remark" placeholder="请输入备注" />
-        </el-form-item>
+    <el-dialog :title="title" :visible.sync="open" width="800px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="100px">
+        <!-- 编辑时显示作业单号 -->
+        <el-row :gutter="20" v-if="title.indexOf('修改') !== -1">
+          <el-col :span="24">
+            <el-form-item label="作业单号" prop="workOrderId">
+              <el-input v-model="form.workOrderId" placeholder="系统自动生成" :disabled="true" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        
+        <!-- 第一步:选择所属农场(必填) -->
+        <el-row :gutter="20">
+          <el-col :span="24">
+            <el-form-item label="所属农场" prop="farmName">
+              <el-select 
+                v-model="form.farmName" 
+                placeholder="请先选择所属农场" 
+                style="width: 100%" 
+                @change="handleFarmChange">
+                <el-option
+                  v-for="farm in farmOptions"
+                  :key="farm.value"
+                  :label="farm.label"
+                  :value="farm.value"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        
+        <!-- 第二步:根据农场过滤的字段 -->
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="农机名称" prop="machineName">
+              <el-select 
+                v-model="form.machineName" 
+                placeholder="请选择农机" 
+                style="width: 100%" 
+                @change="handleMachineNameChange"
+                :disabled="!form.farmName">
+                <el-option
+                  v-for="machine in filteredMachineOptions"
+                  :key="machine.value"
+                  :label="machine.label"
+                  :value="machine.value"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="作业地块" prop="fieldName">
+              <el-select 
+                v-model="form.fieldName" 
+                placeholder="请选择作业地块" 
+                style="width: 100%"
+                :disabled="!form.farmName">
+                <el-option
+                  v-for="field in filteredFieldOptions"
+                  :key="field.value"
+                  :label="field.label"
+                  :value="field.value"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="操作员" prop="operatorName">
+              <el-select 
+                v-model="form.operatorName" 
+                placeholder="请选择操作员" 
+                filterable 
+                style="width: 100%"
+                :disabled="!form.farmName">
+                <el-option
+                  v-for="operator in filteredOperatorOptions"
+                  :key="operator.value"
+                  :label="operator.label"
+                  :value="operator.value"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="作业类型" prop="taskType">
+              <el-select v-model="form.taskType" placeholder="请选择作业类型" style="width: 100%">
+                <el-option
+                  v-for="dict in taskTypeOptions"
+                  :key="dict.value"
+                  :label="dict.label"
+                  :value="dict.value"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="作业名称" prop="taskName">
+              <el-input v-model="form.taskName" placeholder="请输入作业名称" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="作业状态" prop="status">
+              <el-select v-model="form.status" placeholder="请选择作业状态" style="width: 100%">
+                <el-option
+                  v-for="dict in statusOptions"
+                  :key="dict.value"
+                  :label="dict.label"
+                  :value="dict.value"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="开始时间" prop="startTime">
+              <el-date-picker clearable
+                v-model="form.startTime"
+                type="datetime"
+                value-format="yyyy-MM-dd HH:mm:ss"
+                placeholder="请选择开始时间"
+                style="width: 100%">
+              </el-date-picker>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="结束时间" prop="endTime">
+              <el-date-picker clearable
+                v-model="form.endTime"
+                type="datetime"
+                value-format="yyyy-MM-dd HH:mm:ss"
+                placeholder="请选择结束时间"
+                style="width: 100%">
+              </el-date-picker>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        
+        <el-row>
+          <el-col :span="24">
+            <el-form-item label="备注" prop="remark">
+              <el-input v-model="form.remark" type="textarea" :rows="3" placeholder="请输入备注信息" />
+            </el-form-item>
+          </el-col>
+        </el-row>
       </el-form>
       <div slot="footer" class="dialog-footer">
         <el-button type="primary" @click="submitForm">确 定</el-button>
@@ -268,7 +394,7 @@ import { listMachineWorkRecords, getMachineWorkRecords, delMachineWorkRecords, a
 
 export default {
   name: "MachineWorkRecords",
-  dicts: ['machine_work_task_type', 'machine_work_status'],
+  dicts: ['machine_work_task_type', 'machine_work_status', 'agricultural_machine_type'],
   data() {
     return {
       // 遮罩层
@@ -289,46 +415,287 @@ export default {
       title: "",
       // 是否显示弹出层
       open: false,
+      // 开始时间范围
+      daterangeStartTime: [],
+      // 结束时间范围
+      daterangeEndTime: [],
+      
+      // 字典数据
+      statusOptions: [
+        { value: '0', label: '待开始' },
+        { value: '1', label: '进行中' },
+        { value: '2', label: '已完成' },
+        { value: '3', label: '已取消' }
+      ],
+      taskTypeOptions: [
+        { value: '0', label: '耕地' },
+        { value: '1', label: '收割' },
+        { value: '2', label: '播种' },
+        { value: '3', label: '施肥' },
+        { value: '4', label: '灌溉' }
+      ],
+      machineTypeOptions: [
+        { value: '0', label: '拖拉机' },
+        { value: '1', label: '收割机' },
+        { value: '2', label: '播种机' },
+        { value: '3', label: '施肥机' },
+        { value: '4', label: '灌溉机' }
+      ],
+      // 农机选项列表
+      machineOptions: [],
+      // 农场选项列表
+      farmOptions: [],
+      // 地块选项列表
+      fieldOptions: [],
+      // 操作员选项列表
+      operatorOptions: [],
+      // 过滤后的选项列表
+      filteredMachineOptions: [],
+      filteredFieldOptions: [],
+      filteredOperatorOptions: [],
       // 查询参数
       queryParams: {
         pageNum: 1,
         pageSize: 10,
-        machineId: null,
-        fieldId: null,
+        machineCode: null,
+        machineName: null,
+        farmName: null,
+        fieldName: null,
         taskName: null,
         taskType: null,
-        startTime: null,
-        endTime: null,
-        workArea: null,
-        fuelConsumption: null,
-        operatorId: null,
         status: null,
+        operatorName: null
       },
       // 表单参数
       form: {},
       // 表单校验
       rules: {
-        machineId: [
-          { required: true, message: "农机ID不能为空", trigger: "blur" }
+        farmName: [
+          { required: true, message: "所属农场不能为空", trigger: "change" }
+        ],
+        machineName: [
+          { required: true, message: "农机名称不能为空", trigger: "change" }
         ],
         taskName: [
-          { required: true, message: "任务名称不能为空", trigger: "blur" }
+          { required: true, message: "作业名称不能为空", trigger: "blur" }
+        ],
+        taskType: [
+          { required: true, message: "作业类型不能为空", trigger: "change" }
+        ],
+        status: [
+          { required: true, message: "作业状态不能为空", trigger: "change" }
+        ],
+        startTime: [
+          { required: true, message: "开始时间不能为空", trigger: "change" }
         ],
+        operatorName: [
+          { required: true, message: "操作员不能为空", trigger: "change" }
+        ]
       }
     }
   },
   created() {
     this.getList()
+    this.getMachineOptions()
+    this.getFarmOptions()
+    this.getFieldOptions()
+    this.getOperatorOptions()
+
   },
   methods: {
+    /** 获取农机选项 */
+    getMachineOptions() {
+      // 模拟数据,实际应该从API获取,包含农场关联
+      this.machineOptions = [
+        { value: 'M001', label: '拖拉机A型', farmId: 'F001', machineCode: 'M001', machineType: '0' },
+        { value: 'M002', label: '收割机B型', farmId: 'F002', machineCode: 'M002', machineType: '1' },
+        { value: 'M003', label: '播种机C型', farmId: 'F003', machineCode: 'M003', machineType: '2' },
+        { value: 'M004', label: '拖拉机B型', farmId: 'F001', machineCode: 'M004', machineType: '0' },
+        { value: 'M005', label: '施肥机A型', farmId: 'F002', machineCode: 'M005', machineType: '3' }
+      ]
+    },
+    /** 获取农场选项 */
+    getFarmOptions() {
+      // 模拟数据,实际应该从API获取
+      this.farmOptions = [
+        { value: 'F001', label: '东部农场' },
+        { value: 'F002', label: '西部农场' },
+        { value: 'F003', label: '南部农场' }
+      ]
+    },
+    /** 获取地块选项 */
+    getFieldOptions() {
+      // 模拟数据,实际应该从API获取,包含农场关联
+      this.fieldOptions = [
+        { value: 'FD001', label: '东部-1号地块', farmId: 'F001' },
+        { value: 'FD002', label: '东部-2号地块', farmId: 'F001' },
+        { value: 'FD003', label: '东部-3号地块', farmId: 'F001' },
+        { value: 'FD004', label: '西部-1号地块', farmId: 'F002' },
+        { value: 'FD005', label: '西部-2号地块', farmId: 'F002' },
+        { value: 'FD006', label: '南部-1号地块', farmId: 'F003' },
+        { value: 'FD007', label: '南部-2号地块', farmId: 'F003' }
+      ]
+    },
+    /** 获取操作员选项 */
+    getOperatorOptions() {
+      // 模拟数据,实际应该从API获取,包含农场关联
+      this.operatorOptions = [
+        { value: 'OP001', label: '张三', farmId: 'F001' },
+        { value: 'OP002', label: '李四', farmId: 'F002' },
+        { value: 'OP003', label: '王五', farmId: 'F003' },
+        { value: 'OP004', label: '赵六', farmId: 'F001' },
+        { value: 'OP005', label: '钱七', farmId: 'F002' }
+      ]
+    },
     /** 查询农机作业记录列表 */
     getList() {
       this.loading = true
+      this.queryParams.params = {}
+      if (null != this.daterangeStartTime && '' != this.daterangeStartTime) {
+        this.queryParams.params["beginStartTime"] = this.daterangeStartTime[0]
+        this.queryParams.params["endStartTime"] = this.daterangeStartTime[1]
+      }
+      if (null != this.daterangeEndTime && '' != this.daterangeEndTime) {
+        this.queryParams.params["beginEndTime"] = this.daterangeEndTime[0]
+        this.queryParams.params["endEndTime"] = this.daterangeEndTime[1]
+      }
+      
+      // 直接使用示例数据,确保作业单号正确显示
+      this.addExampleData()
+      this.loading = false
+      
+      // 暂时注释掉API调用,因为返回的数据格式可能不符合预期
+      /*
       listMachineWorkRecords(this.queryParams).then(response => {
-        this.machineWorkRecordsList = response.rows
+        // 如果返回的数据中没有作业单号,则为每条记录生成一个
+        this.machineWorkRecordsList = response.rows.map(item => {
+          if (!item.id || item.id === 'null' || item.id === '') {
+            item.id = this.generateWorkOrderId()
+          }
+          return item
+        })
         this.total = response.total
         this.loading = false
+        
+        // 如果没有数据,添加一些示例数据用于展示
+        if (this.machineWorkRecordsList.length === 0 && this.queryParams.pageNum === 1) {
+          this.addExampleData()
+        }
+      }).catch(error => {
+        // 如果API调用失败,使用示例数据
+        console.warn('API调用失败,使用示例数据:', error)
+        this.addExampleData()
+        this.loading = false
       })
+      */
+    },
+    
+    /** 添加示例数据 */
+    addExampleData() {
+      const now = new Date()
+      const yesterday = new Date(now)
+      yesterday.setDate(yesterday.getDate() - 1)
+      
+      // 生成固定的示例作业单号
+      const exampleWorkOrderId1 = 'Z20250723154530001'
+      const exampleWorkOrderId2 = 'Z20250723160015002'
+      const exampleWorkOrderId3 = 'Z20250724080000003'
+      
+      const exampleData = [
+        {
+          id: 1, // 数字类型主键
+          workOrderId: exampleWorkOrderId1, // 作业单号
+          machineCode: 'M001',
+          machineName: 'M001', // 对应农机选项的value
+          machineType: '0', // 拖拉机
+          farmName: 'F001', // 对应农场选项的value
+          fieldName: 'FD001', // 对应地块选项的value
+          taskName: '春季耕地',
+          taskType: '0', // 耕地
+          status: '2', // 已完成
+          startTime: this.formatDateTime(yesterday, 8, 30),
+          endTime: this.formatDateTime(yesterday, 11, 45),
+          workDuration: 3.25,
+          workArea: 15.5,
+          fuelConsumption: 25.8,
+          operatorName: 'OP001', // 对应操作员选项的value
+          remark: '土壤湿度适宜,作业顺利完成'
+        },
+        {
+          id: 2, // 数字类型主键
+          workOrderId: exampleWorkOrderId2, // 作业单号
+          machineCode: 'M002',
+          machineName: 'M002', // 对应农机选项的value
+          machineType: '1', // 收割机
+          farmName: 'F002', // 对应农场选项的value
+          fieldName: 'FD004', // 对应地块选项的value
+          taskName: '小麦收割',
+          taskType: '1', // 收割
+          status: '1', // 进行中
+          startTime: this.formatDateTime(now, 9, 15),
+          endTime: null,
+          workDuration: 2.5,
+          workArea: 10.2,
+          fuelConsumption: 18.5,
+          operatorName: 'OP002', // 对应操作员选项的value
+          remark: '小麦成熟度良好,预计今日完成收割'
+        },
+        {
+          id: 3, // 数字类型主键
+          workOrderId: exampleWorkOrderId3, // 作业单号
+          machineCode: 'M003',
+          machineName: 'M003', // 对应农机选项的value
+          machineType: '2', // 播种机
+          farmName: 'F003', // 对应农场选项的value
+          fieldName: 'FD006', // 对应地块选项的value
+          taskName: '玉米播种',
+          taskType: '2', // 播种
+          status: '0', // 待开始
+          startTime: this.formatDateTime(new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1), 8, 0),
+          endTime: null,
+          workDuration: 0,
+          workArea: 20,
+          fuelConsumption: 0,
+          operatorName: 'OP003', // 对应操作员选项的value
+          remark: '计划明日开始播种作业'
+        }
+      ]
+      
+      this.machineWorkRecordsList = exampleData
+      this.total = exampleData.length
+    },
+    
+    /** 格式化日期时间 */
+    formatDateTime(date, hour, minute) {
+      const year = date.getFullYear()
+      const month = String(date.getMonth() + 1).padStart(2, '0')
+      const day = String(date.getDate()).padStart(2, '0')
+      const hours = String(hour || 0).padStart(2, '0')
+      const minutes = String(minute || 0).padStart(2, '0')
+      
+      return `${year}-${month}-${day} ${hours}:${minutes}:00`
+    },
+    
+    /** 生成作业单号 */
+    generateWorkOrderId(customDate) {
+      // 格式: ZYYYYMMDDHHMMSSNN
+      const now = customDate || new Date()
+      
+      // 获取年月日
+      const year = now.getFullYear()
+      const month = String(now.getMonth() + 1).padStart(2, '0')
+      const day = String(now.getDate()).padStart(2, '0')
+      
+      // 获取时分秒
+      const hours = String(now.getHours()).padStart(2, '0')
+      const minutes = String(now.getMinutes()).padStart(2, '0')
+      const seconds = String(now.getSeconds()).padStart(2, '0')
+      
+      // 生成3位随机序号,避免同一秒内重复
+      const randomNum = String(Math.floor(Math.random() * 1000)).padStart(3, '0')
+      
+      // 组合成最终的作业单号,确保格式为 ZYYYYMMDDHHMMSSNN
+      return `Z${year}${month}${day}${hours}${minutes}${seconds}${randomNum}`
     },
     // 取消按钮
     cancel() {
@@ -339,22 +706,28 @@ export default {
     reset() {
       this.form = {
         id: null,
-        machineId: null,
-        fieldId: null,
+        workOrderId: null,
+        machineCode: null,
+        machineName: null,
+        machineType: null,
+        farmName: null,
+        fieldName: null,
         taskName: null,
         taskType: null,
         startTime: null,
         endTime: null,
-        workArea: null,
-        fuelConsumption: null,
-        operatorId: null,
-        status: null,
+        operatorName: null,
+        status: '0', // 默认待开始
         createBy: null,
         createTime: null,
         updateBy: null,
         updateTime: null,
         remark: null
       }
+      // 清空过滤选项
+      this.filteredMachineOptions = []
+      this.filteredFieldOptions = []
+      this.filteredOperatorOptions = []
       this.resetForm("form")
     },
     /** 搜索按钮操作 */
@@ -364,6 +737,8 @@ export default {
     },
     /** 重置按钮操作 */
     resetQuery() {
+      this.daterangeStartTime = []
+      this.daterangeEndTime = []
       this.resetForm("queryForm")
       this.handleQuery()
     },
@@ -376,43 +751,99 @@ export default {
     /** 新增按钮操作 */
     handleAdd() {
       this.reset()
+      // 生成作业单号
+      this.form.workOrderId = this.generateWorkOrderId()
       this.open = true
       this.title = "添加农机作业记录"
     },
+    
     /** 修改按钮操作 */
     handleUpdate(row) {
       this.reset()
+      
+      // 直接使用行数据进行回显(因为目前使用模拟数据)
+      this.form = { ...row }
+      
+      // 确保所有字段都正确回显
+      this.form.workOrderId = row.workOrderId || row.id
+      this.form.machineCode = row.machineCode
+      this.form.machineName = row.machineName  
+      this.form.machineType = row.machineType
+      this.form.farmName = row.farmName
+      this.form.fieldName = row.fieldName
+      this.form.taskName = row.taskName
+      this.form.taskType = row.taskType
+      this.form.status = row.status
+      this.form.startTime = row.startTime
+      this.form.endTime = row.endTime
+      this.form.operatorName = row.operatorName
+      this.form.remark = row.remark
+      
+      // 编辑时根据农场初始化过滤选项(传递初始化标志,保持原有值)
+      if (this.form.farmName) {
+        this.handleFarmChange(this.form.farmName, true)
+      }
+      
+      this.open = true
+      this.title = "修改农机作业记录"
+      
+      // 如果将来需要使用API,可以使用以下代码
+      /*
       const id = row.id || this.ids
       getMachineWorkRecords(id).then(response => {
         this.form = response.data
+        // 确保保留原始作业单号
+        if (!this.form.workOrderId) {
+          this.form.workOrderId = row.workOrderId
+        }
+        // 编辑时根据农场初始化过滤选项
+        if (this.form.farmName) {
+          this.handleFarmChange(this.form.farmName)
+        }
         this.open = true
         this.title = "修改农机作业记录"
+      }).catch(error => {
+        console.warn('API调用失败,使用当前行数据:', error)
+        // 回退到使用行数据的逻辑
       })
+      */
     },
     /** 提交按钮 */
     submitForm() {
       this.$refs["form"].validate(valid => {
         if (valid) {
-          if (this.form.id != null) {
+          // 确保有作业单号,无论是新增还是修改
+          if (!this.form.workOrderId || this.form.workOrderId === 'null' || this.form.workOrderId === '') {
+            this.form.workOrderId = this.generateWorkOrderId()
+          }
+          
+          if (this.title.indexOf("修改") !== -1) {
             updateMachineWorkRecords(this.form).then(response => {
               this.$modal.msgSuccess("修改成功")
               this.open = false
               this.getList()
+            }).catch(error => {
+              this.$modal.msgError("修改失败: " + (error.message || '未知错误'))
             })
           } else {
             addMachineWorkRecords(this.form).then(response => {
               this.$modal.msgSuccess("新增成功")
               this.open = false
               this.getList()
+            }).catch(error => {
+              this.$modal.msgError("新增失败: " + (error.message || '未知错误'))
             })
           }
         }
       })
     },
+    
+
     /** 删除按钮操作 */
     handleDelete(row) {
       const ids = row.id || this.ids
-      this.$modal.confirm('是否确认删除农机作业记录编号为"' + ids + '"的数据项?').then(function() {
+      const workOrderId = row.workOrderId || '未知'
+      this.$modal.confirm('是否确认删除作业单号为"' + workOrderId + '"的数据项?').then(function() {
         return delMachineWorkRecords(ids)
       }).then(() => {
         this.getList()
@@ -424,7 +855,183 @@ export default {
       this.download('base/machineWorkRecords/export', {
         ...this.queryParams
       }, `machineWorkRecords_${new Date().getTime()}.xlsx`)
-    }
+    },
+    // 获取状态标签的类名
+    getStatusClass(status) {
+      const statusMap = {
+        '0': 'pending',     // 待开始(灰)
+        '1': 'in-progress', // 进行中(蓝)
+        '2': 'completed',   // 已完成(绿)
+        '3': 'cancelled'    // 已取消(红)
+      }
+      return statusMap[status] || ''
+    },
+    // 获取农机类型标签
+    getMachineTypeLabel(value) {
+      const dict = this.machineTypeOptions.find(item => item.value === value)
+      return dict ? dict.label : value
+    },
+    // 获取作业类型标签
+    getTaskTypeLabel(value) {
+      const dict = this.taskTypeOptions.find(item => item.value === value)
+      return dict ? dict.label : value
+    },
+    // 获取作业状态标签
+    getStatusLabel(value) {
+      const dict = this.statusOptions.find(item => item.value === value)
+      return dict ? dict.label : value
+    },
+    /** 农场变更处理 */
+    handleFarmChange(farmValue, isInitialLoad = false) {
+      if (farmValue) {
+        // 根据选择的农场过滤相关选项
+        this.filteredMachineOptions = this.machineOptions.filter(machine => machine.farmId === farmValue)
+        this.filteredFieldOptions = this.fieldOptions.filter(field => field.farmId === farmValue)
+        this.filteredOperatorOptions = this.operatorOptions.filter(operator => operator.farmId === farmValue)
+        
+        // 只有在用户主动变更农场时才清空依赖字段,初始化加载时不清空
+        if (!isInitialLoad) {
+          this.form.machineName = null
+          this.form.fieldName = null
+          this.form.operatorName = null
+        }
+      } else {
+        // 清空过滤选项
+        this.filteredMachineOptions = []
+        this.filteredFieldOptions = []
+        this.filteredOperatorOptions = []
+        
+        // 清空依赖字段
+        this.form.machineName = null
+        this.form.fieldName = null
+        this.form.operatorName = null
+      }
+    },
+    
+    /** 农机名称变更处理 */
+    handleMachineNameChange(machineValue) {
+      const selectedMachine = this.machineOptions.find(m => m.value === machineValue)
+      if (selectedMachine) {
+        // 自动填充农机编号和类型(编辑时使用)
+        this.form.machineCode = selectedMachine.machineCode
+        this.form.machineType = selectedMachine.machineType
+      }
+    },
+
+    
+
+
   }
 }
 </script>
+
+<style scoped>
+
+
+
+/* 作业状态标签样式 */
+.work-status-tag {
+  display: inline-block !important;
+  padding: 4px 12px !important;
+  border-radius: 12px !important;
+  font-size: 12px !important;
+  font-weight: 500 !important;
+  text-align: center !important;
+  min-width: 60px !important;
+  line-height: 1.2 !important;
+  white-space: nowrap !important;
+  border: 1px solid !important;
+  overflow: visible !important;
+  text-overflow: clip !important;
+}
+
+/* 确保表格单元格不显示省略号 */
+.el-table td .cell {
+  overflow: visible !important;
+  text-overflow: clip !important;
+}
+
+/* 专门针对作业状态列的单元格样式 */
+.el-table .el-table__body-wrapper .el-table__body td .cell {
+  overflow: visible !important;
+  text-overflow: clip !important;
+  white-space: nowrap !important;
+}
+
+/* 更强的选择器覆盖Element UI默认样式 */
+.el-table__body tr td .cell {
+  overflow: visible !important;
+  text-overflow: clip !important;
+}
+
+/* 全局移除表格省略号,使用最高优先级 */
+.el-table .cell {
+  overflow: visible !important;
+  text-overflow: clip !important;
+  white-space: nowrap !important;
+}
+
+/* 专门针对包含work-status-tag的单元格 */
+.el-table .cell:has(.work-status-tag),
+.el-table td:has(.work-status-tag) .cell {
+  overflow: visible !important;
+  text-overflow: clip !important;
+  white-space: nowrap !important;
+}
+
+/* 待开始状态 - 灰色 */
+.work-status-tag.pending {
+  background-color: #f9fafb !important;
+  color: #6b7280 !important;
+  border-color: #d1d5db !important;
+}
+
+/* 进行中状态 - 蓝色 */
+.work-status-tag.in-progress {
+  background-color: #eff6ff !important;
+  color: #2563eb !important;
+  border-color: #bfdbfe !important;
+}
+
+/* 已完成状态 - 绿色 */
+.work-status-tag.completed {
+  background-color: #f0fdf4 !important;
+  color: #16a34a !important;
+  border-color: #bbf7d0 !important;
+}
+
+/* 已取消状态 - 红色 */
+.work-status-tag.cancelled {
+  background-color: #fef2f2 !important;
+  color: #dc2626 !important;
+  border-color: #fecaca !important;
+}
+
+/* 备注文本样式 */
+.remark-text {
+  display: inline-block;
+  max-width: 150px;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+
+/* 表单样式优化 */
+.el-form-item {
+  margin-bottom: 18px;
+}
+
+/* 表单对话框样式优化 */
+.el-dialog__body {
+  padding: 20px 25px;
+}
+
+.el-form-item__label {
+  font-weight: 500;
+  color: #606266;
+}
+
+.el-row {
+  margin-bottom: 0;
+}
+</style>

+ 17 - 1
src/views/base/machines/index.vue

@@ -174,6 +174,7 @@
           v-hasPermi="['base:machines:export']"
         >导出</el-button>
       </el-col>
+
       <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
     </el-row>
 
@@ -232,6 +233,12 @@
       <el-table-column label="报警次数" align="center" prop="alarmCount" />
       <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
         <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-view"
+            @click="handleView(scope.row)"
+          >查看</el-button>
           <el-button
             size="mini"
             type="text"
@@ -606,6 +613,14 @@ export default {
       this.open = true
       this.title = "添加农机管理列表"
     },
+    /** 查看按钮操作 */
+    handleView(row) {
+      const machineId = row.id
+      this.$router.push({
+        path: '/base/machines/monitor',
+        query: { id: machineId }
+      })
+    },
     /** 修改按钮操作 */
     handleUpdate(row) {
       this.reset()
@@ -651,7 +666,8 @@ export default {
       this.download('base/machines/export', {
         ...this.queryParams
       }, `machines_${new Date().getTime()}.xlsx`)
-    }
+    },
+
   }
 }
 </script>

+ 4852 - 0
src/views/base/machines/machines-monitor.vue

@@ -0,0 +1,4852 @@
+<!--
+  农机监控汇总页面
+  功能:实时显示所有农机设备状态、位置分布、作业统计等
+-->
+<template>
+  <div class="machines-monitor-container">
+
+
+    <!-- 控制面板 -->
+    <div class="control-panel">
+      <div class="control-left">
+        <div class="form-group">
+          <label>设备类型</label>
+          <select v-model="filters.machineType" @change="applyFilters">
+            <option value="">全部类型</option>
+            <option value="tractor">拖拉机</option>
+            <option value="harvester">收割机</option>
+            <option value="seeder">播种机</option>
+            <option value="sprayer">喷药机</option>
+            <option value="cultivator">耕地机</option>
+                    </select>
+        </div>
+                <div class="form-group">
+          <label>农场选择</label>
+          <select v-model="filters.farmId" @change="applyFilters">
+            <option value="">全部农场</option>
+            <option v-for="farm in farmList" :key="farm.id" :value="farm.id">{{ farm.name }}</option>
+          </select>
+        </div>
+        <div class="form-group">
+          <label>时间范围</label>
+          <select v-model="timeRange" @change="onTimeRangeChange">
+            <option value="realtime">实时数据</option>
+            <option value="1h">近1小时</option>
+            <option value="24h">近24小时</option>
+          </select>
+        </div>
+      </div>
+      <div class="control-right">
+        <button class="refresh-btn" @click="refreshData">
+          <i class="el-icon-refresh"></i>
+          刷新数据
+        </button>
+        <div class="auto-refresh">
+          <span>自动刷新:</span>
+          <select v-model="settings.refreshInterval" class="auto-refresh-select" @change="restartAutoRefresh">
+            <option value="30">30秒</option>
+            <option value="60">1分钟</option>
+            <option value="120">2分钟</option>
+            <option value="300">5分钟</option>
+          </select>
+        </div>
+        <div class="last-update">
+          最后更新:<span>刚刚</span>
+        </div>
+      </div>
+    </div>
+
+    <!-- 统计信息卡片 -->
+    <el-row :gutter="20" class="stats-row">
+      <el-col :span="6">
+        <el-card class="stat-card total" shadow="hover">
+          <div class="stat-content">
+            <div class="stat-label">农机总数</div>
+            <div class="stat-value">{{ statistics.total }}</div>
+            <div class="stat-trend">
+              <i class="el-icon-info"></i>
+              <span>系统注册设备</span>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="6">
+        <el-card class="stat-card online" shadow="hover">
+          <div class="stat-content">
+            <div class="stat-label">在线设备</div>
+            <div class="stat-value">{{ statistics.online }}</div>
+            <div class="stat-trend">
+              <i class="el-icon-top" style="color: #67C23A;"></i>
+              <span>在线率 {{ onlineRate }}%</span>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="6">
+        <el-card class="stat-card working" shadow="hover">
+          <div class="stat-content">
+            <div class="stat-label">作业中</div>
+            <div class="stat-value">{{ statistics.working }}</div>
+            <div class="stat-trend">
+              <i class="el-icon-video-play"></i>
+              <span>正在执行任务</span>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="6">
+        <el-card class="stat-card warning" shadow="hover">
+          <div class="stat-content">
+            <div class="stat-label">告警设备</div>
+            <div class="stat-value">{{ statistics.warning }}</div>
+            <div class="stat-trend">
+              <i class="el-icon-warning" style="color: #F56C6C;"></i>
+              <span>需要关注</span>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
+
+    <!-- 保养统计信息卡片 -->
+    <el-row :gutter="20" class="stats-row">
+      <el-col :span="6">
+        <el-card class="stat-card maintenance-due" shadow="hover">
+          <div class="stat-content">
+            <div class="stat-label">待保养设备</div>
+            <div class="stat-value">{{ maintenanceStats.due }}</div>
+            <div class="stat-trend">
+              <i class="el-icon-time" style="color: #E6A23C;"></i>
+              <span>本周到期</span>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="6">
+        <el-card class="stat-card maintenance-progress" shadow="hover">
+          <div class="stat-content">
+            <div class="stat-label">保养进行中</div>
+            <div class="stat-value">{{ maintenanceStats.inProgress }}</div>
+            <div class="stat-trend">
+              <i class="el-icon-setting" style="color: #409EFF;"></i>
+              <span>正在维护</span>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="6">
+        <el-card class="stat-card maintenance-overdue" shadow="hover">
+          <div class="stat-content">
+            <div class="stat-label">保养超期</div>
+            <div class="stat-value">{{ maintenanceStats.overdue }}</div>
+            <div class="stat-trend">
+              <i class="el-icon-warning" style="color: #F56C6C;"></i>
+              <span>需紧急处理</span>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="6">
+        <el-card class="stat-card maintenance-cost" shadow="hover">
+          <div class="stat-content">
+            <div class="stat-label">本月保养费用</div>
+            <div class="stat-value">¥{{ formatCurrency(maintenanceStats.monthlyCost) }}</div>
+            <div class="stat-trend">
+              <i class="el-icon-bottom" style="color: #67C23A;"></i>
+              <span>较上月 -12%</span>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
+
+    <!-- 地图区域 -->
+    <el-card class="map-card" shadow="hover">
+      <div slot="header" class="map-header">
+        <span class="map-title">农机位置分布图</span>
+        <div class="map-controls">
+          <el-button-group>
+            <el-button size="small" @click="zoomIn" icon="el-icon-zoom-in"></el-button>
+            <el-button size="small" @click="zoomOut" icon="el-icon-zoom-out"></el-button>
+            <el-button size="small" @click="centerMap" icon="el-icon-position"></el-button>
+            <el-button size="small" @click="toggleMapFullscreen" icon="el-icon-full-screen"></el-button>
+          </el-button-group>
+        </div>
+      </div>
+      
+      <div class="map-container" ref="mapContainer">
+        <div v-if="mapLoading" class="map-loading">
+          <i class="el-icon-loading"></i>
+          <div>地图加载中...</div>
+        </div>
+        
+        <!-- 高德地图容器 -->
+        <div v-else id="amap-container" ref="amapContainer" class="amap-container"></div>
+
+      </div>
+    </el-card>
+
+    <!-- 作业统计分析 -->
+    <el-card class="analysis-card" shadow="hover">
+      <div slot="header" class="analysis-header">
+        <div class="header-left">
+          <h3 class="analysis-title">农机作业统计分析</h3>
+          <p class="analysis-subtitle">数据来源:农机作业实时上报</p>
+        </div>
+        <div class="header-right">
+          <el-select v-model="analysisTimeRange" placeholder="选择时间范围" @change="updateAnalysisData">
+            <el-option label="最近7天" value="7"></el-option>
+            <el-option label="最近30天" value="30"></el-option>
+            <el-option label="最近90天" value="90"></el-option>
+          </el-select>
+          <el-dropdown @command="handleExport" style="margin-left: 12px;">
+            <el-button type="primary">
+              导出<i class="el-icon-arrow-down el-icon--right"></i>
+            </el-button>
+            <el-dropdown-menu slot="dropdown">
+              <el-dropdown-item command="image">导出图片</el-dropdown-item>
+              <el-dropdown-item command="excel">导出Excel</el-dropdown-item>
+              <el-dropdown-item command="pdf">导出PDF</el-dropdown-item>
+            </el-dropdown-menu>
+          </el-dropdown>
+        </div>
+      </div>
+
+      <!-- 核心指标卡片 -->
+      <el-row :gutter="24" class="metrics-row">
+        <el-col :span="8">
+          <div class="work-metric-card area-metric">
+            <div class="metric-header">
+              <div class="metric-icon-wrapper">
+                <i class="el-icon-crop"></i>
+              </div>
+              <div class="metric-trend-badge positive">
+                <i class="el-icon-top"></i>
+                <span>+12.5%</span>
+              </div>
+            </div>
+            <div class="metric-body">
+              <div class="metric-value">{{ workAnalysis.totalArea }} <span class="metric-unit">亩</span></div>
+              <div class="metric-label">总作业面积</div>
+              <div class="metric-desc">累计完成作业面积</div>
+            </div>
+            <div class="metric-footer">
+              <div class="progress-bar">
+                <div class="progress-fill" style="width: 85%"></div>
+              </div>
+              <span class="progress-text">完成率 85%</span>
+            </div>
+          </div>
+        </el-col>
+        <el-col :span="8">
+          <div class="work-metric-card time-metric">
+            <div class="metric-header">
+              <div class="metric-icon-wrapper">
+                <i class="el-icon-time"></i>
+              </div>
+              <div class="metric-trend-badge positive">
+                <i class="el-icon-top"></i>
+                <span>+8.3%</span>
+              </div>
+            </div>
+            <div class="metric-body">
+              <div class="metric-value">{{ workAnalysis.totalHours }} <span class="metric-unit">小时</span></div>
+              <div class="metric-label">总作业时长</div>
+              <div class="metric-desc">设备累计工作时间</div>
+            </div>
+            <div class="metric-footer">
+              <div class="progress-bar">
+                <div class="progress-fill" style="width: 72%"></div>
+              </div>
+              <span class="progress-text">利用率 72%</span>
+            </div>
+          </div>
+        </el-col>
+        <el-col :span="8">
+          <div class="work-metric-card efficiency-metric">
+            <div class="metric-header">
+              <div class="metric-icon-wrapper">
+                <i class="el-icon-lightning"></i>
+              </div>
+              <div class="metric-trend-badge positive">
+                <i class="el-icon-top"></i>
+                <span>+5.7%</span>
+              </div>
+            </div>
+            <div class="metric-body">
+              <div class="metric-value">{{ workAnalysis.avgEfficiency }} <span class="metric-unit">亩/小时</span></div>
+              <div class="metric-label">平均作业效率</div>
+              <div class="metric-desc">单位时间作业面积</div>
+            </div>
+            <div class="metric-footer">
+              <div class="progress-bar">
+                <div class="progress-fill" style="width: 92%"></div>
+              </div>
+              <span class="progress-text">效率等级 A+</span>
+            </div>
+          </div>
+        </el-col>
+      </el-row>
+
+      <!-- 图表区域 -->
+      <el-row :gutter="24" class="charts-row">
+        <el-col :span="12">
+          <div class="chart-card work-chart-card">
+            <div class="chart-header">
+              <h4 class="chart-title">农机类型作业占比</h4>
+            </div>
+            <div class="chart-content chart-flex-content">
+                                <div class="work-donut-chart-horizontal">
+                <!-- 左侧:饼图区域 -->
+                <div class="work-donut-container-side">
+                  <svg width="280" height="280" viewBox="0 0 280 280">
+                    <!-- 环形图 -->
+                    <circle cx="140" cy="140" r="85" fill="none" stroke="#E5F4E8" stroke-width="35"/>
+                    <circle cx="140" cy="140" r="85" fill="none" stroke="#3BB44A" stroke-width="35" 
+                            stroke-dasharray="267 534" stroke-dashoffset="0" transform="rotate(-90 140 140)"
+                            class="work-segment" data-type="tractor"
+                            />
+                    <circle cx="140" cy="140" r="85" fill="none" stroke="#66C574" stroke-width="35" 
+                            stroke-dasharray="160 534" stroke-dashoffset="-267" transform="rotate(-90 140 140)"
+                            class="work-segment" data-type="harvester"
+                            />
+                    <circle cx="140" cy="140" r="85" fill="none" stroke="#99D6A3" stroke-width="35" 
+                            stroke-dasharray="107 534" stroke-dashoffset="-427" transform="rotate(-90 140 140)"
+                            class="work-segment" data-type="seeder"
+                            />
+                    
+                    <!-- 中心文字 -->
+                    <text x="140" y="125" text-anchor="middle" class="work-donut-center-label">总台数</text>
+                    <text x="140" y="155" text-anchor="middle" class="work-donut-center-value">28</text>
+                  </svg>
+                </div>
+                <!-- 右侧:图例区域 -->
+                <div class="work-donut-legend-side">
+                  <div class="work-legend-item-enhanced" data-type="tractor" style="--index: 0;">
+                    <div class="work-legend-color" style="background-color: #3BB44A;"></div>
+                    <div class="work-legend-content-enhanced">
+                      <span class="work-legend-label">拖拉机</span>
+                      <span class="work-legend-value">50%</span>
+                  </div>
+                  </div>
+                  <div class="work-legend-item-enhanced" data-type="harvester" style="--index: 1;">
+                    <div class="work-legend-color" style="background-color: #66C574;"></div>
+                    <div class="work-legend-content-enhanced">
+                      <span class="work-legend-label">收割机</span>
+                      <span class="work-legend-value">30%</span>
+                    </div>
+                  </div>
+                  <div class="work-legend-item-enhanced" data-type="seeder" style="--index: 2;">
+                    <div class="work-legend-color" style="background-color: #99D6A3;"></div>
+                    <div class="work-legend-content-enhanced">
+                      <span class="work-legend-label">播种机</span>
+                      <span class="work-legend-value">20%</span>
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </div>
+        </el-col>
+        <el-col :span="12">
+          <div class="chart-card work-chart-card">
+            <div class="chart-header">
+              <h4 class="chart-title">作业变化趋势</h4>
+              <div class="chart-controls">
+                <el-radio-group v-model="trendMetric" size="small" @change="updateTrendChart">
+                  <el-radio-button label="area">面积</el-radio-button>
+                  <el-radio-button label="time">时长</el-radio-button>
+                  <el-radio-button label="efficiency">效率</el-radio-button>
+                </el-radio-group>
+              </div>
+            </div>
+            <div class="chart-content chart-flex-content">
+              <div class="work-trend-chart">
+                <div class="work-chart-area">
+                  <div class="work-chart-unit-label">单位:亩</div>
+                  <svg width="100%" height="240" viewBox="0 0 600 240">
+                    <!-- 网格线 -->
+                    <defs>
+                      <pattern id="grid" width="60" height="60" patternUnits="userSpaceOnUse">
+                        <path d="M 60 0 L 0 0 0 60" fill="none" stroke="#F0F4F1" stroke-width="1"/>
+                      </pattern>
+                      <linearGradient id="trendGradient" x1="0%" y1="0%" x2="0%" y2="100%">
+                        <stop offset="0%" style="stop-color:#3BB44A;stop-opacity:0.3"/>
+                        <stop offset="100%" style="stop-color:#3BB44A;stop-opacity:0"/>
+                      </linearGradient>
+                    </defs>
+                    <rect width="100%" height="100%" fill="url(#grid)"/>
+                    <!-- 趋势面积 -->
+                    <path d="M40,220 L100,170 L160,140 L220,110 L280,130 L340,100 L400,75 L460,60 L520,45 L580,35 L580,240 L40,240 Z" 
+                          fill="url(#trendGradient)"/>
+                    <!-- 趋势线 -->
+                    <polyline points="40,220 100,170 160,140 220,110 280,130 340,100 400,75 460,60 520,45 580,35" 
+                              fill="none" stroke="#3BB44A" stroke-width="4"/>
+                    <!-- 数据点 -->
+                    <circle cx="40" cy="220" r="6" fill="#3BB44A" class="data-point" style="--index: 0;" 
+                            @mouseenter="showDataTooltip($event, 0)" @mouseleave="hideDataTooltip"/>
+                    <circle cx="100" cy="170" r="6" fill="#3BB44A" class="data-point" style="--index: 1;" 
+                            @mouseenter="showDataTooltip($event, 1)" @mouseleave="hideDataTooltip"/>
+                    <circle cx="160" cy="140" r="6" fill="#3BB44A" class="data-point" style="--index: 2;" 
+                            @mouseenter="showDataTooltip($event, 2)" @mouseleave="hideDataTooltip"/>
+                    <circle cx="220" cy="110" r="6" fill="#3BB44A" class="data-point" style="--index: 3;" 
+                            @mouseenter="showDataTooltip($event, 3)" @mouseleave="hideDataTooltip"/>
+                    <circle cx="280" cy="130" r="6" fill="#3BB44A" class="data-point" style="--index: 4;" 
+                            @mouseenter="showDataTooltip($event, 4)" @mouseleave="hideDataTooltip"/>
+                    <circle cx="340" cy="100" r="6" fill="#3BB44A" class="data-point" style="--index: 5;" 
+                            @mouseenter="showDataTooltip($event, 5)" @mouseleave="hideDataTooltip"/>
+                    <circle cx="400" cy="75" r="6" fill="#3BB44A" class="data-point" style="--index: 6;" 
+                            @mouseenter="showDataTooltip($event, 6)" @mouseleave="hideDataTooltip"/>
+                    <circle cx="460" cy="60" r="6" fill="#3BB44A" class="data-point" style="--index: 7;" 
+                            @mouseenter="showDataTooltip($event, 7)" @mouseleave="hideDataTooltip"/>
+                    <circle cx="520" cy="45" r="6" fill="#3BB44A" class="data-point" style="--index: 8;" 
+                            @mouseenter="showDataTooltip($event, 8)" @mouseleave="hideDataTooltip"/>
+                    <circle cx="580" cy="35" r="6" fill="#3BB44A" class="data-point" style="--index: 9;" 
+                            @mouseenter="showDataTooltip($event, 9)" @mouseleave="hideDataTooltip"/>
+                    <!-- X轴标签 -->
+                    <text x="40" y="230" text-anchor="middle" class="axis-label">1/9</text>
+                    <text x="100" y="230" text-anchor="middle" class="axis-label">1/10</text>
+                    <text x="160" y="230" text-anchor="middle" class="axis-label">1/11</text>
+                    <text x="220" y="230" text-anchor="middle" class="axis-label">1/12</text>
+                    <text x="280" y="230" text-anchor="middle" class="axis-label">1/13</text>
+                    <text x="340" y="230" text-anchor="middle" class="axis-label">1/14</text>
+                    <text x="400" y="230" text-anchor="middle" class="axis-label">1/15</text>
+                    <text x="460" y="230" text-anchor="middle" class="axis-label">1/16</text>
+                    <text x="520" y="230" text-anchor="middle" class="axis-label">1/17</text>
+                    <text x="580" y="230" text-anchor="middle" class="axis-label">今日</text>
+                  </svg>
+                </div>
+              </div>
+            </div>
+            <div class="work-trend-summary">
+              <div class="work-summary-item">
+                <span class="work-summary-label">今日作业</span>
+                <span class="work-summary-value primary">{{ trendSummary.today }}</span>
+              </div>
+              <div class="work-summary-item">
+                <span class="work-summary-label">昨日作业</span>
+                <span class="work-summary-value">{{ trendSummary.yesterday }}</span>
+              </div>
+              <div class="work-summary-item">
+                <span class="work-summary-label">环比增长</span>
+                <span class="work-summary-value positive">{{ trendSummary.growth }}</span>
+              </div>
+            </div>
+          </div>
+        </el-col>
+      </el-row>
+    </el-card>
+
+    <!-- 保养统计分析 -->
+    <el-card class="analysis-card" shadow="hover">
+      <div slot="header" class="analysis-header">
+        <div class="header-left">
+          <h3 class="analysis-title">保养统计分析</h3>
+          <p class="analysis-subtitle">设备维护状况监控与预测分析</p>
+        </div>
+        <div class="header-right">
+          <el-select v-model="maintenanceTimeRange" placeholder="选择时间范围" @change="updateMaintenanceAnalysisData">
+            <el-option label="近7天" value="7"></el-option>
+            <el-option label="近30天" value="30"></el-option>
+            <el-option label="近90天" value="90"></el-option>
+          </el-select>
+        </div>
+      </div>
+
+      <!-- 保养核心指标 -->
+      <el-row :gutter="24" class="metrics-row">
+        <el-col :span="8">
+          <div class="maintenance-metric-card execution-metric">
+            <div class="maintenance-metric-header">
+              <div class="maintenance-metric-icon-wrapper">
+                <i class="el-icon-check"></i>
+              </div>
+              <div class="maintenance-metric-trend-badge positive">
+                <i class="el-icon-top"></i>
+                <span>+5.2%</span>
+              </div>
+            </div>
+            <div class="maintenance-metric-body">
+              <div class="maintenance-metric-value">{{ maintenanceAnalysis.executionRate }}<span class="maintenance-metric-unit">%</span></div>
+              <div class="maintenance-metric-label">保养计划执行率</div>
+              <div class="maintenance-metric-desc">按时完成保养的设备比例</div>
+            </div>
+            <div class="maintenance-metric-footer">
+              <div class="maintenance-progress-bar">
+                <div class="maintenance-progress-fill" style="width: 89.6%"></div>
+              </div>
+              <span class="maintenance-progress-text">执行率 89.6%</span>
+            </div>
+          </div>
+        </el-col>
+        <el-col :span="8">
+          <div class="maintenance-metric-card cycle-metric">
+            <div class="maintenance-metric-header">
+              <div class="maintenance-metric-icon-wrapper">
+                <i class="el-icon-time"></i>
+              </div>
+              <div class="maintenance-metric-trend-badge neutral">
+                <i class="el-icon-minus"></i>
+                <span>持平</span>
+              </div>
+            </div>
+            <div class="maintenance-metric-body">
+              <div class="maintenance-metric-value">{{ maintenanceAnalysis.avgCycle }}<span class="maintenance-metric-unit">天</span></div>
+              <div class="maintenance-metric-label">平均保养周期</div>
+              <div class="maintenance-metric-desc">各类设备保养间隔时间</div>
+            </div>
+            <div class="maintenance-metric-footer">
+              <div class="maintenance-progress-bar">
+                <div class="maintenance-progress-fill cycle-fill" style="width: 78.3%"></div>
+              </div>
+              <span class="maintenance-progress-text">周期优化 78.3%</span>
+            </div>
+          </div>
+        </el-col>
+        <el-col :span="8">
+          <div class="maintenance-metric-card cost-metric">
+            <div class="maintenance-metric-header">
+              <div class="maintenance-metric-icon-wrapper">
+                <i class="el-icon-money"></i>
+              </div>
+              <div class="maintenance-metric-trend-badge positive">
+                <i class="el-icon-bottom"></i>
+                <span>-8.1%</span>
+              </div>
+            </div>
+            <div class="maintenance-metric-body">
+              <div class="maintenance-metric-value">¥{{ maintenanceAnalysis.avgCost }}<span class="maintenance-metric-unit">/台</span></div>
+              <div class="maintenance-metric-label">保养成本控制</div>
+              <div class="maintenance-metric-desc">单台设备月均保养费用</div>
+            </div>
+            <div class="maintenance-metric-footer">
+              <div class="maintenance-progress-bar">
+                <div class="maintenance-progress-fill cost-fill" style="width: 91.9%"></div>
+              </div>
+              <span class="maintenance-progress-text">成本控制 91.9%</span>
+            </div>
+          </div>
+        </el-col>
+      </el-row>
+
+      <!-- 保养图表区域 -->
+      <el-row :gutter="32" class="charts-row">
+        <el-col :span="12">
+          <div class="chart-card maintenance-chart-card">
+            <div class="chart-header">
+              <h4 class="chart-title">设备保养状态分布</h4>
+            </div>
+            <div class="chart-content chart-flex-content">
+                                <div class="maintenance-donut-chart-horizontal">
+                <!-- 左侧:饼图区域 -->
+                <div class="maintenance-donut-container-side">
+                  <svg width="280" height="280" viewBox="0 0 280 280">
+                    <!-- 环形图 -->
+                    <circle cx="140" cy="140" r="85" fill="none" stroke="#E5F4E8" stroke-width="35"/>
+                    <circle cx="140" cy="140" r="85" fill="none" stroke="#4CAF50" stroke-width="35" 
+                            stroke-dasharray="267 534" stroke-dashoffset="0" transform="rotate(-90 140 140)"
+                            class="maintenance-segment" data-status="normal"
+                            />
+                    <circle cx="140" cy="140" r="85" fill="none" stroke="#FFC107" stroke-width="35" 
+                            stroke-dasharray="107 534" stroke-dashoffset="-267" transform="rotate(-90 140 140)"
+                            class="maintenance-segment" data-status="due"
+                            />
+                    <circle cx="140" cy="140" r="85" fill="none" stroke="#FF5722" stroke-width="35" 
+                            stroke-dasharray="53 534" stroke-dashoffset="-374" transform="rotate(-90 140 140)"
+                            class="maintenance-segment" data-status="overdue"
+                            />
+                    <circle cx="140" cy="140" r="85" fill="none" stroke="#2196F3" stroke-width="35" 
+                            stroke-dasharray="107 534" stroke-dashoffset="-427" transform="rotate(-90 140 140)"
+                            class="maintenance-segment" data-status="progress"
+                            />
+                    
+                    <!-- 中心文字 -->
+                    <text x="140" y="125" text-anchor="middle" class="maintenance-donut-center-label">总设备</text>
+                    <text x="140" y="155" text-anchor="middle" class="maintenance-donut-center-value">24</text>
+                  </svg>
+                </div>
+                <!-- 右侧:图例区域 -->
+                <div class="maintenance-donut-legend-side">
+                  <div class="maintenance-legend-item-enhanced" data-status="normal" style="--index: 0;">
+                    <div class="maintenance-legend-color" style="background-color: #4CAF50;"></div>
+                    <div class="maintenance-legend-content-enhanced">
+                      <span class="maintenance-legend-label">保养正常</span>
+                      <span class="maintenance-legend-value">50%</span>
+                    </div>
+                  </div>
+                  <div class="maintenance-legend-item-enhanced" data-status="due" style="--index: 1;">
+                    <div class="maintenance-legend-color" style="background-color: #FFC107;"></div>
+                    <div class="maintenance-legend-content-enhanced">
+                      <span class="maintenance-legend-label">即将到期</span>
+                      <span class="maintenance-legend-value">20%</span>
+                    </div>
+                  </div>
+                  <div class="maintenance-legend-item-enhanced" data-status="overdue" style="--index: 2;">
+                    <div class="maintenance-legend-color" style="background-color: #FF5722;"></div>
+                    <div class="maintenance-legend-content-enhanced">
+                      <span class="maintenance-legend-label">保养超期</span>
+                      <span class="maintenance-legend-value">10%</span>
+                    </div>
+                  </div>
+                  <div class="maintenance-legend-item-enhanced" data-status="progress" style="--index: 3;">
+                    <div class="maintenance-legend-color" style="background-color: #2196F3;"></div>
+                    <div class="maintenance-legend-content-enhanced">
+                      <span class="maintenance-legend-label">保养中</span>
+                      <span class="maintenance-legend-value">20%</span>
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </div>
+        </el-col>
+        <el-col :span="12">
+          <div class="chart-card maintenance-chart-card">
+            <div class="chart-header">
+              <h4 class="chart-title">保养成本变化趋势</h4>
+              <div class="chart-controls">
+                <el-radio-group v-model="maintenanceTrendMetric" size="small" @change="updateMaintenanceTrendChart">
+                  <el-radio-button label="cost">成本</el-radio-button>
+                  <el-radio-button label="frequency">频次</el-radio-button>
+                  <el-radio-button label="efficiency">效率</el-radio-button>
+                </el-radio-group>
+              </div>
+            </div>
+            <div class="chart-content chart-flex-content">
+              <div class="maintenance-trend-chart">
+                <div class="maintenance-chart-area">
+                  <div class="maintenance-chart-unit-label">单位:元</div>
+                  <svg width="100%" height="260" viewBox="0 0 500 260">
+                    <!-- 网格线 -->
+                    <defs>
+                      <pattern id="maintenanceGrid" width="50" height="50" patternUnits="userSpaceOnUse">
+                        <path d="M 50 0 L 0 0 0 50" fill="none" stroke="#F0F4F1" stroke-width="1"/>
+                      </pattern>
+                      <linearGradient id="maintenanceTrendGradient" x1="0%" y1="0%" x2="0%" y2="100%">
+                        <stop offset="0%" style="stop-color:#FF9800;stop-opacity:0.3"/>
+                        <stop offset="100%" style="stop-color:#FF9800;stop-opacity:0"/>
+                      </linearGradient>
+                    </defs>
+                    <rect width="100%" height="100%" fill="url(#maintenanceGrid)"/>
+                    
+                    <!-- 趋势面积 -->
+                    <path d="M30,180 L90,160 L150,140 L210,120 L270,130 L330,110 L390,95 L450,80 L450,260 L30,260 Z" 
+                          fill="url(#maintenanceTrendGradient)"/>
+                    
+                    <!-- 趋势线 -->
+                    <polyline points="30,180 90,160 150,140 210,120 270,130 330,110 390,95 450,80" 
+                              fill="none" stroke="#FF9800" stroke-width="4"/>
+                    
+                    <!-- 数据点 -->
+                    <circle cx="30" cy="180" r="6" fill="#FF9800" class="maintenance-data-point" style="--index: 0;" 
+                            @mouseenter="showMaintenanceDataTooltip($event, 0)" @mouseleave="hideMaintenanceDataTooltip"/>
+                    <circle cx="90" cy="160" r="6" fill="#FF9800" class="maintenance-data-point" style="--index: 1;" 
+                            @mouseenter="showMaintenanceDataTooltip($event, 1)" @mouseleave="hideMaintenanceDataTooltip"/>
+                    <circle cx="150" cy="140" r="6" fill="#FF9800" class="maintenance-data-point" style="--index: 2;" 
+                            @mouseenter="showMaintenanceDataTooltip($event, 2)" @mouseleave="hideMaintenanceDataTooltip"/>
+                    <circle cx="210" cy="120" r="6" fill="#FF9800" class="maintenance-data-point" style="--index: 3;" 
+                            @mouseenter="showMaintenanceDataTooltip($event, 3)" @mouseleave="hideMaintenanceDataTooltip"/>
+                    <circle cx="270" cy="130" r="6" fill="#FF9800" class="maintenance-data-point" style="--index: 4;" 
+                            @mouseenter="showMaintenanceDataTooltip($event, 4)" @mouseleave="hideMaintenanceDataTooltip"/>
+                    <circle cx="330" cy="110" r="6" fill="#FF9800" class="maintenance-data-point" style="--index: 5;" 
+                            @mouseenter="showMaintenanceDataTooltip($event, 5)" @mouseleave="hideMaintenanceDataTooltip"/>
+                    <circle cx="390" cy="95" r="6" fill="#FF9800" class="maintenance-data-point" style="--index: 6;" 
+                            @mouseenter="showMaintenanceDataTooltip($event, 6)" @mouseleave="hideMaintenanceDataTooltip"/>
+                    <circle cx="450" cy="80" r="6" fill="#FF9800" class="maintenance-data-point" style="--index: 7;" 
+                            @mouseenter="showMaintenanceDataTooltip($event, 7)" @mouseleave="hideMaintenanceDataTooltip"/>
+                    
+                    <!-- X轴标签 -->
+                    <text x="30" y="240" text-anchor="middle" class="maintenance-axis-label">1/9</text>
+                    <text x="90" y="240" text-anchor="middle" class="maintenance-axis-label">1/10</text>
+                    <text x="150" y="240" text-anchor="middle" class="maintenance-axis-label">1/11</text>
+                    <text x="210" y="240" text-anchor="middle" class="maintenance-axis-label">1/12</text>
+                    <text x="270" y="240" text-anchor="middle" class="maintenance-axis-label">1/13</text>
+                    <text x="330" y="240" text-anchor="middle" class="maintenance-axis-label">1/14</text>
+                    <text x="390" y="240" text-anchor="middle" class="maintenance-axis-label">1/15</text>
+                    <text x="450" y="240" text-anchor="middle" class="maintenance-axis-label">今日</text>
+                  </svg>
+                </div>
+              </div>
+            </div>
+            <div class="maintenance-trend-summary">
+              <div class="maintenance-summary-item">
+                <span class="maintenance-summary-label">今日保养{{ getMaintenanceMetricLabel() }}</span>
+                <span class="maintenance-summary-value primary">{{ maintenanceSummary.today }}</span>
+              </div>
+              <div class="maintenance-summary-item">
+                <span class="maintenance-summary-label">昨日保养{{ getMaintenanceMetricLabel() }}</span>
+                <span class="maintenance-summary-value">{{ maintenanceSummary.yesterday }}</span>
+              </div>
+              <div class="maintenance-summary-item">
+                <span class="maintenance-summary-label">环比变化</span>
+                <span class="maintenance-summary-value positive">{{ maintenanceSummary.growth }}</span>
+              </div>
+            </div>
+          </div>
+        </el-col>
+      </el-row>
+    </el-card>
+
+
+
+    <!-- 监控设置对话框 -->
+    <el-dialog title="监控设置" :visible.sync="settingsVisible" width="600px">
+      <el-form :model="settings" label-width="120px">
+        <el-form-item label="刷新间隔">
+          <el-select v-model="settings.refreshInterval">
+            <el-option label="30秒" value="30"></el-option>
+            <el-option label="1分钟" value="60"></el-option>
+            <el-option label="2分钟" value="120"></el-option>
+            <el-option label="5分钟" value="300"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="告警通知">
+          <el-switch v-model="settings.alertNotification"></el-switch>
+        </el-form-item>
+        <el-form-item label="声音提醒">
+          <el-switch v-model="settings.soundAlert"></el-switch>
+        </el-form-item>
+        <el-form-item label="地图类型">
+          <el-radio-group v-model="settings.mapType">
+            <el-radio label="satellite">卫星图</el-radio>
+            <el-radio label="standard">标准地图</el-radio>
+          </el-radio-group>
+        </el-form-item>
+      </el-form>
+      <div slot="footer">
+        <el-button @click="settingsVisible = false">取消</el-button>
+        <el-button type="primary" @click="saveSettings">保存</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { getMachines } from "@/api/base/machines"
+
+export default {
+  name: "MachinesMonitor",
+  data() {
+    return {
+      // 页面状态
+      refreshing: false,
+      mapLoading: false,
+      updateTime: '',
+      timeRange: 'realtime',
+      
+      // 筛选条件
+      filters: {
+        machineType: '',
+        farmId: ''
+      },
+      
+      // 农场列表
+      farmList: [
+        { id: 'farm1', name: '东湖智慧农场' },
+        { id: 'farm2', name: '西湖有机农场' },
+        { id: 'farm3', name: '南山生态农场' }
+      ],
+      
+      // 统计数据
+      statistics: {
+        total: 24,
+        online: 18,
+        working: 12,
+        warning: 3
+      },
+      
+      // 保养统计
+      maintenanceStats: {
+        due: 5,
+        inProgress: 2,
+        overdue: 1,
+        monthlyCost: 28500
+      },
+      
+      // 农机列表
+      machinesList: [],
+      originalMachines: [], // 原始农机数据,用于筛选重置
+      visibleMachines: [],
+      
+      // 地图相关
+      selectedMachine: null,
+      popupPosition: {
+        left: '0px',
+        top: '0px'
+      },
+      amap: null, // 高德地图实例
+      machineMarkers: [], // 农机标记数组
+      infoWindow: null, // 信息窗口
+      mapCenter: [117.065029, 34.227274], // 地图中心点坐标
+      
+      // 分析数据
+      analysisTimeRange: '7',
+      maintenanceTimeRange: '30',
+      trendMetric: 'area',
+      maintenanceTrendMetric: 'cost',
+      
+      // 作业分析数据
+      workAnalysis: {
+        totalArea: '1,248.5',
+        totalHours: '89.2',
+        avgEfficiency: '14.2'
+      },
+      
+      // 保养分析数据
+      maintenanceAnalysis: {
+        executionRate: '89.6',
+        avgCycle: '23.5',
+        avgCost: '1,245'
+      },
+      
+      // 趋势汇总
+      trendSummary: {
+        today: '156.8 亩',
+        yesterday: '142.3 亩',
+        growth: '+10.2%'
+      },
+      
+      // 保养趋势汇总
+      maintenanceSummary: {
+        today: '¥2,500',
+        yesterday: '¥2,800',
+        growth: '-10.7%'
+      },
+      
+      // 设置
+      settingsVisible: false,
+      settings: {
+        refreshInterval: '120',
+        alertNotification: true,
+        soundAlert: false,
+        mapType: 'standard'
+      },
+      
+      // 定时器
+      timers: [],
+      
+      // 筛选防抖定时器
+      filterTimeout: null
+    }
+  },
+  computed: {
+    onlineRate() {
+      if (this.statistics.total === 0) return 0
+      return Math.round((this.statistics.online / this.statistics.total) * 100)
+    }
+  },
+  created() {
+    this.loadData()
+    this.startAutoRefresh()
+    this.updateCurrentTime()
+  },
+  mounted() {
+    this.initCharts()
+    this.initAmap()
+    this.updateTrendChartData() // 初始化趋势图表数据
+    
+    // 添加全局方法供信息窗口调用
+    window.viewMachineDetail = (machineId) => {
+      this.$router.push(`/base/machines/monitor/${machineId}`)
+    }
+  },
+  beforeDestroy() {
+    this.timers.forEach(timer => clearInterval(timer))
+    if (this.filterTimeout) {
+      clearTimeout(this.filterTimeout)
+    }
+    
+    // 清理地图资源
+    if (this.amap) {
+      this.clearMachineMarkers()
+      this.amap.destroy()
+      this.amap = null
+    }
+    
+    // 清理全局方法
+    if (window.viewMachineDetail) {
+      delete window.viewMachineDetail
+    }
+  },
+  methods: {
+    // 加载数据
+    async loadData() {
+      try {
+        await this.loadMachinesList()
+        this.loadStatistics()
+        this.loadMaintenanceStats()
+        this.generateMockMachines()
+      } catch (error) {
+        this.$message.error('数据加载失败')
+        console.error(error)
+      }
+    },
+    
+    // 加载农机列表
+    async loadMachinesList() {
+      try {
+        const response = await getMachines()
+        this.machinesList = response.rows || []
+        this.applyFilters()
+      } catch (error) {
+        console.error('加载农机列表失败:', error)
+      }
+    },
+    
+    // 加载统计数据
+    loadStatistics() {
+      // 实际项目中应该调用API获取统计数据
+      // 这里使用模拟数据
+      this.statistics = {
+        total: this.machinesList.length || 24,
+        online: Math.floor(Math.random() * 6) + 16,
+        working: Math.floor(Math.random() * 5) + 10,
+        warning: Math.floor(Math.random() * 3) + 1
+      }
+    },
+    
+    // 加载保养统计
+    loadMaintenanceStats() {
+      this.maintenanceStats = {
+        due: Math.floor(Math.random() * 3) + 4,
+        inProgress: Math.floor(Math.random() * 2) + 1,
+        overdue: Math.floor(Math.random() * 2),
+        monthlyCost: Math.floor(Math.random() * 5000) + 25000
+      }
+    },
+    
+    // 生成模拟农机数据
+    generateMockMachines() {
+      const mockMachines = [
+        {
+          id: 1,
+          machineName: '东方红拖拉机',
+          machineCode: 'TL001',
+          machineType: 'tractor',
+          onlineStatus: 2,
+          maintenanceStatus: 0,
+          operator: '张师傅',
+          currentTask: '深松作业',
+          fieldArea: '东区1号地块',
+          workProgress: 65,
+          lastMaintenance: '2024-01-02',
+          nextMaintenance: '2024-01-25',
+          maintenanceMileage: '850/1000',
+          position: { x: 25, y: 30 }
+        },
+        {
+          id: 2,
+          machineName: '久保田收割机',
+          machineCode: 'SJ002',
+          machineType: 'harvester',
+          onlineStatus: 1,
+          maintenanceStatus: 1,
+          operator: '李师傅',
+          currentTask: '待分配',
+          fieldArea: '西区2号地块',
+          workProgress: 0,
+          lastMaintenance: '2023-12-15',
+          nextMaintenance: '2024-01-16',
+          maintenanceMileage: '980/1000',
+          position: { x: 60, y: 45 }
+        },
+        {
+          id: 3,
+          machineName: '东风喷药机',
+          machineCode: 'PY003',
+          machineType: 'sprayer',
+          onlineStatus: 3,
+          maintenanceStatus: 2,
+          operator: '王师傅',
+          currentTask: '告警检修',
+          fieldArea: '南区3号地块',
+          workProgress: 0,
+          lastMaintenance: '2023-11-20',
+          nextMaintenance: '2024-01-05',
+          maintenanceMileage: '1200/1000',
+          position: { x: 40, y: 65 }
+        },
+        {
+          id: 4,
+          machineName: '雷沃播种机',
+          machineCode: 'BZ004',
+          machineType: 'seeder',
+          onlineStatus: 2,
+          maintenanceStatus: 0,
+          operator: '赵师傅',
+          currentTask: '播种作业',
+          fieldArea: '北区4号地块',
+          workProgress: 80,
+          lastMaintenance: '2024-01-08',
+          nextMaintenance: '2024-02-10',
+          maintenanceMileage: '320/1000',
+          position: { x: 75, y: 20 }
+        },
+        {
+          id: 5,
+          machineName: '东方红拖拉机',
+          machineCode: 'TL005',
+          machineType: 'tractor',
+          onlineStatus: 1,
+          maintenanceStatus: 3,
+          operator: '孙师傅',
+          currentTask: '保养维护',
+          fieldArea: '维修车间',
+          workProgress: 60,
+          lastMaintenance: '2024-01-15',
+          nextMaintenance: '2024-02-20',
+          maintenanceMileage: '0/1000',
+          position: { x: 20, y: 80 }
+        },
+        {
+          id: 6,
+          machineName: '东方红耕地机',
+          machineCode: 'GD006',
+          machineType: 'cultivator',
+          onlineStatus: 1,
+          maintenanceStatus: 1,
+          operator: '钱师傅',
+          currentTask: '待分配',
+          fieldArea: '东区5号地块',
+          workProgress: 0,
+          lastMaintenance: '2023-12-20',
+          nextMaintenance: '2024-01-18',
+          maintenanceMileage: '950/1000',
+          position: { x: 85, y: 55 }
+        },
+        {
+          id: 7,
+          machineName: '约翰迪尔播种机',
+          machineCode: 'BZ007',
+          machineType: 'seeder',
+          onlineStatus: 2,
+          maintenanceStatus: 0,
+          operator: '刘师傅',
+          currentTask: '精量播种',
+          fieldArea: '东区6号地块',
+          workProgress: 45,
+          lastMaintenance: '2024-01-10',
+          nextMaintenance: '2024-02-15',
+          maintenanceMileage: '420/1000',
+          position: { x: 15, y: 25 }
+        },
+        {
+          id: 8,
+          machineName: '凯斯收割机',
+          machineCode: 'SJ008',
+          machineType: 'harvester',
+          onlineStatus: 0,
+          maintenanceStatus: 1,
+          operator: '周师傅',
+          currentTask: '离线维修',
+          fieldArea: '维修车间',
+          workProgress: 0,
+          lastMaintenance: '2023-12-25',
+          nextMaintenance: '2024-01-20',
+          maintenanceMileage: '870/1000',
+          position: { x: 30, y: 75 }
+        }
+      ]
+      
+      // 保存原始数据,用于筛选重置
+      this.originalMachines = [...mockMachines]
+      this.visibleMachines = [...mockMachines]
+    },
+    
+    // 应用筛选
+    applyFilters() {
+      let filtered = [...this.originalMachines]
+      
+      // 设备类型筛选
+      if (this.filters.machineType) {
+        filtered = filtered.filter(m => m.machineType === this.filters.machineType)
+      }
+      
+      // 农场筛选(这里使用模拟逻辑,实际项目中会根据农机的农场ID筛选)
+      if (this.filters.farmId) {
+        // 模拟根据农场筛选
+        filtered = filtered.filter(m => {
+          // 实际项目中这里会有farmId字段
+          return true // 暂时返回所有数据
+        })
+      }
+      
+      // 更新可见的农机列表
+      this.visibleMachines = filtered
+      
+      // 更新统计数据
+      this.updateFilteredStatistics(filtered)
+      
+      // 更新地图标记
+      this.$nextTick(() => {
+        this.addMachineMarkers()
+      })
+    },
+    
+    // 更新筛选后的统计数据
+    updateFilteredStatistics(filtered) {
+      this.statistics.total = filtered.length
+      this.statistics.online = filtered.filter(m => m.onlineStatus > 0).length
+      this.statistics.working = filtered.filter(m => m.onlineStatus === 2).length
+      this.statistics.warning = filtered.filter(m => m.onlineStatus === 3).length
+    },
+    
+    // 重置筛选
+    resetFilters() {
+      this.filters = {
+        machineType: '',
+        farmId: ''
+      }
+      this.visibleMachines = [...this.originalMachines]
+      this.loadStatistics()
+    },
+    
+    // 刷新数据
+    async refreshData() {
+      this.refreshing = true
+      try {
+        await this.loadData()
+        this.updateCurrentTime()
+        this.$message.success('数据已刷新')
+      } catch (error) {
+        this.$message.error('刷新失败')
+      } finally {
+        setTimeout(() => {
+          this.refreshing = false
+        }, 1000)
+      }
+    },
+    
+    // 开始自动刷新
+    startAutoRefresh() {
+      // 时间更新定时器
+      const timeTimer = setInterval(() => {
+        this.updateCurrentTime()
+      }, 1000)
+      this.timers.push(timeTimer)
+      
+      // 数据刷新定时器
+      const dataTimer = setInterval(() => {
+        this.loadStatistics()
+        this.loadMaintenanceStats()
+      }, parseInt(this.settings.refreshInterval) * 1000)
+      this.timers.push(dataTimer)
+    },
+    
+    // 更新当前时间
+    updateCurrentTime() {
+      const now = new Date()
+      const year = now.getFullYear()
+      const month = String(now.getMonth() + 1).padStart(2, '0')
+      const day = String(now.getDate()).padStart(2, '0')
+      const hours = String(now.getHours()).padStart(2, '0')
+      const minutes = String(now.getMinutes()).padStart(2, '0')
+      const seconds = String(now.getSeconds()).padStart(2, '0')
+      
+      this.updateTime = `${year}/${month}/${day} ${hours}:${minutes}:${seconds}`
+    },
+    
+    // 地图控制方法
+    zoomIn() {
+      this.$message.info('地图放大功能')
+    },
+    
+    zoomOut() {
+      this.$message.info('地图缩小功能')
+    },
+    
+    centerMap() {
+      this.$message.info('地图居中功能')
+    },
+    
+    toggleMapFullscreen() {
+      const mapContainer = this.$refs.mapContainer
+      if (!document.fullscreenElement) {
+        mapContainer.requestFullscreen().then(() => {
+          this.$message.success('已进入全屏模式')
+        })
+      } else {
+        document.exitFullscreen().then(() => {
+          this.$message.success('已退出全屏')
+        })
+      }
+    },
+    
+    // 显示农机弹层
+    showMachinePopup(machine, event) {
+      this.selectedMachine = machine
+      
+      const rect = event.target.getBoundingClientRect()
+      const containerRect = this.$refs.mapContainer.getBoundingClientRect()
+      
+      this.popupPosition = {
+        left: Math.max(10, Math.min(rect.left - containerRect.left - 140, containerRect.width - 290)) + 'px',
+        top: Math.max(10, rect.top - containerRect.top - 200) + 'px'
+      }
+    },
+    
+    // 关闭农机弹层
+    closeMachinePopup() {
+      this.selectedMachine = null
+    },
+    
+    // 查看农机详情
+    viewMachineDetail() {
+      if (this.selectedMachine) {
+        this.$router.push(`/base/machines/monitor/${this.selectedMachine.id}`)
+      }
+    },
+    
+    // 获取农机标记样式类
+    getMachineMarkerClass(machine) {
+      const statusClass = {
+        0: 'offline',
+        1: 'online',
+        2: 'working',
+        3: 'warning'
+      }[machine.onlineStatus] || 'offline'
+      
+      const maintenanceClass = {
+        0: 'maintenance-normal',
+        1: 'maintenance-due',
+        2: 'maintenance-overdue',
+        3: 'maintenance-progress'
+      }[machine.maintenanceStatus] || 'maintenance-normal'
+      
+      return `${statusClass} ${maintenanceClass}`
+    },
+    
+    // 获取农机位置样式
+    getMachinePosition(machine) {
+      return {
+        left: machine.position.x + '%',
+        top: machine.position.y + '%'
+      }
+    },
+    
+    // 获取农机图标
+    getMachineIcon(machineType) {
+      const iconMap = {
+        'tractor': 'el-icon-truck',
+        'harvester': 'el-icon-goods',
+        'seeder': 'el-icon-set-up',
+        'sprayer': 'el-icon-grape',
+        'cultivator': 'el-icon-menu'
+      }
+      return iconMap[machineType] || 'el-icon-truck'
+    },
+    
+    // 获取农机提示信息
+    getMachineTooltip(machine) {
+      return `${machine.machineName} #${machine.machineCode} - ${this.getStatusText(machine.onlineStatus)} | ${this.getMaintenanceStatusText(machine.maintenanceStatus)}`
+    },
+    
+    // 获取状态文本
+    getStatusText(status) {
+      const statusMap = {
+        0: '离线',
+        1: '在线',
+        2: '作业中',
+        3: '告警'
+      }
+      return statusMap[status] || '未知'
+    },
+    
+    // 获取状态标签类型
+    getStatusTagType(status) {
+      const typeMap = {
+        0: 'info',
+        1: 'success',
+        2: 'primary',
+        3: 'warning'
+      }
+      return typeMap[status] || 'info'
+    },
+    
+    // 获取保养状态文本
+    getMaintenanceStatusText(status) {
+      const statusMap = {
+        0: '正常',
+        1: '即将到期',
+        2: '已超期',
+        3: '保养中'
+      }
+      return statusMap[status] || '未知'
+    },
+    
+    // 获取保养状态标签类型
+    getMaintenanceTagType(status) {
+      const typeMap = {
+        0: 'success',
+        1: 'warning',
+        2: 'danger',
+        3: 'primary'
+      }
+      return typeMap[status] || 'info'
+    },
+    
+    // 格式化货币
+    formatCurrency(amount) {
+      return amount.toLocaleString()
+    },
+    
+    // 更新分析数据
+    updateAnalysisData() {
+      // 根据时间范围更新作业分析数据
+      const mockData = {
+        '7': {
+          totalArea: '1,248.5',
+          totalHours: '89.2',
+          avgEfficiency: '14.2'
+        },
+        '30': {
+          totalArea: '5,432.1',
+          totalHours: '392.7',
+          avgEfficiency: '13.8'
+        },
+        '90': {
+          totalArea: '16,847.3',
+          totalHours: '1,203.5',
+          avgEfficiency: '14.0'
+        }
+      }
+      
+      this.workAnalysis = mockData[this.analysisTimeRange]
+      this.updateCharts()
+    },
+    
+    // 更新保养分析数据
+    updateMaintenanceAnalysisData() {
+      const mockData = {
+        '7': {
+          executionRate: '91.2',
+          avgCycle: '21.8',
+          avgCost: '1,180'
+        },
+        '30': {
+          executionRate: '89.6',
+          avgCycle: '23.5',
+          avgCost: '1,245'
+        },
+        '90': {
+          executionRate: '87.3',
+          avgCycle: '25.2',
+          avgCost: '1,320'
+        }
+      }
+      
+      this.maintenanceAnalysis = mockData[this.maintenanceTimeRange]
+      this.updateMaintenanceCharts()
+    },
+    
+    // 更新趋势图
+    updateTrendChart() {
+      const summaryData = {
+        area: {
+          today: '156.8 亩',
+          yesterday: '142.3 亩',
+          growth: '+10.2%'
+        },
+        time: {
+          today: '11.2 小时',
+          yesterday: '10.1 小时',
+          growth: '+10.9%'
+        },
+        efficiency: {
+          today: '14.5 亩/小时',
+          yesterday: '13.8 亩/小时',
+          growth: '+5.1%'
+        }
+      }
+      
+      // 更新汇总数据
+      this.trendSummary = summaryData[this.trendMetric]
+      
+      // 更新图表数据和单位
+      this.updateTrendChartData()
+    },
+    
+    // 更新趋势图表数据
+    updateTrendChartData() {
+      // 根据不同的指标设置不同的数据点和单位
+      const chartData = {
+        area: {
+          unit: '亩',
+          points: [120, 135, 145, 160, 155, 170, 185, 200, 215, 230],
+          yCoords: [200, 175, 165, 150, 155, 140, 125, 110, 95, 80],
+          path: 'M40,200 L100,175 L160,165 L220,150 L280,155 L340,140 L400,125 L460,110 L520,95 L580,80',
+          areaPath: 'M40,200 L100,175 L160,165 L220,150 L280,155 L340,140 L400,125 L460,110 L520,95 L580,80 L580,240 L40,240 Z'
+        },
+        time: {
+          unit: '小时',
+          points: [8, 9, 9.5, 10, 9.8, 10.5, 11, 11.5, 12, 12.5],
+          yCoords: [220, 200, 190, 180, 185, 170, 160, 150, 140, 130],
+          path: 'M40,220 L100,200 L160,190 L220,180 L280,185 L340,170 L400,160 L460,150 L520,140 L580,130',
+          areaPath: 'M40,220 L100,200 L160,190 L220,180 L280,185 L340,170 L400,160 L460,150 L520,140 L580,130 L580,240 L40,240 Z'
+        },
+        efficiency: {
+          unit: '亩/小时',
+          points: [12, 13, 13.5, 14, 13.8, 14.2, 14.8, 15.2, 15.8, 16.2],
+          yCoords: [200, 185, 175, 165, 170, 155, 145, 135, 125, 115],
+          path: 'M40,200 L100,185 L160,175 L220,165 L280,170 L340,155 L400,145 L460,135 L520,125 L580,115',
+          areaPath: 'M40,200 L100,185 L160,175 L220,165 L280,170 L340,155 L400,145 L460,135 L520,125 L580,115 L580,240 L40,240 Z'
+        }
+      }
+      
+      const currentData = chartData[this.trendMetric]
+      
+      // 更新单位标签
+      this.$nextTick(() => {
+        const unitLabel = document.querySelector('.work-chart-unit-label')
+        if (unitLabel) {
+          unitLabel.textContent = `单位:${currentData.unit}`
+        }
+        
+        // 更新SVG路径
+        const trendLine = document.querySelector('.work-trend-chart polyline')
+        const trendArea = document.querySelector('.work-trend-chart path[fill="url(#trendGradient)"]')
+        
+        if (trendLine) {
+          // 将路径字符串转换为points格式
+          const points = currentData.path.replace(/[ML]/g, ' ').trim().split(' ').filter(p => p !== '')
+          const pointsString = points.join(' ')
+          trendLine.setAttribute('points', pointsString)
+        }
+        
+        if (trendArea) {
+          trendArea.setAttribute('d', currentData.areaPath)
+        }
+        
+        // 更新数据点位置
+        const dataPoints = document.querySelectorAll('.work-trend-chart .data-point')
+        dataPoints.forEach((point, index) => {
+          if (index < currentData.yCoords.length) {
+            // 使用预定义的Y坐标,确保与线条路径完全匹配
+            const y = currentData.yCoords[index]
+            point.setAttribute('cy', y)
+          }
+        })
+      })
+    },
+    
+    // 初始化图表
+    initCharts() {
+      // 在实际项目中,这里会初始化ECharts或其他图表库
+      console.log('初始化图表')
+      
+      // 确保图表数据正确初始化
+      this.$nextTick(() => {
+        this.updateTrendChartData()
+        this.updateMaintenanceTrendChartData()
+      })
+    },
+    
+    // 更新图表
+    updateCharts() {
+      // 更新作业统计图表
+      console.log('更新作业统计图表')
+    },
+    
+    // 更新保养图表
+    updateMaintenanceCharts() {
+      // 更新保养统计图表
+      console.log('更新保养统计图表')
+    },
+    
+    // 处理导出
+    handleExport(command) {
+      this.$message.success(`正在导出${command}...`)
+      // 实际项目中实现导出功能
+    },
+    
+    // 打开设置
+    openSettings() {
+      this.settingsVisible = true
+    },
+    
+    // 保存设置
+    saveSettings() {
+      this.settingsVisible = false
+      this.$message.success('设置已保存')
+      
+      // 重新设置定时器
+      this.timers.forEach(timer => clearInterval(timer))
+      this.timers = []
+      this.startAutoRefresh()
+          },
+      
+      // 防抖应用筛选
+    debouncedApplyFilters() {
+      if (this.filterTimeout) {
+        clearTimeout(this.filterTimeout)
+      }
+      this.filterTimeout = setTimeout(() => {
+        this.applyFilters()
+      }, 500)
+    },
+    
+
+    
+    // 重启自动刷新
+    restartAutoRefresh() {
+      this.timers.forEach(timer => clearInterval(timer))
+      this.timers = []
+      this.startAutoRefresh()
+    },
+    
+    // 时间范围变化处理
+    onTimeRangeChange() {
+      // 可以在这里添加时间范围变化的处理逻辑
+      // 例如:重新加载数据、更新图表等
+      console.log('时间范围已更改为:', this.timeRange)
+      this.loadData()
+    },
+    
+    // 初始化高德地图
+    initAmap() {
+      if (typeof AMap === 'undefined') {
+        console.error('高德地图API未加载,请检查API引用')
+        return
+      }
+      
+      this.mapLoading = true
+      
+      // 创建地图实例
+      this.amap = new AMap.Map('amap-container', {
+        center: this.mapCenter, // 设置地图中心点坐标
+        zoom: 12, // 设置地图缩放级别
+        mapStyle: 'amap://styles/light', // 设置地图样式为浅色
+        viewMode: '2D', // 设置地图模式为2D
+        features: ['bg', 'road', 'building'], // 设置地图显示要素
+        showLabel: true // 显示地图标注
+      })
+      
+      // 地图加载完成后的回调
+      this.amap.on('complete', () => {
+        this.mapLoading = false
+        this.addMachineMarkers()
+        console.log('高德地图初始化完成')
+      })
+      
+      // 创建信息窗口
+      this.infoWindow = new AMap.InfoWindow({
+        anchor: 'bottom-center',
+        offset: new AMap.Pixel(0, -30)
+      })
+    },
+    
+    // 添加农机标记到地图
+    addMachineMarkers() {
+      if (!this.amap) return
+      
+      // 清除现有标记
+      this.clearMachineMarkers()
+      
+      this.visibleMachines.forEach(machine => {
+        // 将百分比位置转换为真实坐标(这里需要根据实际情况调整)
+        const lng = this.mapCenter[0] + (machine.position.x - 50) * 0.01
+        const lat = this.mapCenter[1] + (50 - machine.position.y) * 0.01
+        
+        // 创建自定义标记DOM元素
+        const markerDiv = document.createElement('div')
+        markerDiv.className = 'custom-marker'
+        markerDiv.innerHTML = this.createMarkerContent(machine)
+        
+        // 创建标记
+        const marker = new AMap.Marker({
+          position: [lng, lat],
+          title: machine.machineName,
+          content: markerDiv,
+          anchor: 'center',
+          offset: new AMap.Pixel(0, 0)
+        })
+        
+        // 添加点击事件
+        marker.on('click', () => {
+          this.showMachineInfoWindow(machine, marker)
+        })
+        
+        // 添加标记到地图
+        this.amap.add(marker)
+        this.machineMarkers.push(marker)
+      })
+    },
+    
+    // 创建农机标记内容
+    createMarkerContent(machine) {
+      const statusColor = this.getMarkerColor(machine.onlineStatus)
+      const icon = this.getMachineIcon(machine.machineType)
+      
+      return `
+        <div class="amap-marker" style="background-color: ${statusColor}; width: 36px; height: 36px; border-radius: 50%; display: flex; align-items: center; justify-content: center; box-shadow: 0 2px 8px rgba(0,0,0,0.15); border: 2px solid white; cursor: pointer; transition: all 0.3s ease;">
+          <i class="${icon}" style="color: white; font-size: 16px;"></i>
+        </div>
+      `
+    },
+    
+    // 获取标记颜色
+    getMarkerColor(status) {
+      const colorMap = {
+        0: '#9ca3af', // 离线
+        1: '#10b981', // 在线
+        2: '#3b82f6', // 作业中
+        3: '#f59e0b'  // 告警
+      }
+      return colorMap[status] || '#9ca3af'
+    },
+    
+    // 显示农机信息窗口
+    showMachineInfoWindow(machine, marker) {
+      const content = `
+        <div class="machine-info-window">
+          <div class="info-header">
+            <h4>${machine.machineName}</h4>
+            <span class="status-tag status-${machine.onlineStatus}">${this.getStatusText(machine.onlineStatus)}</span>
+          </div>
+          <div class="info-content">
+            <p><strong>设备编号:</strong>${machine.machineCode}</p>
+            <p><strong>负责人:</strong>${machine.operator}</p>
+            <p><strong>当前任务:</strong>${machine.currentTask}</p>
+            <p><strong>所在地块:</strong>${machine.fieldArea}</p>
+            <p><strong>作业进度:</strong>${machine.workProgress}%</p>
+          </div>
+          <div class="info-actions">
+            <button onclick="window.viewMachineDetail('${machine.id}')" class="detail-btn">查看详情</button>
+          </div>
+        </div>
+      `
+      
+      this.infoWindow.setContent(content)
+      this.infoWindow.open(this.amap, marker.getPosition())
+    },
+    
+    // 清除农机标记
+    clearMachineMarkers() {
+      if (this.machineMarkers.length > 0) {
+        this.amap.remove(this.machineMarkers)
+        this.machineMarkers = []
+      }
+    },
+    
+    // 地图控制方法更新
+    zoomIn() {
+      if (this.amap) {
+        this.amap.zoomIn()
+      }
+    },
+    
+    zoomOut() {
+      if (this.amap) {
+        this.amap.zoomOut()
+      }
+    },
+    
+    centerMap() {
+      if (this.amap) {
+        this.amap.setCenter(this.mapCenter)
+        this.amap.setZoom(12)
+      }
+    },
+    
+    toggleMapFullscreen() {
+      const mapContainer = this.$refs.mapContainer
+      if (!document.fullscreenElement) {
+        mapContainer.requestFullscreen().then(() => {
+          this.$message.success('已进入全屏模式')
+          // 全屏后重新调整地图大小
+          setTimeout(() => {
+            if (this.amap) {
+              this.amap.getSize()
+            }
+          }, 100)
+        })
+      } else {
+        document.exitFullscreen().then(() => {
+          this.$message.success('已退出全屏')
+          // 退出全屏后重新调整地图大小
+          setTimeout(() => {
+            if (this.amap) {
+              this.amap.getSize()
+            }
+          }, 100)
+        })
+      }
+    },
+
+    // 显示数据提示
+    showDataTooltip(event, index) {
+      const tooltip = this.createTooltip();
+      
+      // 根据当前选择的指标获取对应的数据
+      const chartData = {
+        area: {
+          unit: '亩',
+          points: [120, 135, 145, 160, 155, 170, 185, 200, 215, 230]
+        },
+        time: {
+          unit: '小时',
+          points: [8, 9, 9.5, 10, 9.8, 10.5, 11, 11.5, 12, 12.5]
+        },
+        efficiency: {
+          unit: '亩/小时',
+          points: [12, 13, 13.5, 14, 13.8, 14.2, 14.8, 15.2, 15.8, 16.2]
+        }
+      };
+      
+      const dates = ['1/9', '1/10', '1/11', '1/12', '1/13', '1/14', '1/15', '1/16', '1/17', '今日'];
+      const currentData = chartData[this.trendMetric];
+      
+      if (currentData && index < currentData.points.length) {
+        const value = currentData.points[index];
+        const unit = currentData.unit;
+        const date = dates[index];
+        
+        tooltip.innerHTML = `
+          <div style="font-weight: 600; margin-bottom: 4px;">${date}</div>
+          <div style="color: #3BB44A;">${value} ${unit}</div>
+        `;
+        
+        const rect = event.target.getBoundingClientRect();
+        tooltip.style.left = rect.left + 'px';
+        tooltip.style.top = (rect.top - 70) + 'px';
+        tooltip.style.opacity = '1';
+        tooltip.style.display = 'block';
+        tooltip.style.visibility = 'visible';
+        tooltip.style.position = 'fixed';
+        tooltip.style.zIndex = '99999';
+      }
+    },
+
+    // 隐藏数据提示
+    hideDataTooltip() {
+      const tooltip = document.getElementById('chart-tooltip');
+      if (tooltip) {
+        tooltip.style.opacity = '0';
+        setTimeout(() => {
+          tooltip.style.display = 'none';
+        }, 200);
+      }
+    },
+
+    // 显示保养数据提示
+    showMaintenanceDataTooltip(event, index) {
+      const tooltip = this.createMaintenanceTooltip();
+      
+      // 根据当前选择的指标获取对应的数据
+      const chartData = {
+        cost: {
+          unit: '元',
+          points: [3200, 3450, 3180, 2950, 3100, 2850, 2700, 2500]
+        },
+        frequency: {
+          unit: '次/天',
+          points: [2.1, 2.2, 2.0, 1.9, 2.1, 2.0, 1.8, 1.7]
+        },
+        efficiency: {
+          unit: '%',
+          points: [82, 84, 81, 79, 83, 80, 78, 76]
+        }
+      };
+      
+      const dates = ['1/9', '1/10', '1/11', '1/12', '1/13', '1/14', '1/15', '今日'];
+      const currentData = chartData[this.maintenanceTrendMetric];
+      
+      console.log('保养tooltip调试:', {
+        metric: this.maintenanceTrendMetric,
+        index: index,
+        currentData: currentData,
+        value: currentData ? currentData.points[index] : null
+      });
+      
+      if (currentData && index < currentData.points.length) {
+        const value = currentData.points[index];
+        const unit = currentData.unit;
+        const date = dates[index];
+        
+        let displayValue;
+        if (this.maintenanceTrendMetric === 'cost') {
+          displayValue = `¥${value.toLocaleString()}`;
+        } else if (this.maintenanceTrendMetric === 'frequency') {
+          displayValue = `${value} ${unit}`;
+        } else {
+          displayValue = `${value}${unit}`;
+        }
+        
+        console.log('保养tooltip显示值:', displayValue);
+        
+        tooltip.innerHTML = `
+          <div style="font-weight: 600; margin-bottom: 4px;">${date}</div>
+          <div style="color: #FF9800;">${displayValue}</div>
+        `;
+        
+        const rect = event.target.getBoundingClientRect();
+        tooltip.style.left = rect.left + 'px';
+        tooltip.style.top = (rect.top - 70) + 'px';
+        tooltip.style.opacity = '1';
+        tooltip.style.display = 'block';
+        tooltip.style.visibility = 'visible';
+        tooltip.style.position = 'fixed';
+        tooltip.style.zIndex = '99999';
+      }
+    },
+
+    // 隐藏保养数据提示
+    hideMaintenanceDataTooltip() {
+      const tooltip = document.getElementById('maintenance-chart-tooltip');
+      if (tooltip) {
+        tooltip.style.opacity = '0';
+        setTimeout(() => {
+          tooltip.style.display = 'none';
+        }, 200);
+      }
+    },
+
+    // 创建保养提示框
+    createMaintenanceTooltip() {
+      let tooltip = document.getElementById('maintenance-chart-tooltip');
+      if (!tooltip) {
+        tooltip = document.createElement('div');
+        tooltip.id = 'maintenance-chart-tooltip';
+        tooltip.className = 'maintenance-chart-tooltip';
+        tooltip.style.display = 'none';
+        tooltip.style.opacity = '0';
+        document.body.appendChild(tooltip);
+      }
+      return tooltip;
+    },
+
+    // 更新保养趋势图
+    updateMaintenanceTrendChart() {
+      const summaryData = {
+        cost: {
+          today: '¥2,500',
+          yesterday: '¥2,800',
+          growth: '-10.7%'
+        },
+        frequency: {
+          today: '2.3 次/天',
+          yesterday: '2.1 次/天',
+          growth: '+9.5%'
+        },
+        efficiency: {
+          today: '85.2%',
+          yesterday: '82.1%',
+          growth: '+3.8%'
+        }
+      };
+      
+      // 更新底部统计数据
+      this.maintenanceSummary = summaryData[this.maintenanceTrendMetric];
+      
+      // 更新图表数据
+      this.updateMaintenanceTrendChartData();
+    },
+
+    // 更新保养趋势图表数据
+    updateMaintenanceTrendChartData() {
+      // 根据不同的指标设置不同的数据点和单位
+      const chartData = {
+        cost: {
+          unit: '元',
+          points: [3200, 3450, 3180, 2950, 3100, 2850, 2700, 2500],
+          yCoords: [180, 160, 140, 120, 130, 110, 95, 80],
+          path: 'M30,180 L90,160 L150,140 L210,120 L270,130 L330,110 L390,95 L450,80',
+          areaPath: 'M30,180 L90,160 L150,140 L210,120 L270,130 L330,110 L390,95 L450,80 L450,260 L30,260 Z'
+        },
+        frequency: {
+          unit: '次/天',
+          points: [2.1, 2.2, 2.0, 1.9, 2.1, 2.0, 1.8, 1.7],
+          yCoords: [170, 160, 180, 190, 170, 180, 200, 210],
+          path: 'M30,170 L90,160 L150,180 L210,190 L270,170 L330,180 L390,200 L450,210',
+          areaPath: 'M30,170 L90,160 L150,180 L210,190 L270,170 L330,180 L390,200 L450,210 L450,260 L30,260 Z'
+        },
+        efficiency: {
+          unit: '%',
+          points: [82, 84, 81, 79, 83, 80, 78, 76],
+          yCoords: [160, 140, 170, 190, 150, 180, 200, 220],
+          path: 'M30,160 L90,140 L150,170 L210,190 L270,150 L330,180 L390,200 L450,220',
+          areaPath: 'M30,160 L90,140 L150,170 L210,190 L270,150 L330,180 L390,200 L450,220 L450,260 L30,260 Z'
+        }
+      };
+      
+      const currentData = chartData[this.maintenanceTrendMetric];
+      
+      console.log('保养图表更新调试:', {
+        metric: this.maintenanceTrendMetric,
+        currentData: currentData
+      });
+      
+      // 更新单位标签
+      this.$nextTick(() => {
+        const unitLabel = document.querySelector('.maintenance-chart-unit-label');
+        if (unitLabel) {
+          unitLabel.textContent = `单位:${currentData.unit}`;
+        }
+        
+        // 更新SVG路径
+        const trendLine = document.querySelector('.maintenance-trend-chart polyline');
+        const trendArea = document.querySelector('.maintenance-trend-chart path[fill="url(#maintenanceTrendGradient)"]');
+        
+        if (trendLine) {
+          // 将路径字符串转换为points格式
+          const points = currentData.path.replace(/[ML]/g, ' ').trim().split(' ').filter(p => p !== '');
+          const pointsString = points.join(' ');
+          trendLine.setAttribute('points', pointsString);
+        }
+        
+        if (trendArea) {
+          trendArea.setAttribute('d', currentData.areaPath);
+        }
+        
+        // 更新数据点位置
+        const dataPoints = document.querySelectorAll('.maintenance-trend-chart .maintenance-data-point');
+        dataPoints.forEach((point, index) => {
+          if (index < currentData.yCoords.length) {
+            // 使用预定义的Y坐标,确保与线条路径完全匹配
+            const y = currentData.yCoords[index];
+            point.setAttribute('cy', y);
+          }
+        });
+      });
+    },
+
+    // 获取保养指标标签
+    getMaintenanceMetricLabel() {
+      const labels = {
+        cost: '费用',
+        frequency: '频次',
+        efficiency: '效率'
+      };
+      return labels[this.maintenanceTrendMetric] || '费用';
+    },
+
+    // 创建提示框
+    createTooltip() {
+      let tooltip = document.getElementById('chart-tooltip');
+      if (!tooltip) {
+        tooltip = document.createElement('div');
+        tooltip.id = 'chart-tooltip';
+        tooltip.className = 'chart-tooltip';
+        tooltip.style.display = 'none';
+        tooltip.style.opacity = '0';
+        document.body.appendChild(tooltip);
+      }
+      return tooltip;
+    },
+
+    // 保养图表交互方法
+    handleMaintenanceLegendHover(status, isEnter) {
+      const segments = document.querySelectorAll('.maintenance-segment');
+      const legendItems = document.querySelectorAll('.maintenance-legend-item-enhanced');
+      
+      if (isEnter) {
+        // 高亮对应的饼图段
+        segments.forEach(segment => {
+          if (segment.dataset.status === status) {
+            segment.classList.add('highlighted');
+          } else {
+            segment.classList.add('dimmed');
+          }
+        });
+        
+        // 高亮对应的图例项
+        legendItems.forEach(item => {
+          if (item.dataset.status === status) {
+            item.classList.add('active');
+          }
+        });
+      } else {
+        // 移除所有高亮和暗化效果
+        segments.forEach(segment => {
+          segment.classList.remove('highlighted', 'dimmed');
+        });
+        
+        legendItems.forEach(item => {
+          item.classList.remove('active');
+        });
+      }
+    },
+
+
+
+
+  }
+}
+</script>
+
+<style scoped>
+.machines-monitor-container {
+  padding: 20px;
+  background: #f5f7f9;
+  min-height: 100vh;
+}
+
+
+
+/* 控制面板 */
+.machines-monitor-container > .control-panel {
+  background: white;
+  border: 1px solid #e5e7eb;
+  border-radius: 16px;
+  padding: 1.5rem;
+  margin-bottom: 2rem;
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  gap: 2rem;
+  transition: all 0.3s ease;
+  box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
+}
+
+.machines-monitor-container > .control-panel:hover {
+  transform: translateY(-4px);
+  box-shadow: 0 10px 20px -5px rgba(0, 0, 0, 0.15);
+  border-color: #10b981;
+}
+
+.control-left {
+  display: flex;
+  gap: 1.5rem;
+  flex: 1;
+}
+
+.form-group {
+  display: flex;
+  align-items: center;
+  gap: 0.5rem;
+}
+
+.form-group label {
+  font-size: 0.875rem;
+  color: #6b7280;
+  white-space: nowrap;
+}
+
+.form-group select {
+  background-color: white;
+  border: 1px solid #d1d5db;
+  color: #1f2937;
+  padding: 8px 12px;
+  border-radius: 8px;
+  min-width: 150px;
+}
+
+.form-group select:focus {
+  outline: none;
+  border-color: #10b981;
+  box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.1);
+}
+
+.control-right {
+  display: flex;
+  align-items: center;
+  gap: 1rem;
+}
+
+.refresh-btn {
+  background-color: #10b981;
+  color: white;
+  border: none;
+  padding: 10px 20px;
+  border-radius: 8px;
+  cursor: pointer;
+  display: flex;
+  align-items: center;
+  gap: 8px;
+  font-weight: 500;
+  transition: all 0.2s ease;
+}
+
+.refresh-btn:hover {
+  background-color: #059669;
+  transform: translateY(-1px);
+  box-shadow: 0 4px 12px rgba(16, 185, 129, 0.4);
+}
+
+.auto-refresh {
+  display: flex;
+  align-items: center;
+  gap: 0.5rem;
+  font-size: 0.875rem;
+  color: #6b7280;
+}
+
+.auto-refresh-select {
+  background-color: white;
+  border: 1px solid #d1d5db;
+  color: #1f2937;
+  padding: 4px 8px;
+  border-radius: 6px;
+  font-size: 0.875rem;
+}
+
+.auto-refresh-select:focus {
+  outline: none;
+  border-color: #10b981;
+  box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.1);
+}
+
+.last-update {
+  font-size: 0.875rem;
+  color: #6b7280;
+}
+
+.last-update span {
+  color: #1f2937;
+  font-weight: 500;
+}
+
+/* 统计卡片 */
+.stats-row {
+  margin-bottom: 20px;
+}
+
+.stat-card {
+  background: white;
+  border: 1px solid #e5e7eb;
+  border-radius: 12px;
+  transition: all 0.3s ease;
+  position: relative;
+  overflow: hidden;
+  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
+}
+
+.stat-card:hover {
+  transform: translateY(-4px);
+  box-shadow: 0 8px 25px rgba(16, 185, 129, 0.25);
+  border-color: #10b981;
+  border-width: 2px;
+}
+
+.stat-content {
+  padding: 20px;
+}
+
+.stat-label {
+  font-size: 14px;
+  color: #6b7280;
+  margin-bottom: 8px;
+}
+
+.stat-value {
+  font-size: 32px;
+  font-weight: 700;
+  color: #1f2937;
+  margin-bottom: 12px;
+}
+
+/* 不同类型卡片的数值颜色 */
+.stat-card.total .stat-value {
+  color: #10b981;
+}
+
+.stat-card.online .stat-value {
+  color: #3b82f6;
+}
+
+.stat-card.working .stat-value {
+  color: #10b981;
+}
+
+.stat-card.warning .stat-value {
+  color: #f59e0b;
+}
+
+.stat-card.maintenance-due .stat-value {
+  color: #f59e0b;
+}
+
+.stat-card.maintenance-progress .stat-value {
+  color: #3b82f6;
+}
+
+.stat-card.maintenance-overdue .stat-value {
+  color: #ef4444;
+}
+
+.stat-card.maintenance-cost .stat-value {
+  color: #10b981;
+}
+
+.stat-trend {
+  display: flex;
+  align-items: center;
+  gap: 6px;
+  font-size: 12px;
+  color: #6b7280;
+}
+
+/* 地图卡片 */
+.map-card {
+  margin-bottom: 20px;
+}
+
+.map-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+
+.map-title {
+  font-size: 16px;
+  font-weight: 600;
+  color: #374151;
+}
+
+.map-container {
+  position: relative;
+  height: 400px;
+  background: #f8fafc;
+  border-radius: 8px;
+  overflow: hidden;
+}
+
+.amap-container {
+  width: 100%;
+  height: 100%;
+  border-radius: 8px;
+}
+
+.map-loading {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  height: 100%;
+  color: #6b7280;
+}
+
+.map-area {
+  width: 100%;
+  height: 100%;
+  background: linear-gradient(45deg, #f3f4f6 25%, transparent 25%), 
+              linear-gradient(-45deg, #f3f4f6 25%, transparent 25%), 
+              linear-gradient(45deg, transparent 75%, #f3f4f6 75%), 
+              linear-gradient(-45deg, transparent 75%, #f3f4f6 75%);
+  background-size: 20px 20px;
+  background-position: 0 0, 0 10px, 10px -10px, -10px 0px;
+  background-color: #e5e7eb;
+  position: relative;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+.map-placeholder {
+  text-align: center;
+  color: #6b7280;
+}
+
+.map-placeholder i {
+  font-size: 48px;
+  margin-bottom: 16px;
+  color: #9ca3af;
+}
+
+.placeholder-title {
+  font-size: 18px;
+  font-weight: 600;
+  margin-bottom: 8px;
+  color: #374151;
+}
+
+.placeholder-desc {
+  font-size: 14px;
+}
+
+/* 高德地图农机标记样式 */
+.custom-marker {
+  position: relative;
+  z-index: 10;
+}
+
+.amap-marker {
+  width: 36px;
+  height: 36px;
+  border-radius: 50%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  box-shadow: 0 2px 8px rgba(0,0,0,0.15);
+  border: 2px solid white;
+  cursor: pointer;
+  transition: all 0.3s ease;
+  position: relative;
+}
+
+.amap-marker:hover {
+  transform: scale(1.2);
+  box-shadow: 0 4px 12px rgba(0,0,0,0.25);
+}
+
+.amap-marker i {
+  font-size: 16px !important;
+  color: white !important;
+}
+
+/* 高德地图信息窗口样式 */
+.machine-info-window {
+  width: 280px;
+  font-family: 'Helvetica Neue', Arial, sans-serif;
+}
+
+.machine-info-window .info-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 12px;
+  padding-bottom: 8px;
+  border-bottom: 1px solid #e5e7eb;
+}
+
+.machine-info-window .info-header h4 {
+  margin: 0;
+  color: #1f2937;
+  font-size: 16px;
+  font-weight: 600;
+}
+
+.machine-info-window .status-tag {
+  padding: 2px 8px;
+  border-radius: 12px;
+  font-size: 12px;
+  font-weight: 500;
+}
+
+.machine-info-window .status-tag.status-0 {
+  background-color: rgba(156, 163, 175, 0.1);
+  color: #6b7280;
+}
+
+.machine-info-window .status-tag.status-1 {
+  background-color: rgba(16, 185, 129, 0.1);
+  color: #10b981;
+}
+
+.machine-info-window .status-tag.status-2 {
+  background-color: rgba(59, 130, 246, 0.1);
+  color: #3b82f6;
+}
+
+.machine-info-window .status-tag.status-3 {
+  background-color: rgba(245, 158, 11, 0.1);
+  color: #f59e0b;
+}
+
+.machine-info-window .info-content p {
+  margin: 8px 0;
+  font-size: 14px;
+  color: #374151;
+  line-height: 1.4;
+}
+
+.machine-info-window .info-actions {
+  margin-top: 12px;
+  padding-top: 12px;
+  border-top: 1px solid #e5e7eb;
+}
+
+.machine-info-window .detail-btn {
+  background-color: #10b981;
+  color: white;
+  border: none;
+  padding: 6px 12px;
+  border-radius: 6px;
+  font-size: 12px;
+  cursor: pointer;
+  transition: background-color 0.2s;
+}
+
+.machine-info-window .detail-btn:hover {
+  background-color: #059669;
+}
+
+/* 农机弹层 */
+.machine-popup {
+  position: absolute;
+  background: white;
+  border-radius: 12px;
+  padding: 20px;
+  min-width: 280px;
+  box-shadow: 0 8px 24px rgba(0,0,0,0.15);
+  z-index: 30;
+  border: 1px solid #e5e7eb;
+}
+
+.machine-popup::before {
+  content: '';
+  position: absolute;
+  bottom: -8px;
+  left: 50%;
+  transform: translateX(-50%);
+  width: 0;
+  height: 0;
+  border: 8px solid transparent;
+  border-top-color: white;
+}
+
+.popup-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: flex-start;
+  margin-bottom: 16px;
+}
+
+.machine-name {
+  font-size: 16px;
+  font-weight: 600;
+  color: #1f2937;
+  margin-bottom: 4px;
+}
+
+.machine-id {
+  font-size: 12px;
+  color: #6b7280;
+}
+
+.popup-content {
+  margin-bottom: 16px;
+}
+
+.info-item {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 8px;
+  font-size: 14px;
+}
+
+.info-item .label {
+  color: #6b7280;
+}
+
+.info-item .value {
+  font-weight: 500;
+  color: #374151;
+}
+
+.maintenance-section {
+  border-top: 1px solid #e5e7eb;
+  padding-top: 12px;
+  margin-bottom: 16px;
+}
+
+.section-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 8px;
+}
+
+.section-title {
+  font-size: 14px;
+  font-weight: 600;
+  color: #374151;
+}
+
+.maintenance-details .info-item {
+  margin-bottom: 6px;
+}
+
+.popup-actions {
+  display: flex;
+  gap: 8px;
+}
+
+/* 分析卡片 */
+.analysis-card {
+  margin-bottom: 20px;
+}
+
+.analysis-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: flex-start;
+}
+
+.header-left {
+  flex: 1;
+}
+
+.analysis-title {
+  font-size: 18px;
+  font-weight: 600;
+  color: #1f2937;
+  margin: 0 0 4px 0;
+}
+
+.analysis-subtitle {
+  font-size: 14px;
+  color: #6b7280;
+  margin: 0;
+}
+
+.header-right {
+  display: flex;
+  align-items: center;
+  gap: 12px;
+}
+
+/* 作业统计指标卡片 */
+.metrics-row {
+  margin-bottom: 24px;
+}
+
+.work-metric-card {
+  background: linear-gradient(135deg, #ffffff 0%, #f8fafc 100%);
+  border: 1px solid #e5e7eb;
+  border-radius: 16px;
+  padding: 24px;
+  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
+  position: relative;
+  overflow: hidden;
+  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
+  animation: fadeInUp 0.6s ease-out;
+}
+
+@keyframes fadeInUp {
+  from {
+    opacity: 0;
+    transform: translateY(20px);
+  }
+  to {
+    opacity: 1;
+    transform: translateY(0);
+  }
+}
+
+/* 为不同卡片添加延迟动画 */
+.work-metric-card:nth-child(1) {
+  animation-delay: 0.1s;
+}
+
+.work-metric-card:nth-child(2) {
+  animation-delay: 0.2s;
+}
+
+.work-metric-card:nth-child(3) {
+  animation-delay: 0.3s;
+}
+
+.work-metric-card:hover {
+  transform: translateY(-6px);
+  box-shadow: 0 12px 32px rgba(16, 185, 129, 0.15);
+  border-color: #10b981;
+}
+
+.metric-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: flex-start;
+  margin-bottom: 20px;
+}
+
+.metric-icon-wrapper {
+  width: 56px;
+  height: 56px;
+  border-radius: 16px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  background: linear-gradient(135deg, #f0fdf4 0%, #dcfce7 100%);
+  border: 2px solid #bbf7d0;
+  transition: all 0.3s ease;
+}
+
+.work-metric-card:hover .metric-icon-wrapper {
+  transform: scale(1.1);
+  box-shadow: 0 4px 12px rgba(16, 185, 129, 0.2);
+}
+
+.metric-icon-wrapper i {
+  font-size: 24px;
+  color: #10b981;
+}
+
+/* 不同类型卡片的图标背景色 */
+.area-metric .metric-icon-wrapper {
+  background: linear-gradient(135deg, #f0fdf4 0%, #dcfce7 100%);
+  border-color: #bbf7d0;
+}
+
+.area-metric .metric-icon-wrapper i {
+  color: #10b981;
+}
+
+.time-metric .metric-icon-wrapper {
+  background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);
+  border-color: #bfdbfe;
+}
+
+.time-metric .metric-icon-wrapper i {
+  color: #3b82f6;
+}
+
+.efficiency-metric .metric-icon-wrapper {
+  background: linear-gradient(135deg, #fffbeb 0%, #fef3c7 100%);
+  border-color: #fde68a;
+}
+
+.efficiency-metric .metric-icon-wrapper i {
+  color: #f59e0b;
+}
+
+.metric-trend-badge {
+  display: flex;
+  align-items: center;
+  gap: 4px;
+  padding: 6px 12px;
+  border-radius: 20px;
+  font-size: 12px;
+  font-weight: 600;
+  transition: all 0.3s ease;
+}
+
+.metric-trend-badge.positive {
+  background: linear-gradient(135deg, #dcfce7 0%, #bbf7d0 100%);
+  color: #10b981;
+  border: 1px solid #86efac;
+}
+
+.metric-trend-badge.negative {
+  background: linear-gradient(135deg, #fee2e2 0%, #fecaca 100%);
+  color: #ef4444;
+  border: 1px solid #fca5a5;
+}
+
+.metric-trend-badge.neutral {
+  background: linear-gradient(135deg, #f3f4f6 0%, #e5e7eb 100%);
+  color: #6b7280;
+  border: 1px solid #d1d5db;
+}
+
+.metric-body {
+  margin-bottom: 20px;
+}
+
+.metric-value {
+  font-size: 32px;
+  font-weight: 800;
+  color: #1f2937;
+  line-height: 1.1;
+  margin-bottom: 8px;
+  letter-spacing: -0.5px;
+}
+
+.metric-unit {
+  font-size: 16px;
+  font-weight: 600;
+  color: #6b7280;
+  margin-left: 4px;
+}
+
+.metric-label {
+  font-size: 16px;
+  font-weight: 600;
+  color: #374151;
+  margin-bottom: 6px;
+}
+
+.metric-desc {
+  font-size: 13px;
+  color: #9ca3af;
+  line-height: 1.4;
+}
+
+.metric-footer {
+  display: flex;
+  align-items: center;
+  gap: 12px;
+}
+
+.progress-bar {
+  flex: 1;
+  height: 6px;
+  background: #f3f4f6;
+  border-radius: 3px;
+  overflow: hidden;
+}
+
+.progress-fill {
+  height: 100%;
+  background: linear-gradient(90deg, #10b981, #34d399);
+  border-radius: 3px;
+  transition: width 0.8s cubic-bezier(0.4, 0, 0.2, 1);
+  position: relative;
+  overflow: hidden;
+}
+
+.progress-fill::after {
+  content: '';
+  position: absolute;
+  top: 0;
+  left: -100%;
+  width: 100%;
+  height: 100%;
+  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent);
+  animation: shimmer 2s infinite;
+}
+
+@keyframes shimmer {
+  0% {
+    left: -100%;
+  }
+  100% {
+    left: 100%;
+  }
+}
+
+/* 不同类型卡片的进度条颜色 */
+.time-metric .progress-fill {
+  background: linear-gradient(90deg, #3b82f6, #60a5fa);
+}
+
+.efficiency-metric .progress-fill {
+  background: linear-gradient(90deg, #f59e0b, #fbbf24);
+}
+
+.progress-text {
+  font-size: 12px;
+  font-weight: 600;
+  color: #6b7280;
+  white-space: nowrap;
+}
+
+/* 保养统计指标卡片样式 */
+.maintenance-metric-card {
+  background: linear-gradient(135deg, #ffffff 0%, #f8fafc 100%);
+  border: 1px solid #e5e7eb;
+  border-radius: 16px;
+  padding: 24px;
+  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
+  position: relative;
+  overflow: hidden;
+  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
+  animation: fadeInUp 0.6s ease-out;
+}
+
+/* 为不同卡片添加延迟动画 */
+.maintenance-metric-card:nth-child(1) {
+  animation-delay: 0.1s;
+}
+
+.maintenance-metric-card:nth-child(2) {
+  animation-delay: 0.2s;
+}
+
+.maintenance-metric-card:nth-child(3) {
+  animation-delay: 0.3s;
+}
+
+.maintenance-metric-card:hover {
+  transform: translateY(-6px);
+  box-shadow: 0 12px 32px rgba(16, 185, 129, 0.15);
+  border-color: #10b981;
+}
+
+.maintenance-metric-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: flex-start;
+  margin-bottom: 20px;
+}
+
+.maintenance-metric-icon-wrapper {
+  width: 56px;
+  height: 56px;
+  border-radius: 16px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  background: linear-gradient(135deg, #f0fdf4 0%, #dcfce7 100%);
+  border: 2px solid #bbf7d0;
+  transition: all 0.3s ease;
+}
+
+.maintenance-metric-card:hover .maintenance-metric-icon-wrapper {
+  transform: scale(1.1);
+  box-shadow: 0 4px 12px rgba(16, 185, 129, 0.2);
+}
+
+.maintenance-metric-icon-wrapper i {
+  font-size: 24px;
+  color: #10b981;
+}
+
+/* 不同类型保养卡片的图标背景色 */
+.execution-metric .maintenance-metric-icon-wrapper {
+  background: linear-gradient(135deg, #f0fdf4 0%, #dcfce7 100%);
+  border-color: #bbf7d0;
+}
+
+.execution-metric .maintenance-metric-icon-wrapper i {
+  color: #10b981;
+}
+
+.cycle-metric .maintenance-metric-icon-wrapper {
+  background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);
+  border-color: #bfdbfe;
+}
+
+.cycle-metric .maintenance-metric-icon-wrapper i {
+  color: #3b82f6;
+}
+
+.cost-metric .maintenance-metric-icon-wrapper {
+  background: linear-gradient(135deg, #fffbeb 0%, #fef3c7 100%);
+  border-color: #fde68a;
+}
+
+.cost-metric .maintenance-metric-icon-wrapper i {
+  color: #f59e0b;
+}
+
+.maintenance-metric-trend-badge {
+  display: flex;
+  align-items: center;
+  gap: 4px;
+  padding: 6px 12px;
+  border-radius: 20px;
+  font-size: 12px;
+  font-weight: 600;
+  transition: all 0.3s ease;
+}
+
+.maintenance-metric-trend-badge.positive {
+  background: linear-gradient(135deg, #dcfce7 0%, #bbf7d0 100%);
+  color: #10b981;
+  border: 1px solid #86efac;
+}
+
+.maintenance-metric-trend-badge.negative {
+  background: linear-gradient(135deg, #fee2e2 0%, #fecaca 100%);
+  color: #ef4444;
+  border: 1px solid #fca5a5;
+}
+
+.maintenance-metric-trend-badge.neutral {
+  background: linear-gradient(135deg, #f3f4f6 0%, #e5e7eb 100%);
+  color: #6b7280;
+  border: 1px solid #d1d5db;
+}
+
+.maintenance-metric-body {
+  margin-bottom: 20px;
+}
+
+.maintenance-metric-value {
+  font-size: 32px;
+  font-weight: 800;
+  color: #1f2937;
+  line-height: 1.1;
+  margin-bottom: 8px;
+  letter-spacing: -0.5px;
+}
+
+.maintenance-metric-unit {
+  font-size: 16px;
+  font-weight: 600;
+  color: #6b7280;
+  margin-left: 4px;
+}
+
+.maintenance-metric-label {
+  font-size: 16px;
+  font-weight: 600;
+  color: #374151;
+  margin-bottom: 6px;
+}
+
+.maintenance-metric-desc {
+  font-size: 13px;
+  color: #9ca3af;
+  line-height: 1.4;
+}
+
+.maintenance-metric-footer {
+  display: flex;
+  align-items: center;
+  gap: 12px;
+}
+
+.maintenance-progress-bar {
+  flex: 1;
+  height: 6px;
+  background: #f3f4f6;
+  border-radius: 3px;
+  overflow: hidden;
+}
+
+.maintenance-progress-fill {
+  height: 100%;
+  background: linear-gradient(90deg, #10b981, #34d399);
+  border-radius: 3px;
+  transition: width 0.8s cubic-bezier(0.4, 0, 0.2, 1);
+  position: relative;
+  overflow: hidden;
+}
+
+.maintenance-progress-fill::after {
+  content: '';
+  position: absolute;
+  top: 0;
+  left: -100%;
+  width: 100%;
+  height: 100%;
+  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent);
+  animation: shimmer 2s infinite;
+}
+
+/* 不同类型保养卡片的进度条颜色 */
+.cycle-metric .maintenance-progress-fill {
+  background: linear-gradient(90deg, #3b82f6, #60a5fa);
+}
+
+.cost-metric .maintenance-progress-fill {
+  background: linear-gradient(90deg, #f59e0b, #fbbf24);
+}
+
+.maintenance-progress-text {
+  font-size: 12px;
+  font-weight: 600;
+  color: #6b7280;
+  white-space: nowrap;
+}
+
+/* 保留原有的保养指标卡片样式(兼容性) */
+.metric-card {
+  background: linear-gradient(135deg, #ffffff 0%, #f9fafb 100%);
+  border: 1px solid #e5e7eb;
+  border-radius: 12px;
+  padding: 20px;
+  transition: all 0.3s;
+  position: relative;
+  overflow: hidden;
+}
+
+.metric-card::before {
+  content: '';
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  height: 4px;
+  background: linear-gradient(90deg, #10b981, #34d399);
+}
+
+.metric-card:hover {
+  transform: translateY(-4px);
+  box-shadow: 0 8px 24px rgba(16, 185, 129, 0.12);
+}
+
+.metric-icon {
+  margin-bottom: 12px;
+}
+
+.metric-icon i {
+  font-size: 32px;
+  color: #10b981;
+}
+
+.metric-content {
+  margin-bottom: 12px;
+}
+
+.metric-label {
+  font-size: 14px;
+  color: #6b7280;
+  margin-bottom: 8px;
+  font-weight: 500;
+}
+
+.metric-value {
+  font-size: 28px;
+  font-weight: 700;
+  color: #1f2937;
+  line-height: 1.1;
+}
+
+.metric-unit {
+  font-size: 14px;
+  font-weight: 500;
+  color: #6b7280;
+  margin-left: 4px;
+}
+
+.metric-trend {
+  display: flex;
+  flex-direction: column;
+  gap: 4px;
+}
+
+.metric-trend.positive .trend-text {
+  color: #10b981;
+}
+
+.trend-text {
+  font-size: 14px;
+  font-weight: 600;
+}
+
+.trend-desc {
+  font-size: 12px;
+  color: #9ca3af;
+}
+
+/* 保养指标特殊样式 */
+.metric-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 16px;
+}
+
+.metric-title {
+  font-size: 14px;
+  font-weight: 600;
+  color: #374151;
+  margin: 0;
+}
+
+.metric-trend.neutral {
+  color: #6b7280;
+}
+
+.metric-body {
+  margin-bottom: 12px;
+}
+
+.metric-subtitle {
+  font-size: 12px;
+  color: #9ca3af;
+  margin-top: 8px;
+}
+
+/* 图表区域 */
+.charts-row {
+  margin-bottom: 24px;
+}
+
+.chart-card {
+  background: white;
+  border: 1px solid #e5e7eb;
+  border-radius: 12px;
+  padding: 20px;
+  transition: all 0.3s;
+  min-height: 400px;
+}
+
+.chart-card:hover {
+  box-shadow: 0 4px 12px rgba(0,0,0,0.08);
+}
+
+.chart-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 16px;
+  padding-bottom: 12px;
+  border-bottom: 1px solid #f0f0f0;
+}
+
+.chart-title {
+  font-size: 16px;
+  font-weight: 600;
+  color: #1f2937;
+  margin: 0;
+}
+
+.chart-content {
+  padding: 16px 0;
+}
+
+.chart-container {
+  height: 260px;
+  background: #f8fafc;
+  border-radius: 8px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  color: #6b7280;
+  font-size: 14px;
+}
+
+/* 趋势汇总 */
+.trend-summary {
+  display: flex;
+  justify-content: space-around;
+  padding: 16px 0;
+  border-top: 1px solid #f0f0f0;
+  margin-top: 16px;
+}
+
+.summary-item {
+  text-align: center;
+}
+
+.summary-label {
+  display: block;
+  font-size: 12px;
+  color: #6b7280;
+  margin-bottom: 6px;
+  font-weight: 500;
+}
+
+.summary-value {
+  font-size: 16px;
+  font-weight: 600;
+  color: #374151;
+}
+
+.summary-value.primary {
+  color: #10b981;
+}
+
+.summary-value.positive {
+  color: #10b981;
+}
+
+/* 响应式设计 */
+@media (max-width: 1200px) {
+  
+  .control-panel {
+    flex-direction: column;
+    gap: 1rem;
+  }
+  
+  .control-left, .control-right {
+    justify-content: space-between;
+  }
+  
+  .charts-row {
+    display: block;
+  }
+  
+  .charts-row .el-col {
+    width: 100%;
+    margin-bottom: 20px;
+  }
+  
+  /* 作业统计卡片响应式 */
+  .metrics-row .el-col {
+    margin-bottom: 20px;
+  }
+  
+  .work-metric-card {
+    padding: 20px;
+  }
+  
+  .metric-value {
+    font-size: 28px;
+  }
+  
+  .metric-icon-wrapper {
+    width: 48px;
+    height: 48px;
+  }
+  
+  .metric-icon-wrapper i {
+    font-size: 20px;
+  }
+}
+
+@media (max-width: 768px) {
+  .machines-monitor-container {
+    padding: 12px;
+  }
+  
+  .control-panel {
+    padding: 1rem;
+    flex-direction: column;
+    gap: 1rem;
+    align-items: stretch;
+  }
+  
+  .control-left {
+    flex-direction: column;
+    gap: 1rem;
+  }
+  
+  .control-right {
+    flex-direction: column;
+    align-items: stretch;
+    gap: 1rem;
+  }
+  
+  .form-group {
+    justify-content: space-between;
+  }
+  
+  .stats-row .el-col {
+    margin-bottom: 12px;
+  }
+  
+  .metrics-row .el-col {
+    margin-bottom: 16px;
+  }
+  
+  /* 作业统计卡片移动端优化 */
+  .work-metric-card {
+    padding: 16px;
+  }
+  
+  .metric-header {
+    margin-bottom: 16px;
+  }
+  
+  .metric-icon-wrapper {
+    width: 44px;
+    height: 44px;
+  }
+  
+  .metric-icon-wrapper i {
+    font-size: 18px;
+  }
+  
+  .metric-value {
+    font-size: 24px;
+  }
+  
+  .metric-label {
+    font-size: 14px;
+  }
+  
+  .metric-desc {
+    font-size: 12px;
+  }
+  
+  .metric-footer {
+    flex-direction: column;
+    align-items: flex-start;
+    gap: 8px;
+  }
+  
+  .progress-bar {
+    width: 100%;
+  }
+  
+  /* 保养统计卡片移动端优化 */
+  .maintenance-metric-card {
+    padding: 16px;
+  }
+  
+  .maintenance-metric-header {
+    margin-bottom: 16px;
+  }
+  
+  .maintenance-metric-icon-wrapper {
+    width: 44px;
+    height: 44px;
+  }
+  
+  .maintenance-metric-icon-wrapper i {
+    font-size: 18px;
+  }
+  
+  .maintenance-metric-value {
+    font-size: 24px;
+  }
+  
+  .maintenance-metric-label {
+    font-size: 14px;
+  }
+  
+  .maintenance-metric-desc {
+    font-size: 12px;
+  }
+  
+  .maintenance-metric-footer {
+    flex-direction: column;
+    align-items: flex-start;
+    gap: 8px;
+  }
+  
+  .maintenance-progress-bar {
+    width: 100%;
+  }
+  
+  .map-container {
+    height: 300px;
+  }
+  
+  .machine-popup {
+    min-width: 240px;
+    padding: 16px;
+  }
+  
+  .popup-actions {
+    flex-direction: column;
+  }
+}
+
+@media (max-width: 480px) {
+  .work-metric-card {
+    padding: 12px;
+  }
+  
+  .metric-header {
+    flex-direction: column;
+    align-items: flex-start;
+    gap: 12px;
+  }
+  
+  .metric-trend-badge {
+    align-self: flex-end;
+  }
+  
+  .metric-value {
+    font-size: 20px;
+  }
+  
+  .metric-unit {
+    font-size: 14px;
+  }
+  
+  .metric-label {
+    font-size: 13px;
+  }
+  
+  /* 保养统计卡片小屏幕优化 */
+  .maintenance-metric-card {
+    padding: 12px;
+  }
+  
+  .maintenance-metric-header {
+    flex-direction: column;
+    align-items: flex-start;
+    gap: 12px;
+  }
+  
+  .maintenance-metric-trend-badge {
+    align-self: flex-end;
+  }
+  
+  .maintenance-metric-value {
+    font-size: 20px;
+  }
+  
+  .maintenance-metric-unit {
+    font-size: 14px;
+  }
+  
+  .maintenance-metric-label {
+    font-size: 13px;
+  }
+}
+
+/* 图表卡片内容横向布局和高度统一 */
+.chart-flex-content {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  flex: 1;
+  padding: 0;
+  position: relative;
+  box-sizing: border-box;
+  min-height: 0;
+}
+
+.donut-chart-flex {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: 100%;
+  height: 100%;
+  gap: 40px;
+}
+
+.donut-container {
+  flex-shrink: 0;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: 240px;
+  height: 240px;
+}
+
+.donut-legend-vertical {
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  gap: 24px;
+  min-width: 140px;
+}
+
+.donut-legend-vertical .legend-item {
+  display: flex;
+  align-items: center;
+  gap: 12px;
+  font-size: 16px;
+  color: #374151;
+  padding: 8px 12px;
+  border-radius: 8px;
+  transition: all 0.2s ease;
+}
+
+.donut-legend-vertical .legend-item:hover {
+  background-color: #f9fafb;
+  transform: translateX(4px);
+}
+
+.donut-legend-vertical .legend-color {
+  width: 20px;
+  height: 20px;
+  border-radius: 6px;
+  flex-shrink: 0;
+  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+}
+
+.donut-legend-vertical .legend-label {
+  font-weight: 600;
+  min-width: 64px;
+  color: #1f2937;
+}
+
+.donut-legend-vertical .legend-value {
+  font-weight: 700;
+  color: #10b981;
+  margin-left: auto;
+  font-size: 18px;
+}
+
+.trend-chart {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: 100%;
+  height: 100%;
+}
+
+.chart-area {
+  width: 100%;
+  height: 240px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  position: relative;
+}
+
+.trend-summary-align {
+  display: flex;
+  justify-content: space-around;
+  align-items: center;
+  padding: 20px 0 0 0;
+  border-top: 1px solid #e5e7eb;
+  margin-top: 0;
+  background: linear-gradient(135deg, #f9fafb 0%, #f3f4f6 100%);
+  border-radius: 0 0 12px 12px;
+}
+
+.summary-item {
+  text-align: center;
+  padding: 16px 20px;
+  border-radius: 8px;
+  transition: all 0.2s ease;
+}
+
+.summary-item:hover {
+  background-color: white;
+  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+  transform: translateY(-2px);
+}
+
+.summary-label {
+  display: block;
+  font-size: 13px;
+  color: #6b7280;
+  margin-bottom: 8px;
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.5px;
+}
+
+.summary-value {
+  font-size: 18px;
+  font-weight: 700;
+  color: #374151;
+  display: block;
+}
+
+.summary-value.primary {
+  color: #10b981;
+  font-size: 20px;
+}
+
+.summary-value.positive {
+  color: #10b981;
+}
+
+/* 图表卡片布局优化 */
+.chart-card-donut {
+  min-height: 420px;
+  background: linear-gradient(135deg, #ffffff 0%, #f8fafc 100%);
+  border: 1px solid #e5e7eb;
+  border-radius: 16px;
+  transition: all 0.3s ease;
+}
+
+.chart-card-donut:hover {
+  transform: translateY(-4px);
+  box-shadow: 0 12px 32px rgba(16, 185, 129, 0.15);
+  border-color: #10b981;
+}
+
+.chart-card-trend {
+  min-height: 420px;
+  background: linear-gradient(135deg, #ffffff 0%, #f8fafc 100%);
+  border: 1px solid #e5e7eb;
+  border-radius: 16px;
+  transition: all 0.3s ease;
+}
+
+.chart-card-trend:hover {
+  transform: translateY(-4px);
+  box-shadow: 0 12px 32px rgba(16, 185, 129, 0.15);
+  border-color: #10b981;
+}
+
+.chart-unit-label {
+  position: absolute;
+  top: 12px;
+  right: 20px;
+  font-size: 13px;
+  color: #6B7280;
+  font-weight: 600;
+  z-index: 10;
+  background: rgba(255, 255, 255, 0.9);
+  padding: 4px 8px;
+  border-radius: 6px;
+  border: 1px solid #e5e7eb;
+}
+
+/* 数据点交互样式 */
+.data-point {
+  cursor: pointer;
+  transition: all 0.3s ease;
+}
+
+.data-point:hover {
+  r: 8;
+  fill: #2A8F38;
+  stroke: white;
+  stroke-width: 3;
+  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.2));
+}
+
+/* Tooltip样式 */
+.chart-tooltip {
+  position: fixed !important;
+  background: rgba(0, 0, 0, 0.9) !important;
+  color: white !important;
+  padding: 10px 14px !important;
+  border-radius: 8px !important;
+  font-size: 13px !important;
+  pointer-events: none !important;
+  z-index: 99999 !important;
+  opacity: 0;
+  transition: opacity 0.3s ease !important;
+  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.2) !important;
+  border: 1px solid rgba(255, 255, 255, 0.1) !important;
+  display: none;
+  min-width: 80px;
+  text-align: center;
+}
+
+.chart-tooltip.show {
+  opacity: 1;
+}
+
+.chart-tooltip::before {
+  content: '';
+  position: absolute;
+  top: 100%;
+  left: 50%;
+  transform: translateX(-50%);
+  width: 0;
+  height: 0;
+  border: 5px solid transparent;
+  border-top-color: rgba(0, 0, 0, 0.9);
+}
+
+/* 图表标题样式优化 */
+.chart-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 20px;
+  padding-bottom: 16px;
+  border-bottom: 2px solid #f0f4f1;
+}
+
+.chart-title {
+  font-size: 18px;
+  font-weight: 700;
+  color: #1f2937;
+  margin: 0;
+  position: relative;
+}
+
+
+
+.chart-controls {
+  display: flex;
+  align-items: center;
+  gap: 8px;
+}
+
+/* 响应式布局优化 */
+@media (max-width: 1200px) {
+  .chart-flex-content {
+    flex: 1;
+    min-height: 0;
+    box-sizing: border-box;
+  }
+  
+  .donut-chart-flex {
+    flex-direction: column;
+    gap: 24px;
+  }
+  
+  .donut-legend-vertical {
+    flex-direction: row;
+    justify-content: center;
+    gap: 20px;
+    margin-top: 0;
+  }
+  
+  .chart-area {
+    width: 100%;
+    min-width: 0;
+  }
+  
+  .chart-card-donut,
+  .chart-card-trend {
+    min-height: 360px;
+  }
+}
+
+@media (max-width: 768px) {
+  .chart-flex-content {
+    flex: 1;
+    min-height: 0;
+    box-sizing: border-box;
+  }
+  
+  .donut-container {
+    width: 200px;
+    height: 200px;
+  }
+  
+  .donut-legend-vertical {
+    flex-direction: column;
+    gap: 16px;
+    align-items: flex-start;
+  }
+  
+  .donut-legend-vertical .legend-item {
+    font-size: 14px;
+    gap: 10px;
+  }
+  
+  .donut-legend-vertical .legend-color {
+    width: 18px;
+    height: 18px;
+  }
+  
+  .donut-legend-vertical .legend-label {
+    min-width: 56px;
+  }
+  
+  .donut-legend-vertical .legend-value {
+    font-size: 16px;
+  }
+  
+  .chart-unit-label {
+    top: 8px;
+    right: 16px;
+    font-size: 12px;
+  }
+  
+  .trend-summary-align {
+    flex-direction: column;
+    gap: 12px;
+    padding: 16px 0 0 0;
+  }
+  
+  .summary-item {
+    padding: 12px 16px;
+  }
+  
+  .summary-value {
+    font-size: 16px;
+  }
+  
+  .summary-value.primary {
+    font-size: 18px;
+  }
+}
+
+/* 作业图表卡片样式 */
+.work-chart-card {
+  display: flex;
+  flex-direction: column;
+  height: 540px;
+  background: linear-gradient(135deg, #ffffff 0%, #f8fafc 100%);
+  border: 1px solid #e5e7eb;
+  border-radius: 16px;
+  transition: all 0.3s ease;
+  box-sizing: border-box;
+}
+
+.work-chart-card:hover {
+  transform: translateY(-4px);
+  box-shadow: 0 12px 32px rgba(59, 180, 74, 0.15);
+  border-color: #3BB44A;
+}
+
+/* 作业环形图样式 - 水平布局 */
+.work-donut-chart-horizontal {
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  justify-content: space-between;
+  padding: 24px;
+  flex: 1;
+  position: relative;
+  box-sizing: border-box;
+  overflow: hidden;
+  min-height: 0;
+  gap: 32px;
+}
+
+/* 左侧饼图容器 */
+.work-donut-container-side {
+  flex-shrink: 0;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: 280px;
+  height: 280px;
+}
+
+/* 右侧图例区域 */
+.work-donut-legend-side {
+  display: flex;
+  flex-direction: column;
+  gap: 20px;
+  padding: 20px 0;
+  flex: 1;
+  justify-content: center;
+  align-items: flex-start;
+  position: relative;
+  z-index: 1;
+}
+
+/* 作业图表图例项 */
+.work-legend-item-enhanced {
+  display: flex;
+  align-items: center;
+  gap: 12px;
+  padding: 12px 16px;
+  border-radius: 8px;
+  background: rgba(255, 255, 255, 0.8);
+  border: 1px solid #e5e7eb;
+  transition: all 0.3s ease;
+  cursor: pointer;
+  width: 100%;
+  box-sizing: border-box;
+  animation: fadeInSlide 0.6s ease-out;
+  animation-delay: calc(var(--index) * 0.1s);
+  animation-fill-mode: both;
+}
+
+.work-legend-item-enhanced:hover {
+  background: white;
+  border-color: #3BB44A;
+  transform: translateX(4px);
+  box-shadow: 0 4px 12px rgba(59, 180, 74, 0.2);
+}
+
+.work-legend-color {
+  width: 16px;
+  height: 16px;
+  border-radius: 4px;
+  flex-shrink: 0;
+  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+}
+
+.work-legend-content-enhanced {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  width: 100%;
+}
+
+.work-legend-label {
+  font-size: 14px;
+  font-weight: 600;
+  color: #374151;
+}
+
+.work-legend-value {
+  font-size: 16px;
+  font-weight: 700;
+  color: #3BB44A;
+}
+
+
+
+/* 作业环形图中心样式 */
+.work-donut-center-label {
+  font-size: 16px;
+  fill: #6B7280;
+  font-weight: 500;
+  font-family: 'Helvetica Neue', Arial, sans-serif;
+}
+
+.work-donut-center-value {
+  font-size: 32px;
+  fill: #3BB44A;
+  font-weight: 700;
+  font-family: 'Helvetica Neue', Arial, sans-serif;
+}
+
+/* 作业趋势图样式 */
+.work-trend-chart {
+  display: flex;
+  flex-direction: column;
+  height: 100%;
+  flex: 1;
+  min-height: 0;
+}
+
+.work-chart-area {
+  width: 100%;
+  height: 260px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  position: relative;
+  flex: 1;
+}
+
+.work-chart-unit-label {
+  position: absolute;
+  top: 16px;
+  right: 24px;
+  font-size: 13px;
+  color: #6b7280;
+  font-weight: 500;
+  background: rgba(255, 255, 255, 0.9);
+  padding: 4px 8px;
+  border-radius: 4px;
+  border: 1px solid #e5e7eb;
+}
+
+/* 作业趋势汇总 */
+.work-trend-summary {
+  display: flex;
+  justify-content: space-around;
+  align-items: center;
+  padding: 20px 0;
+  border-top: 1px solid #e5e7eb;
+  margin-top: 0;
+  background: linear-gradient(135deg, #f9fafb 0%, #f3f4f6 100%);
+  border-radius: 0 0 12px 12px;
+  min-height: 80px;
+}
+
+.work-summary-item {
+  text-align: center;
+  padding: 16px 20px;
+  border-radius: 8px;
+  transition: all 0.2s ease;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+  height: 100%;
+}
+
+.work-summary-item:hover {
+  background-color: white;
+  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+  transform: translateY(-2px);
+}
+
+.work-summary-label {
+  display: block;
+  font-size: 13px;
+  color: #6b7280;
+  margin-bottom: 8px;
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.5px;
+}
+
+.work-summary-value {
+  font-size: 18px;
+  font-weight: 700;
+  color: #374151;
+  display: block;
+}
+
+.work-summary-value.primary {
+  color: #3BB44A;
+  font-size: 20px;
+}
+
+.work-summary-value.positive {
+  color: #10b981;
+}
+
+
+
+/* 图表动画效果 */
+.chart-card-donut,
+.chart-card-trend,
+.work-chart-card {
+  animation: fadeInUp 0.6s ease-out;
+}
+
+@keyframes fadeInUp {
+  from {
+    opacity: 0;
+    transform: translateY(20px);
+  }
+  to {
+    opacity: 1;
+    transform: translateY(0);
+  }
+}
+
+/* 环形图动画 */
+.donut-container svg circle {
+  animation: drawCircle 1.5s ease-out;
+}
+
+@keyframes drawCircle {
+  from {
+    stroke-dasharray: 0 263;
+  }
+  to {
+    stroke-dasharray: var(--dash-array) 263;
+  }
+}
+
+/* 趋势线动画 */
+.chart-area svg polyline {
+  animation: drawLine 2s ease-out;
+}
+
+@keyframes drawLine {
+  from {
+    stroke-dasharray: 0 1000;
+  }
+  to {
+    stroke-dasharray: 1000 0;
+  }
+}
+
+/* 数据点动画 */
+.data-point {
+  animation: fadeInScale 0.8s ease-out;
+  animation-delay: calc(var(--index) * 0.1s);
+}
+
+@keyframes fadeInScale {
+  from {
+    opacity: 0;
+    transform: scale(0);
+  }
+  to {
+    opacity: 1;
+    transform: scale(1);
+  }
+}
+
+/* 图例项动画 */
+.donut-legend-vertical .legend-item {
+  animation: slideInRight 0.6s ease-out;
+  animation-delay: calc(var(--index) * 0.2s);
+}
+
+@keyframes slideInRight {
+  from {
+    opacity: 0;
+    transform: translateX(20px);
+  }
+  to {
+    opacity: 1;
+    transform: translateX(0);
+  }
+}
+
+@keyframes slideInUp {
+  from {
+    opacity: 0;
+    transform: translateY(15px);
+  }
+  to {
+    opacity: 1;
+    transform: translateY(0);
+  }
+}
+
+/* 图表卡片阴影效果 */
+.chart-card-donut::before,
+.chart-card-trend::before {
+  content: '';
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  background: linear-gradient(135deg, rgba(16, 185, 129, 0.05) 0%, transparent 100%);
+  border-radius: 16px;
+  pointer-events: none;
+  opacity: 0;
+  transition: opacity 0.3s ease;
+}
+
+.chart-card-donut:hover::before,
+.chart-card-trend:hover::before {
+  opacity: 1;
+}
+
+/* 保养统计卡片增强效果 */
+.maintenance-metric-card::before {
+  content: '';
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  background: linear-gradient(135deg, rgba(16, 185, 129, 0.03) 0%, transparent 100%);
+  border-radius: 16px;
+  pointer-events: none;
+  opacity: 0;
+  transition: opacity 0.3s ease;
+}
+
+.maintenance-metric-card:hover::before {
+  opacity: 1;
+}
+
+/* 保养统计卡片装饰边框 - 已移除 */
+
+/* 保养统计卡片图标动画 */
+.maintenance-metric-icon-wrapper {
+  position: relative;
+}
+
+.maintenance-metric-icon-wrapper::before {
+  content: '';
+  position: absolute;
+  top: -2px;
+  left: -2px;
+  right: -2px;
+  bottom: -2px;
+  background: linear-gradient(45deg, transparent, rgba(16, 185, 129, 0.1), transparent);
+  border-radius: 18px;
+  opacity: 0;
+  transition: opacity 0.3s ease;
+}
+
+.maintenance-metric-card:hover .maintenance-metric-icon-wrapper::before {
+  opacity: 1;
+}
+
+/* 保养统计卡片数值动画 */
+.maintenance-metric-value {
+  position: relative;
+  display: inline-block;
+}
+
+.maintenance-metric-card:hover .maintenance-metric-value {
+  animation: pulse 0.6s ease-in-out;
+}
+
+@keyframes pulse {
+  0%, 100% {
+    transform: scale(1);
+  }
+  50% {
+    transform: scale(1.05);
+  }
+}
+
+/* 保养统计卡片进度条动画增强 */
+.maintenance-progress-fill {
+  position: relative;
+}
+
+.maintenance-progress-fill::before {
+  content: '';
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.4), transparent);
+  animation: progressShine 2s infinite;
+}
+
+@keyframes progressShine {
+  0% {
+    transform: translateX(-100%);
+  }
+  100% {
+    transform: translateX(100%);
+  }
+}
+
+/* 图表标题装饰 */
+.chart-title::before {
+  content: '';
+  position: absolute;
+  left: -8px;
+  top: 50%;
+  transform: translateY(-50%);
+  width: 4px;
+  height: 20px;
+  background: linear-gradient(180deg, #10b981, #34d399);
+  border-radius: 2px;
+}
+
+/* 控制按钮样式优化 */
+.chart-controls .el-radio-group .el-radio-button__inner {
+  border-color: #e5e7eb;
+  color: #6b7280;
+  background: white;
+  transition: all 0.2s ease;
+}
+
+.chart-controls .el-radio-group .el-radio-button__inner:hover {
+  border-color: #10b981;
+  color: #10b981;
+}
+
+.chart-controls .el-radio-group .el-radio-button__orig-radio:checked + .el-radio-button__inner {
+  background: #10b981;
+  border-color: #10b981;
+  color: white;
+  box-shadow: 0 2px 8px rgba(16, 185, 129, 0.3);
+}
+
+/* 轴标签样式 */
+.axis-label {
+  font-size: 12px;
+  fill: #6b7280;
+  font-weight: 500;
+  font-family: 'Helvetica Neue', Arial, sans-serif;
+}
+
+/* 图表网格线优化 */
+.chart-area svg pattern path {
+  stroke: #f0f4f1;
+  stroke-width: 1;
+  opacity: 0.8;
+}
+
+/* 趋势线渐变优化 */
+.chart-area svg polyline {
+  stroke-linecap: round;
+  stroke-linejoin: round;
+  filter: drop-shadow(0 2px 4px rgba(59, 180, 74, 0.2));
+}
+
+/* 趋势面积渐变优化 */
+.chart-area svg path[fill="url(#trendGradient)"] {
+  opacity: 0.8;
+  filter: drop-shadow(0 1px 2px rgba(59, 180, 74, 0.1));
+}
+
+/* 保养图表样式 */
+.maintenance-chart-card {
+  display: flex;
+  flex-direction: column;
+  height: 540px;
+  background: linear-gradient(135deg, #ffffff 0%, #f8fafc 100%);
+  border: 1px solid #e5e7eb;
+  border-radius: 16px;
+  transition: all 0.3s ease;
+  box-sizing: border-box;
+}
+
+.maintenance-chart-card:hover {
+  transform: translateY(-4px);
+  box-shadow: 0 12px 32px rgba(16, 185, 129, 0.15);
+  border-color: #10b981;
+}
+
+/* 保养环形图样式 - 水平布局 */
+.maintenance-donut-chart-horizontal {
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  justify-content: space-between;
+  padding: 24px;
+  flex: 1;
+  position: relative;
+  box-sizing: border-box;
+  overflow: hidden;
+  min-height: 0;
+  gap: 32px;
+}
+
+/* 保养环形图样式 - 垂直布局(保持兼容性) */
+.maintenance-donut-chart-vertical {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  padding: 20px 0;
+  min-height: 280px;
+}
+
+/* 保养环形图样式 - 原水平布局(保持兼容性) */
+.maintenance-donut-chart {
+  display: flex;
+  align-items: center;
+  gap: 40px;
+  padding: 10px 0;
+  min-height: 320px;
+}
+
+.maintenance-donut-container {
+  flex-shrink: 0;
+}
+
+.maintenance-donut-container-centered {
+  flex-shrink: 0;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  margin-bottom: 24px;
+}
+
+/* 左侧饼图容器 */
+.maintenance-donut-container-side {
+  flex-shrink: 0;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: 280px;
+  height: 280px;
+}
+
+
+
+.maintenance-donut-center-label {
+  font-size: 16px;
+  fill: #6B7280;
+  font-weight: 500;
+  font-family: 'Helvetica Neue', Arial, sans-serif;
+}
+
+.maintenance-donut-center-value {
+  font-size: 32px;
+  fill: #1a1a1a;
+  font-weight: 700;
+  font-family: 'Helvetica Neue', Arial, sans-serif;
+}
+
+
+
+/* 横向图例样式 */
+.maintenance-donut-legend-horizontal {
+  display: flex;
+  flex-direction: column;
+  gap: 16px;
+  padding: 0 20px;
+  width: 100%;
+  max-width: 400px;
+}
+
+.maintenance-legend-row {
+  display: flex;
+  justify-content: space-between;
+  gap: 20px;
+}
+
+.maintenance-legend-item-horizontal {
+  display: flex;
+  align-items: center;
+  gap: 10px;
+  flex: 1;
+  padding: 12px 16px;
+  background: rgba(248, 250, 252, 0.8);
+  border-radius: 8px;
+  transition: all 0.2s ease;
+  animation: slideInUp 0.6s ease-out;
+  animation-delay: calc(var(--index) * 0.15s);
+}
+
+.maintenance-legend-item-horizontal:hover {
+  background-color: #f0f9ff;
+  transform: translateY(-2px);
+  box-shadow: 0 4px 12px rgba(16, 185, 129, 0.15);
+}
+
+.maintenance-legend-content-horizontal {
+  display: flex;
+  flex-direction: column;
+  flex: 1;
+}
+
+.maintenance-legend-content-horizontal .maintenance-legend-label {
+  font-size: 13px;
+  color: #6b7280;
+  font-weight: 500;
+  margin-bottom: 2px;
+}
+
+.maintenance-legend-content-horizontal .maintenance-legend-value {
+  font-size: 16px;
+  color: #1f2937;
+  font-weight: 700;
+}
+
+/* 右侧图例区域 */
+.maintenance-donut-legend-side {
+  display: flex;
+  flex-direction: column;
+  gap: 20px;
+  padding: 20px 0;
+  flex: 1;
+  justify-content: center;
+  align-items: flex-start;
+  position: relative;
+  z-index: 1;
+}
+
+.maintenance-legend-row-spaced {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  gap: 24px;
+  flex-wrap: wrap;
+}
+
+.maintenance-legend-item-enhanced {
+  display: flex;
+  align-items: center;
+  gap: 12px;
+  flex: 0 1 auto;
+  min-width: 180px;
+  max-width: 220px;
+  padding: 16px 20px;
+  background: linear-gradient(135deg, rgba(248, 250, 252, 0.9) 0%, rgba(241, 245, 249, 0.8) 100%);
+  border-radius: 12px;
+  border: 1px solid rgba(226, 232, 240, 0.8);
+  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
+  cursor: pointer;
+  animation: slideInUp 0.6s ease-out;
+  animation-delay: calc(var(--index) * 0.15s);
+  position: relative;
+  overflow: hidden;
+}
+
+.maintenance-legend-item-enhanced::before {
+  content: '';
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  background: linear-gradient(135deg, rgba(255, 255, 255, 0.5) 0%, transparent 100%);
+  opacity: 0;
+  transition: opacity 0.3s ease;
+}
+
+.maintenance-legend-item-enhanced:hover {
+  background: linear-gradient(135deg, rgba(240, 253, 244, 0.9) 0%, rgba(220, 252, 231, 0.8) 100%);
+  border-color: #10b981;
+  transform: translateY(-3px);
+  box-shadow: 0 8px 25px rgba(16, 185, 129, 0.2);
+}
+
+.maintenance-legend-item-enhanced:hover::before {
+  opacity: 1;
+}
+
+.maintenance-legend-item-enhanced.active {
+  background: linear-gradient(135deg, rgba(16, 185, 129, 0.1) 0%, rgba(52, 211, 153, 0.05) 100%);
+  border-color: #10b981;
+  box-shadow: 0 4px 12px rgba(16, 185, 129, 0.2);
+}
+
+.maintenance-legend-content-enhanced {
+  display: flex;
+  flex-direction: column;
+  flex: 1;
+}
+
+.maintenance-legend-content-enhanced .maintenance-legend-label {
+  font-size: 14px;
+  color: #6b7280;
+  font-weight: 500;
+  margin-bottom: 4px;
+  transition: color 0.3s ease;
+}
+
+.maintenance-legend-content-enhanced .maintenance-legend-value {
+  font-size: 18px;
+  color: #1f2937;
+  font-weight: 700;
+  transition: color 0.3s ease;
+}
+
+.maintenance-legend-item-enhanced:hover .maintenance-legend-content-enhanced .maintenance-legend-label {
+  color: #059669;
+}
+
+.maintenance-legend-item-enhanced:hover .maintenance-legend-content-enhanced .maintenance-legend-value {
+  color: #047857;
+}
+
+/* 保养趋势图样式 */
+.maintenance-trend-chart {
+  padding: 10px 0;
+  min-height: 320px;
+}
+
+.maintenance-chart-area {
+  margin-bottom: 20px;
+  position: relative;
+}
+
+.maintenance-chart-area svg {
+  width: 100%;
+  height: 260px;
+}
+
+.maintenance-chart-unit-label {
+  position: absolute;
+  top: 12px;
+  right: 20px;
+  font-size: 13px;
+  color: #6B7280;
+  font-weight: 600;
+  z-index: 10;
+  background: rgba(255, 255, 255, 0.9);
+  padding: 4px 8px;
+  border-radius: 6px;
+  border: 1px solid #e5e7eb;
+}
+
+/* 保养数据点交互样式 */
+.maintenance-data-point {
+  cursor: pointer;
+  transition: all 0.3s ease;
+  animation: fadeInScale 0.8s ease-out;
+  animation-delay: calc(var(--index) * 0.1s);
+}
+
+.maintenance-data-point:hover {
+  r: 8;
+  fill: #E65100;
+  stroke: white;
+  stroke-width: 3;
+  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.2));
+}
+
+/* 保养轴标签样式 */
+.maintenance-axis-label {
+  font-size: 12px;
+  fill: #6b7280;
+  font-weight: 500;
+  font-family: 'Helvetica Neue', Arial, sans-serif;
+}
+
+/* 保养趋势汇总样式 */
+.maintenance-trend-summary {
+  display: flex;
+  justify-content: space-around;
+  align-items: center;
+  padding: 20px 0;
+  border-top: 1px solid #e5e7eb;
+  margin-top: 0;
+  background: linear-gradient(135deg, #f9fafb 0%, #f3f4f6 100%);
+  border-radius: 0 0 12px 12px;
+  min-height: 80px;
+}
+
+.maintenance-summary-item {
+  text-align: center;
+  padding: 16px 20px;
+  border-radius: 8px;
+  transition: all 0.2s ease;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+  height: 100%;
+}
+
+.maintenance-summary-item:hover {
+  background-color: white;
+  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+  transform: translateY(-2px);
+}
+
+.maintenance-summary-label {
+  display: block;
+  font-size: 13px;
+  color: #6b7280;
+  margin-bottom: 8px;
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.5px;
+}
+
+.maintenance-summary-value {
+  font-size: 18px;
+  font-weight: 700;
+  color: #374151;
+  display: block;
+}
+
+.maintenance-summary-value.primary {
+  color: #FF9800;
+  font-size: 20px;
+}
+
+.maintenance-summary-value.positive {
+  color: #10b981;
+}
+
+.maintenance-summary-value.warning {
+  color: #f59e0b;
+}
+
+/* 保养图表汇总信息样式 */
+.maintenance-chart-summary {
+  display: flex;
+  justify-content: space-around;
+  align-items: center;
+  padding: 20px 0;
+  border-top: 1px solid #e5e7eb;
+  margin-top: 0;
+  background: linear-gradient(135deg, #f9fafb 0%, #f3f4f6 100%);
+  border-radius: 0 0 12px 12px;
+  min-height: 80px;
+}
+
+.maintenance-chart-summary-item {
+  text-align: center;
+  padding: 16px 20px;
+  border-radius: 8px;
+  transition: all 0.2s ease;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+  height: 100%;
+}
+
+.maintenance-chart-summary-item:hover {
+  background-color: white;
+  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+  transform: translateY(-2px);
+}
+
+.maintenance-chart-summary-label {
+  display: block;
+  font-size: 13px;
+  color: #6b7280;
+  margin-bottom: 8px;
+  font-weight: 500;
+  text-transform: uppercase;
+  letter-spacing: 0.5px;
+}
+
+.maintenance-chart-summary-value {
+  font-size: 18px;
+  font-weight: 700;
+  color: #374151;
+  display: block;
+}
+
+.maintenance-chart-summary-value.primary {
+  color: #4CAF50;
+  font-size: 20px;
+}
+
+.maintenance-chart-summary-value.warning {
+  color: #FF5722;
+}
+
+/* 保养图表提示框样式 */
+.maintenance-chart-tooltip {
+  position: fixed !important;
+  background: rgba(0, 0, 0, 0.9) !important;
+  color: white !important;
+  padding: 10px 14px !important;
+  border-radius: 8px !important;
+  font-size: 13px !important;
+  pointer-events: none !important;
+  z-index: 99999 !important;
+  opacity: 0;
+  transition: opacity 0.3s ease !important;
+  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.2) !important;
+  border: 1px solid rgba(255, 255, 255, 0.1) !important;
+  display: none;
+  min-width: 80px;
+  text-align: center;
+}
+
+.maintenance-chart-tooltip.show {
+  opacity: 1;
+}
+
+.maintenance-chart-tooltip::before {
+  content: '';
+  position: absolute;
+  top: 100%;
+  left: 50%;
+  transform: translateX(-50%);
+  width: 0;
+  height: 0;
+  border: 5px solid transparent;
+  border-top-color: rgba(0, 0, 0, 0.9);
+}
+
+/* 保养图表动画效果 */
+.maintenance-chart-card {
+  animation: fadeInUp 0.6s ease-out;
+}
+
+/* 保养环形图动画 */
+.maintenance-donut-container svg circle {
+  animation: drawCircle 1.5s ease-out;
+}
+
+
+
+/* 保养趋势线动画 */
+.maintenance-chart-area svg polyline {
+  animation: drawLine 2s ease-out;
+}
+
+/* 响应式布局优化 */
+@media (max-width: 1200px) {
+  .maintenance-donut-chart {
+    flex-direction: column;
+    gap: 24px;
+    text-align: center;
+  }
+  
+  .maintenance-donut-chart-vertical {
+    padding: 16px 0;
+    min-height: 260px;
+  }
+  
+  .maintenance-donut-chart-horizontal {
+    flex-direction: column;
+    padding: 16px;
+    gap: 16px;
+    align-items: center;
+    justify-content: center;
+    box-sizing: border-box;
+  }
+  
+  .work-donut-chart-horizontal {
+    flex-direction: column;
+    padding: 16px;
+    gap: 16px;
+    align-items: center;
+    justify-content: center;
+    box-sizing: border-box;
+  }
+  
+
+  
+  .maintenance-chart-area {
+    width: 100%;
+    min-width: 0;
+  }
+  
+  .maintenance-chart-card {
+    height: 500px;
+    box-sizing: border-box;
+  }
+  
+  .work-chart-card {
+    height: 500px;
+    box-sizing: border-box;
+  }
+  
+  .work-donut-container-side {
+    width: 240px;
+    height: 240px;
+  }
+  
+  .work-donut-container-side svg {
+    width: 240px;
+    height: 240px;
+  }
+  
+  .work-donut-legend-side {
+    padding: 16px 0;
+    gap: 16px;
+    align-items: center;
+  }
+}
+
+@media (max-width: 768px) {
+  .maintenance-chart-card {
+    height: 420px;
+    box-sizing: border-box;
+  }
+  
+  .maintenance-donut-chart {
+    flex-direction: column;
+    gap: 20px;
+  }
+  
+  .maintenance-donut-chart-vertical {
+    padding: 12px 0;
+    min-height: 240px;
+  }
+  
+  .maintenance-donut-chart-horizontal {
+    flex-direction: column;
+    padding: 12px;
+    gap: 12px;
+    align-items: center;
+    justify-content: center;
+    box-sizing: border-box;
+  }
+  
+  .work-donut-chart-horizontal {
+    flex-direction: column;
+    padding: 12px;
+    gap: 12px;
+    align-items: center;
+    justify-content: center;
+    box-sizing: border-box;
+  }
+  
+
+  
+  .maintenance-donut-container-side {
+    width: 200px;
+    height: 200px;
+  }
+  
+  .maintenance-donut-container-side svg {
+    width: 200px;
+    height: 200px;
+  }
+  
+  .maintenance-donut-legend-side {
+    padding: 12px 0;
+    gap: 12px;
+    align-items: center;
+  }
+  
+  .work-chart-card {
+    height: 420px;
+    box-sizing: border-box;
+  }
+  
+  .work-donut-container-side {
+    width: 200px;
+    height: 200px;
+  }
+  
+  .work-donut-container-side svg {
+    width: 200px;
+    height: 200px;
+  }
+  
+  .work-donut-legend-side {
+    padding: 12px 0;
+    gap: 12px;
+    align-items: center;
+  }
+  
+  .maintenance-legend-row-spaced {
+    gap: 16px;
+    justify-content: center;
+  }
+  
+  .maintenance-legend-item-enhanced {
+    padding: 12px 16px;
+    gap: 10px;
+    min-width: 140px;
+    max-width: 180px;
+    flex: 0 1 auto;
+  }
+  
+  .maintenance-legend-content-enhanced .maintenance-legend-label {
+    font-size: 13px;
+  }
+  
+  .maintenance-legend-content-enhanced .maintenance-legend-value {
+    font-size: 16px;
+  }
+  
+  .maintenance-donut-legend-horizontal {
+    padding: 0 16px;
+    gap: 12px;
+  }
+  
+  .maintenance-legend-row {
+    gap: 12px;
+  }
+  
+  .maintenance-legend-item-horizontal {
+    padding: 8px 12px;
+    gap: 8px;
+  }
+  
+  .maintenance-legend-content-horizontal .maintenance-legend-label {
+    font-size: 12px;
+  }
+  
+  .maintenance-legend-content-horizontal .maintenance-legend-value {
+    font-size: 14px;
+  }
+  
+
+  
+  .maintenance-donut-container {
+    width: 200px;
+    height: 200px;
+  }
+  
+  .maintenance-donut-container svg {
+    width: 200px;
+    height: 200px;
+  }
+  
+
+  
+  .maintenance-chart-unit-label {
+    top: 8px;
+    right: 16px;
+    font-size: 12px;
+  }
+  
+  .maintenance-trend-summary {
+    flex-direction: column;
+    gap: 12px;
+    padding: 16px 0 0 0;
+  }
+  
+  .maintenance-summary-item {
+    padding: 12px 16px;
+  }
+  
+  .maintenance-summary-value {
+    font-size: 16px;
+  }
+  
+  .maintenance-summary-value.primary {
+    font-size: 18px;
+  }
+}
+</style> 

+ 2318 - 0
src/views/base/machines/monitor.vue

@@ -0,0 +1,2318 @@
+<!--
+  农机监控详情页
+  注意事项:
+  1. 需要申请高德地图API Key并在loadAmapScript方法中替换YOUR_AMAP_KEY
+  2. 确保项目域名已在高德开放平台白名单中
+  3. 生产环境需要替换模拟数据为真实API调用
+-->
+<template>
+  <div class="machine-monitor-container">
+    <!-- 顶部信息卡 -->
+    <div class="info-header">
+      <div class="machine-info-card">
+        <div class="machine-header">
+          <div class="machine-avatar">
+            <i class="el-icon-truck"></i>
+          </div>
+          <div class="machine-title">
+            <h2 class="machine-name">{{ machineData.machineName || '东方红-LX1000' }}</h2>
+            <span class="machine-id">设备编号: {{ machineData.machineCode || 'M20230001' }}</span>
+          </div>
+          <el-button 
+            type="primary" 
+            icon="el-icon-refresh" 
+            @click="refreshData"
+            :loading="refreshing"
+            class="refresh-btn"
+          >
+            刷新数据
+          </el-button>
+        </div>
+        
+        <div class="info-grid">
+          <div class="info-item">
+            <div class="info-label">
+              <i class="el-icon-map-location"></i>
+              所属地块
+            </div>
+            <div class="info-value">{{ machineData.fieldArea || '东区A-12' }}</div>
+          </div>
+          <div class="info-item">
+            <div class="info-label">
+              <i class="el-icon-circle-check"></i>
+              当前状态
+            </div>
+            <div class="info-value">
+              <el-tag 
+                :type="getStatusType(machineData.onlineStatus)" 
+                effect="light"
+                size="small"
+              >
+                {{ getStatusText(machineData.onlineStatus) }}
+              </el-tag>
+            </div>
+          </div>
+          <div class="info-item">
+            <div class="info-label">
+              <i class="el-icon-s-operation"></i>
+              当前任务
+            </div>
+            <div class="info-value">{{ machineData.currentTask || '稻田耕种' }}</div>
+          </div>
+          <div class="info-item">
+            <div class="info-label">
+              <i class="el-icon-location"></i>
+              定位状态
+            </div>
+            <div class="info-value">
+              <el-tag 
+                :type="getLocationStatusType(machineData.locationStatus)" 
+                effect="light"
+                size="small"
+              >
+                {{ getLocationStatusText(machineData.locationStatus) }}
+              </el-tag>
+            </div>
+          </div>
+        </div>
+      </div>
+      
+      <div class="status-overview">
+        <h3 class="status-title">
+          <i class="el-icon-data-analysis"></i>
+          实时状态
+        </h3>
+        <div class="status-grid">
+          <div class="status-item">
+            <span class="status-label">在线状态</span>
+            <el-tag :type="machineData.onlineStatus == 1 ? 'success' : 'danger'" size="small">
+              {{ machineData.onlineStatus == 1 ? '在线' : '离线' }}
+            </el-tag>
+          </div>
+          <div class="status-item">
+            <span class="status-label">信号强度</span>
+            <span class="status-value" :style="{ color: getSignalColor(realtimeData.signalStrength) }">
+              {{ getSignalText(realtimeData.signalStrength) }}
+            </span>
+          </div>
+          <div class="status-item">
+            <span class="status-label">最后通信</span>
+            <span class="status-value">{{ realtimeData.lastCommunication }}</span>
+          </div>
+          <div class="status-item">
+            <span class="status-label">作业时长</span>
+            <span class="status-value">{{ realtimeData.workingTime }}</span>
+          </div>
+        </div>
+      </div>
+    </div>
+    
+    <!-- 状态信息区域 -->
+    <div class="status-section">
+      <div class="status-cards">
+        <el-card class="status-card" shadow="hover">
+          <div slot="header" class="card-title">
+            <i class="el-icon-s-operation"></i>
+            运行参数
+          </div>
+          <div class="metrics-grid">
+            <div class="metric-item">
+              <div class="metric-label">
+                <i class="el-icon-s-operation"></i>
+                工作模式
+              </div>
+              <div class="metric-value" style="color: #67C23A;">{{ realtimeData.workMode }}</div>
+            </div>
+            <div class="metric-item">
+              <div class="metric-label">
+                <i class="el-icon-lightning"></i>
+                电量
+              </div>
+              <div class="metric-value" style="color: #67C23A;">{{ realtimeData.battery }}%</div>
+            </div>
+            <div class="metric-item">
+              <div class="metric-label">
+                <i class="el-icon-s-tools"></i>
+                保养状态
+              </div>
+              <div class="metric-value" :style="{ color: getMaintenanceColor(machineData.maintenanceStatus) }">
+                {{ getMaintenanceText(machineData.maintenanceStatus) }}
+              </div>
+            </div>
+
+          </div>
+        </el-card>
+        
+        <el-card class="status-card" shadow="hover">
+          <div slot="header" class="card-title">
+            <i class="el-icon-monitor"></i>
+            设备状态
+          </div>
+          <div class="metrics-grid">
+            <div class="metric-item">
+              <div class="metric-label">
+                <i class="el-icon-sunny"></i>
+                发动机温度
+              </div>
+              <div class="metric-value">{{ realtimeData.engineTemp }}°C</div>
+            </div>
+            <div class="metric-item">
+              <div class="metric-label">
+                <i class="el-icon-odometer"></i>
+                液压压力
+              </div>
+              <div class="metric-value">{{ realtimeData.hydraulicPressure }}MPa</div>
+            </div>
+            <div class="metric-item">
+              <div class="metric-label">
+                <i class="el-icon-goods"></i>
+                燃油余量
+              </div>
+              <div class="metric-value" style="color: #E6A23C;">{{ realtimeData.fuelLevel }}%</div>
+            </div>
+            <div class="metric-item">
+              <div class="metric-label">
+                <i class="el-icon-time"></i>
+                累计工时
+              </div>
+              <div class="metric-value">{{ realtimeData.totalWorkTime }}h</div>
+            </div>
+          </div>
+        </el-card>
+        
+        <el-card class="status-card" shadow="hover">
+          <div slot="header" class="card-title">
+            <i class="el-icon-s-tools"></i>
+            维护信息
+          </div>
+          <div class="metrics-grid">
+            <div class="metric-item">
+              <div class="metric-label">
+                <i class="el-icon-date"></i>
+                上次保养
+              </div>
+              <div class="metric-value">{{ realtimeData.lastMaintenance }}</div>
+            </div>
+            <div class="metric-item">
+              <div class="metric-label">
+                <i class="el-icon-alarm-clock"></i>
+                下次保养
+              </div>
+              <div class="metric-value" style="color: #E6A23C;">{{ realtimeData.nextMaintenance }}</div>
+            </div>
+            <div class="metric-item">
+              <div class="metric-label">
+                <i class="el-icon-odometer"></i>
+                保养里程
+              </div>
+              <div class="metric-value">{{ realtimeData.maintenanceMileage }}km</div>
+            </div>
+            <div class="metric-item">
+              <div class="metric-label">
+                <i class="el-icon-circle-check"></i>
+                保养状态
+              </div>
+              <div class="metric-value" style="color: #67C23A;">正常</div>
+            </div>
+          </div>
+        </el-card>
+      </div>
+    </div>
+    
+    <!-- 主要内容区域 -->
+    <div class="main-content">
+      <!-- 监控视图 -->
+      <el-card class="monitor-view" shadow="hover">
+        <div slot="header" class="monitor-header">
+          <h3 class="monitor-title">
+            <i class="el-icon-video-camera"></i>
+            实时监控
+          </h3>
+          <el-button type="primary" size="small" @click="toggleFullscreen" class="fullscreen-btn">
+            <i class="el-icon-full-screen"></i>
+            全屏
+          </el-button>
+        </div>
+        
+        <!-- 视频预览区域 -->
+        <div class="monitor-display" ref="monitorDisplay">
+          <div class="monitor-status">
+            <div class="signal-status">
+              <i class="el-icon-connection"></i>
+              信号强度: {{ getSignalText(realtimeData.signalStrength) }}
+            </div>
+            <div class="monitor-time">
+              {{ currentTime }}
+            </div>
+          </div>
+          
+          <!-- 加载动画 -->
+          <div v-if="cameraLoading" class="camera-loading">
+            <div class="loading-spinner">
+              <div class="spinner-ring"></div>
+            </div>
+            <p class="loading-text">摄像头画面加载中,请稍候...</p>
+          </div>
+          
+          <!-- 正常显示内容 -->
+          <div v-else class="monitor-placeholder">
+            <i class="el-icon-video-camera"></i>
+            <h4>{{ getCurrentCameraInfo().title }}</h4>
+            <p class="monitor-description">{{ getCurrentCameraInfo().description }}</p>
+          </div>
+        </div>
+        
+        <!-- 操作控制栏 -->
+        <div class="monitor-controls-bar">
+          <div class="camera-controls">
+            <span class="control-label">摄像头:</span>
+            <el-button-group class="camera-buttons">
+              <el-button 
+                v-for="camera in cameraList" 
+                :key="camera.value"
+                :type="currentCamera === camera.value ? 'primary' : ''"
+                size="small"
+                @click="switchCamera(camera.value)"
+                class="camera-btn"
+              >
+                {{ camera.shortLabel }}
+              </el-button>
+            </el-button-group>
+          </div>
+          <div class="camera-info-bar">
+            <span class="info-item">
+              <i class="el-icon-circle-check"></i>
+              状态: {{ getCurrentCameraInfo().status }}
+            </span>
+            <span class="info-item">
+              <i class="el-icon-monitor"></i>
+              {{ getCurrentCameraInfo().resolution }}
+            </span>
+            <el-popover
+              placement="top"
+              width="200"
+              trigger="hover"
+              :content="getCurrentCameraInfo().description"
+            >
+              <el-button slot="reference" type="text" size="mini" class="help-btn">
+                <i class="el-icon-question"></i>
+              </el-button>
+            </el-popover>
+          </div>
+        </div>
+      </el-card>
+      
+      <!-- 地图轨迹卡片 -->
+      <el-card class="map-track-card" shadow="hover">
+        <div slot="header" class="map-header">
+          <h4 class="map-title">
+            <i class="el-icon-location-outline"></i>
+            作业轨迹
+          </h4>
+          <div class="map-controls">
+            <el-radio-group v-model="mapViewMode" size="small" @change="updateMapView">
+              <el-radio-button label="realtime">实时轨迹</el-radio-button>
+              <el-radio-button label="history">历史轨迹</el-radio-button>
+            </el-radio-group>
+            <el-button type="primary" size="small" @click="toggleMapFullscreen" class="map-fullscreen-btn">
+              <i class="el-icon-full-screen"></i>
+              全屏
+            </el-button>
+          </div>
+        </div>
+        
+        <!-- 地图容器 -->
+        <div class="map-container" ref="mapContainer">
+          <!-- 地图加载动画 -->
+          <div v-if="mapLoading" class="map-loading">
+            <div class="map-loading-spinner">
+              <div class="spinner-ring"></div>
+            </div>
+            <p class="map-loading-text">地图加载中...</p>
+          </div>
+          
+          <!-- 高德地图容器 -->
+          <div v-show="!mapLoading" id="amapContainer" class="amap-container"></div>
+          
+          <!-- 历史轨迹悬浮查询条件 -->
+          <div v-show="mapViewMode === 'history' && !mapLoading" class="history-query-overlay">
+            <div class="query-panel" :class="{ 'collapsed': queryPanelCollapsed }">
+              <div class="query-header">
+                <div class="query-title">
+                  <i class="el-icon-date"></i>
+                  <span>历史轨迹查询</span>
+                </div>
+                <el-button 
+                  type="text" 
+                  size="mini" 
+                  @click="toggleQueryPanel"
+                  class="collapse-btn"
+                >
+                  <i :class="queryPanelCollapsed ? 'el-icon-arrow-down' : 'el-icon-arrow-up'"></i>
+                </el-button>
+              </div>
+              <div v-show="!queryPanelCollapsed" class="query-content">
+                <div class="date-picker-wrapper">
+                  <el-date-picker
+                    v-model="historyDateRange"
+                    type="daterange"
+                    range-separator="至"
+                    start-placeholder="开始日期"
+                    end-placeholder="结束日期"
+                    size="small"
+                    @change="loadHistoryTrack"
+                    :picker-options="datePickerOptions"
+                    class="history-date-picker"
+                  />
+                </div>
+                <el-button 
+                  type="primary" 
+                  size="small" 
+                  @click="loadHistoryTrack" 
+                  :loading="mapLoading"
+                  class="query-btn"
+                >
+                  <i class="el-icon-search"></i>
+                  查询轨迹
+                </el-button>
+              </div>
+            </div>
+          </div>
+          
+          <!-- 无数据提示 -->
+          <div v-if="!mapLoading && !hasTrackData" class="no-track-data">
+            <i class="el-icon-map-location"></i>
+            <h5>暂无作业轨迹数据</h5>
+            <p>{{ mapViewMode === 'realtime' ? '设备可能离线或未开始作业' : '选择的时间范围内无轨迹记录' }}</p>
+          </div>
+          
+          <!-- 地图控制按钮组 -->
+          <div v-show="!mapLoading && hasTrackData" class="map-control-buttons">
+            <el-tooltip content="定位到农机" placement="left">
+              <el-button circle size="small" @click="locateToMachine">
+                <i class="el-icon-position"></i>
+              </el-button>
+            </el-tooltip>
+            <el-tooltip content="适应轨迹范围" placement="left">
+              <el-button circle size="small" @click="fitTrackBounds">
+                <i class="el-icon-zoom-in"></i>
+              </el-button>
+            </el-tooltip>
+            <el-tooltip content="重新加载" placement="left">
+              <el-button circle size="small" @click="reloadMapData" :loading="mapLoading">
+                <i class="el-icon-refresh"></i>
+              </el-button>
+            </el-tooltip>
+          </div>
+        </div>
+        
+        <!-- 底部统计信息 -->
+        <div class="track-info">
+          <div class="track-stats">
+            <div class="track-stat">
+              <div class="track-label">
+                <i class="el-icon-odometer"></i>
+                今日里程
+              </div>
+              <div class="track-value primary">{{ trackData.todayDistance }}km</div>
+            </div>
+            <div class="track-stat">
+              <div class="track-label">
+                <i class="el-icon-crop"></i>
+                作业面积
+              </div>
+              <div class="track-value primary">{{ trackData.workArea }}亩</div>
+            </div>
+            <div class="track-stat">
+              <div class="track-label">
+                <i class="el-icon-odometer"></i>
+                平均速度
+              </div>
+              <div class="track-value">{{ trackData.avgSpeed }}km/h</div>
+            </div>
+            <div class="track-stat">
+              <div class="track-label">
+                <i class="el-icon-map-location"></i>
+                当前位置
+              </div>
+              <div class="track-value">{{ trackData.currentLocation }}</div>
+            </div>
+          </div>
+        </div>
+      </el-card>
+    </div>
+    
+
+    
+    <!-- 底部快捷按钮 -->
+    <div class="action-buttons">
+      <el-button type="primary" icon="el-icon-document">
+        查看保养记录
+      </el-button>
+      <el-button type="primary" icon="el-icon-time">
+        查看作业历史
+      </el-button>
+      <el-button type="success" icon="el-icon-monitor" @click="goToMonitorOverview">
+        监控汇总
+      </el-button>
+    </div>
+  </div>
+</template>
+
+<script>
+import { getMachines } from "@/api/base/machines"
+
+export default {
+  name: "MachineMonitor",
+  data() {
+    return {
+      // 农机基础数据
+      machineData: {},
+      // 实时数据
+      realtimeData: {
+        signalStrength: 'strong',
+        lastCommunication: '2分钟前',
+        workingTime: '3小时22分',
+        workMode: '自动',
+        battery: 87,
+        engineTemp: 85,
+        hydraulicPressure: 16.5,
+        fuelLevel: 65,
+        totalWorkTime: 1245,
+        lastMaintenance: '7天前',
+        nextMaintenance: '23天后',
+        maintenanceMileage: 850
+      },
+      // 轨迹数据
+      trackData: {
+        todayDistance: 12.8,
+        workArea: 45.2,
+        avgSpeed: 3.8,
+        currentLocation: '东区A-12'
+      },
+      // 当前时间
+      currentTime: '',
+      // 刷新状态
+      refreshing: false,
+      // 当前摄像头
+      currentCamera: 'front',
+      // 摄像头加载状态
+      cameraLoading: false,
+      // 摄像头列表
+      cameraList: [
+        { value: 'front', label: '前置摄像头', shortLabel: '前', online: true },
+        { value: 'rear', label: '后置摄像头', shortLabel: '后', online: true },
+        { value: 'left', label: '左侧摄像头', shortLabel: '左', online: true },
+        { value: 'right', label: '右侧摄像头', shortLabel: '右', online: true },
+        { value: 'work', label: '作业区摄像头', shortLabel: '作业', online: true }
+      ],
+      // 地图视图模式
+      mapViewMode: 'realtime',
+      // 地图加载状态
+      mapLoading: false,
+      // 是否有轨迹数据
+      hasTrackData: true,
+      // 历史轨迹日期范围
+      historyDateRange: [],
+      // 查询面板折叠状态
+      queryPanelCollapsed: false,
+      // 日期选择器配置
+      datePickerOptions: {
+        shortcuts: [{
+          text: '最近一周',
+          onClick(picker) {
+            const end = new Date()
+            const start = new Date()
+            start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
+            picker.$emit('pick', [start, end])
+          }
+        }, {
+          text: '最近一个月',
+          onClick(picker) {
+            const end = new Date()
+            const start = new Date()
+            start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
+            picker.$emit('pick', [start, end])
+          }
+        }, {
+          text: '最近三个月',
+          onClick(picker) {
+            const end = new Date()
+            const start = new Date()
+            start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
+            picker.$emit('pick', [start, end])
+          }
+        }],
+        disabledDate(time) {
+          return time.getTime() > Date.now()
+        }
+      },
+      // 高德地图实例
+      amapInstance: null,
+      // 农机标记点
+      machineMarker: null,
+      // 轨迹线
+      trackPolyline: null,
+      // 当前农机位置
+      currentPosition: [117.065029, 34.227274], // 默认作业区域坐标
+      // 轨迹点数据
+      trackPoints: [],
+      // 定时器
+      timers: [],
+      // 原始背景设置
+      originalBodyBg: '',
+      originalBodyColor: '',
+      originalAppBg: ''
+    }
+  },
+  created() {
+    this.loadMachineData()
+    this.startRealTimeUpdates()
+    this.initializeCamera()
+  },
+  mounted() {
+    // 保存原始背景色并设置页面背景
+    this.originalBodyBg = document.body.style.background || ''
+    this.originalBodyColor = document.body.style.color || ''
+    this.originalAppBg = document.getElementById('app')?.style.background || ''
+    
+    // 应用渐变背景到整个页面
+    document.body.style.background = 'linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%)'
+    document.body.style.color = '#1f2937'
+    const appEl = document.getElementById('app')
+    if (appEl) {
+      appEl.style.background = 'linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%)'
+    }
+    
+    // 初始化地图
+    this.loadAmapScript()
+  },
+  beforeDestroy() {
+    // 恢复原始背景色
+    document.body.style.background = this.originalBodyBg
+    document.body.style.color = this.originalBodyColor
+    const appEl = document.getElementById('app')
+    if (appEl) {
+      appEl.style.background = this.originalAppBg
+    }
+    
+    // 清理地图资源
+    if (this.amapInstance) {
+      this.amapInstance.destroy()
+      this.amapInstance = null
+    }
+    
+    // 清理定时器
+    this.timers.forEach(timer => clearInterval(timer))
+  },
+  methods: {
+    // 加载农机数据
+    async loadMachineData() {
+      const machineId = this.$route.params.id || this.$route.query.id
+      if (machineId) {
+        try {
+          const response = await getMachines(machineId)
+          this.machineData = response.data
+        } catch (error) {
+          this.$message.error('加载农机数据失败')
+          console.error(error)
+        }
+      }
+    },
+    
+
+    
+    // 初始化摄像头
+    initializeCamera() {
+      // 初始加载时显示loading
+      this.cameraLoading = true
+      
+      // 模拟初始摄像头加载时间
+      setTimeout(() => {
+        this.cameraLoading = false
+      }, 1500 + Math.random() * 1000)
+    },
+
+    // 刷新数据
+    async refreshData() {
+      this.refreshing = true
+      // 刷新时也重新加载摄像头
+      this.cameraLoading = true
+      
+      try {
+        await this.loadMachineData()
+        this.updateRealtimeData()
+        
+        // 模拟摄像头重新连接
+        setTimeout(() => {
+          this.cameraLoading = false
+        }, 800 + Math.random() * 700)
+        
+        this.$message.success('数据已刷新')
+      } catch (error) {
+        this.cameraLoading = false
+        this.$message.error('刷新失败')
+      } finally {
+        setTimeout(() => {
+          this.refreshing = false
+        }, 1000)
+      }
+    },
+    
+
+    
+    // 开始实时更新
+    startRealTimeUpdates() {
+      // 更新时间
+      this.updateCurrentTime()
+      const timeTimer = setInterval(() => {
+        this.updateCurrentTime()
+      }, 1000)
+      this.timers.push(timeTimer)
+      
+      // 模拟数据更新
+      const dataTimer = setInterval(() => {
+        this.updateRealtimeData()
+      }, 30000)
+      this.timers.push(dataTimer)
+    },
+    
+    // 更新当前时间
+    updateCurrentTime() {
+      const now = new Date()
+      this.currentTime = now.toLocaleString('zh-CN', {
+        year: 'numeric',
+        month: '2-digit',
+        day: '2-digit',
+        hour: '2-digit',
+        minute: '2-digit',
+        second: '2-digit'
+      })
+    },
+    
+    // 更新实时数据
+    updateRealtimeData() {
+      // 随机更新电量
+      this.realtimeData.battery = Math.max(this.realtimeData.battery - Math.floor(Math.random() * 3), 0)
+      
+      // 随机更新里程
+      this.trackData.todayDistance = (this.trackData.todayDistance + Math.random() * 0.5).toFixed(1)
+      
+      // 随机更新作业面积
+      this.trackData.workArea = (this.trackData.workArea + Math.random() * 0.3).toFixed(1)
+      
+      // 随机更新发动机温度
+      this.realtimeData.engineTemp = this.realtimeData.engineTemp + Math.floor(Math.random() * 5) - 2
+    },
+    
+    // 切换摄像头
+    switchCamera(cameraType) {
+      // 如果切换到相同摄像头,不执行操作
+      if (this.currentCamera === cameraType) return
+      
+      // 显示加载动画
+      this.cameraLoading = true
+      
+      // 模拟摄像头切换加载时间
+      setTimeout(() => {
+        this.currentCamera = cameraType
+        
+        // 模拟视频流加载时间(1-2秒)
+        const loadTime = 1000 + Math.random() * 1000
+        setTimeout(() => {
+          this.cameraLoading = false
+          this.$message.success(`已切换到${this.getCurrentCameraInfo().title}`)
+        }, loadTime)
+      }, 300) // 先显示300ms的切换动画
+    },
+    
+    // 获取当前摄像头信息
+    getCurrentCameraInfo() {
+      const cameraInfo = {
+        'front': {
+          title: '前置摄像头',
+          label: '前置摄像头',
+          description: '显示农机前方视角,用于导航和障碍物检测',
+          status: '正常',
+          resolution: '1920×1080'
+        },
+        'rear': {
+          title: '后置摄像头',
+          label: '后置摄像头', 
+          description: '显示农机后方视角,用于倒车和监控拖拽设备',
+          status: '正常',
+          resolution: '1920×1080'
+        },
+        'left': {
+          title: '左侧摄像头',
+          label: '左侧摄像头',
+          description: '显示农机左侧视角,监控左侧作业区域',
+          status: '正常',
+          resolution: '1280×720'
+        },
+        'right': {
+          title: '右侧摄像头',
+          label: '右侧摄像头',
+          description: '显示农机右侧视角,监控右侧作业区域',
+          status: '正常',
+          resolution: '1280×720'
+        },
+        'work': {
+          title: '作业区摄像头',
+          label: '作业区摄像头',
+          description: '监控农机作业区域,观察耕种、播种、收割等作业过程',
+          status: '正常',
+          resolution: '1920×1080'
+        }
+      }
+      return cameraInfo[this.currentCamera] || cameraInfo['front']
+    },
+    
+    // 全屏切换
+    toggleFullscreen() {
+      const element = this.$refs.monitorDisplay
+      if (document.fullscreenElement) {
+        document.exitFullscreen()
+        this.$message.success('已退出全屏')
+      } else {
+        element.requestFullscreen().then(() => {
+          this.$message.success('已进入全屏模式')
+        }).catch(() => {
+          this.$message.error('全屏功能不支持')
+        })
+      }
+    },
+    
+    // 加载高德地图脚本
+    loadAmapScript() {
+      // 检查是否已加载高德地图API
+      if (window.AMap) {
+        this.initMap()
+        return
+      }
+      
+      // 动态加载高德地图API
+      const script = document.createElement('script')
+      script.type = 'text/javascript'
+      script.src = 'https://webapi.amap.com/maps?v=1.4.15&key=YOUR_AMAP_KEY&plugin=AMap.PolyLine,AMap.Marker' // 需要替换为实际的API Key
+      script.onload = () => {
+        this.initMap()
+      }
+      script.onerror = () => {
+        console.error('高德地图加载失败')
+        this.$message.error('地图加载失败,请检查网络连接')
+        this.mapLoading = false
+      }
+      document.head.appendChild(script)
+    },
+
+    // 初始化地图
+    initMap() {
+      this.mapLoading = true
+      
+      setTimeout(() => {
+        try {
+          // 创建地图实例
+          this.amapInstance = new AMap.Map('amapContainer', {
+            zoom: 15,
+            center: this.currentPosition,
+            mapStyle: 'amap://styles/light', // 浅色简洁风格
+            viewMode: '2D'
+          })
+          
+          // 添加地图控件
+          this.amapInstance.addControl(new AMap.Scale())
+          
+          // 生成模拟轨迹数据
+          this.generateMockTrackData()
+          
+          // 绘制轨迹和标记
+          this.drawTrackLine()
+          this.createMachineMarker()
+          
+          // 适应轨迹范围
+          this.fitTrackBounds()
+          
+          this.mapLoading = false
+          
+          // 开始实时更新农机位置
+          this.startMachinePositionUpdate()
+          
+        } catch (error) {
+          console.error('地图初始化失败:', error)
+          this.$message.error('地图初始化失败')
+          this.mapLoading = false
+        }
+      }, 1000) // 模拟加载时间
+    },
+
+    // 生成模拟轨迹数据
+    generateMockTrackData() {
+      const basePosition = this.currentPosition
+      const trackPointCount = this.mapViewMode === 'realtime' ? 20 : 50
+      
+      this.trackPoints = []
+      for (let i = 0; i < trackPointCount; i++) {
+        // 生成围绕当前位置的随机轨迹点
+        const deltaLng = (Math.random() - 0.5) * 0.01
+        const deltaLat = (Math.random() - 0.5) * 0.01
+        this.trackPoints.push([
+          basePosition[0] + deltaLng,
+          basePosition[1] + deltaLat
+        ])
+      }
+      
+      // 更新农机当前位置为轨迹的最后一点
+      if (this.trackPoints.length > 0) {
+        this.currentPosition = this.trackPoints[this.trackPoints.length - 1]
+      }
+      
+      this.hasTrackData = this.trackPoints.length > 0
+    },
+
+    // 绘制轨迹线
+    drawTrackLine() {
+      if (!this.amapInstance || this.trackPoints.length === 0) return
+      
+      // 移除现有轨迹线
+      if (this.trackPolyline) {
+        this.amapInstance.remove(this.trackPolyline)
+      }
+      
+      // 创建新的轨迹线
+      this.trackPolyline = new AMap.Polyline({
+        path: this.trackPoints,
+        strokeColor: '#10b981', // 绿色轨迹线
+        strokeWeight: 4,
+        strokeOpacity: 0.8,
+        strokeStyle: 'solid',
+        strokeDasharray: [10, 5],
+        lineJoin: 'round',
+        lineCap: 'round'
+      })
+      
+      this.amapInstance.add(this.trackPolyline)
+    },
+
+    // 创建农机标记点
+    createMachineMarker() {
+      if (!this.amapInstance) return
+      
+      // 移除现有标记
+      if (this.machineMarker) {
+        this.amapInstance.remove(this.machineMarker)
+      }
+      
+      // 创建农机图标
+      const machineIcon = new AMap.Icon({
+        size: new AMap.Size(32, 32),
+        image: 'data:image/svg+xml;base64,' + btoa(`
+          <svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
+            <circle cx="16" cy="16" r="14" fill="#10b981" stroke="#ffffff" stroke-width="2"/>
+            <path d="M10 12h12v8H10z" fill="#ffffff"/>
+            <circle cx="12" cy="22" r="2" fill="#ffffff"/>
+            <circle cx="20" cy="22" r="2" fill="#ffffff"/>
+            <rect x="14" y="8" width="4" height="4" fill="#ffffff"/>
+          </svg>
+        `),
+        imageSize: new AMap.Size(32, 32)
+      })
+      
+      // 创建标记点
+      this.machineMarker = new AMap.Marker({
+        position: this.currentPosition,
+        icon: machineIcon,
+        anchor: 'center',
+        animation: 'AMAP_ANIMATION_NONE'
+      })
+      
+      // 添加点击事件
+      this.machineMarker.on('click', () => {
+        const infoWindow = new AMap.InfoWindow({
+          content: `
+            <div style="padding: 10px;">
+              <h4 style="margin: 0 0 8px 0; color: #10b981;">${this.machineData.machineName || '东方红-LX1000'}</h4>
+              <p style="margin: 0; font-size: 12px; color: #666;">当前位置: ${this.trackData.currentLocation}</p>
+              <p style="margin: 4px 0 0 0; font-size: 12px; color: #666;">状态: ${this.getStatusText(this.machineData.onlineStatus)}</p>
+            </div>
+          `,
+          anchor: 'bottom-center',
+          offset: new AMap.Pixel(0, -30)
+        })
+        infoWindow.open(this.amapInstance, this.currentPosition)
+      })
+      
+      this.amapInstance.add(this.machineMarker)
+    },
+
+    // 更新地图视图
+    updateMapView() {
+      this.mapLoading = true
+      
+      // 切换到历史模式时,确保查询面板展开
+      if (this.mapViewMode === 'history') {
+        this.queryPanelCollapsed = false
+        this.trackData = {
+          todayDistance: 156.4,
+          workArea: 312.8,
+          avgSpeed: 4.2,
+          currentLocation: '多地块'
+        }
+      } else {
+        this.trackData = {
+          todayDistance: 12.8,
+          workArea: 45.2,
+          avgSpeed: 3.8,
+          currentLocation: '东区A-12'
+        }
+      }
+      
+      // 重新生成轨迹数据
+      setTimeout(() => {
+        this.generateMockTrackData()
+        this.drawTrackLine()
+        this.createMachineMarker()
+        this.fitTrackBounds()
+        this.mapLoading = false
+      }, 1000)
+    },
+
+    // 加载历史轨迹
+    loadHistoryTrack() {
+      if (!this.historyDateRange || this.historyDateRange.length !== 2) {
+        this.$message.warning('请选择查询日期范围')
+        return
+      }
+      
+      this.mapLoading = true
+      
+      // 模拟API调用
+      setTimeout(() => {
+        this.generateMockTrackData()
+        this.drawTrackLine()
+        this.createMachineMarker()
+        this.fitTrackBounds()
+        this.mapLoading = false
+        
+        const startDate = this.historyDateRange[0].toLocaleDateString()
+        const endDate = this.historyDateRange[1].toLocaleDateString()
+        this.$message.success(`已加载 ${startDate} 至 ${endDate} 的轨迹数据`)
+      }, 1500)
+    },
+    
+    // 获取状态类型
+    getStatusType(status) {
+      const statusMap = { '0': 'info', '1': 'success', '2': 'warning', '3': 'danger', 0: 'info', 1: 'success', 2: 'warning', 3: 'danger' }
+      return statusMap[status] || 'info'
+    },
+    
+    // 获取状态文本
+    getStatusText(status) {
+      const statusMap = { '0': '离线', '1': '作业中', '2': '忙碌', '3': '故障', 0: '离线', 1: '作业中', 2: '忙碌', 3: '故障' }
+      return statusMap[status] || '离线'
+    },
+    
+    // 获取定位状态类型
+    getLocationStatusType(status) {
+      const statusMap = { '0': 'info', '1': 'success', '2': 'warning', '3': 'danger', 0: 'info', 1: 'success', 2: 'warning', 3: 'danger' }
+      return statusMap[status] || 'info'
+    },
+    
+    // 获取定位状态文本
+    getLocationStatusText(status) {
+      const statusMap = { '0': '未定位', '1': '良好', '2': '信号弱', '3': '定位异常', 0: '未定位', 1: '良好', 2: '信号弱', 3: '定位异常' }
+      return statusMap[status] || '未定位'
+    },
+    
+    // 获取信号颜色
+    getSignalColor(strength) {
+      const colorMap = { 'strong': '#67C23A', 'medium': '#E6A23C', 'weak': '#F56C6C' }
+      return colorMap[strength] || '#909399'
+    },
+    
+    // 获取信号文本
+    getSignalText(strength) {
+      const textMap = { 'strong': '强', 'medium': '中', 'weak': '弱' }
+      return textMap[strength] || '未知'
+    },
+    
+    // 获取保养状态颜色
+    getMaintenanceColor(status) {
+      const colorMap = { '0': '#67C23A', '1': '#E6A23C', '2': '#F56C6C', '3': '#409EFF', 0: '#67C23A', 1: '#E6A23C', 2: '#F56C6C', 3: '#409EFF' }
+      return colorMap[status] || '#909399'
+    },
+    
+    // 获取保养状态文本
+    getMaintenanceText(status) {
+      const textMap = { '0': '正常', '1': '需要保养', '2': '过期', '3': '保养中', 0: '正常', 1: '需要保养', 2: '过期', 3: '保养中' }
+      return textMap[status] || '正常'
+    },
+    
+
+
+    // 地图全屏切换
+    toggleMapFullscreen() {
+      const mapContainer = this.$refs.mapContainer
+      if (document.fullscreenElement) {
+        document.exitFullscreen()
+        this.$message.success('已退出全屏')
+      } else {
+        mapContainer.requestFullscreen().then(() => {
+          this.$message.success('已进入全屏模式')
+          // 全屏后重新调整地图大小
+          setTimeout(() => {
+            if (this.amapInstance) {
+              this.amapInstance.getSize()
+            }
+          }, 100)
+        }).catch(() => {
+          this.$message.error('全屏功能不支持')
+        })
+      }
+    },
+
+    // 定位到农机
+    locateToMachine() {
+      if (!this.amapInstance || !this.currentPosition) {
+        this.$message.warning('无法获取农机位置')
+        return
+      }
+      
+      this.amapInstance.setCenter(this.currentPosition)
+      this.amapInstance.setZoom(16)
+      
+      // 添加农机位置闪烁动效
+      if (this.machineMarker) {
+        this.machineMarker.setAnimation('AMAP_ANIMATION_BOUNCE')
+        setTimeout(() => {
+          this.machineMarker.setAnimation('AMAP_ANIMATION_NONE')
+        }, 2000)
+      }
+      
+      this.$message.success('已定位到农机位置')
+    },
+
+    // 适应轨迹范围
+    fitTrackBounds() {
+      if (!this.amapInstance || !this.trackPoints || this.trackPoints.length === 0) return
+      
+      try {
+        const bounds = new AMap.Bounds()
+        this.trackPoints.forEach(point => {
+          bounds.extend(point)
+        })
+        
+        // 添加当前农机位置
+        if (this.currentPosition) {
+          bounds.extend(this.currentPosition)
+        }
+        
+        this.amapInstance.setBounds(bounds, false, [50, 50, 50, 50])
+      } catch (error) {
+        console.error('适应轨迹范围失败:', error)
+      }
+    },
+
+    // 重新加载地图数据
+    reloadMapData() {
+      this.mapLoading = true
+      
+      setTimeout(() => {
+        this.generateMockTrackData()
+        this.drawTrackLine()
+        this.createMachineMarker()
+        this.fitTrackBounds()
+        this.mapLoading = false
+        this.$message.success('地图数据已刷新')
+      }, 1000)
+    },
+
+    // 开始农机位置实时更新
+    startMachinePositionUpdate() {
+      if (this.mapViewMode !== 'realtime') return
+      
+      // 每30秒更新一次农机位置
+      const positionTimer = setInterval(() => {
+        this.updateMachinePosition()
+      }, 30000)
+      
+      this.timers.push(positionTimer)
+    },
+
+    // 更新农机位置
+    updateMachinePosition() {
+      if (!this.amapInstance || !this.machineMarker || this.mapViewMode !== 'realtime') return
+      
+      // 模拟位置微调(实际项目中从API获取)
+      const currentPos = this.machineMarker.getPosition()
+      const newLng = currentPos.lng + (Math.random() - 0.5) * 0.001
+      const newLat = currentPos.lat + (Math.random() - 0.5) * 0.001
+      const newPosition = [newLng, newLat]
+      
+      // 更新农机标记位置
+      this.machineMarker.setPosition(newPosition)
+      this.currentPosition = newPosition
+      
+      // 添加新轨迹点
+      this.trackPoints.push(newPosition)
+      
+      // 重新绘制轨迹线
+      this.drawTrackLine()
+      
+      // 更新里程数据
+      this.trackData.todayDistance = (parseFloat(this.trackData.todayDistance) + Math.random() * 0.1).toFixed(1)
+      this.trackData.workArea = (parseFloat(this.trackData.workArea) + Math.random() * 0.05).toFixed(1)
+    },
+
+    // 切换查询面板展开/折叠
+    toggleQueryPanel() {
+      this.queryPanelCollapsed = !this.queryPanelCollapsed
+    },
+    
+    // 跳转到监控汇总页面
+    goToMonitorOverview() {
+      this.$router.push('/base/machines/machines-monitor')
+    }
+  }
+}
+</script>
+
+<style scoped>
+.machine-monitor-container {
+  max-width: 1600px;
+  margin: 0 auto;
+  padding: 24px;
+  background: transparent;
+  color: #1f2937;
+  min-height: 100vh;
+  position: relative;
+}
+
+
+
+/* 顶部信息卡 */
+.info-header {
+  display: grid;
+  grid-template-columns: 2fr 1fr;
+  gap: 20px;
+  margin-bottom: 20px;
+  position: relative;
+  z-index: 1;
+}
+
+.machine-info-card {
+  background: rgba(255, 255, 255, 0.95);
+  border-radius: 16px;
+  padding: 28px;
+  box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
+  border: 1px solid #e5e7eb;
+  backdrop-filter: blur(10px);
+  transition: all 0.3s ease;
+}
+
+.machine-info-card:hover {
+  transform: translateY(-4px);
+  box-shadow: 0 10px 20px -5px rgba(0, 0, 0, 0.15);
+  border-color: #10b981;
+}
+
+.machine-header {
+  display: flex;
+  align-items: center;
+  gap: 20px;
+  margin-bottom: 24px;
+}
+
+.machine-avatar {
+  width: 80px;
+  height: 80px;
+  border-radius: 16px;
+  background: linear-gradient(135deg, #3BB44A 0%, #66C574 100%);
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  color: white;
+  font-size: 32px;
+}
+
+.machine-title {
+  flex: 1;
+}
+
+.machine-name {
+  font-size: 28px;
+  font-weight: 700;
+  color: #1a1a1a;
+  margin-bottom: 8px;
+}
+
+.machine-id {
+  font-size: 16px;
+  color: #6B7280;
+  background: #F9FAFB;
+  padding: 4px 12px;
+  border-radius: 6px;
+  display: inline-block;
+}
+
+.refresh-btn {
+  background: #10b981;
+  border-color: #10b981;
+}
+
+.refresh-btn:hover {
+  background: #059669;
+  border-color: #059669;
+}
+
+.info-grid {
+  display: grid;
+  grid-template-columns: repeat(4, 1fr);
+  gap: 16px;
+}
+
+.info-item {
+  text-align: left;
+  padding: 16px;
+  background: #F9FAFB;
+  border-radius: 8px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+}
+
+.info-label {
+  font-size: 12px;
+  color: #6B7280;
+  margin-bottom: 4px;
+  display: flex;
+  align-items: center;
+  gap: 6px;
+  white-space: nowrap;
+}
+
+.info-label i {
+  color: #10b981;
+  font-size: 14px;
+}
+
+.info-value {
+  font-size: 20px;
+  font-weight: 700;
+  color: #1a1a1a;
+  line-height: 1.2;
+  text-align: left;
+}
+
+/* 状态快览卡 */
+.status-overview {
+  background: rgba(255, 255, 255, 0.95);
+  border-radius: 16px;
+  padding: 28px;
+  box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
+  border: 1px solid #e5e7eb;
+  backdrop-filter: blur(10px);
+  transition: all 0.3s ease;
+  position: relative;
+  z-index: 1;
+}
+
+.status-overview:hover {
+  transform: translateY(-4px);
+  box-shadow: 0 10px 20px -5px rgba(0, 0, 0, 0.15);
+  border-color: #10b981;
+}
+
+.status-title {
+  font-size: 18px;
+  font-weight: 600;
+  color: #1a1a1a;
+  margin: 0 0 24px 0;
+  display: flex;
+  align-items: center;
+  gap: 8px;
+}
+
+.status-title i {
+  color: #10b981;
+  font-size: 20px;
+}
+
+.status-grid {
+  display: grid;
+  gap: 16px;
+}
+
+.status-item {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 12px 0;
+  border-bottom: 1px solid #F0F4F1;
+}
+
+.status-item:last-child {
+  border-bottom: none;
+}
+
+.status-label {
+  font-size: 14px;
+  color: #6B7280;
+}
+
+.status-value {
+  font-weight: 600;
+}
+
+/* 状态信息区域 */
+.status-section {
+  margin-bottom: 20px;
+  position: relative;
+  z-index: 1;
+}
+
+.status-cards {
+  display: grid;
+  grid-template-columns: repeat(3, 1fr);
+  gap: 20px;
+}
+
+.status-card {
+  border: 1px solid #e5e7eb;
+  border-radius: 16px;
+  background: rgba(255, 255, 255, 0.95);
+  backdrop-filter: blur(10px);
+  transition: all 0.3s ease;
+  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+}
+
+.status-card:hover {
+  transform: translateY(-4px);
+  box-shadow: 0 10px 20px -5px rgba(0, 0, 0, 0.15);
+  border-color: #10b981;
+}
+
+.card-title {
+  font-size: 16px;
+  font-weight: 600;
+  color: #1a1a1a;
+  display: flex;
+  align-items: center;
+  gap: 8px;
+}
+
+.card-title i {
+  color: #10b981;
+  font-size: 18px;
+}
+
+.metrics-grid {
+  display: grid;
+  grid-template-columns: 1fr 1fr;
+  gap: 16px;
+}
+
+.metric-item {
+  text-align: center;
+  padding: 16px;
+  background: #F9FAFB;
+  border-radius: 8px;
+}
+
+.metric-label {
+  font-size: 12px;
+  color: #6B7280;
+  margin-bottom: 8px;
+  display: flex;
+  align-items: center;
+  gap: 6px;
+}
+
+.metric-label i {
+  color: #10b981;
+  font-size: 14px;
+}
+
+.metric-value {
+  font-size: 20px;
+  font-weight: 700;
+  color: #1a1a1a;
+}
+
+/* 主要内容区域 */
+.main-content {
+  display: grid;
+  grid-template-columns: 1.2fr 1fr;
+  gap: 20px;
+  margin-bottom: 20px;
+  position: relative;
+  z-index: 1;
+}
+
+/* 监控视图 */
+.monitor-view {
+  border: 1px solid #e5e7eb;
+  border-radius: 16px;
+  background: rgba(255, 255, 255, 0.95);
+  backdrop-filter: blur(10px);
+  transition: all 0.3s ease;
+  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+}
+
+.monitor-view:hover {
+  transform: translateY(-4px);
+  box-shadow: 0 10px 20px -5px rgba(0, 0, 0, 0.15);
+  border-color: #10b981;
+}
+
+.monitor-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+
+.monitor-title {
+  font-size: 18px;
+  font-weight: 600;
+  color: #1a1a1a;
+  margin: 0;
+  display: flex;
+  align-items: center;
+  gap: 8px;
+}
+
+.monitor-title i {
+  color: #10b981;
+  font-size: 20px;
+}
+
+.fullscreen-btn {
+  background: #10b981;
+  border-color: #10b981;
+}
+
+.fullscreen-btn:hover {
+  background: #059669;
+  border-color: #059669;
+}
+
+.monitor-display {
+  position: relative;
+  height: 360px;
+  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  color: white;
+  border-radius: 8px;
+  margin: 0;
+}
+
+.monitor-placeholder {
+  text-align: center;
+}
+
+.monitor-placeholder i {
+  font-size: 64px;
+  margin-bottom: 20px;
+  opacity: 0.9;
+}
+
+.monitor-placeholder h4 {
+  font-size: 20px;
+  margin-bottom: 8px;
+  font-weight: 600;
+}
+
+.monitor-description {
+  font-size: 14px;
+  opacity: 0.8;
+  max-width: 300px;
+  line-height: 1.4;
+}
+
+/* 摄像头加载动画 */
+.camera-loading {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  text-align: center;
+}
+
+.loading-spinner {
+  margin-bottom: 20px;
+}
+
+.spinner-ring {
+  width: 60px;
+  height: 60px;
+  border: 4px solid rgba(255, 255, 255, 0.3);
+  border-top: 4px solid #10b981;
+  border-radius: 50%;
+  animation: spin 1s linear infinite;
+}
+
+.loading-text {
+  color: rgba(255, 255, 255, 0.9);
+  font-size: 14px;
+  margin: 0;
+  opacity: 0.8;
+  animation: pulse 2s ease-in-out infinite;
+}
+
+/* 旋转动画 */
+@keyframes spin {
+  0% { transform: rotate(0deg); }
+  100% { transform: rotate(360deg); }
+}
+
+/* 脉冲动画 */
+@keyframes pulse {
+  0%, 100% { opacity: 0.8; }
+  50% { opacity: 1; }
+}
+
+.monitor-status {
+  position: absolute;
+  top: 16px;
+  left: 16px;
+  right: 16px;
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+
+.signal-status, .monitor-time {
+  background: rgba(255,255,255,0.2);
+  padding: 8px 16px;
+  border-radius: 20px;
+  backdrop-filter: blur(10px);
+  font-size: 13px;
+}
+
+/* 操作控制栏 */
+.monitor-controls-bar {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 12px 20px;
+  background: #f8fafc;
+  border-top: 1px solid #e5e7eb;
+  border-radius: 0 0 8px 8px;
+  min-height: 60px;
+}
+
+.camera-controls {
+  display: flex;
+  align-items: center;
+  gap: 12px;
+  flex-wrap: wrap;
+}
+
+.control-label {
+  font-size: 14px;
+  color: #6b7280;
+  font-weight: 500;
+}
+
+.camera-buttons {
+  display: flex;
+  gap: 4px;
+}
+
+.camera-btn {
+  border-radius: 6px;
+  font-weight: 500;
+  min-width: 45px;
+  padding: 6px 12px;
+}
+
+.camera-info-bar {
+  display: flex;
+  align-items: center;
+  gap: 16px;
+  color: #6b7280;
+}
+
+.info-item {
+  display: flex;
+  align-items: center;
+  gap: 4px;
+  font-size: 13px;
+}
+
+.info-item i {
+  color: #10b981;
+  font-size: 14px;
+}
+
+.help-btn {
+  color: #6b7280;
+  padding: 4px;
+}
+
+.help-btn:hover {
+  color: #10b981;
+}
+
+/* 全屏模式样式 */
+.monitor-display:fullscreen {
+  height: 100vh;
+  border-radius: 0;
+  margin: 0;
+}
+
+.monitor-display:fullscreen .monitor-placeholder {
+  transform: scale(1.2);
+}
+
+.monitor-display:fullscreen .monitor-status {
+  top: 30px;
+  left: 30px;
+  right: 30px;
+}
+
+.monitor-display:fullscreen .camera-loading {
+  transform: scale(1.5);
+}
+
+.monitor-display:fullscreen .spinner-ring {
+  width: 80px;
+  height: 80px;
+  border-width: 5px;
+}
+
+.monitor-display:fullscreen .loading-text {
+  font-size: 16px;
+}
+
+/* 地图轨迹卡片 */
+.map-track-card {
+  border: 1px solid #e5e7eb;
+  border-radius: 16px;
+  background: rgba(255, 255, 255, 0.95);
+  backdrop-filter: blur(10px);
+  transition: all 0.3s ease;
+  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+}
+
+.map-track-card:hover {
+  transform: translateY(-4px);
+  box-shadow: 0 10px 20px -5px rgba(0, 0, 0, 0.15);
+  border-color: #10b981;
+}
+
+.map-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+
+.map-title {
+  font-size: 18px;
+  font-weight: 600;
+  color: #1a1a1a;
+  margin: 0;
+  display: flex;
+  align-items: center;
+  gap: 8px;
+}
+
+.map-title i {
+  color: #10b981;
+  font-size: 20px;
+}
+
+.map-controls {
+  display: flex;
+  align-items: center;
+  gap: 12px;
+}
+
+.map-fullscreen-btn {
+  background: #10b981;
+  border-color: #10b981;
+}
+
+.map-fullscreen-btn:hover {
+  background: #059669;
+  border-color: #059669;
+}
+
+/* 历史轨迹悬浮查询面板 */
+.history-query-overlay {
+  position: absolute;
+  top: 20px;
+  left: 50%;
+  transform: translateX(-50%);
+  z-index: 8;
+  min-width: 300px;
+  max-width: 90%;
+}
+
+.query-panel {
+  background: rgba(255, 255, 255, 0.95);
+  backdrop-filter: blur(10px);
+  border-radius: 12px;
+  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12);
+  border: 1px solid rgba(255, 255, 255, 0.3);
+  overflow: hidden;
+  transition: all 0.3s ease;
+}
+
+.query-panel.collapsed .query-content {
+  max-height: 0;
+  padding: 0 16px;
+  opacity: 0;
+}
+
+.query-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 12px 16px;
+  background: rgba(16, 185, 129, 0.1);
+  border-bottom: 1px solid rgba(16, 185, 129, 0.2);
+}
+
+.query-title {
+  display: flex;
+  align-items: center;
+  gap: 8px;
+  font-weight: 600;
+  color: #10b981;
+  font-size: 14px;
+}
+
+.query-title i {
+  font-size: 16px;
+}
+
+.collapse-btn {
+  color: #10b981;
+  padding: 4px;
+  min-width: auto;
+  transition: all 0.2s ease;
+}
+
+.collapse-btn:hover {
+  background: rgba(16, 185, 129, 0.1);
+}
+
+.query-content {
+  padding: 16px;
+  display: flex;
+  align-items: center;
+  gap: 12px;
+  flex-wrap: wrap;
+  max-height: 200px;
+  overflow: hidden;
+  transition: all 0.3s ease;
+  opacity: 1;
+}
+
+.date-picker-wrapper {
+  flex: 1;
+  min-width: 200px;
+}
+
+.history-date-picker {
+  width: 100%;
+}
+
+.query-btn {
+  background: #10b981;
+  border-color: #10b981;
+  flex-shrink: 0;
+}
+
+.query-btn:hover {
+  background: #059669;
+  border-color: #059669;
+}
+
+/* 地图容器 */
+.map-container {
+  position: relative;
+  height: 360px;
+  background: #f8fafc;
+  overflow: hidden;
+}
+
+.amap-container {
+  width: 100%;
+  height: 100%;
+}
+
+/* 地图加载动画 */
+.map-loading {
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  background: rgba(248, 250, 252, 0.9);
+  z-index: 10;
+}
+
+.map-loading-spinner {
+  margin-bottom: 16px;
+}
+
+.map-loading-text {
+  color: #6b7280;
+  font-size: 14px;
+  margin: 0;
+}
+
+/* 无数据提示 */
+.no-track-data {
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  text-align: center;
+  color: #6b7280;
+  z-index: 5;
+}
+
+.no-track-data i {
+  font-size: 64px;
+  margin-bottom: 16px;
+  opacity: 0.6;
+  color: #10b981;
+}
+
+.no-track-data h5 {
+  font-size: 18px;
+  margin: 0 0 8px 0;
+  color: #374151;
+}
+
+.no-track-data p {
+  font-size: 14px;
+  margin: 0;
+  max-width: 300px;
+  line-height: 1.4;
+}
+
+/* 地图控制按钮组 */
+.map-control-buttons {
+  position: absolute;
+  top: 20px;
+  right: 20px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  gap: 8px;
+  z-index: 5;
+}
+
+.map-control-buttons .el-button {
+  background: rgba(255, 255, 255, 0.9);
+  border-color: #e5e7eb;
+  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+  backdrop-filter: blur(10px);
+  width: 40px !important;
+  height: 40px !important;
+  padding: 0 !important;
+  display: flex !important;
+  align-items: center !important;
+  justify-content: center !important;
+  margin: 0 !important;
+  border-radius: 50% !important;
+}
+
+.map-control-buttons .el-button i {
+  font-size: 16px;
+  line-height: 1;
+  margin: 0 !important;
+}
+
+.map-control-buttons .el-button:hover {
+  background: #10b981;
+  border-color: #10b981;
+  color: white;
+}
+
+/* 全屏模式下的地图样式 */
+.map-container:fullscreen {
+  height: 100vh;
+}
+
+.map-container:fullscreen .map-control-buttons {
+  top: 40px;
+  right: 40px;
+}
+
+.map-container:fullscreen .map-control-buttons .el-button {
+  width: 44px !important;
+  height: 44px !important;
+}
+
+.map-container:fullscreen .map-control-buttons .el-button i {
+  font-size: 18px;
+}
+
+.map-container:fullscreen .amap-container {
+  height: 100vh;
+}
+
+.map-container:fullscreen .history-query-overlay {
+  top: 40px;
+  min-width: 400px;
+  max-width: 80%;
+}
+
+.map-container:fullscreen .query-panel {
+  font-size: 16px;
+}
+
+.map-container:fullscreen .query-header {
+  padding: 16px 20px;
+}
+
+.map-container:fullscreen .query-content {
+  padding: 20px;
+}
+
+.track-info {
+  padding: 20px 24px;
+  background: #F9FAFB;
+  border-top: 1px solid #e5f4e8;
+}
+
+.track-stats {
+  display: grid;
+  grid-template-columns: repeat(4, 1fr);
+  gap: 16px;
+}
+
+.track-stat {
+  text-align: center;
+  padding: 12px;
+  background: white;
+  border-radius: 8px;
+  border: 1px solid #F0F4F1;
+}
+
+.track-label {
+  font-size: 12px;
+  color: #6B7280;
+  margin-bottom: 6px;
+  display: flex;
+  align-items: center;
+  gap: 6px;
+}
+
+.track-label i {
+  color: #10b981;
+  font-size: 14px;
+}
+
+.track-value {
+  font-size: 16px;
+  font-weight: 600;
+  color: #1a1a1a;
+}
+
+.track-value.primary {
+  color: #3BB44A;
+}
+
+
+
+/* 底部快捷按钮 */
+.action-buttons {
+  display: flex;
+  gap: 16px;
+  justify-content: center;
+}
+
+/* 自定义状态徽章样式 (覆盖Element UI默认样式) */
+.el-tag {
+  display: inline-flex !important;
+  align-items: center !important;
+  padding: 3px 10px !important;
+  border-radius: 10px !important;
+  font-size: 11px !important;
+  font-weight: 500 !important;
+  gap: 3px !important;
+  border: none !important;
+}
+
+.el-tag--success {
+  background: #d1fae5 !important;
+  color: #065f46 !important;
+}
+
+.el-tag--warning {
+  background: #fef3c7 !important;
+  color: #92400e !important;
+}
+
+.el-tag--danger {
+  background: #fee2e2 !important;
+  color: #b91c1c !important;
+}
+
+.el-tag--info {
+  background: #e0f2fe !important;
+  color: #0369a1 !important;
+}
+
+/* 响应式设计 */
+@media (max-width: 1400px) {
+  .machine-monitor-container {
+    max-width: 1200px;
+    padding: 18px;
+  }
+}
+
+@media (max-width: 1200px) {
+  .machine-monitor-container {
+    max-width: 1000px;
+    padding: 16px;
+  }
+  
+  .info-header {
+    grid-template-columns: 1fr;
+    gap: 16px;
+  }
+  
+  .main-content {
+    grid-template-columns: 1fr;
+    gap: 16px;
+  }
+  
+  .status-cards {
+    grid-template-columns: 1fr 1fr;
+    gap: 16px;
+  }
+  
+  .info-grid {
+    grid-template-columns: repeat(2, 1fr);
+    gap: 16px;
+  }
+  
+  .track-stats {
+    grid-template-columns: repeat(2, 1fr);
+  }
+  
+  .monitor-display {
+    height: 300px;
+  }
+  
+  .map-container {
+    height: 300px;
+  }
+  
+  .map-control-buttons {
+    top: 15px;
+    right: 15px;
+    gap: 6px;
+  }
+  
+  /* 中等屏幕优化查询面板 */
+  .history-query-overlay {
+    min-width: 280px;
+    max-width: 95%;
+  }
+  
+  .query-content {
+    flex-direction: column;
+    align-items: stretch;
+    gap: 10px;
+  }
+  
+  .date-picker-wrapper {
+    min-width: auto;
+  }
+  
+  /* 中等屏幕优化加载动画 */
+  .spinner-ring {
+    width: 50px;
+    height: 50px;
+    border-width: 3px;
+  }
+  
+  .loading-text {
+    font-size: 13px;
+  }
+}
+
+@media (max-width: 768px) {
+  .machine-monitor-container {
+    padding: 12px;
+    max-width: 100%;
+  }
+  
+  .machine-info-card {
+    padding: 20px;
+    border-radius: 12px;
+  }
+  
+  .machine-header {
+    flex-direction: column;
+    text-align: center;
+    gap: 16px;
+  }
+  
+  .info-grid {
+    grid-template-columns: 1fr;
+    gap: 12px;
+  }
+  
+  .info-item {
+    padding: 12px 8px;
+  }
+  
+  .info-label {
+    font-size: 11px;
+    margin-bottom: 3px;
+  }
+  
+  .info-value {
+    font-size: 18px;
+  }
+  
+  .status-cards {
+    grid-template-columns: 1fr;
+    gap: 12px;
+  }
+  
+  .metrics-grid {
+    grid-template-columns: 1fr;
+  }
+  
+  .track-stats {
+    grid-template-columns: 1fr;
+  }
+  
+  .action-buttons {
+    flex-direction: column;
+  }
+  
+  .monitor-display {
+    height: 250px;
+  }
+  
+  .monitor-controls-bar {
+    flex-direction: column;
+    gap: 8px;
+    align-items: flex-start;
+    padding: 10px 16px;
+  }
+  
+  .camera-info-bar {
+    flex-direction: column;
+    align-items: flex-start;
+    gap: 8px;
+  }
+  
+  /* 移动端优化加载动画 */
+  .spinner-ring {
+    width: 40px;
+    height: 40px;
+    border-width: 3px;
+  }
+  
+  .loading-text {
+    font-size: 12px;
+    max-width: 200px;
+    line-height: 1.3;
+  }
+  
+  .loading-spinner {
+    margin-bottom: 16px;
+  }
+  
+  /* 移动端地图优化 */
+  .map-container {
+    height: 220px;
+  }
+  
+  .map-control-buttons {
+    top: 10px;
+    right: 10px;
+    gap: 4px;
+  }
+  
+  .map-control-buttons .el-button {
+    width: 36px !important;
+    height: 36px !important;
+    padding: 0 !important;
+    min-width: 36px !important;
+  }
+  
+  .map-control-buttons .el-button i {
+    font-size: 14px;
+  }
+  
+  /* 移动端优化查询面板 */
+  .history-query-overlay {
+    top: 10px;
+    min-width: 260px;
+    max-width: 96%;
+  }
+  
+  .query-panel {
+    border-radius: 8px;
+    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
+  }
+  
+  .query-header {
+    padding: 10px 12px;
+  }
+  
+  .query-title {
+    font-size: 13px;
+  }
+  
+  .query-content {
+    padding: 12px;
+    flex-direction: column;
+    align-items: stretch;
+    gap: 8px;
+  }
+  
+  .date-picker-wrapper {
+    min-width: auto;
+  }
+  
+  .history-date-picker {
+    font-size: 12px;
+  }
+  
+
+  
+  .no-track-data i {
+    font-size: 48px;
+  }
+  
+  .no-track-data h5 {
+    font-size: 16px;
+  }
+  
+  .no-track-data p {
+    font-size: 12px;
+    max-width: 250px;
+  }
+  
+  .status-card,
+  .monitor-view,
+  .map-track-card {
+    border-radius: 12px;
+  }
+}
+</style>