Selaa lähdekoodia

新增2-3系统接口

wangshuangpan 1 kuukausi sitten
vanhempi
commit
7ba3626c02
21 muutettua tiedostoa jossa 3000 lisäystä ja 10 poistoa
  1. 88 0
      pm-admin/src/main/java/com/pm/web/controller/subsystem/ElevatorController.java
  2. 133 0
      pm-admin/src/main/java/com/pm/web/controller/subsystem/LightingController.java
  3. 42 0
      pm-admin/src/main/java/com/pm/web/controller/subsystem/SubsystemCommonController.java
  4. 28 0
      pm-system/src/main/java/com/pm/subsystem/mapper/CommonMapper.java
  5. 67 0
      pm-system/src/main/java/com/pm/subsystem/mapper/ElevatorMapper.java
  6. 77 0
      pm-system/src/main/java/com/pm/subsystem/mapper/LightingMapper.java
  7. 28 0
      pm-system/src/main/java/com/pm/subsystem/service/ICommonService.java
  8. 52 0
      pm-system/src/main/java/com/pm/subsystem/service/IElevatorService.java
  9. 85 0
      pm-system/src/main/java/com/pm/subsystem/service/ILightingService.java
  10. 44 0
      pm-system/src/main/java/com/pm/subsystem/service/impl/CommonServiceImpl.java
  11. 116 0
      pm-system/src/main/java/com/pm/subsystem/service/impl/ElevatorServiceImpl.java
  12. 172 0
      pm-system/src/main/java/com/pm/subsystem/service/impl/LightingServiceImpl.java
  13. 22 0
      pm-system/src/main/resources/mapper/subsystem/CommonMapper.xml
  14. 130 0
      pm-system/src/main/resources/mapper/subsystem/ElevatorMapper.xml
  15. 160 0
      pm-system/src/main/resources/mapper/subsystem/LightingMapper.xml
  16. 1 1
      pm_ui/package.json
  17. 53 0
      pm_ui/src/api/subsystem/elevator.js
  18. 99 0
      pm_ui/src/api/subsystem/lighting.js
  19. 778 0
      pm_ui/src/views/dtxt/index.vue
  20. 9 9
      pm_ui/src/views/spafjkxt/index.vue
  21. 816 0
      pm_ui/src/views/zmxt/index.vue

+ 88 - 0
pm-admin/src/main/java/com/pm/web/controller/subsystem/ElevatorController.java

@@ -0,0 +1,88 @@
+package com.pm.web.controller.subsystem;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import com.pm.common.annotation.Log;
+import com.pm.common.core.controller.BaseController;
+import com.pm.common.core.domain.AjaxResult;
+import com.pm.common.enums.BusinessType;
+import com.pm.common.config.PageData;
+import com.pm.subsystem.service.IElevatorService;
+import com.pm.common.core.page.TableDataInfo;
+
+/**
+ * 电梯系统Controller
+ * 
+ * @author pm
+ * @date 2025-01-01
+ */
+@RestController
+@RequestMapping("/subsystem/elevator")
+public class ElevatorController extends BaseController
+{
+    @Autowired
+    private IElevatorService elevatorService;
+
+    /**
+     * 查询电梯设备列表
+     */
+    @PreAuthorize("@ss.hasPermi('subsystem:elevator:list')")
+    @GetMapping("/device/list")
+    public TableDataInfo deviceList()
+    {
+        PageData pd = this.getPageData();
+        startPage();
+        List<PageData> list = elevatorService.selectElevatorDeviceList(pd);
+        return getDataTable(list);
+    }
+
+    /**
+     * 查询电梯运行记录列表
+     */
+    @PreAuthorize("@ss.hasPermi('subsystem:elevator:record')")
+    @GetMapping("/record/list")
+    public TableDataInfo recordList()
+    {
+        PageData pd = this.getPageData();
+        startPage();
+        List<PageData> list = elevatorService.selectElevatorRecordList(pd);
+        return getDataTable(list);
+    }
+
+    /**
+     * 查询电梯报警列表
+     */
+    @PreAuthorize("@ss.hasPermi('subsystem:elevator:alarm')")
+    @GetMapping("/alarm/list")
+    public TableDataInfo alarmList()
+    {
+        PageData pd = this.getPageData();
+        startPage();
+        List<PageData> list = elevatorService.selectElevatorAlarmList(pd);
+        return getDataTable(list);
+    }
+
+    /**
+     * 处理电梯报警
+     */
+    @PreAuthorize("@ss.hasPermi('subsystem:elevator:alarm')")
+    @Log(title = "处理电梯报警", businessType = BusinessType.UPDATE)
+    @PostMapping("/alarm/handle")
+    public AjaxResult handleAlarm(@RequestBody PageData pd)
+    {
+        return toAjax(elevatorService.handleElevatorAlarm(pd));
+    }
+
+    /**
+     * 获取电梯统计数据
+     */
+    @PreAuthorize("@ss.hasPermi('subsystem:elevator:statistics')")
+    @GetMapping("/statistics")
+    public AjaxResult statistics()
+    {
+        return success(elevatorService.getElevatorStatistics());
+    }
+}

+ 133 - 0
pm-admin/src/main/java/com/pm/web/controller/subsystem/LightingController.java

@@ -0,0 +1,133 @@
+package com.pm.web.controller.subsystem;
+
+import java.util.List;
+import javax.servlet.http.HttpServletResponse;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import com.pm.common.annotation.Log;
+import com.pm.common.core.controller.BaseController;
+import com.pm.common.core.domain.AjaxResult;
+import com.pm.common.enums.BusinessType;
+import com.pm.common.config.PageData;
+import com.pm.subsystem.service.ILightingService;
+import com.pm.common.core.page.TableDataInfo;
+
+/**
+ * 照明系统Controller
+ * 
+ * @author pm
+ * @date 2025-01-01
+ */
+@RestController
+@RequestMapping("/subsystem/lighting")
+public class LightingController extends BaseController
+{
+    @Autowired
+    private ILightingService lightingService;
+
+    /**
+     * 查询照明设备列表
+     */
+    @PreAuthorize("@ss.hasPermi('subsystem:lighting:list')")
+    @GetMapping("/device/list")
+    public TableDataInfo deviceList()
+    {
+        PageData pd = this.getPageData();
+        startPage();
+        List<PageData> list = lightingService.selectLightingDeviceList(pd);
+        return getDataTable(list);
+    }
+
+    /**
+     * 控制照明设备
+     */
+    @PreAuthorize("@ss.hasPermi('subsystem:lighting:control')")
+    @Log(title = "照明控制", businessType = BusinessType.UPDATE)
+    @PostMapping("/device/control")
+    public AjaxResult controlDevice(@RequestBody PageData pd)
+    {
+        return toAjax(lightingService.controlLightingDevice(pd));
+    }
+
+    /**
+     * 批量控制照明
+     */
+    @PreAuthorize("@ss.hasPermi('subsystem:lighting:control')")
+    @Log(title = "批量照明控制", businessType = BusinessType.UPDATE)
+    @PostMapping("/device/batchControl")
+    public AjaxResult batchControl(@RequestBody PageData pd)
+    {
+        return toAjax(lightingService.batchControlLighting(pd));
+    }
+
+    /**
+     * 查询照明报警列表
+     */
+    @PreAuthorize("@ss.hasPermi('subsystem:lighting:alarm')")
+    @GetMapping("/alarm/list")
+    public TableDataInfo alarmList()
+    {
+        PageData pd = this.getPageData();
+        startPage();
+        List<PageData> list = lightingService.selectLightingAlarmList(pd);
+        return getDataTable(list);
+    }
+
+    /**
+     * 处理照明报警
+     */
+    @PreAuthorize("@ss.hasPermi('subsystem:lighting:alarm')")
+    @Log(title = "处理照明报警", businessType = BusinessType.UPDATE)
+    @PostMapping("/alarm/handle")
+    public AjaxResult handleAlarm(@RequestBody PageData pd)
+    {
+        return toAjax(lightingService.handleLightingAlarm(pd));
+    }
+
+    /**
+     * 查询照明计划列表
+     */
+    @PreAuthorize("@ss.hasPermi('subsystem:lighting:schedule')")
+    @GetMapping("/schedule/list")
+    public TableDataInfo scheduleList()
+    {
+        PageData pd = this.getPageData();
+        startPage();
+        List<PageData> list = lightingService.selectLightingScheduleList(pd);
+        return getDataTable(list);
+    }
+
+    /**
+     * 新增照明计划
+     */
+    @PreAuthorize("@ss.hasPermi('subsystem:lighting:schedule')")
+    @Log(title = "照明计划", businessType = BusinessType.INSERT)
+    @PostMapping("/schedule")
+    public AjaxResult addSchedule(@RequestBody PageData pd)
+    {
+        return toAjax(lightingService.insertLightingSchedule(pd));
+    }
+
+    /**
+     * 修改照明计划
+     */
+    @PreAuthorize("@ss.hasPermi('subsystem:lighting:schedule')")
+    @Log(title = "照明计划", businessType = BusinessType.UPDATE)
+    @PutMapping("/schedule")
+    public AjaxResult editSchedule(@RequestBody PageData pd)
+    {
+        return toAjax(lightingService.updateLightingSchedule(pd));
+    }
+
+    /**
+     * 删除照明计划
+     */
+    @PreAuthorize("@ss.hasPermi('subsystem:lighting:schedule')")
+    @Log(title = "照明计划", businessType = BusinessType.DELETE)
+    @DeleteMapping("/schedule/{id}")
+    public AjaxResult removeSchedule(@PathVariable Long id)
+    {
+        return toAjax(lightingService.deleteLightingSchedule(id));
+    }
+}

+ 42 - 0
pm-admin/src/main/java/com/pm/web/controller/subsystem/SubsystemCommonController.java

@@ -0,0 +1,42 @@
+package com.pm.web.controller.subsystem;
+
+import java.util.List;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import com.pm.common.core.controller.BaseController;
+import com.pm.common.core.domain.AjaxResult;
+import com.pm.common.config.PageData;
+import com.pm.subsystem.service.ICommonService;
+
+/**
+ * 子系统公共Controller
+ * 
+ * @author pm
+ * @date 2025-01-01
+ */
+@RestController
+@RequestMapping("/subsystem/common")
+public class SubsystemCommonController extends BaseController
+{
+    @Autowired
+    private ICommonService commonService;
+
+    /**
+     * 获取楼栋列表
+     */
+    @GetMapping("/building/list")
+    public AjaxResult buildingList()
+    {
+        return success(commonService.selectBuildingList());
+    }
+
+    /**
+     * 获取楼层列表
+     */
+    @GetMapping("/floor/list")
+    public AjaxResult floorList()
+    {
+        PageData pd = this.getPageData();
+        return success(commonService.selectFloorList(pd));
+    }
+}

+ 28 - 0
pm-system/src/main/java/com/pm/subsystem/mapper/CommonMapper.java

@@ -0,0 +1,28 @@
+package com.pm.subsystem.mapper;
+
+import java.util.List;
+import com.pm.common.config.PageData;
+
+/**
+ * 子系统公共Mapper接口
+ * 
+ * @author pm
+ * @date 2025-01-01
+ */
+public interface CommonMapper
+{
+    /**
+     * 查询楼栋列表
+     * 
+     * @return 楼栋集合
+     */
+    public List<PageData> selectBuildingList();
+
+    /**
+     * 查询楼层列表
+     * 
+     * @param pd 查询参数(buildingId)
+     * @return 楼层集合
+     */
+    public List<PageData> selectFloorList(PageData pd);
+}

+ 67 - 0
pm-system/src/main/java/com/pm/subsystem/mapper/ElevatorMapper.java

@@ -0,0 +1,67 @@
+package com.pm.subsystem.mapper;
+
+import java.util.List;
+import com.pm.common.config.PageData;
+
+/**
+ * 电梯系统Mapper接口
+ * 
+ * @author pm
+ * @date 2025-01-01
+ */
+public interface ElevatorMapper
+{
+    /**
+     * 查询电梯设备列表
+     * 
+     * @param pd 查询参数
+     * @return 电梯设备集合
+     */
+    public List<PageData> selectElevatorDeviceList(PageData pd);
+
+    /**
+     * 查询电梯运行记录列表
+     * 
+     * @param pd 查询参数
+     * @return 运行记录集合
+     */
+    public List<PageData> selectElevatorRecordList(PageData pd);
+
+    /**
+     * 查询电梯报警列表
+     * 
+     * @param pd 查询参数
+     * @return 报警集合
+     */
+    public List<PageData> selectElevatorAlarmList(PageData pd);
+
+    /**
+     * 更新电梯报警
+     * 
+     * @param pd 报警信息
+     * @return 结果
+     */
+    public int updateElevatorAlarm(PageData pd);
+
+    /**
+     * 查询电梯数量
+     * 
+     * @param pd 查询参数
+     * @return 数量
+     */
+    public int selectElevatorCount(PageData pd);
+
+    /**
+     * 查询电梯类型分布
+     * 
+     * @return 类型分布
+     */
+    public List<PageData> selectElevatorTypeDistribution();
+
+    /**
+     * 查询电梯楼栋分布
+     * 
+     * @return 楼栋分布
+     */
+    public List<PageData> selectElevatorBuildingDistribution();
+}

+ 77 - 0
pm-system/src/main/java/com/pm/subsystem/mapper/LightingMapper.java

@@ -0,0 +1,77 @@
+package com.pm.subsystem.mapper;
+
+import java.util.List;
+import com.pm.common.config.PageData;
+
+/**
+ * 照明系统Mapper接口
+ * 
+ * @author pm
+ * @date 2025-01-01
+ */
+public interface LightingMapper
+{
+    /**
+     * 查询照明设备列表
+     * 
+     * @param pd 查询参数
+     * @return 照明设备集合
+     */
+    public List<PageData> selectLightingDeviceList(PageData pd);
+
+    /**
+     * 更新照明设备状态
+     * 
+     * @param pd 设备信息
+     * @return 结果
+     */
+    public int updateLightingDevice(PageData pd);
+
+    /**
+     * 查询照明报警列表
+     * 
+     * @param pd 查询参数
+     * @return 报警集合
+     */
+    public List<PageData> selectLightingAlarmList(PageData pd);
+
+    /**
+     * 更新照明报警
+     * 
+     * @param pd 报警信息
+     * @return 结果
+     */
+    public int updateLightingAlarm(PageData pd);
+
+    /**
+     * 查询照明计划列表
+     * 
+     * @param pd 查询参数
+     * @return 计划集合
+     */
+    public List<PageData> selectLightingScheduleList(PageData pd);
+
+    /**
+     * 新增照明计划
+     * 
+     * @param pd 计划信息
+     * @return 结果
+     */
+    public int insertLightingSchedule(PageData pd);
+
+    /**
+     * 修改照明计划
+     * 
+     * @param pd 计划信息
+     * @return 结果
+     */
+    public int updateLightingSchedule(PageData pd);
+
+    /**
+     * 删除照明计划
+     * 
+     * @param id 计划ID
+     * @return 结果
+     */
+    public int deleteLightingSchedule(Long id);
+}

+ 28 - 0
pm-system/src/main/java/com/pm/subsystem/service/ICommonService.java

@@ -0,0 +1,28 @@
+package com.pm.subsystem.service;
+
+import java.util.List;
+import com.pm.common.config.PageData;
+
+/**
+ * 子系统公共Service接口
+ * 
+ * @author pm
+ * @date 2025-01-01
+ */
+public interface ICommonService
+{
+    /**
+     * 查询楼栋列表
+     * 
+     * @return 楼栋集合
+     */
+    public List<PageData> selectBuildingList();
+
+    /**
+     * 查询楼层列表
+     * 
+     * @param pd 查询参数(buildingId)
+     * @return 楼层集合
+     */
+    public List<PageData> selectFloorList(PageData pd);
+}

+ 52 - 0
pm-system/src/main/java/com/pm/subsystem/service/IElevatorService.java

@@ -0,0 +1,52 @@
+package com.pm.subsystem.service;
+
+import java.util.List;
+import com.pm.common.config.PageData;
+
+/**
+ * 电梯系统Service接口
+ * 
+ * @author pm
+ * @date 2025-01-01
+ */
+public interface IElevatorService
+{
+    /**
+     * 查询电梯设备列表
+     * 
+     * @param pd 查询参数
+     * @return 电梯设备集合
+     */
+    public List<PageData> selectElevatorDeviceList(PageData pd);
+
+    /**
+     * 查询电梯运行记录列表
+     * 
+     * @param pd 查询参数
+     * @return 运行记录集合
+     */
+    public List<PageData> selectElevatorRecordList(PageData pd);
+
+    /**
+     * 查询电梯报警列表
+     * 
+     * @param pd 查询参数
+     * @return 报警集合
+     */
+    public List<PageData> selectElevatorAlarmList(PageData pd);
+
+    /**
+     * 处理电梯报警
+     * 
+     * @param pd 处理参数
+     * @return 结果
+     */
+    public int handleElevatorAlarm(PageData pd);
+
+    /**
+     * 获取电梯统计数据
+     * 
+     * @return 统计数据
+     */
+    public PageData getElevatorStatistics();
+}

+ 85 - 0
pm-system/src/main/java/com/pm/subsystem/service/ILightingService.java

@@ -0,0 +1,85 @@
+package com.pm.subsystem.service;
+
+import java.util.List;
+import com.pm.common.config.PageData;
+
+/**
+ * 照明系统Service接口
+ * 
+ * @author pm
+ * @date 2025-01-01
+ */
+public interface ILightingService
+{
+    /**
+     * 查询照明设备列表
+     * 
+     * @param pd 查询参数
+     * @return 照明设备集合
+     */
+    public List<PageData> selectLightingDeviceList(PageData pd);
+
+    /**
+     * 控制照明设备
+     * 
+     * @param pd 控制参数
+     * @return 结果
+     */
+    public int controlLightingDevice(PageData pd);
+
+    /**
+     * 批量控制照明
+     * 
+     * @param pd 控制参数
+     * @return 结果
+     */
+    public int batchControlLighting(PageData pd);
+
+    /**
+     * 查询照明报警列表
+     * 
+     * @param pd 查询参数
+     * @return 报警集合
+     */
+    public List<PageData> selectLightingAlarmList(PageData pd);
+
+    /**
+     * 处理照明报警
+     * 
+     * @param pd 处理参数
+     * @return 结果
+     */
+    public int handleLightingAlarm(PageData pd);
+
+    /**
+     * 查询照明计划列表
+     * 
+     * @param pd 查询参数
+     * @return 计划集合
+     */
+    public List<PageData> selectLightingScheduleList(PageData pd);
+
+    /**
+     * 新增照明计划
+     * 
+     * @param pd 计划信息
+     * @return 结果
+     */
+    public int insertLightingSchedule(PageData pd);
+
+    /**
+     * 修改照明计划
+     * 
+     * @param pd 计划信息
+     * @return 结果
+     */
+    public int updateLightingSchedule(PageData pd);
+
+    /**
+     * 删除照明计划
+     * 
+     * @param id 计划ID
+     * @return 结果
+     */
+    public int deleteLightingSchedule(Long id);
+}

+ 44 - 0
pm-system/src/main/java/com/pm/subsystem/service/impl/CommonServiceImpl.java

@@ -0,0 +1,44 @@
+package com.pm.subsystem.service.impl;
+
+import java.util.List;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.pm.subsystem.mapper.CommonMapper;
+import com.pm.subsystem.service.ICommonService;
+import com.pm.common.config.PageData;
+
+/**
+ * 子系统公共Service业务层处理
+ * 
+ * @author pm
+ * @date 2025-01-01
+ */
+@Service
+public class CommonServiceImpl implements ICommonService
+{
+    @Autowired
+    private CommonMapper commonMapper;
+
+    /**
+     * 查询楼栋列表
+     * 
+     * @return 楼栋集合
+     */
+    @Override
+    public List<PageData> selectBuildingList()
+    {
+        return commonMapper.selectBuildingList();
+    }
+
+    /**
+     * 查询楼层列表
+     * 
+     * @param pd 查询参数(buildingId)
+     * @return 楼层集合
+     */
+    @Override
+    public List<PageData> selectFloorList(PageData pd)
+    {
+        return commonMapper.selectFloorList(pd);
+    }
+}

+ 116 - 0
pm-system/src/main/java/com/pm/subsystem/service/impl/ElevatorServiceImpl.java

@@ -0,0 +1,116 @@
+package com.pm.subsystem.service.impl;
+
+import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
+import com.pm.common.utils.DateUtils;
+import com.pm.common.utils.SecurityUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.pm.subsystem.mapper.ElevatorMapper;
+import com.pm.subsystem.service.IElevatorService;
+import com.pm.common.config.PageData;
+
+/**
+ * 电梯系统Service业务层处理
+ * 
+ * @author pm
+ * @date 2025-01-01
+ */
+@Service
+public class ElevatorServiceImpl implements IElevatorService
+{
+    @Autowired
+    private ElevatorMapper elevatorMapper;
+
+    /**
+     * 查询电梯设备列表
+     * 
+     * @param pd 查询参数
+     * @return 电梯设备
+     */
+    @Override
+    public List<PageData> selectElevatorDeviceList(PageData pd)
+    {
+        // 模拟从第三方接口获取数据
+        List<PageData> list = elevatorMapper.selectElevatorDeviceList(pd);
+        // 这里可以调用第三方接口获取实时数据并更新
+        for (PageData device : list) {
+            // 模拟获取实时状态
+            device.put("last_update_time", DateUtils.getTime());
+            // TODO: 调用电梯系统接口获取实时楼层、运行状态等
+        }
+        return list;
+    }
+
+    /**
+     * 查询电梯运行记录列表
+     * 
+     * @param pd 查询参数
+     * @return 运行记录
+     */
+    @Override
+    public List<PageData> selectElevatorRecordList(PageData pd)
+    {
+        return elevatorMapper.selectElevatorRecordList(pd);
+    }
+
+    /**
+     * 查询电梯报警列表
+     * 
+     * @param pd 查询参数
+     * @return 报警
+     */
+    @Override
+    public List<PageData> selectElevatorAlarmList(PageData pd)
+    {
+        return elevatorMapper.selectElevatorAlarmList(pd);
+    }
+
+    /**
+     * 处理电梯报警
+     * 
+     * @param pd 处理参数
+     * @return 结果
+     */
+    @Override
+    public int handleElevatorAlarm(PageData pd)
+    {
+        pd.put("handleStatus", 1);
+        pd.put("handleTime", DateUtils.getTime());
+        pd.put("handleUser", SecurityUtils.getUsername());
+        return elevatorMapper.updateElevatorAlarm(pd);
+    }
+
+    /**
+     * 获取电梯统计数据
+     * 
+     * @return 统计数据
+     */
+    @Override
+    public PageData getElevatorStatistics()
+    {
+        PageData result = new PageData();
+        
+        // 设备总数
+        result.put("total", elevatorMapper.selectElevatorCount(new PageData()));
+        
+        // 在线设备数
+        PageData onlineParam = new PageData();
+        onlineParam.put("isOnline", 1);
+        result.put("online", elevatorMapper.selectElevatorCount(onlineParam));
+        
+        // 故障设备数
+        PageData faultParam = new PageData();
+        faultParam.put("faultStatus", 1);
+        result.put("fault", elevatorMapper.selectElevatorCount(faultParam));
+        
+        // 类型分布
+        result.put("typeDistribution", elevatorMapper.selectElevatorTypeDistribution());
+        
+        // 楼栋分布
+        result.put("buildingDistribution", elevatorMapper.selectElevatorBuildingDistribution());
+        
+        return result;
+    }
+}

+ 172 - 0
pm-system/src/main/java/com/pm/subsystem/service/impl/LightingServiceImpl.java

@@ -0,0 +1,172 @@
+package com.pm.subsystem.service.impl;
+
+import java.util.List;
+import java.util.Arrays;
+import com.pm.common.utils.DateUtils;
+import com.pm.common.utils.SecurityUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.pm.subsystem.mapper.LightingMapper;
+import com.pm.subsystem.service.ILightingService;
+import com.pm.common.config.PageData;
+
+/**
+ * 照明系统Service业务层处理
+ * 
+ * @author pm
+ * @date 2025-01-01
+ */
+@Service
+public class LightingServiceImpl implements ILightingService
+{
+    @Autowired
+    private LightingMapper lightingMapper;
+
+    /**
+     * 查询照明设备列表
+     * 
+     * @param pd 查询参数
+     * @return 照明设备
+     */
+    @Override
+    public List<PageData> selectLightingDeviceList(PageData pd)
+    {
+        // 模拟从第三方接口获取数据
+        List<PageData> list = lightingMapper.selectLightingDeviceList(pd);
+        // 这里可以调用第三方接口获取实时数据并更新
+        for (PageData device : list) {
+            // 模拟获取实时状态
+            device.put("last_update_time", DateUtils.getTime());
+        }
+        return list;
+    }
+
+    /**
+     * 控制照明设备
+     * 
+     * @param pd 控制参数
+     * @return 结果
+     */
+    @Override
+    public int controlLightingDevice(PageData pd)
+    {
+        // 调用第三方接口发送控制命令
+        String deviceCode = pd.getString("deviceCode");
+        Integer action = (Integer)pd.get("action");
+        Integer brightness = (Integer)pd.get("brightness");
+        
+        // TODO: 调用实际的照明系统接口
+        // boolean result = callThirdPartyAPI(deviceCode, action, brightness);
+        
+        // 更新本地数据库状态
+        pd.put("status", action);
+        pd.put("brightness", brightness);
+        pd.put("lastUpdateTime", DateUtils.getTime());
+        
+        return lightingMapper.updateLightingDevice(pd);
+    }
+
+    /**
+     * 批量控制照明
+     * 
+     * @param pd 控制参数
+     * @return 结果
+     */
+    @Override
+    public int batchControlLighting(PageData pd)
+    {
+        String deviceCodes = pd.getString("deviceCodes");
+        Integer action = (Integer)pd.get("action");
+        Integer brightness = (Integer)pd.get("brightness");
+        
+        String[] codes = deviceCodes.split(",");
+        int count = 0;
+        
+        for (String code : codes) {
+            PageData controlPd = new PageData();
+            controlPd.put("deviceCode", code);
+            controlPd.put("action", action);
+            controlPd.put("brightness", brightness);
+            count += controlLightingDevice(controlPd);
+        }
+        
+        return count;
+    }
+
+    /**
+     * 查询照明报警列表
+     * 
+     * @param pd 查询参数
+     * @return 报警
+     */
+    @Override
+    public List<PageData> selectLightingAlarmList(PageData pd)
+    {
+        return lightingMapper.selectLightingAlarmList(pd);
+    }
+
+    /**
+     * 处理照明报警
+     * 
+     * @param pd 处理参数
+     * @return 结果
+     */
+    @Override
+    public int handleLightingAlarm(PageData pd)
+    {
+        pd.put("handleStatus", 1);
+        pd.put("handleTime", DateUtils.getTime());
+        pd.put("handleUser", SecurityUtils.getUsername());
+        return lightingMapper.updateLightingAlarm(pd);
+    }
+
+    /**
+     * 查询照明计划列表
+     * 
+     * @param pd 查询参数
+     * @return 计划
+     */
+    @Override
+    public List<PageData> selectLightingScheduleList(PageData pd)
+    {
+        return lightingMapper.selectLightingScheduleList(pd);
+    }
+
+    /**
+     * 新增照明计划
+     * 
+     * @param pd 计划信息
+     * @return 结果
+     */
+    @Override
+    public int insertLightingSchedule(PageData pd)
+    {
+        pd.put("createTime", DateUtils.getTime());
+        return lightingMapper.insertLightingSchedule(pd);
+    }
+
+    /**
+     * 修改照明计划
+     * 
+     * @param pd 计划信息
+     * @return 结果
+     */
+    @Override
+    public int updateLightingSchedule(PageData pd)
+    {
+        pd.put("updateTime", DateUtils.getTime());
+        return lightingMapper.updateLightingSchedule(pd);
+    }
+
+    /**
+     * 删除照明计划
+     * 
+     * @param id 计划ID
+     * @return 结果
+     */
+    @Override
+    public int deleteLightingSchedule(Long id)
+    {
+        return lightingMapper.deleteLightingSchedule(id);
+    }
+}

+ 22 - 0
pm-system/src/main/resources/mapper/subsystem/CommonMapper.xml

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.pm.subsystem.mapper.CommonMapper">
+
+    <select id="selectBuildingList" resultType="pd">
+        select distinct building_id as id, building_name as name
+        from ibms_building
+        where building_id is not null
+        order by building_name
+    </select>
+
+    <select id="selectFloorList" parameterType="pd" resultType="pd">
+        select distinct floor_id as id, floor_name as name
+        from ibms_building
+        where building_id = #{buildingId}
+          and floor_id is not null
+        order by floor_id
+    </select>
+
+</mapper>

+ 130 - 0
pm-system/src/main/resources/mapper/subsystem/ElevatorMapper.xml

@@ -0,0 +1,130 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.pm.subsystem.mapper.ElevatorMapper">
+
+    <resultMap type="pd" id="ElevatorDeviceResult">
+        <result property="id"    column="id"    />
+        <result property="deviceCode"    column="device_code"    />
+        <result property="deviceName"    column="device_name"    />
+        <result property="elevatorType"    column="elevator_type"    />
+        <result property="buildingId"    column="building_id"    />
+        <result property="buildingName"    column="building_name"    />
+        <result property="installPosition"    column="install_position"    />
+        <result property="brand"    column="brand"    />
+        <result property="model"    column="model"    />
+        <result property="maxFloor"    column="max_floor"    />
+        <result property="minFloor"    column="min_floor"    />
+        <result property="ratedLoad"    column="rated_load"    />
+        <result property="ratedSpeed"    column="rated_speed"    />
+        <result property="currentFloor"    column="current_floor"    />
+        <result property="doorStatus"    column="door_status"    />
+        <result property="runStatus"    column="run_status"    />
+        <result property="direction"    column="direction"    />
+        <result property="isOnline"    column="is_online"    />
+        <result property="faultStatus"    column="fault_status"    />
+        <result property="maintenanceDate"    column="maintenance_date"    />
+        <result property="nextMaintenanceDate"    column="next_maintenance_date"    />
+        <result property="lastUpdateTime"    column="last_update_time"    />
+        <result property="createTime"    column="create_time"    />
+    </resultMap>
+
+    <sql id="selectElevatorDeviceVo">
+        select id, device_code, device_name, elevator_type, building_id, building_name,
+               install_position, brand, model, max_floor, min_floor, rated_load, rated_speed,
+               current_floor, door_status, run_status, direction, is_online, fault_status,
+               maintenance_date, next_maintenance_date, last_update_time, create_time
+        from ibms_elevator_device
+    </sql>
+
+    <select id="selectElevatorDeviceList" parameterType="pd" resultMap="ElevatorDeviceResult">
+        <include refid="selectElevatorDeviceVo"/>
+        <where>
+            <if test="buildingId != null"> and building_id = #{buildingId}</if>
+            <if test="elevatorType != null and elevatorType != ''"> and elevator_type = #{elevatorType}</if>
+            <if test="runStatus != null"> and run_status = #{runStatus}</if>
+            <if test="deviceName != null and deviceName != ''">
+                and device_name like concat('%', #{deviceName}, '%')
+            </if>
+        </where>
+        order by building_id, device_code
+    </select>
+
+    <select id="selectElevatorRecordList" parameterType="pd" resultType="pd">
+        select id, device_code, device_name, start_floor, end_floor, start_time,
+        end_time, passenger_count, load_weight, run_duration, create_time
+        from ibms_elevator_record
+        <where>
+            <if test="deviceName != null and deviceName != ''">
+                and device_name like concat('%', #{deviceName}, '%')
+            </if>
+            <if test="beginTime != null and beginTime != ''">
+                and start_time &gt;= #{beginTime}
+            </if>
+            <if test="endTime != null and endTime != ''">
+                and start_time &lt;= #{endTime}
+            </if>
+        </where>
+        order by start_time desc
+    </select>
+
+    <select id="selectElevatorAlarmList" parameterType="pd" resultType="pd">
+        select id, device_code, device_name, alarm_type, alarm_level, alarm_desc,
+        alarm_time, handle_status, handle_time, handle_user, handle_remark, create_time
+        from ibms_elevator_alarm
+        <where>
+            <if test="deviceName != null and deviceName != ''">
+                and device_name like concat('%', #{deviceName}, '%')
+            </if>
+            <if test="alarmType != null and alarmType != ''">
+                and alarm_type = #{alarmType}
+            </if>
+            <if test="alarmLevel != null">
+                and alarm_level = #{alarmLevel}
+            </if>
+            <if test="handleStatus != null">
+                and handle_status = #{handleStatus}
+            </if>
+            <if test="beginTime != null and beginTime != ''">
+                and alarm_time &gt;= #{beginTime}
+            </if>
+            <if test="endTime != null and endTime != ''">
+                and alarm_time &lt;= #{endTime}
+            </if>
+        </where>
+        order by alarm_time desc
+    </select>
+
+    <update id="updateElevatorAlarm" parameterType="pd">
+        update ibms_elevator_alarm
+        <set>
+            <if test="handleStatus != null">handle_status = #{handleStatus},</if>
+            <if test="handleTime != null">handle_time = #{handleTime},</if>
+            <if test="handleUser != null">handle_user = #{handleUser},</if>
+            <if test="handleRemark != null">handle_remark = #{handleRemark},</if>
+        </set>
+        where id = #{id}
+    </update>
+
+    <select id="selectElevatorCount" parameterType="pd" resultType="int">
+        select count(1) from ibms_elevator_device
+        <where>
+            <if test="isOnline != null"> and is_online = #{isOnline}</if>
+            <if test="faultStatus != null"> and fault_status = #{faultStatus}</if>
+        </where>
+    </select>
+
+    <select id="selectElevatorTypeDistribution" resultType="pd">
+        select elevator_type as type, count(1) as count
+        from ibms_elevator_device
+        group by elevator_type
+    </select>
+
+    <select id="selectElevatorBuildingDistribution" resultType="pd">
+        select building_name as building, count(1) as count
+        from ibms_elevator_device
+        group by building_name
+    </select>
+
+</mapper>

+ 160 - 0
pm-system/src/main/resources/mapper/subsystem/LightingMapper.xml

@@ -0,0 +1,160 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.pm.subsystem.mapper.LightingMapper">
+
+    <resultMap type="pd" id="LightingDeviceResult">
+        <result property="id"    column="id"    />
+        <result property="deviceCode"    column="device_code"    />
+        <result property="deviceName"    column="device_name"    />
+        <result property="buildingId"    column="building_id"    />
+        <result property="buildingName"    column="building_name"    />
+        <result property="floorId"    column="floor_id"    />
+        <result property="floorName"    column="floor_name"    />
+        <result property="areaName"    column="area_name"    />
+        <result property="circuitNo"    column="circuit_no"    />
+        <result property="status"    column="status"    />
+        <result property="brightness"    column="brightness"    />
+        <result property="controlMode"    column="control_mode"    />
+        <result property="isOnline"    column="is_online"    />
+        <result property="faultStatus"    column="fault_status"    />
+        <result property="faultDesc"    column="fault_desc"    />
+        <result property="lastUpdateTime"    column="last_update_time"    />
+        <result property="createTime"    column="create_time"    />
+    </resultMap>
+
+    <sql id="selectLightingDeviceVo">
+        select id, device_code, device_name, building_id, building_name, floor_id, floor_name,
+               area_name, circuit_no, status, brightness, control_mode, is_online, fault_status,
+               fault_desc, last_update_time, create_time from ibms_lighting_device
+    </sql>
+
+    <select id="selectLightingDeviceList" parameterType="pd" resultMap="LightingDeviceResult">
+        <include refid="selectLightingDeviceVo"/>
+        <where>
+            <if test="buildingId != null"> and building_id = #{buildingId}</if>
+            <if test="floorId != null"> and floor_id = #{floorId}</if>
+            <if test="areaName != null and areaName != ''"> and area_name like concat('%', #{areaName}, '%')</if>
+            <if test="status != null"> and status = #{status}</if>
+            <if test="controlMode != null"> and control_mode = #{controlMode}</if>
+        </where>
+        order by building_id, floor_id, device_code
+    </select>
+
+    <update id="updateLightingDevice" parameterType="pd">
+        update ibms_lighting_device
+        <set>
+            <if test="status != null">status = #{status},</if>
+            <if test="brightness != null">brightness = #{brightness},</if>
+            <if test="controlMode != null">control_mode = #{controlMode},</if>
+            <if test="faultStatus != null">fault_status = #{faultStatus},</if>
+            <if test="faultDesc != null">fault_desc = #{faultDesc},</if>
+            <if test="lastUpdateTime != null">last_update_time = #{lastUpdateTime},</if>
+            update_time = now()
+        </set>
+        where device_code = #{deviceCode}
+    </update>
+
+    <select id="selectLightingAlarmList" parameterType="pd" resultType="pd">
+        select id, device_code, device_name, alarm_type, alarm_level, alarm_desc,
+        alarm_time, handle_status, handle_time, handle_user, handle_remark, create_time
+        from ibms_lighting_alarm
+        <where>
+            <if test="deviceName != null and deviceName != ''">
+                and device_name like concat('%', #{deviceName}, '%')
+            </if>
+            <if test="alarmType != null and alarmType != ''">
+                and alarm_type = #{alarmType}
+            </if>
+            <if test="alarmLevel != null">
+                and alarm_level = #{alarmLevel}
+            </if>
+            <if test="handleStatus != null">
+                and handle_status = #{handleStatus}
+            </if>
+            <if test="beginTime != null and beginTime != ''">
+                and alarm_time &gt;= #{beginTime}
+            </if>
+            <if test="endTime != null and endTime != ''">
+                and alarm_time &lt;= #{endTime}
+            </if>
+        </where>
+        order by alarm_time desc
+    </select>
+
+    <update id="updateLightingAlarm" parameterType="pd">
+        update ibms_lighting_alarm
+        <set>
+            <if test="handleStatus != null">handle_status = #{handleStatus},</if>
+            <if test="handleTime != null">handle_time = #{handleTime},</if>
+            <if test="handleUser != null">handle_user = #{handleUser},</if>
+            <if test="handleRemark != null">handle_remark = #{handleRemark},</if>
+        </set>
+        where id = #{id}
+    </update>
+
+    <select id="selectLightingScheduleList" parameterType="pd" resultType="pd">
+        select id, schedule_name, device_ids, schedule_type, start_time, end_time,
+               week_days, month_days, exclude_holidays, action_type, brightness, is_enabled,
+               create_time, update_time
+        from ibms_lighting_schedule
+        order by create_time desc
+    </select>
+
+    <insert id="insertLightingSchedule" parameterType="pd" useGeneratedKeys="true" keyProperty="id">
+        insert into ibms_lighting_schedule
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="scheduleName != null">schedule_name,</if>
+            <if test="deviceIds != null">device_ids,</if>
+            <if test="scheduleType != null">schedule_type,</if>
+            <if test="startTime != null">start_time,</if>
+            <if test="endTime != null">end_time,</if>
+            <if test="weekDays != null">week_days,</if>
+            <if test="monthDays != null">month_days,</if>
+            <if test="excludeHolidays != null">exclude_holidays,</if>
+            <if test="actionType != null">action_type,</if>
+            <if test="brightness != null">brightness,</if>
+            <if test="isEnabled != null">is_enabled,</if>
+            create_time
+        </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="scheduleName != null">#{scheduleName},</if>
+            <if test="deviceIds != null">#{deviceIds},</if>
+            <if test="scheduleType != null">#{scheduleType},</if>
+            <if test="startTime != null">#{startTime},</if>
+            <if test="endTime != null">#{endTime},</if>
+            <if test="weekDays != null">#{weekDays},</if>
+            <if test="monthDays != null">#{monthDays},</if>
+            <if test="excludeHolidays != null">#{excludeHolidays},</if>
+            <if test="actionType != null">#{actionType},</if>
+            <if test="brightness != null">#{brightness},</if>
+            <if test="isEnabled != null">#{isEnabled},</if>
+            now()
+        </trim>
+    </insert>
+
+    <update id="updateLightingSchedule" parameterType="pd">
+        update ibms_lighting_schedule
+        <set>
+            <if test="scheduleName != null">schedule_name = #{scheduleName},</if>
+            <if test="deviceIds != null">device_ids = #{deviceIds},</if>
+            <if test="scheduleType != null">schedule_type = #{scheduleType},</if>
+            <if test="startTime != null">start_time = #{startTime},</if>
+            <if test="endTime != null">end_time = #{endTime},</if>
+            <if test="weekDays != null">week_days = #{weekDays},</if>
+            <if test="monthDays != null">month_days = #{monthDays},</if>
+            <if test="excludeHolidays != null">exclude_holidays = #{excludeHolidays},</if>
+            <if test="actionType != null">action_type = #{actionType},</if>
+            <if test="brightness != null">brightness = #{brightness},</if>
+            <if test="isEnabled != null">is_enabled = #{isEnabled},</if>
+            update_time = now()
+        </set>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteLightingSchedule" parameterType="Long">
+        delete from ibms_lighting_schedule where id = #{id}
+    </delete>
+
+</mapper>

+ 1 - 1
pm_ui/package.json

@@ -16,7 +16,7 @@
     "url": "git地址"
   },
   "dependencies": {
-    "@element-plus/icons-vue": "2.3.1",
+    "@element-plus/icons-vue": "^2.3.1",
     "@stomp/stompjs": "^7.1.1",
     "@vueup/vue-quill": "1.2.0",
     "@vueuse/core": "10.11.0",

+ 53 - 0
pm_ui/src/api/subsystem/elevator.js

@@ -0,0 +1,53 @@
+import request from '@/utils/request'
+
+// 查询电梯设备列表
+export function listElevatorDevice(query) {
+    return request({
+        url: '/subsystem/elevator/device/list',
+        method: 'get',
+        params: query
+    })
+}
+
+// 查询电梯运行记录列表
+export function listElevatorRecord(query) {
+    return request({
+        url: '/subsystem/elevator/record/list',
+        method: 'get',
+        params: query
+    })
+}
+
+// 查询电梯报警列表
+export function listElevatorAlarm(query) {
+    return request({
+        url: '/subsystem/elevator/alarm/list',
+        method: 'get',
+        params: query
+    })
+}
+
+// 处理电梯报警
+export function handleElevatorAlarm(data) {
+    return request({
+        url: '/subsystem/elevator/alarm/handle',
+        method: 'post',
+        data: data
+    })
+}
+
+// 获取电梯统计数据
+export function getElevatorStatistics() {
+    return request({
+        url: '/subsystem/elevator/statistics',
+        method: 'get'
+    })
+}
+
+// 获取楼栋列表
+export function getBuildingList() {
+    return request({
+        url: '/subsystem/common/building/list',
+        method: 'get'
+    })
+}

+ 99 - 0
pm_ui/src/api/subsystem/lighting.js

@@ -0,0 +1,99 @@
+import request from '@/utils/request'
+
+// 查询照明设备列表
+export function listLightingDevice(query) {
+    return request({
+        url: '/subsystem/lighting/device/list',
+        method: 'get',
+        params: query
+    })
+}
+
+// 控制照明设备
+export function controlLightingDevice(data) {
+    return request({
+        url: '/subsystem/lighting/device/control',
+        method: 'post',
+        data: data
+    })
+}
+
+// 批量控制照明
+export function batchControlLighting(data) {
+    return request({
+        url: '/subsystem/lighting/device/batchControl',
+        method: 'post',
+        data: data
+    })
+}
+
+// 查询照明报警列表
+export function listLightingAlarm(query) {
+    return request({
+        url: '/subsystem/lighting/alarm/list',
+        method: 'get',
+        params: query
+    })
+}
+
+// 处理照明报警
+export function handleLightingAlarm(data) {
+    return request({
+        url: '/subsystem/lighting/alarm/handle',
+        method: 'post',
+        data: data
+    })
+}
+
+// 查询照明计划列表
+export function listLightingSchedule(query) {
+    return request({
+        url: '/subsystem/lighting/schedule/list',
+        method: 'get',
+        params: query
+    })
+}
+
+// 新增照明计划
+export function addLightingSchedule(data) {
+    return request({
+        url: '/subsystem/lighting/schedule',
+        method: 'post',
+        data: data
+    })
+}
+
+// 修改照明计划
+export function updateLightingSchedule(data) {
+    return request({
+        url: '/subsystem/lighting/schedule',
+        method: 'put',
+        data: data
+    })
+}
+
+// 删除照明计划
+export function deleteLightingSchedule(id) {
+    return request({
+        url: '/subsystem/lighting/schedule/' + id,
+        method: 'delete'
+    })
+}
+
+// 获取楼栋列表
+export function getBuildingList() {
+    return request({
+        url: '/subsystem/common/building/list',
+        method: 'get'
+    })
+}
+
+
+// 获取楼层列表
+export function getFloorList(query) {
+    return request({
+        url: '/subsystem/common/floor/list',
+        method: 'get',
+        params: query
+    })
+}

+ 778 - 0
pm_ui/src/views/dtxt/index.vue

@@ -0,0 +1,778 @@
+<template>
+  <div class="app-container">
+    <el-tabs v-model="activeTab">
+      <!-- 电梯监控标签页 -->
+      <el-tab-pane label="电梯监控" name="monitor">
+        <el-form :model="elevatorQuery" ref="elevatorQueryRef" :inline="true" label-width="80px">
+          <el-form-item label="楼栋" prop="buildingId">
+            <el-select v-model="elevatorQuery.buildingId" placeholder="请选择楼栋" clearable>
+              <el-option
+                  v-for="item in buildingList"
+                  :key="item.id"
+                  :label="item.name"
+                  :value="item.id"
+              />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="电梯类型" prop="elevatorType">
+            <el-select v-model="elevatorQuery.elevatorType" placeholder="请选择类型" clearable>
+              <el-option label="客梯" value="客梯" />
+              <el-option label="货梯" value="货梯" />
+              <el-option label="扶梯" value="扶梯" />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="运行状态" prop="runStatus">
+            <el-select v-model="elevatorQuery.runStatus" placeholder="请选择状态" clearable>
+              <el-option label="停止" :value="0" />
+              <el-option label="上行" :value="1" />
+              <el-option label="下行" :value="2" />
+              <el-option label="维保" :value="3" />
+              <el-option label="故障" :value="4" />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="设备名称" prop="deviceName">
+            <el-input v-model="elevatorQuery.deviceName" placeholder="请输入设备名称" clearable />
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" icon="Search" @click="getElevatorList">搜索</el-button>
+            <el-button icon="Refresh" @click="resetElevatorQuery">重置</el-button>
+          </el-form-item>
+        </el-form>
+
+        <el-row :gutter="10" class="mb8">
+          <el-col :span="1.5">
+            <el-button
+                type="primary"
+                plain
+                icon="View"
+                @click="handleBatchView"
+            >三维展示</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button
+                type="success"
+                plain
+                icon="PictureFilled"
+                @click="handleSystemDiagram"
+            >系统组态图</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button
+                type="info"
+                plain
+                icon="DataAnalysis"
+                @click="handleStatistics"
+            >统计分析</el-button>
+          </el-col>
+        </el-row>
+
+        <el-table v-loading="elevatorLoading" :data="elevatorList" stripe border>
+          <el-table-column label="设备编码" prop="deviceCode" />
+          <el-table-column label="设备名称" prop="deviceName"  />
+          <el-table-column label="电梯类型" prop="elevatorType" width="100" />
+          <el-table-column label="楼栋" prop="buildingName"  />
+          <el-table-column label="安装位置" prop="installPosition"  show-overflow-tooltip />
+          <el-table-column label="当前楼层" prop="currentFloor"  align="center">
+            <template #default="scope">
+              <el-tag type="primary" size="large">{{ scope.row.currentFloor }}F</el-tag>
+            </template>
+          </el-table-column>
+          <el-table-column label="运行状态" prop="run_status"  align="center">
+            <template #default="scope">
+              <el-tag :type="runStatusType(scope.row.runStatus)">
+                {{ runStatusText(scope.row.runStatus) }}
+              </el-tag>
+            </template>
+          </el-table-column>
+          <el-table-column label="运行方向" prop="direction"  align="center">
+           <template #default="scope">
+            <i v-if="scope.row.direction === '1'" style="font-size: 20px; color: #67C23A;">
+              <el-icon><ArrowUp /></el-icon>
+            </i>
+            <i v-else-if="scope.row.direction === '2'" style="font-size: 20px; color: #F56C6C;">
+              <el-icon><ArrowDown /></el-icon>
+            </i>
+            <span v-else>-</span>
+          </template>
+          </el-table-column>
+          <el-table-column label="门状态" prop="door_status"  align="center">
+            <template #default="scope">
+              <el-tag :type="scope.row.door_status === 0 ? 'info' : 'success'">
+                {{ scope.row.door_status === 0 ? '关闭' : '开启' }}
+              </el-tag>
+            </template>
+          </el-table-column>
+          <el-table-column label="在线状态" prop="is_online"  align="center">
+            <template #default="scope">
+              <el-tag :type="scope.row.isOnline === 1 ? 'success' : 'info'">
+                {{ scope.row.isOnline === 1 ? '在线' : '离线' }}
+              </el-tag>
+            </template>
+          </el-table-column>
+          <el-table-column label="下次维保" prop="next_maintenance_date" >
+            <template #default="scope">
+              <span :class="{ 'text-danger': isMaintenanceDue(scope.row.nextMaintenanceDate) }">
+                {{ parseTime(scope.row.nextMaintenanceDate, '{y}-{m}-{d}') }}
+              </span>
+            </template>
+          </el-table-column>
+          <el-table-column label="更新时间" prop="last_update_time">
+            <template #default="scope">
+              <span>{{ parseTime(scope.row.last_update_time) }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="操作" fixed="right" width="150">
+            <template #default="scope">
+              <el-button link type="primary" icon="Monitor" @click="handleMonitor(scope.row)">监控</el-button>
+              <el-button link type="primary" icon="Document" @click="handleDetail(scope.row)">详情</el-button>
+            </template>
+          </el-table-column>
+        </el-table>
+
+        <pagination
+            v-show="elevatorTotal > 0"
+            :total="elevatorTotal"
+            v-model:page="elevatorQuery.pageNum"
+            v-model:limit="elevatorQuery.pageSize"
+            @pagination="getElevatorList"
+        />
+      </el-tab-pane>
+
+      <!-- 运行记录标签页 -->
+      <el-tab-pane label="运行记录" name="record">
+        <el-form :model="recordQuery" ref="recordQueryRef" :inline="true" label-width="80px">
+          <el-form-item label="设备名称" prop="deviceName">
+            <el-input v-model="recordQuery.deviceName" placeholder="请输入设备名称" clearable />
+          </el-form-item>
+          <el-form-item label="时间范围" prop="timeRange">
+            <el-date-picker
+                v-model="recordQuery.timeRange"
+                type="datetimerange"
+                range-separator="至"
+                start-placeholder="开始时间"
+                end-placeholder="结束时间"
+                value-format="YYYY-MM-DD HH:mm:ss"
+            />
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" icon="Search" @click="getRecordList">搜索</el-button>
+            <el-button icon="Refresh" @click="resetRecordQuery">重置</el-button>
+          </el-form-item>
+        </el-form>
+
+        <el-table v-loading="recordLoading" :data="recordList" stripe border>
+          <el-table-column label="设备编码" prop="device_code" width="120" />
+          <el-table-column label="设备名称" prop="device_name" width="150" />
+          <el-table-column label="起始楼层" prop="start_floor" width="100" align="center">
+            <template #default="scope">
+              {{ scope.row.start_floor }}F
+            </template>
+          </el-table-column>
+          <el-table-column label="目标楼层" prop="end_floor"  align="center">
+            <template #default="scope">
+              {{ scope.row.end_floor }}F
+            </template>
+          </el-table-column>
+          <el-table-column label="开始时间" prop="start_time" >
+            <template #default="scope">
+              <span>{{ parseTime(scope.row.start_time) }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="结束时间" prop="end_time">
+            <template #default="scope">
+              <span>{{ parseTime(scope.row.end_time) }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="运行时长" prop="run_duration"  align="center">
+            <template #default="scope">
+              {{ scope.row.run_duration }}秒
+            </template>
+          </el-table-column>
+          <el-table-column label="乘客数量" prop="passenger_count"  align="center" />
+          <el-table-column label="载重(kg)" prop="load_weight"  align="center" />
+        </el-table>
+
+        <pagination
+            v-show="recordTotal > 0"
+            :total="recordTotal"
+            v-model:page="recordQuery.pageNum"
+            v-model:limit="recordQuery.pageSize"
+            @pagination="getRecordList"
+        />
+      </el-tab-pane>
+
+      <!-- 报警记录标签页 -->
+      <el-tab-pane label="报警记录" name="alarm">
+        <el-form :model="alarmQuery" ref="alarmQueryRef" :inline="true" label-width="80px">
+          <el-form-item label="设备名称" prop="deviceName">
+            <el-input v-model="alarmQuery.deviceName" placeholder="请输入设备名称" clearable />
+          </el-form-item>
+          <el-form-item label="报警类型" prop="alarmType">
+            <el-select v-model="alarmQuery.alarmType" placeholder="请选择报警类型" clearable>
+              <el-option label="超载报警" value="overload" />
+              <el-option label="困人报警" value="trapped" />
+              <el-option label="故障报警" value="fault" />
+              <el-option label="维保提醒" value="maintenance" />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="报警级别" prop="alarmLevel">
+            <el-select v-model="alarmQuery.alarmLevel" placeholder="请选择报警级别" clearable>
+              <el-option label="提示" :value="1" />
+              <el-option label="一般" :value="2" />
+              <el-option label="严重" :value="3" />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="处理状态" prop="handleStatus">
+            <el-select v-model="alarmQuery.handleStatus" placeholder="请选择处理状态" clearable>
+              <el-option label="未处理" :value="0" />
+              <el-option label="已处理" :value="1" />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="时间范围" prop="timeRange">
+            <el-date-picker
+                v-model="alarmQuery.timeRange"
+                type="datetimerange"
+                range-separator="至"
+                start-placeholder="开始时间"
+                end-placeholder="结束时间"
+                value-format="YYYY-MM-DD HH:mm:ss"
+            />
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" icon="Search" @click="getAlarmList">搜索</el-button>
+            <el-button icon="Refresh" @click="resetAlarmQuery">重置</el-button>
+          </el-form-item>
+        </el-form>
+
+        <el-table v-loading="alarmLoading" :data="alarmList" stripe border>
+          <el-table-column label="设备编码" prop="device_code" width="120" />
+          <el-table-column label="设备名称" prop="device_name" width="150" />
+          <el-table-column label="报警类型" prop="alarm_type" width="120" />
+          <el-table-column label="报警级别" prop="alarm_level" width="100" align="center">
+            <template #default="scope">
+              <el-tag :type="alarmLevelType(scope.row.alarm_level)">
+                {{ alarmLevelText(scope.row.alarm_level) }}
+              </el-tag>
+            </template>
+          </el-table-column>
+          <el-table-column label="报警描述" prop="alarm_desc" show-overflow-tooltip />
+          <el-table-column label="报警时间" prop="alarm_time" width="160">
+            <template #default="scope">
+              <span>{{ parseTime(scope.row.alarm_time) }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="处理状态" prop="handle_status" width="100" align="center">
+            <template #default="scope">
+              <el-tag :type="scope.row.handle_status === 1 ? 'success' : 'warning'">
+                {{ scope.row.handle_status === 1 ? '已处理' : '未处理' }}
+              </el-tag>
+            </template>
+          </el-table-column>
+          <el-table-column label="处理人" prop="handle_user" width="100" />
+          <el-table-column label="处理时间" prop="handle_time" width="160">
+            <template #default="scope">
+              <span>{{ parseTime(scope.row.handle_time) }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="操作" fixed="right" width="120">
+            <template #default="scope">
+              <el-button
+                  link
+                  type="primary"
+                  icon="Edit"
+                  @click="handleAlarm(scope.row)"
+                  v-if="scope.row.handle_status === 0"
+              >处理</el-button>
+              <el-button
+                  link
+                  type="primary"
+                  icon="View"
+                  @click="handleAlarmDetail(scope.row)"
+                  v-else
+              >详情</el-button>
+            </template>
+          </el-table-column>
+        </el-table>
+
+        <pagination
+            v-show="alarmTotal > 0"
+            :total="alarmTotal"
+            v-model:page="alarmQuery.pageNum"
+            v-model:limit="alarmQuery.pageSize"
+            @pagination="getAlarmList"
+        />
+      </el-tab-pane>
+    </el-tabs>
+
+    <!-- 电梯监控对话框 -->
+    <el-dialog v-model="monitorVisible" :title="monitorTitle" width="800px" append-to-body>
+      <div class="elevator-monitor">
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <div class="monitor-section">
+              <h4>基本信息</h4>
+              <el-descriptions :column="1" border size="small">
+                <el-descriptions-item label="设备编码">{{ currentElevator.deviceCode }}</el-descriptions-item>
+                <el-descriptions-item label="设备名称">{{ currentElevator.deviceName }}</el-descriptions-item>
+                <el-descriptions-item label="楼栋位置">{{ currentElevator.buildingName }} - {{ currentElevator.installPosition }}</el-descriptions-item>
+                <el-descriptions-item label="品牌型号">{{ currentElevator.brand }} {{ currentElevator.model }}</el-descriptions-item>
+                <el-descriptions-item label="额定载重">{{ currentElevator.ratedLoad }}kg</el-descriptions-item>
+                <el-descriptions-item label="额定速度">{{ currentElevator.ratedSpeed }}m/s</el-descriptions-item>
+              </el-descriptions>
+            </div>
+          </el-col>
+          <el-col :span="12">
+            <div class="monitor-section">
+              <h4>实时状态</h4>
+              <div class="elevator-visual">
+                <div class="building-floors">
+                  <div
+                      v-for="floor in elevatorFloors"
+                      :key="floor"
+                      class="floor-item"
+                      :class="{ 'current-floor': floor === currentElevator.currentFloor }"
+                  >
+                    <span class="floor-number">{{ floor }}F</span>
+                    <div class="floor-line"></div>
+                    <div v-if="floor === currentElevator.currentFloor" class="elevator-car">
+                      <i class="el-icon-s-help"></i>
+                    </div>
+                  </div>
+                </div>
+                <div class="status-info">
+                  <p>当前楼层:<strong>{{ currentElevator.currentFloor }}F</strong></p>
+                  <p>运行状态:<el-tag :type="runStatusType(currentElevator.runStatus)">{{ runStatusText(currentElevator.runStatus) }}</el-tag></p>
+                  <p>运行方向:
+                    <i v-if="currentElevator.direction === '1'" class="el-icon-top" style="color: #67C23A;"> <el-icon><ArrowUp /></el-icon></i>
+                    <i v-else-if="currentElevator.direction === '2'" class="el-icon-bottom" style="color: #F56C6C;"> <el-icon><ArrowDown /></el-icon></i>
+                    <span v-else>停止</span>
+                  </p>
+                  <p>门状态:<el-tag :type="currentElevator.doorStatus === 0 ? 'info' : 'success'">{{ currentElevator.doorStatus === 0 ? '关闭' : '开启' }}</el-tag></p>
+                </div>
+              </div>
+            </div>
+          </el-col>
+        </el-row>
+      </div>
+    </el-dialog>
+
+    <!-- 统计分析对话框 -->
+    <el-dialog v-model="statisticsVisible" title="电梯统计分析" width="1000px" append-to-body>
+      <el-row :gutter="20">
+        <el-col :span="8">
+          <el-card>
+            <template #header>
+              <span>设备统计</span>
+            </template>
+            <el-statistic title="电梯总数" :value="statistics.total" />
+            <el-statistic title="在线设备" :value="statistics.online" />
+            <el-statistic title="故障设备" :value="statistics.fault" />
+          </el-card>
+        </el-col>
+        <el-col :span="8">
+          <el-card>
+            <template #header>
+              <span>类型分布</span>
+            </template>
+            <div v-for="item in statistics.typeDistribution" :key="item.type" class="stat-item">
+              <span>{{ item.type }}:</span>
+              <span>{{ item.count }}台</span>
+            </div>
+          </el-card>
+        </el-col>
+        <el-col :span="8">
+          <el-card>
+            <template #header>
+              <span>楼栋分布</span>
+            </template>
+            <div v-for="item in statistics.buildingDistribution" :key="item.building" class="stat-item">
+              <span>{{ item.building }}:</span>
+              <span>{{ item.count }}台</span>
+            </div>
+          </el-card>
+        </el-col>
+      </el-row>
+    </el-dialog>
+
+    <!-- 处理报警对话框 -->
+    <el-dialog v-model="handleAlarmVisible" title="处理报警" width="500px" append-to-body>
+      <el-form ref="handleAlarmRef" :model="handleAlarmForm" label-width="80px">
+        <el-form-item label="设备名称">
+          <el-input v-model="handleAlarmForm.deviceName" disabled />
+        </el-form-item>
+        <el-form-item label="报警描述">
+          <el-input v-model="handleAlarmForm.alarmDesc" type="textarea" :rows="3" disabled />
+        </el-form-item>
+        <el-form-item label="处理备注" prop="handleRemark">
+          <el-input v-model="handleAlarmForm.handleRemark" type="textarea" :rows="3" placeholder="请输入处理备注" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="handleAlarmVisible = false">取消</el-button>
+          <el-button type="primary" @click="submitHandleAlarm">确定</el-button>
+        </span>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, computed, onMounted } from 'vue'
+import { ArrowUp, ArrowDown } from '@element-plus/icons-vue'
+import {
+  listElevatorDevice,
+  listElevatorRecord,
+  listElevatorAlarm,
+  handleElevatorAlarm,
+  getElevatorStatistics,
+  getBuildingList
+} from '@/api/subsystem/elevator'
+
+const { proxy } = getCurrentInstance()
+const activeTab = ref('monitor')
+
+// 电梯监控查询相关
+const elevatorQuery = reactive({
+  pageNum: 1,
+  pageSize: 10,
+  buildingId: null,
+  elevatorType: null,
+  runStatus: null,
+  deviceName: null
+})
+const elevatorList = ref([])
+const elevatorTotal = ref(0)
+const elevatorLoading = ref(false)
+
+// 运行记录查询相关
+const recordQuery = reactive({
+  pageNum: 1,
+  pageSize: 10,
+  deviceName: null,
+  timeRange: []
+})
+const recordList = ref([])
+const recordTotal = ref(0)
+const recordLoading = ref(false)
+
+// 报警记录查询相关
+const alarmQuery = reactive({
+  pageNum: 1,
+  pageSize: 10,
+  deviceName: null,
+  alarmType: null,
+  alarmLevel: null,
+  handleStatus: null,
+  timeRange: []
+})
+const alarmList = ref([])
+const alarmTotal = ref(0)
+const alarmLoading = ref(false)
+
+// 楼栋数据
+const buildingList = ref([])
+
+// 电梯监控相关
+const monitorVisible = ref(false)
+const monitorTitle = ref('')
+const currentElevator = ref({})
+const elevatorFloors = computed(() => {
+  if (!currentElevator.value.max_floor || !currentElevator.value.min_floor) {
+    return []
+  }
+  const floors = []
+  for (let i = currentElevator.value.max_floor; i >= currentElevator.value.min_floor; i--) {
+    floors.push(i)
+  }
+  return floors
+})
+
+// 统计分析相关
+const statisticsVisible = ref(false)
+const statistics = reactive({
+  total: 0,
+  online: 0,
+  fault: 0,
+  typeDistribution: [],
+  buildingDistribution: []
+})
+
+// 处理报警相关
+const handleAlarmVisible = ref(false)
+const handleAlarmForm = reactive({
+  id: null,
+  deviceName: '',
+  alarmDesc: '',
+  handleRemark: ''
+})
+
+// 运行状态类型
+const runStatusType = (status) => {
+  const types = ['info', 'success', 'warning', 'danger', 'danger']
+  return types[status] || 'info'
+}
+
+// 运行状态文本
+const runStatusText = (status) => {
+  const texts = ['停止', '上行', '下行', '维保', '故障']
+  return texts[status] || '未知'
+}
+
+// 报警级别类型
+const alarmLevelType = (level) => {
+  const types = ['', 'info', 'warning', 'danger']
+  return types[level] || 'info'
+}
+
+// 报警级别文本
+const alarmLevelText = (level) => {
+  const texts = ['', '提示', '一般', '严重']
+  return texts[level] || '未知'
+}
+
+// 判断是否需要维保
+const isMaintenanceDue = (date) => {
+  if (!date) return false
+  const nextDate = new Date(date)
+  const today = new Date()
+  const diffDays = Math.ceil((nextDate - today) / (1000 * 60 * 60 * 24))
+  return diffDays <= 7 // 7天内需要维保
+}
+
+// 获取楼栋列表
+async function loadBuildingList() {
+  const res = await getBuildingList()
+  buildingList.value = res.data
+}
+
+// 查询电梯设备列表
+function getElevatorList() {
+  elevatorLoading.value = true
+  const params = {
+    ...elevatorQuery,
+    pageNum: elevatorQuery.pageNum,
+    pageSize: elevatorQuery.pageSize
+  }
+  listElevatorDevice(params).then(response => {
+    elevatorList.value = response.rows
+    elevatorTotal.value = response.total
+    elevatorLoading.value = false
+  })
+}
+
+// 重置电梯查询
+function resetElevatorQuery() {
+  proxy.resetForm('elevatorQueryRef')
+  elevatorQuery.pageNum = 1
+  getElevatorList()
+}
+
+// 电梯监控
+function handleMonitor(row) {
+  currentElevator.value = row
+  monitorTitle.value = `电梯监控 - ${row.deviceName}`
+  monitorVisible.value = true
+}
+
+// 查看详情
+function handleDetail(row) {
+  // 可以跳转到详情页面或打开详情对话框
+  proxy.$modal.msgWarning(`设备编码:${row.deviceCode}`)
+}
+
+// 三维展示
+function handleBatchView() {
+  proxy.$modal.msgWarning('三维展示功能开发中...')
+}
+
+// 系统组态图
+function handleSystemDiagram() {
+  proxy.$modal.msgWarning('系统组态图功能开发中...')
+}
+
+// 统计分析
+async function handleStatistics() {
+  const res = await getElevatorStatistics()
+  Object.assign(statistics, res.data)
+  statisticsVisible.value = true
+}
+
+// 查询运行记录列表
+function getRecordList() {
+  recordLoading.value = true
+  const params = {
+    ...recordQuery,
+    pageNum: recordQuery.pageNum,
+    pageSize: recordQuery.pageSize
+  }
+  if (recordQuery.timeRange && recordQuery.timeRange.length === 2) {
+    params.beginTime = recordQuery.timeRange[0]
+    params.endTime = recordQuery.timeRange[1]
+  }
+  listElevatorRecord(params).then(response => {
+    recordList.value = response.rows
+    recordTotal.value = response.total
+    recordLoading.value = false
+  })
+}
+
+// 重置运行记录查询
+function resetRecordQuery() {
+  proxy.resetForm('recordQueryRef')
+  recordQuery.pageNum = 1
+  getRecordList()
+}
+
+// 查询报警列表
+function getAlarmList() {
+  alarmLoading.value = true
+  const params = {
+    ...alarmQuery,
+    pageNum: alarmQuery.pageNum,
+    pageSize: alarmQuery.pageSize
+  }
+  if (alarmQuery.timeRange && alarmQuery.timeRange.length === 2) {
+    params.beginTime = alarmQuery.timeRange[0]
+    params.endTime = alarmQuery.timeRange[1]
+  }
+  listElevatorAlarm(params).then(response => {
+    alarmList.value = response.rows
+    alarmTotal.value = response.total
+    alarmLoading.value = false
+  })
+}
+
+// 重置报警查询
+function resetAlarmQuery() {
+  proxy.resetForm('alarmQueryRef')
+  alarmQuery.pageNum = 1
+  getAlarmList()
+}
+
+// 处理报警
+function handleAlarm(row) {
+  handleAlarmForm.id = row.id
+  handleAlarmForm.deviceName = row.device_name
+  handleAlarmForm.alarmDesc = row.alarm_desc
+  handleAlarmForm.handleRemark = ''
+  handleAlarmVisible.value = true
+}
+
+// 提交处理报警
+function submitHandleAlarm() {
+  handleElevatorAlarm({
+    id: handleAlarmForm.id,
+    handleRemark: handleAlarmForm.handleRemark
+  }).then(() => {
+    proxy.$modal.msgSuccess('处理成功')
+    handleAlarmVisible.value = false
+    getAlarmList()
+  })
+}
+
+// 查看报警详情
+function handleAlarmDetail(row) {
+  proxy.$modal.msgWarning(`处理备注:${row.handle_remark || '无'}`)
+}
+
+// 初始化
+onMounted(() => {
+  loadBuildingList()
+  getElevatorList()
+})
+</script>
+
+<style scoped>
+.elevator-monitor {
+  padding: 20px;
+}
+
+.monitor-section {
+  margin-bottom: 20px;
+}
+
+.monitor-section h4 {
+  margin-bottom: 15px;
+  color: #333;
+}
+
+.elevator-visual {
+  background: #f5f5f5;
+  padding: 20px;
+  border-radius: 8px;
+}
+
+.building-floors {
+  position: relative;
+  margin-bottom: 20px;
+}
+
+.floor-item {
+  display: flex;
+  align-items: center;
+  height: 30px;
+  margin-bottom: 5px;
+  position: relative;
+}
+
+.floor-number {
+  width: 40px;
+  text-align: right;
+  margin-right: 10px;
+  font-weight: bold;
+}
+
+.floor-line {
+  flex: 1;
+  height: 2px;
+  background: #ddd;
+  position: relative;
+}
+
+.current-floor .floor-line {
+  background: #409EFF;
+}
+
+.elevator-car {
+  position: absolute;
+  right: 20px;
+  top: -15px;
+  width: 50px;
+  height: 60px;
+  background: #409EFF;
+  border-radius: 4px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  color: white;
+  font-size: 24px;
+  box-shadow: 0 2px 8px rgba(0,0,0,0.15);
+}
+
+.status-info p {
+  margin-bottom: 10px;
+  line-height: 1.5;
+}
+
+.status-info strong {
+  color: #409EFF;
+  font-size: 18px;
+}
+
+.stat-item {
+  display: flex;
+  justify-content: space-between;
+  margin-bottom: 10px;
+  padding: 5px 0;
+  border-bottom: 1px solid #eee;
+}
+
+.text-danger {
+  color: #F56C6C;
+}
+
+.mb8 {
+  margin-bottom: 8px;
+}
+</style>

+ 9 - 9
pm_ui/src/views/spafjkxt/index.vue

@@ -129,13 +129,13 @@
         </el-row>
 
         <el-table v-loading="linkageLoading" :data="linkageList" stripe border>
-          <el-table-column label="规则名称" prop="ruleName"  />
-          <el-table-column label="触发设备" prop="triggerDeviceName"  />
-          <el-table-column label="触发条件" prop="triggerCondition"  />
-          <el-table-column label="联动摄像机" prop="linkageCameraNname"  />
-          <el-table-column label="联动动作" prop="linkageAction" >
+          <el-table-column label="规则名称" prop="rule_name"  />
+          <el-table-column label="触发设备" prop="trigger_device_name"  />
+          <el-table-column label="触发条件" prop="trigger_condition"  />
+          <el-table-column label="联动摄像机" prop="linkage_camera_name"  />
+          <el-table-column label="联动动作" prop="linkage_action" >
             <template #default="scope">
-              <el-tag>{{ getLinkageActionText(scope.row.linkageAction) }}</el-tag>
+              <el-tag>{{ getLinkageActionText(scope.row.linkage_action) }}</el-tag>
             </template>
           </el-table-column>
           <el-table-column label="延迟时间" prop="delayTime" width="100">
@@ -150,9 +150,9 @@
               </el-tag>
             </template>
           </el-table-column>
-          <el-table-column label="创建时间" prop="createTime" width="150">
+          <el-table-column label="创建时间" prop="create_time" width="150">
             <template #default="scope">
-              <span>{{ parseTime(scope.row.createTime) }}</span>
+              <span>{{ parseTime(scope.row.create_time) }}</span>
             </template>
           </el-table-column>
           <el-table-column label="操作" width="250" fixed="right">
@@ -639,7 +639,7 @@ function handleCameraDetail(row) {
 
 // 录像回放
 function handlePlayback(row) {
-  proxy.$modal.msgInfo('录像回放功能开发中...')
+  proxy.$modal.msgWarning('录像回放功能开发中...')
 }
 
 // 新增联动规则

+ 816 - 0
pm_ui/src/views/zmxt/index.vue

@@ -0,0 +1,816 @@
+<template>
+  <div class="app-container">
+    <el-tabs v-model="activeTab">
+      <!-- 照明监控标签页 -->
+      <el-tab-pane label="照明监控" name="monitor">
+        <el-form :model="lightingQuery" ref="lightingQueryRef" :inline="true" label-width="80px">
+          <el-form-item label="楼栋" prop="buildingId">
+            <el-select v-model="lightingQuery.buildingId" placeholder="请选择楼栋" clearable @change="handleBuildingChange">
+              <el-option
+                  v-for="item in buildingList"
+                  :key="item.id"
+                  :label="item.name"
+                  :value="item.id"
+              />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="楼层" prop="floorId">
+            <el-select v-model="lightingQuery.floorId" placeholder="请选择楼层" clearable :disabled="!lightingQuery.buildingId">
+              <el-option
+                  v-for="item in floorList"
+                  :key="item.id"
+                  :label="item.name"
+                  :value="item.id"
+              />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="区域" prop="areaName">
+            <el-input v-model="lightingQuery.areaName" placeholder="请输入区域名称" clearable />
+          </el-form-item>
+          <el-form-item label="状态" prop="status">
+            <el-select v-model="lightingQuery.status" placeholder="请选择状态" clearable>
+              <el-option label="关闭" :value="0" />
+              <el-option label="开启" :value="1" />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="控制模式" prop="controlMode">
+            <el-select v-model="lightingQuery.controlMode" placeholder="请选择控制模式" clearable>
+              <el-option label="手动" :value="0" />
+              <el-option label="自动" :value="1" />
+              <el-option label="定时" :value="2" />
+            </el-select>
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" icon="Search" @click="getLightingList">搜索</el-button>
+            <el-button icon="Refresh" @click="resetLightingQuery">重置</el-button>
+          </el-form-item>
+        </el-form>
+
+        <el-row :gutter="10" class="mb8">
+          <el-col :span="1.5">
+            <el-button
+                type="success"
+                plain
+                icon="Operation"
+                @click="handleBatchControl"
+                :disabled="lightingSelection.length === 0"
+            >批量控制</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button
+                type="warning"
+                plain
+                icon="Clock"
+                @click="handleSchedule"
+            >定时计划</el-button>
+          </el-col>
+        </el-row>
+
+        <el-table v-loading="lightingLoading" :data="lightingList" stripe border @selection-change="handleLightingSelectionChange">
+          <el-table-column type="selection" width="55" align="center" />
+          <el-table-column label="设备编码" prop="deviceCode"  />
+          <el-table-column label="设备名称" prop="deviceName"  />
+          <el-table-column label="楼栋" prop="buildingName"  />
+          <el-table-column label="楼层" prop="floorName"  />
+          <el-table-column label="区域" prop="areaName" />
+          <el-table-column label="回路" prop="circuitNo"  />
+          <el-table-column label="状态" prop="status" width="80" align="center">
+            <template #default="scope">
+              <el-switch
+                  v-model="scope.row.status"
+                  :active-value="1"
+                  :inactive-value="0"
+                  @change="handleStatusChange(scope.row)"
+                  :disabled="scope.row.control_mode !== 0"
+              />
+            </template>
+          </el-table-column>
+          <el-table-column label="亮度" prop="brightness"  align="center">
+            <template #default="scope">
+              <el-slider
+                  v-model="scope.row.brightness"
+                  :disabled="scope.row.status === 0 || scope.row.control_mode !== 0"
+                  @change="handleBrightnessChange(scope.row)"
+                  size="small"
+              />
+            </template>
+          </el-table-column>
+          <el-table-column label="控制模式" prop="control_mode"  align="center">
+            <template #default="scope">
+              <el-tag :type="controlModeType(scope.row.control_mode)">
+                {{ controlModeText(scope.row.control_mode) }}
+              </el-tag>
+            </template>
+          </el-table-column>
+          <el-table-column label="在线状态" prop="is_online"  align="center">
+            <template #default="scope">
+              <el-tag :type="scope.row.is_online === 1 ? 'success' : 'info'">
+                {{ scope.row.is_online === 1 ? '在线' : '离线' }}
+              </el-tag>
+            </template>
+          </el-table-column>
+          <el-table-column label="故障状态" prop="fault_status"  align="center">
+            <template #default="scope">
+              <el-tag :type="scope.row.fault_status === 0 ? 'success' : 'danger'">
+                {{ scope.row.fault_status === 0 ? '正常' : '故障' }}
+              </el-tag>
+            </template>
+          </el-table-column>
+          <el-table-column label="更新时间" prop="last_update_time" width="160">
+            <template #default="scope">
+              <span>{{ parseTime(scope.row.last_update_time) }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="操作" fixed="right" width="120">
+            <template #default="scope">
+              <el-button link type="primary" icon="Setting" @click="handleDeviceDetail(scope.row)">详情</el-button>
+            </template>
+          </el-table-column>
+        </el-table>
+
+        <pagination
+            v-show="lightingTotal > 0"
+            :total="lightingTotal"
+            v-model:page="lightingQuery.pageNum"
+            v-model:limit="lightingQuery.pageSize"
+            @pagination="getLightingList"
+        />
+      </el-tab-pane>
+
+      <!-- 报警记录标签页 -->
+      <el-tab-pane label="报警记录" name="alarm">
+        <el-form :model="alarmQuery" ref="alarmQueryRef" :inline="true" label-width="80px">
+          <el-form-item label="设备名称" prop="deviceName">
+            <el-input v-model="alarmQuery.deviceName" placeholder="请输入设备名称" clearable />
+          </el-form-item>
+          <el-form-item label="报警类型" prop="alarmType">
+            <el-select v-model="alarmQuery.alarmType" placeholder="请选择报警类型" clearable>
+              <el-option label="通信故障" value="communication" />
+              <el-option label="灯具故障" value="lamp" />
+              <el-option label="线路故障" value="circuit" />
+              <el-option label="控制器故障" value="controller" />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="报警级别" prop="alarmLevel">
+            <el-select v-model="alarmQuery.alarmLevel" placeholder="请选择报警级别" clearable>
+              <el-option label="提示" :value="1" />
+              <el-option label="一般" :value="2" />
+              <el-option label="严重" :value="3" />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="处理状态" prop="handleStatus">
+            <el-select v-model="alarmQuery.handleStatus" placeholder="请选择处理状态" clearable>
+              <el-option label="未处理" :value="0" />
+              <el-option label="已处理" :value="1" />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="时间范围" prop="timeRange">
+            <el-date-picker
+                v-model="alarmQuery.timeRange"
+                type="datetimerange"
+                range-separator="至"
+                start-placeholder="开始时间"
+                end-placeholder="结束时间"
+                value-format="YYYY-MM-DD HH:mm:ss"
+            />
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" icon="Search" @click="getAlarmList">搜索</el-button>
+            <el-button icon="Refresh" @click="resetAlarmQuery">重置</el-button>
+          </el-form-item>
+        </el-form>
+
+        <el-table v-loading="alarmLoading" :data="alarmList" stripe border>
+          <el-table-column label="设备编码" prop="device_code" width="120" />
+          <el-table-column label="设备名称" prop="device_name" width="150" />
+          <el-table-column label="报警类型" prop="alarm_type" width="120" />
+          <el-table-column label="报警级别" prop="alarm_level" width="100" align="center">
+            <template #default="scope">
+              <el-tag :type="alarmLevelType(scope.row.alarm_level)">
+                {{ alarmLevelText(scope.row.alarm_level) }}
+              </el-tag>
+            </template>
+          </el-table-column>
+          <el-table-column label="报警描述" prop="alarm_desc" show-overflow-tooltip />
+          <el-table-column label="报警时间" prop="alarm_time" width="160">
+            <template #default="scope">
+              <span>{{ parseTime(scope.row.alarm_time) }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="处理状态" prop="handle_status" width="100" align="center">
+            <template #default="scope">
+              <el-tag :type="scope.row.handle_status === 1 ? 'success' : 'warning'">
+                {{ scope.row.handle_status === 1 ? '已处理' : '未处理' }}
+              </el-tag>
+            </template>
+          </el-table-column>
+          <el-table-column label="处理人" prop="handle_user" width="100" />
+          <el-table-column label="处理时间" prop="handle_time" width="160">
+            <template #default="scope">
+              <span>{{ parseTime(scope.row.handle_time) }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="操作" fixed="right" width="120">
+            <template #default="scope">
+              <el-button
+                  link
+                  type="primary"
+                  icon="Edit"
+                  @click="handleAlarm(scope.row)"
+                  v-if="scope.row.handle_status === 0"
+              >处理</el-button>
+              <el-button
+                  link
+                  type="primary"
+                  icon="View"
+                  @click="handleAlarmDetail(scope.row)"
+                  v-else
+              >详情</el-button>
+            </template>
+          </el-table-column>
+        </el-table>
+
+        <pagination
+            v-show="alarmTotal > 0"
+            :total="alarmTotal"
+            v-model:page="alarmQuery.pageNum"
+            v-model:limit="alarmQuery.pageSize"
+            @pagination="getAlarmList"
+        />
+      </el-tab-pane>
+    </el-tabs>
+
+    <!-- 批量控制对话框 -->
+    <el-dialog v-model="batchControlVisible" title="批量控制" width="500px" append-to-body>
+      <el-form ref="batchControlRef" :model="batchControlForm" label-width="80px">
+        <el-form-item label="控制动作">
+          <el-radio-group v-model="batchControlForm.action">
+            <el-radio :label="0">关闭</el-radio>
+            <el-radio :label="1">开启</el-radio>
+            <el-radio :label="2">调光</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="亮度调节" v-if="batchControlForm.action === 2">
+          <el-slider v-model="batchControlForm.brightness" :min="0" :max="100" show-input />
+        </el-form-item>
+        <el-form-item label="选中设备">
+          <el-tag v-for="item in lightingSelection" :key="item.id" class="mr8 mb8">
+            {{ item.deviceName }}
+          </el-tag>
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="batchControlVisible = false">取消</el-button>
+          <el-button type="primary" @click="submitBatchControl">确定</el-button>
+        </span>
+      </template>
+    </el-dialog>
+
+    <!-- 定时计划对话框 -->
+    <el-dialog v-model="scheduleVisible" title="定时计划管理" width="900px" append-to-body>
+      <el-button type="primary" icon="Plus" @click="handleAddSchedule" class="mb8">新增计划</el-button>
+      <el-table :data="scheduleList" stripe border>
+        <el-table-column label="计划名称" prop="schedule_name" />
+        <el-table-column label="计划类型" prop="schedule_type" width="100" align="center">
+          <template #default="scope">
+            {{ scheduleTypeText(scope.row.schedule_type) }}
+          </template>
+        </el-table-column>
+        <el-table-column label="执行时间" width="160">
+          <template #default="scope">
+            {{ scope.row.start_time }} - {{ scope.row.end_time }}
+          </template>
+        </el-table-column>
+        <el-table-column label="动作" prop="action_type" width="100" align="center">
+          <template #default="scope">
+            {{ actionTypeText(scope.row.action_type) }}
+          </template>
+        </el-table-column>
+        <el-table-column label="状态" prop="is_enabled" width="80" align="center">
+          <template #default="scope">
+            <el-switch
+                v-model="scope.row.is_enabled"
+                :active-value="1"
+                :inactive-value="0"
+                @change="handleScheduleStatusChange(scope.row)"
+            />
+          </template>
+        </el-table-column>
+        <el-table-column label="操作" width="150" align="center">
+          <template #default="scope">
+            <el-button link type="primary" icon="Edit" @click="handleEditSchedule(scope.row)">编辑</el-button>
+            <el-button link type="danger" icon="Delete" @click="handleDeleteSchedule(scope.row)">删除</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-dialog>
+
+    <!-- 新增/编辑计划对话框 -->
+    <el-dialog v-model="scheduleFormVisible" :title="scheduleFormTitle" width="600px" append-to-body>
+      <el-form ref="scheduleFormRef" :model="scheduleForm" :rules="scheduleRules" label-width="100px">
+        <el-form-item label="计划名称" prop="scheduleName">
+          <el-input v-model="scheduleForm.scheduleName" placeholder="请输入计划名称" />
+        </el-form-item>
+        <el-form-item label="选择设备" prop="deviceIds">
+          <el-select v-model="scheduleForm.deviceIds" multiple placeholder="请选择设备" style="width: 100%">
+            <el-option
+                v-for="item in allLightingList"
+                :key="item.id"
+                :label="item.device_name"
+                :value="item.id"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="计划类型" prop="scheduleType">
+          <el-radio-group v-model="scheduleForm.scheduleType">
+            <el-radio :label="0">单次执行</el-radio>
+            <el-radio :label="1">每日执行</el-radio>
+            <el-radio :label="2">每周执行</el-radio>
+            <el-radio :label="3">每月执行</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="执行时间" prop="timeRange">
+          <el-time-picker
+              v-model="scheduleForm.startTime"
+              placeholder="开始时间"
+              format="HH:mm"
+              value-format="HH:mm"
+          />
+          <span class="mx8">至</span>
+          <el-time-picker
+              v-model="scheduleForm.endTime"
+              placeholder="结束时间"
+              format="HH:mm"
+              value-format="HH:mm"
+          />
+        </el-form-item>
+        <el-form-item label="周执行日" v-if="scheduleForm.scheduleType === 2" prop="weekDays">
+          <el-checkbox-group v-model="scheduleForm.weekDays">
+            <el-checkbox :label="1">周一</el-checkbox>
+            <el-checkbox :label="2">周二</el-checkbox>
+            <el-checkbox :label="3">周三</el-checkbox>
+            <el-checkbox :label="4">周四</el-checkbox>
+            <el-checkbox :label="5">周五</el-checkbox>
+            <el-checkbox :label="6">周六</el-checkbox>
+            <el-checkbox :label="7">周日</el-checkbox>
+          </el-checkbox-group>
+        </el-form-item>
+        <el-form-item label="月执行日" v-if="scheduleForm.scheduleType === 3" prop="monthDays">
+          <el-select v-model="scheduleForm.monthDays" multiple placeholder="请选择日期" style="width: 100%">
+            <el-option v-for="i in 31" :key="i" :label="i + '日'" :value="i" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="排除节假日" prop="excludeHolidays">
+          <el-switch v-model="scheduleForm.excludeHolidays" />
+        </el-form-item>
+        <el-form-item label="执行动作" prop="actionType">
+          <el-radio-group v-model="scheduleForm.actionType">
+            <el-radio :label="0">关闭</el-radio>
+            <el-radio :label="1">开启</el-radio>
+            <el-radio :label="2">调光</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item label="亮度设置" v-if="scheduleForm.actionType === 2" prop="brightness">
+          <el-slider v-model="scheduleForm.brightness" :min="0" :max="100" show-input />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="scheduleFormVisible = false">取消</el-button>
+          <el-button type="primary" @click="submitScheduleForm">确定</el-button>
+        </span>
+      </template>
+    </el-dialog>
+
+    <!-- 处理报警对话框 -->
+    <el-dialog v-model="handleAlarmVisible" title="处理报警" width="500px" append-to-body>
+      <el-form ref="handleAlarmRef" :model="handleAlarmForm" label-width="80px">
+        <el-form-item label="设备名称">
+          <el-input v-model="handleAlarmForm.deviceName" disabled />
+        </el-form-item>
+        <el-form-item label="报警描述">
+          <el-input v-model="handleAlarmForm.alarmDesc" type="textarea" :rows="3" disabled />
+        </el-form-item>
+        <el-form-item label="处理备注" prop="handleRemark">
+          <el-input v-model="handleAlarmForm.handleRemark" type="textarea" :rows="3" placeholder="请输入处理备注" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="handleAlarmVisible = false">取消</el-button>
+          <el-button type="primary" @click="submitHandleAlarm">确定</el-button>
+        </span>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, onMounted } from 'vue'
+import {
+  listLightingDevice,
+  controlLightingDevice,
+  batchControlLighting,
+  listLightingAlarm,
+  handleLightingAlarm,
+  listLightingSchedule,
+  addLightingSchedule,
+  updateLightingSchedule,
+  deleteLightingSchedule,
+  getBuildingList,
+  getFloorList
+} from '@/api/subsystem/lighting'
+
+const { proxy } = getCurrentInstance()
+const activeTab = ref('monitor')
+
+// 照明监控查询相关
+const lightingQuery = reactive({
+  pageNum: 1,
+  pageSize: 10,
+  buildingId: null,
+  floorId: null,
+  areaName: null,
+  status: null,
+  controlMode: null
+})
+const lightingList = ref([])
+const lightingTotal = ref(0)
+const lightingLoading = ref(false)
+const lightingSelection = ref([])
+const allLightingList = ref([])
+
+// 报警记录查询相关
+const alarmQuery = reactive({
+  pageNum: 1,
+  pageSize: 10,
+  deviceName: null,
+  alarmType: null,
+  alarmLevel: null,
+  handleStatus: null,
+  timeRange: []
+})
+const alarmList = ref([])
+const alarmTotal = ref(0)
+const alarmLoading = ref(false)
+
+// 楼栋楼层数据
+const buildingList = ref([])
+const floorList = ref([])
+
+// 批量控制相关
+const batchControlVisible = ref(false)
+const batchControlForm = reactive({
+  action: 1,
+  brightness: 50
+})
+
+// 定时计划相关
+const scheduleVisible = ref(false)
+const scheduleList = ref([])
+const scheduleFormVisible = ref(false)
+const scheduleFormTitle = ref('')
+const scheduleForm = reactive({
+  id: null,
+  scheduleName: '',
+  deviceIds: [],
+  scheduleType: 1,
+  startTime: '',
+  endTime: '',
+  weekDays: [],
+  monthDays: [],
+  excludeHolidays: false,
+  actionType: 1,
+  brightness: 50
+})
+const scheduleRules = {
+  scheduleName: [{ required: true, message: '请输入计划名称', trigger: 'blur' }],
+  deviceIds: [{ required: true, message: '请选择设备', trigger: 'change' }],
+  scheduleType: [{ required: true, message: '请选择计划类型', trigger: 'change' }],
+  actionType: [{ required: true, message: '请选择执行动作', trigger: 'change' }]
+}
+
+// 处理报警相关
+const handleAlarmVisible = ref(false)
+const handleAlarmForm = reactive({
+  id: null,
+  deviceName: '',
+  alarmDesc: '',
+  handleRemark: ''
+})
+
+// 控制模式类型
+const controlModeType = (mode) => {
+  const types = ['', 'success', 'warning']
+  return types[mode] || ''
+}
+
+// 控制模式文本
+const controlModeText = (mode) => {
+  const texts = ['手动', '自动', '定时']
+  return texts[mode] || '未知'
+}
+
+// 报警级别类型
+const alarmLevelType = (level) => {
+  const types = ['', 'info', 'warning', 'danger']
+  return types[level] || 'info'
+}
+
+// 报警级别文本
+const alarmLevelText = (level) => {
+  const texts = ['', '提示', '一般', '严重']
+  return texts[level] || '未知'
+}
+
+// 计划类型文本
+const scheduleTypeText = (type) => {
+  const texts = ['单次', '每日', '每周', '每月']
+  return texts[type] || '未知'
+}
+
+// 动作类型文本
+const actionTypeText = (type) => {
+  const texts = ['关闭', '开启', '调光']
+  return texts[type] || '未知'
+}
+
+// 获取楼栋列表
+async function loadBuildingList() {
+  const res = await getBuildingList()
+  buildingList.value = res.data
+}
+
+// 楼栋变化处理
+async function handleBuildingChange(val) {
+  lightingQuery.floorId = null
+  floorList.value = []
+  if (val) {
+    const res = await getFloorList({ buildingId: val })
+    floorList.value = res.data
+  }
+}
+
+// 查询照明设备列表
+function getLightingList() {
+  lightingLoading.value = true
+  const params = {
+    ...lightingQuery,
+    pageNum: lightingQuery.pageNum,
+    pageSize: lightingQuery.pageSize
+  }
+  listLightingDevice(params).then(response => {
+    lightingList.value = response.rows
+    lightingTotal.value = response.total
+    lightingLoading.value = false
+  })
+}
+
+// 获取所有照明设备(用于选择)
+async function getAllLightingList() {
+  const res = await listLightingDevice({ pageSize: 1000 })
+  allLightingList.value = res.rows
+}
+
+// 重置照明查询
+function resetLightingQuery() {
+  proxy.resetForm('lightingQueryRef')
+  lightingQuery.pageNum = 1
+  getLightingList()
+}
+
+// 选择变化
+function handleLightingSelectionChange(selection) {
+  lightingSelection.value = selection
+}
+
+// 状态切换
+function handleStatusChange(row) {
+  const text = row.status === 1 ? '开启' : '关闭'
+  proxy.$modal.confirm(`确认${text}照明设备"${row.device_name}"吗?`).then(() => {
+    return controlLightingDevice({
+      deviceCode: row.device_code,
+      action: row.status,
+      brightness: row.brightness
+    })
+  }).then(() => {
+    proxy.$modal.msgSuccess(`${text}成功`)
+    getLightingList()
+  }).catch(() => {
+    row.status = row.status === 1 ? 0 : 1
+  })
+}
+
+// 亮度调节
+function handleBrightnessChange(row) {
+  controlLightingDevice({
+    deviceCode: row.device_code,
+    action: 2,
+    brightness: row.brightness
+  }).then(() => {
+    proxy.$modal.msgSuccess('亮度调节成功')
+  })
+}
+
+// 批量控制
+function handleBatchControl() {
+  batchControlVisible.value = true
+}
+
+// 提交批量控制
+function submitBatchControl() {
+  const deviceCodes = lightingSelection.value.map(item => item.device_code)
+  batchControlLighting({
+    deviceCodes: deviceCodes,
+    action: batchControlForm.action,
+    brightness: batchControlForm.brightness
+  }).then(() => {
+    proxy.$modal.msgSuccess('批量控制成功')
+    batchControlVisible.value = false
+    getLightingList()
+  })
+}
+
+// 定时计划管理
+function handleSchedule() {
+  scheduleVisible.value = true
+  getScheduleList()
+}
+
+// 获取计划列表
+function getScheduleList() {
+  listLightingSchedule().then(response => {
+    scheduleList.value = response.rows
+  })
+}
+
+// 新增计划
+function handleAddSchedule() {
+  resetScheduleForm()
+  scheduleFormTitle.value = '新增定时计划'
+  scheduleFormVisible.value = true
+}
+
+// 编辑计划
+function handleEditSchedule(row) {
+  resetScheduleForm()
+  scheduleFormTitle.value = '编辑定时计划'
+  Object.assign(scheduleForm, {
+    id: row.id,
+    scheduleName: row.schedule_name,
+    deviceIds: row.device_ids ? row.device_ids.split(',').map(Number) : [],
+    scheduleType: row.schedule_type,
+    startTime: row.start_time,
+    endTime: row.end_time,
+    weekDays: row.week_days ? row.week_days.split(',').map(Number) : [],
+    monthDays: row.month_days ? row.month_days.split(',').map(Number) : [],
+    excludeHolidays: row.exclude_holidays === 1,
+    actionType: row.action_type,
+    brightness: row.brightness || 50
+  })
+  scheduleFormVisible.value = true
+}
+
+// 删除计划
+function handleDeleteSchedule(row) {
+  proxy.$modal.confirm(`确认删除计划"${row.schedule_name}"吗?`).then(() => {
+    return deleteLightingSchedule(row.id)
+  }).then(() => {
+    proxy.$modal.msgSuccess('删除成功')
+    getScheduleList()
+  })
+}
+
+// 计划状态切换
+function handleScheduleStatusChange(row) {
+  updateLightingSchedule({
+    id: row.id,
+    isEnabled: row.is_enabled
+  }).then(() => {
+    proxy.$modal.msgSuccess('状态更新成功')
+  })
+}
+
+// 重置计划表单
+function resetScheduleForm() {
+  scheduleForm.id = null
+  scheduleForm.scheduleName = ''
+  scheduleForm.deviceIds = []
+  scheduleForm.scheduleType = 1
+  scheduleForm.startTime = ''
+  scheduleForm.endTime = ''
+  scheduleForm.weekDays = []
+  scheduleForm.monthDays = []
+  scheduleForm.excludeHolidays = false
+  scheduleForm.actionType = 1
+  scheduleForm.brightness = 50
+  proxy.resetForm('scheduleFormRef')
+}
+
+// 提交计划表单
+function submitScheduleForm() {
+  proxy.$refs['scheduleFormRef'].validate(valid => {
+    if (valid) {
+      const data = {
+        ...scheduleForm,
+        deviceIds: scheduleForm.deviceIds.join(','),
+        weekDays: scheduleForm.weekDays.join(','),
+        monthDays: scheduleForm.monthDays.join(','),
+        excludeHolidays: scheduleForm.excludeHolidays ? 1 : 0
+      }
+      if (scheduleForm.id) {
+        updateLightingSchedule(data).then(() => {
+          proxy.$modal.msgSuccess('修改成功')
+          scheduleFormVisible.value = false
+          getScheduleList()
+        })
+      } else {
+        addLightingSchedule(data).then(() => {
+          proxy.$modal.msgSuccess('新增成功')
+          scheduleFormVisible.value = false
+          getScheduleList()
+        })
+      }
+    }
+  })
+}
+
+// 查询报警列表
+function getAlarmList() {
+  alarmLoading.value = true
+  const params = {
+    ...alarmQuery,
+    pageNum: alarmQuery.pageNum,
+    pageSize: alarmQuery.pageSize
+  }
+  if (alarmQuery.timeRange && alarmQuery.timeRange.length === 2) {
+    params.beginTime = alarmQuery.timeRange[0]
+    params.endTime = alarmQuery.timeRange[1]
+  }
+  listLightingAlarm(params).then(response => {
+    alarmList.value = response.rows
+    alarmTotal.value = response.total
+    alarmLoading.value = false
+  })
+}
+
+// 重置报警查询
+function resetAlarmQuery() {
+  proxy.resetForm('alarmQueryRef')
+  alarmQuery.pageNum = 1
+  getAlarmList()
+}
+
+// 处理报警
+function handleAlarm(row) {
+  handleAlarmForm.id = row.id
+  handleAlarmForm.deviceName = row.device_name
+  handleAlarmForm.alarmDesc = row.alarm_desc
+  handleAlarmForm.handleRemark = ''
+  handleAlarmVisible.value = true
+}
+
+// 提交处理报警
+function submitHandleAlarm() {
+  handleLightingAlarm({
+    id: handleAlarmForm.id,
+    handleRemark: handleAlarmForm.handleRemark
+  }).then(() => {
+    proxy.$modal.msgSuccess('处理成功')
+    handleAlarmVisible.value = false
+    getAlarmList()
+  })
+}
+
+// 查看报警详情
+function handleAlarmDetail(row) {
+  // 可以打开详情对话框显示更多信息
+  proxy.$modal.msgWarning(`待开发`)
+}
+
+// 查看设备详情
+function handleDeviceDetail(row) {
+  // 可以跳转到设备详情页面或打开详情对话框
+  proxy.$modal.msgWarning(`设备编码:${row.deviceCode}`+'详情对话框')
+}
+
+// 初始化
+onMounted(() => {
+  loadBuildingList()
+  getLightingList()
+  getAllLightingList()
+})
+</script>
+
+<style scoped>
+.mr8 {
+  margin-right: 8px;
+}
+.mb8 {
+  margin-bottom: 8px;
+}
+.mx8 {
+  margin: 0 8px;
+}
+</style>