Преглед изворни кода

1、电源状态信息前端数据解析,并页面展示
2、电源控制 一键开启、关闭按钮
3、定时控制新增,列表展示修改

lihao16 пре 5 месеци
родитељ
комит
8bc0d5312a
20 измењених фајлова са 1021 додато и 26 уклоњено
  1. 109 0
      smsb-modules/smsb-device/src/main/java/com/inspur/device/controller/SmsbDevicePowerScheduleController.java
  2. 90 0
      smsb-modules/smsb-device/src/main/java/com/inspur/device/domain/SmsbDevicePowerSchedule.java
  3. 82 0
      smsb-modules/smsb-device/src/main/java/com/inspur/device/domain/bo/SmsbDevicePowerScheduleBo.java
  4. 6 0
      smsb-modules/smsb-device/src/main/java/com/inspur/device/domain/constants/DeviceConstants.java
  5. 6 0
      smsb-modules/smsb-device/src/main/java/com/inspur/device/domain/constants/DeviceTaskConstants.java
  6. 2 2
      smsb-modules/smsb-device/src/main/java/com/inspur/device/domain/vo/FrontMultiCardUploadVo.java
  7. 74 0
      smsb-modules/smsb-device/src/main/java/com/inspur/device/domain/vo/SmsbDevicePowerScheduleVo.java
  8. 15 0
      smsb-modules/smsb-device/src/main/java/com/inspur/device/mapper/SmsbDevicePowerScheduleMapper.java
  9. 76 0
      smsb-modules/smsb-device/src/main/java/com/inspur/device/service/ISmsbDevicePowerScheduleService.java
  10. 160 0
      smsb-modules/smsb-device/src/main/java/com/inspur/device/service/impl/SmsbDevicePowerScheduleServiceImpl.java
  11. 22 4
      smsb-modules/smsb-device/src/main/java/com/inspur/device/service/impl/SmsbDeviceServiceImpl.java
  12. 0 9
      smsb-modules/smsb-device/src/main/java/com/inspur/device/service/impl/SmsbDeviceTaskServiceImpl.java
  13. 7 0
      smsb-modules/smsb-device/src/main/resources/mapper/device/SmsbDevicePowerScheduleMapper.xml
  14. 31 0
      smsb-modules/smsb-netty/src/main/java/com/inspur/netty/controller/DeviceController.java
  15. 10 0
      smsb-modules/smsb-netty/src/main/java/com/inspur/netty/message/push/PushMessageType.java
  16. 8 0
      smsb-plus-ui/src/api/smsb/device/device.ts
  17. 70 0
      smsb-plus-ui/src/api/smsb/device/device_power_schedule.ts
  18. 94 0
      smsb-plus-ui/src/api/smsb/device/device_power_schedule_type.ts
  19. 1 1
      smsb-plus-ui/src/assets/styles/element-ui.scss
  20. 158 10
      smsb-plus-ui/src/views/smsb/device/index.vue

+ 109 - 0
smsb-modules/smsb-device/src/main/java/com/inspur/device/controller/SmsbDevicePowerScheduleController.java

@@ -0,0 +1,109 @@
+package com.inspur.device.controller;
+
+import java.util.List;
+
+import lombok.RequiredArgsConstructor;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.constraints.*;
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.validation.annotation.Validated;
+import org.dromara.common.idempotent.annotation.RepeatSubmit;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.excel.utils.ExcelUtil;
+import com.inspur.device.domain.vo.SmsbDevicePowerScheduleVo;
+import com.inspur.device.domain.bo.SmsbDevicePowerScheduleBo;
+import com.inspur.device.service.ISmsbDevicePowerScheduleService;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+
+/**
+ * 多功能卡电源定时开关
+ *
+ * @author Hao Li
+ * @date 2025-05-20
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/smsb/device/powerSchedule")
+public class SmsbDevicePowerScheduleController extends BaseController {
+
+    private final ISmsbDevicePowerScheduleService smsbDevicePowerScheduleService;
+
+    /**
+     * 查询多功能卡电源定时开关列表
+     */
+    @GetMapping("/list")
+    public TableDataInfo<SmsbDevicePowerScheduleVo> list(SmsbDevicePowerScheduleBo bo, PageQuery pageQuery) {
+        return smsbDevicePowerScheduleService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 获取多功能卡电源定时开关详细信息
+     *
+     * @param deviceId 主键
+     */
+    @GetMapping("/list/byDevice/{deviceId}")
+    public R<List<SmsbDevicePowerScheduleVo>> getListByDevice(@NotNull(message = "主键不能为空") @PathVariable Long deviceId) {
+        return R.ok(smsbDevicePowerScheduleService.getListByDevice(deviceId));
+    }
+
+    /**
+     * 导出多功能卡电源定时开关列表
+     */
+    @Log(title = "多功能卡电源定时开关", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(SmsbDevicePowerScheduleBo bo, HttpServletResponse response) {
+        List<SmsbDevicePowerScheduleVo> list = smsbDevicePowerScheduleService.queryList(bo);
+        ExcelUtil.exportExcel(list, "多功能卡电源定时开关", SmsbDevicePowerScheduleVo.class, response);
+    }
+
+    /**
+     * 获取多功能卡电源定时开关详细信息
+     *
+     * @param id 主键
+     */
+    @GetMapping("/{id}")
+    public R<SmsbDevicePowerScheduleVo> getInfo(@NotNull(message = "主键不能为空")
+                                                @PathVariable Long id) {
+        return R.ok(smsbDevicePowerScheduleService.queryById(id));
+    }
+
+    /**
+     * 新增多功能卡电源定时开关
+     */
+    @Log(title = "多功能卡电源定时开关", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping()
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody SmsbDevicePowerScheduleBo bo) {
+        return smsbDevicePowerScheduleService.insertByBo(bo);
+    }
+
+    /**
+     * 修改多功能卡电源定时开关
+     */
+    @Log(title = "多功能卡电源定时开关", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping()
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody SmsbDevicePowerScheduleBo bo) {
+        return smsbDevicePowerScheduleService.updateByBo(bo);
+    }
+
+    /**
+     * 删除多功能卡电源定时开关
+     *
+     * @param ids 主键串
+     */
+    @Log(title = "多功能卡电源定时开关", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public R<Void> remove(@NotEmpty(message = "主键不能为空")
+                          @PathVariable Long[] ids) {
+        return toAjax(smsbDevicePowerScheduleService.deleteWithValidByIds(List.of(ids), true));
+    }
+}

+ 90 - 0
smsb-modules/smsb-device/src/main/java/com/inspur/device/domain/SmsbDevicePowerSchedule.java

@@ -0,0 +1,90 @@
+package com.inspur.device.domain;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.io.Serial;
+import java.util.Date;
+
+/**
+ * 多功能卡电源定时开关对象 smsb_device_power_schedule
+ *
+ * @author Hao Li
+ * @date 2025-05-20
+ */
+@Data
+@TableName("smsb_device_power_schedule")
+public class SmsbDevicePowerSchedule {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 设备ID
+     */
+    private Long deviceId;
+
+    /**
+     * 开始日期
+     */
+    private String startDate;
+
+    /**
+     * 结束日期
+     */
+    private String endDate;
+
+    /**
+     * 亮屏时间
+     */
+    private String powerOnTime;
+
+    /**
+     * 息屏时间
+     */
+    private String powerOffTime;
+
+    /**
+     * 电源类型
+     */
+    private Long powerType;
+
+    /**
+     * 状态 0-停用 1-启用
+     */
+    private Long status;
+
+    /**
+     * 创建人
+     */
+    private String createUser;
+
+    /**
+     * 创建者
+     */
+    @TableField(fill = FieldFill.INSERT)
+    private Long createBy;
+
+    /**
+     * 创建时间
+     */
+    @TableField(fill = FieldFill.INSERT)
+    private Date createTime;
+
+
+    /**
+     * 租户编号
+     */
+    private String tenantId;
+
+
+}

+ 82 - 0
smsb-modules/smsb-device/src/main/java/com/inspur/device/domain/bo/SmsbDevicePowerScheduleBo.java

@@ -0,0 +1,82 @@
+package com.inspur.device.domain.bo;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.inspur.device.domain.SmsbDevicePowerSchedule;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 多功能卡电源定时开关业务对象 smsb_device_power_schedule
+ *
+ * @author Hao Li
+ * @date 2025-05-20
+ */
+@Data
+@AutoMapper(target = SmsbDevicePowerSchedule.class, reverseConvertGenerate = false)
+public class SmsbDevicePowerScheduleBo {
+
+    private Long id;
+
+    /**
+     * 设备ID
+     */
+    private Long deviceId;
+
+    /**
+     * 开始日期
+     */
+    private String startDate;
+
+    /**
+     * 结束日期
+     */
+    private String endDate;
+
+    /**
+     * 亮屏时间
+     */
+    private String powerOnTime;
+
+    /**
+     * 息屏时间
+     */
+    private String powerOffTime;
+
+    /**
+     * 电源类型
+     */
+    private Long powerType;
+
+    /**
+     * 状态 0-停用 1-启用
+     */
+    private Long status;
+
+    /**
+     * 创建者
+     */
+    @TableField(fill = FieldFill.INSERT)
+    private Long createBy;
+
+    /**
+     * 创建时间
+     */
+    @TableField(fill = FieldFill.INSERT)
+    private Date createTime;
+
+    private List<String> dateRange;
+
+    /**
+     * 请求参数
+     */
+    @JsonInclude(JsonInclude.Include.NON_EMPTY)
+    @TableField(exist = false)
+    private Map<String, Object> params = new HashMap<>();
+}

+ 6 - 0
smsb-modules/smsb-device/src/main/java/com/inspur/device/domain/constants/DeviceConstants.java

@@ -35,6 +35,12 @@ public class DeviceConstants {
     /** 设备删除 已删除 */
     public static final Integer DEVICE_DEL_FLAG_YES = 1;
 
+    /** 电源控制 - 开启 */
+    public static final String DEVICE_POWER_ON = "on";
+
+    /** 电源控制 - 关闭 */
+    public static final String DEVICE_POWER_OFF = "off";
+
     /** 设备截屏 Redis key */
     public static final String REDIS_SCREENSHOT_KEY = "global:device:screenshot:";
 

+ 6 - 0
smsb-modules/smsb-device/src/main/java/com/inspur/device/domain/constants/DeviceTaskConstants.java

@@ -38,6 +38,12 @@ public class DeviceTaskConstants {
     /** 结束推流 */
     public static final Integer DEVICE_TASK_STREAM_STOP = 1010;
 
+    /** 电源一键开启 */
+    public static final Integer DEVICE_TASK_POWER_ON = 1011;
+
+    /** 电源一键关闭 */
+    public static final Integer DEVICE_TASK_POWER_OFF = 1012;
+
     /** 设备任务类型 end */
 
     /** 设备任务状态 begin */

+ 2 - 2
smsb-modules/smsb-device/src/main/java/com/inspur/device/domain/vo/FrontMultiCardUploadVo.java

@@ -1,8 +1,8 @@
 package com.inspur.device.domain.vo;
 
+import cn.hutool.json.JSONObject;
 import lombok.Data;
 
-import java.util.List;
 
 /**
  * 前端设备上报多功能卡
@@ -13,6 +13,6 @@ public class FrontMultiCardUploadVo {
 
     private String identifier;
 
-    private List<SmsbDeviceMultiCardVo> portList;
+    private String data;
 
 }

+ 74 - 0
smsb-modules/smsb-device/src/main/java/com/inspur/device/domain/vo/SmsbDevicePowerScheduleVo.java

@@ -0,0 +1,74 @@
+package com.inspur.device.domain.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.inspur.device.domain.SmsbDevicePowerSchedule;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+
+/**
+ * 多功能卡电源定时开关视图对象 smsb_device_power_schedule
+ *
+ * @author Hao Li
+ * @date 2025-05-20
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = SmsbDevicePowerSchedule.class)
+public class SmsbDevicePowerScheduleVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    private Long id;
+
+    private Long deviceId;
+
+    /**
+     * 开始日期
+     */
+    @ExcelProperty(value = "开始日期")
+    private String startDate;
+
+    /**
+     * 结束日期
+     */
+    @ExcelProperty(value = "结束日期")
+    private String endDate;
+
+    /**
+     * 亮屏时间
+     */
+    @ExcelProperty(value = "亮屏时间")
+    private String powerOnTime;
+
+    /**
+     * 息屏时间
+     */
+    @ExcelProperty(value = "息屏时间")
+    private String powerOffTime;
+
+    /**
+     * 电源类型
+     */
+    @ExcelProperty(value = "电源类型")
+    private Long powerType;
+
+    /**
+     * 状态 0-停用 1-启用
+     */
+    @ExcelProperty(value = "状态 0-停用 1-启用")
+    private Long status;
+
+    /**
+     * 创建人
+     */
+    @ExcelProperty(value = "创建人")
+    private String createUser;
+
+
+}

+ 15 - 0
smsb-modules/smsb-device/src/main/java/com/inspur/device/mapper/SmsbDevicePowerScheduleMapper.java

@@ -0,0 +1,15 @@
+package com.inspur.device.mapper;
+
+import com.inspur.device.domain.SmsbDevicePowerSchedule;
+import com.inspur.device.domain.vo.SmsbDevicePowerScheduleVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 多功能卡电源定时开关Mapper接口
+ *
+ * @author Hao Li
+ * @date 2025-05-20
+ */
+public interface SmsbDevicePowerScheduleMapper extends BaseMapperPlus<SmsbDevicePowerSchedule, SmsbDevicePowerScheduleVo> {
+
+}

+ 76 - 0
smsb-modules/smsb-device/src/main/java/com/inspur/device/service/ISmsbDevicePowerScheduleService.java

@@ -0,0 +1,76 @@
+package com.inspur.device.service;
+
+import com.inspur.device.domain.bo.SmsbDevicePowerScheduleBo;
+import com.inspur.device.domain.vo.SmsbDevicePowerScheduleVo;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 多功能卡电源定时开关Service接口
+ *
+ * @author Hao Li
+ * @date 2025-05-20
+ */
+public interface ISmsbDevicePowerScheduleService {
+
+    /**
+     * 查询多功能卡电源定时开关
+     *
+     * @param id 主键
+     * @return 多功能卡电源定时开关
+     */
+    SmsbDevicePowerScheduleVo queryById(Long id);
+
+    /**
+     * 分页查询多功能卡电源定时开关列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 多功能卡电源定时开关分页列表
+     */
+    TableDataInfo<SmsbDevicePowerScheduleVo> queryPageList(SmsbDevicePowerScheduleBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的多功能卡电源定时开关列表
+     *
+     * @param bo 查询条件
+     * @return 多功能卡电源定时开关列表
+     */
+    List<SmsbDevicePowerScheduleVo> queryList(SmsbDevicePowerScheduleBo bo);
+
+    /**
+     * 新增多功能卡电源定时开关
+     *
+     * @param bo 多功能卡电源定时开关
+     * @return 是否新增成功
+     */
+    R<Void> insertByBo(SmsbDevicePowerScheduleBo bo);
+
+    /**
+     * 修改多功能卡电源定时开关
+     *
+     * @param bo 多功能卡电源定时开关
+     * @return 是否修改成功
+     */
+    R<Void> updateByBo(SmsbDevicePowerScheduleBo bo);
+
+    /**
+     * 校验并批量删除多功能卡电源定时开关信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+
+    /**
+     * 根据设备id查询定时开关列表
+     * @param deviceId
+     * @return
+     */
+    List<SmsbDevicePowerScheduleVo> getListByDevice(Long deviceId);
+}

+ 160 - 0
smsb-modules/smsb-device/src/main/java/com/inspur/device/service/impl/SmsbDevicePowerScheduleServiceImpl.java

@@ -0,0 +1,160 @@
+package com.inspur.device.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.inspur.device.domain.SmsbDevicePowerSchedule;
+import com.inspur.device.domain.bo.SmsbDevicePowerScheduleBo;
+import com.inspur.device.domain.vo.SmsbDevicePowerScheduleVo;
+import com.inspur.device.mapper.SmsbDevicePowerScheduleMapper;
+import com.inspur.device.service.ISmsbDevicePowerScheduleService;
+import lombok.RequiredArgsConstructor;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.satoken.utils.LoginHelper;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 多功能卡电源定时开关Service业务层处理
+ *
+ * @author Hao Li
+ * @date 2025-05-20
+ */
+@RequiredArgsConstructor
+@Service
+public class SmsbDevicePowerScheduleServiceImpl implements ISmsbDevicePowerScheduleService {
+
+    private final SmsbDevicePowerScheduleMapper baseMapper;
+
+    /**
+     * 查询多功能卡电源定时开关
+     *
+     * @param id 主键
+     * @return 多功能卡电源定时开关
+     */
+    @Override
+    public SmsbDevicePowerScheduleVo queryById(Long id) {
+        return baseMapper.selectVoById(id);
+    }
+
+    /**
+     * 分页查询多功能卡电源定时开关列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 多功能卡电源定时开关分页列表
+     */
+    @Override
+    public TableDataInfo<SmsbDevicePowerScheduleVo> queryPageList(SmsbDevicePowerScheduleBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<SmsbDevicePowerSchedule> lqw = buildQueryWrapper(bo);
+        Page<SmsbDevicePowerScheduleVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    @Override
+    public List<SmsbDevicePowerScheduleVo> getListByDevice(Long deviceId) {
+        LambdaQueryWrapper<SmsbDevicePowerSchedule> lqw = Wrappers.lambdaQuery();
+        lqw.eq(SmsbDevicePowerSchedule::getDeviceId, deviceId);
+        lqw.orderByDesc(SmsbDevicePowerSchedule::getCreateTime);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    /**
+     * 查询符合条件的多功能卡电源定时开关列表
+     *
+     * @param bo 查询条件
+     * @return 多功能卡电源定时开关列表
+     */
+    @Override
+    public List<SmsbDevicePowerScheduleVo> queryList(SmsbDevicePowerScheduleBo bo) {
+        LambdaQueryWrapper<SmsbDevicePowerSchedule> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<SmsbDevicePowerSchedule> buildQueryWrapper(SmsbDevicePowerScheduleBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<SmsbDevicePowerSchedule> lqw = Wrappers.lambdaQuery();
+        lqw.eq(bo.getDeviceId() != null, SmsbDevicePowerSchedule::getDeviceId, bo.getDeviceId());
+        lqw.eq(bo.getStatus() != null, SmsbDevicePowerSchedule::getStatus, bo.getStatus());
+        return lqw;
+    }
+
+    /**
+     * 新增多功能卡电源定时开关
+     *
+     * @param bo 多功能卡电源定时开关
+     * @return 是否新增成功
+     */
+    @Override
+    public R<Void> insertByBo(SmsbDevicePowerScheduleBo bo) {
+        SmsbDevicePowerSchedule add = MapstructUtils.convert(bo, SmsbDevicePowerSchedule.class);
+        List<String> dateRange = bo.getDateRange();
+        if (CollectionUtils.isEmpty(dateRange) || dateRange.size() != 2) {
+            return R.fail("请输入正确的时间范围!");
+        }
+        String startDate = bo.getDateRange().get(0);
+        String endDate = bo.getDateRange().get(1);
+        add.setStartDate(startDate);
+        add.setEndDate(endDate);
+        add.setStatus(1L);
+        add.setCreateUser(LoginHelper.getLoginUser().getNickname());
+        boolean flag = baseMapper.insert(add) > 0;
+        if (!flag) {
+            return R.fail("数据插入异常,请联系管理员!");
+        }
+        return R.ok();
+    }
+
+    /**
+     * 修改多功能卡电源定时开关
+     *
+     * @param bo 多功能卡电源定时开关
+     * @return 是否修改成功
+     */
+    @Override
+    public R<Void> updateByBo(SmsbDevicePowerScheduleBo bo) {
+        SmsbDevicePowerSchedule update = MapstructUtils.convert(bo, SmsbDevicePowerSchedule.class);
+        List<String> dateRange = bo.getDateRange();
+        if (CollectionUtils.isEmpty(dateRange) || dateRange.size() != 2) {
+            return R.fail("请输入正确的时间范围!");
+        }
+        String startDate = bo.getDateRange().get(0);
+        String endDate = bo.getDateRange().get(1);
+        update.setStartDate(startDate);
+        update.setEndDate(endDate);
+        boolean flag = baseMapper.updateById(update) > 0;
+        if (!flag) {
+            return R.fail("数据插入异常,请联系管理员!");
+        }
+        return R.ok();
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(SmsbDevicePowerSchedule entity) {
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除多功能卡电源定时开关信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if (isValid) {
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+}

+ 22 - 4
smsb-modules/smsb-device/src/main/java/com/inspur/device/service/impl/SmsbDeviceServiceImpl.java

@@ -2,6 +2,9 @@ package com.inspur.device.service.impl;
 
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.date.DateUtil;
+import cn.hutool.json.JSONArray;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson2.JSON;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
@@ -22,6 +25,7 @@ import com.inspur.device.mapper.SmsbDeviceRunInfoMapper;
 import com.inspur.device.service.ISmsbDeviceManufacturerService;
 import com.inspur.device.service.ISmsbDeviceService;
 import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.dromara.common.core.domain.R;
 import org.dromara.common.core.exception.ServiceException;
 import org.dromara.common.core.utils.DateUtils;
@@ -58,6 +62,7 @@ import java.util.*;
  */
 @RequiredArgsConstructor
 @Service
+@Slf4j
 public class SmsbDeviceServiceImpl implements ISmsbDeviceService {
 
     private final SmsbDeviceMapper baseMapper;
@@ -415,14 +420,27 @@ public class SmsbDeviceServiceImpl implements ISmsbDeviceService {
     @Override
     public R<Void> uploadMultiCard(FrontMultiCardUploadVo frontMultiCardUploadVo) {
         String identifier = frontMultiCardUploadVo.getIdentifier();
-        List<SmsbDeviceMultiCardVo> multiCardVoList = frontMultiCardUploadVo.getPortList();
-        // 将多功能卡信息缓存至Redis
-        if (CollectionUtils.isEmpty(multiCardVoList)) {
+        JSONObject data = JSONUtil.parseObj(frontMultiCardUploadVo.getData().replace("'","\""));
+        JSONArray current_status_info = data.getJSONArray("current_status_info");
+        if (current_status_info.size() < 1) {
+            log.info("uploadMultiCard current_status_info size < 1 return");
             return R.ok();
         }
+        JSONArray updatePowerIndexStates = ((JSONObject) current_status_info.get(0)).getJSONArray("updatePowerIndexStates");
+        if (updatePowerIndexStates.size() < 1) {
+            log.info("uploadMultiCard updatePowerIndexStates size < 1 return");
+            return R.ok();
+        }
+        List<SmsbDeviceMultiCardVo> multiCardVoList = new ArrayList<>();
         String syncTime = DateUtil.formatDateTime(new Date());
-        for (SmsbDeviceMultiCardVo multiCardVo : multiCardVoList) {
+        for (Object indexState : updatePowerIndexStates) {
+            JSONObject indexStateJson = (JSONObject) indexState;
+            SmsbDeviceMultiCardVo multiCardVo = new SmsbDeviceMultiCardVo();
             multiCardVo.setSyncTime(syncTime);
+            multiCardVo.setPowerStatus(indexStateJson.getInt("status"));
+            multiCardVo.setIndexNum(indexStateJson.getInt("powerIndex"));
+            multiCardVo.setPowerType(1);
+            multiCardVoList.add(multiCardVo);
         }
         RedisUtils.setCacheObject(DeviceConstants.REDIS_DEVICE_MULTI_CARD_KEY + identifier, multiCardVoList, Duration.ofMinutes(30));
         return R.ok();

+ 0 - 9
smsb-modules/smsb-device/src/main/java/com/inspur/device/service/impl/SmsbDeviceTaskServiceImpl.java

@@ -62,15 +62,6 @@ public class SmsbDeviceTaskServiceImpl implements ISmsbDeviceTaskService {
         lqw.last("limit 1");
         SmsbDeviceTaskVo result = baseMapper.selectVoOne(lqw);
 
-        // 新增一条任务获取数据
-        if (result != null) {
-            SmsbDeviceTaskDetail smsbDeviceTaskDetail = new SmsbDeviceTaskDetail();
-            smsbDeviceTaskDetail.setTaskId(result.getId());
-            smsbDeviceTaskDetail.setTaskStatus(DeviceTaskConstants.DEVICE_TASK_PLAY_LINE_UPDATE);
-            smsbDeviceTaskDetail.setTenantId(result.getTenantId());
-            smsbDeviceTaskDetailMapper.insert(smsbDeviceTaskDetail);
-        }
-
         return R.ok(result);
     }
 

+ 7 - 0
smsb-modules/smsb-device/src/main/resources/mapper/device/SmsbDevicePowerScheduleMapper.xml

@@ -0,0 +1,7 @@
+<?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.inspur.device.mapper.SmsbDevicePowerScheduleMapper">
+
+</mapper>

+ 31 - 0
smsb-modules/smsb-netty/src/main/java/com/inspur/netty/controller/DeviceController.java

@@ -180,6 +180,37 @@ public class DeviceController {
         return isSend ? R.ok() : R.fail("长连接发送失败,设备长连接已断开");
     }
 
+    /**
+     * 多功能卡,一键电源控制
+     *
+     * @param deviceId
+     * @param type 类型
+     * @return
+     */
+    @GetMapping("/powerSet/{deviceId}/{type}")
+    public R<String> powerSet(@PathVariable("deviceId") Long deviceId,@PathVariable("type") String type) {
+        // 1 查询设备信息
+        SmsbDeviceVo deviceVo = smsbDeviceService.getDeviceCacheById(deviceId);
+        if (deviceVo == null) {
+            return R.fail("设备不存在");
+        }
+        // 2 任务中心创建任务
+        String taskParam = "";
+        Integer taskType = 0;
+        if (DeviceConstants.DEVICE_POWER_ON.equals(type)) {
+            taskParam = PushMessageType.CONTROL_POWER_ON.getValue();
+            taskType = DeviceTaskConstants.DEVICE_TASK_POWER_ON;
+        }else {
+            taskParam = PushMessageType.CONTROL_POWER_OFF.getValue();
+            taskType = DeviceTaskConstants.DEVICE_TASK_POWER_OFF;
+        }
+        deviceTaskService.createNewDeviceTask(taskType, deviceVo, taskParam);
+        // 3 组装待机命令 发送长连接
+        String standbyCmd = deviceVo.getIdentifier() + taskParam + NettyConstants.DATA_PACK_SEPARATOR;
+        boolean isSend = PushMsgUtil.sendV2(deviceVo.getIdentifier(), standbyCmd);
+        return isSend ? R.ok() : R.fail("长连接发送失败,设备长连接已断开");
+    }
+
     /**
      * 截屏
      *

+ 10 - 0
smsb-modules/smsb-netty/src/main/java/com/inspur/netty/message/push/PushMessageType.java

@@ -82,6 +82,16 @@ public enum PushMessageType {
      */
     CONTROL_STOP_STREAM("/stop/screenstream"),
 
+    /**
+     * 一键电源开启
+     */
+    CONTROL_POWER_ON("/power/on"),
+
+    /**
+     * 一键电源关闭
+     */
+    CONTROL_POWER_OFF("/power/off"),
+
     /**
      * 检查OTA升级
      */

+ 8 - 0
smsb-plus-ui/src/api/smsb/device/device.ts

@@ -136,6 +136,14 @@ export const brightSet = (id: string | number, brightnessValue: number) => {
     method: 'get'
   });
 };
+
+export const powerSet = (id: string | number, type: string) => {
+  return request({
+    url: '/netty/device/powerSet/' + id + "/" + type,
+    method: 'get'
+  });
+};
+
 export const startStream = (id: string | number) => {
   return request({
     url: '/stream/start/' + id,

+ 70 - 0
smsb-plus-ui/src/api/smsb/device/device_power_schedule.ts

@@ -0,0 +1,70 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import { DevicePowerScheduleVO, DevicePowerScheduleForm, DevicePowerScheduleQuery } from '@/api/smsb/device/device_power_schedule_type';
+
+/**
+ * 查询多功能卡电源定时开关列表
+ * @param query
+ * @returns {*}
+ */
+
+export const listDevicePowerSchedule = (query?: DevicePowerScheduleQuery): AxiosPromise<DevicePowerScheduleVO[]> => {
+  return request({
+    url: '/smsb/device/powerSchedule/list',
+    method: 'get',
+    params: query
+  });
+};
+
+export const listPowerScheduleByDevice = (deviceId: string | number):AxiosPromise<DevicePowerScheduleVO[]> => {
+  return request({
+    url: '/smsb/device/powerSchedule/list/byDevice/' + deviceId,
+    method: 'get',
+  });
+};
+
+/**
+ * 查询多功能卡电源定时开关详细
+ * @param id
+ */
+export const getDevicePowerSchedule = (id: string | number): AxiosPromise<DevicePowerScheduleVO> => {
+  return request({
+    url: '/smsb/device/powerSchedule/' + id,
+    method: 'get'
+  });
+};
+
+/**
+ * 新增多功能卡电源定时开关
+ * @param data
+ */
+export const addDevicePowerSchedule = (data: DevicePowerScheduleForm) => {
+  return request({
+    url: '/smsb/device/powerSchedule',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 修改多功能卡电源定时开关
+ * @param data
+ */
+export const updateDevicePowerSchedule = (data: DevicePowerScheduleForm) => {
+  return request({
+    url: '/smsb/device/powerSchedule',
+    method: 'put',
+    data: data
+  });
+};
+
+/**
+ * 删除多功能卡电源定时开关
+ * @param id
+ */
+export const delDevicePowerSchedule = (id: string | number | Array<string | number>) => {
+  return request({
+    url: '/smsb/device/powerSchedule/' + id,
+    method: 'delete'
+  });
+};

+ 94 - 0
smsb-plus-ui/src/api/smsb/device/device_power_schedule_type.ts

@@ -0,0 +1,94 @@
+export interface DevicePowerScheduleVO {
+  id: number;
+  /**
+   * 开始日期
+   */
+  startDate: string;
+
+  /**
+   * 结束日期
+   */
+  endDate: string;
+
+  /**
+   * 亮屏时间
+   */
+  powerOnTime: string;
+
+  /**
+   * 息屏时间
+   */
+  powerOffTime: string;
+
+  /**
+   * 电源类型
+   */
+  powerType: number;
+
+  /**
+   * 状态 0-停用 1-启用
+   */
+  status: number;
+
+  /**
+   * 创建人
+   */
+  createUser: string;
+
+  dateRange: Array<string | number>;
+
+}
+
+export interface DevicePowerScheduleForm extends BaseEntity {
+  id?: number;
+  /**
+   * 开始日期
+   */
+  startDate?: string;
+
+  /**
+   * 结束日期
+   */
+  endDate?: string;
+
+  /**
+   * 亮屏时间
+   */
+  powerOnTime?: string;
+
+  /**
+   * 息屏时间
+   */
+  powerOffTime?: string;
+
+  /**
+   * 电源类型
+   */
+  powerType?: number;
+
+  dateRange?: Array<string | number>;
+
+  deviceId?: number | string;
+
+}
+
+export interface DevicePowerScheduleQuery extends PageQuery {
+
+  /**
+   * 设备ID
+   */
+  deviceId?: string | number;
+
+  /**
+   * 状态 0-停用 1-启用
+   */
+  status?: number;
+
+  /**
+   * 日期范围参数
+   */
+  params?: any;
+}
+
+
+

+ 1 - 1
smsb-plus-ui/src/assets/styles/element-ui.scss

@@ -77,7 +77,7 @@
       margin: 0 auto !important;
 
       .el-dialog__body {
-        margin-top: 15px !important;
+        margin-top: 10px !important;
         padding: 15px !important;
       }
       .el-dialog__header {

+ 158 - 10
smsb-plus-ui/src/views/smsb/device/index.vue

@@ -215,15 +215,15 @@
       </template>
     </el-dialog>
     <!--设备详情弹窗-->
-    <el-dialog v-model="viewDialog.visible" :title="viewDialog.title" width="900px" style="height: 650px"
-      append-to-body>
+    <el-dialog v-model="viewDialog.visible" :title="viewDialog.title" width="900px" style="height: 680px"
+               append-to-body>
       <el-tabs v-model="activeName" style="height: 500px" @tab-click="handleClickTab">
         <el-tab-pane label="设备详情" name="info">
           <div>
             <span>设备名称:{{ deviceRunInfo.deviceBase.name }}</span>
             <span style="margin-left: 50px">SN:{{ deviceRunInfo.deviceBase.serialNumber }}</span>
             <span style="margin-left: 50px">MAC:{{ deviceRunInfo.deviceBase.mac }}</span>
-            <br />
+            <br/>
           </div>
           <div style="margin-top: 20px">
             <span>分辨率:{{ deviceRunInfo.deviceBase.width }}*{{ deviceRunInfo.deviceBase.height }}</span>
@@ -312,14 +312,49 @@
               </el-table-column>
               <el-table-column label="告警类型" align="center" prop="errorType" width="100">
                 <template #default="scope">
-                  <dict-tag :options="smsb_device_error_type" :value="scope.row.errorType" />
+                  <dict-tag :options="smsb_device_error_type" :value="scope.row.errorType"/>
                 </template>
               </el-table-column>
-              <el-table-column label="创建时间" align="left" prop="createTime" width="160" />
+              <el-table-column label="创建时间" align="left" prop="createTime" width="160"/>
             </el-table>
           </div>
           <pagination v-show="alarmTotal > 0" v-model:page="dialogQueryParams.pageNum"
-            v-model:limit="dialogQueryParams.pageSize" :total="alarmTotal" @pagination="getAlarmList" />
+                      v-model:limit="dialogQueryParams.pageSize" :total="alarmTotal" @pagination="getAlarmList"/>
+        </el-tab-pane>
+        <el-tab-pane label="电源控制" name="power">
+          <div style="margin-top: 10px">
+            <el-button :loading="buttonLoading" type="primary" @click="handlePower('on')">一键开启</el-button>
+            <el-button :loading="buttonLoading" type="primary" @click="handlePower('off')">一键关闭</el-button>
+            <el-button :loading="buttonLoading" type="primary" @click="handleSchedule">定时新增</el-button>
+            <!--            <el-button :loading="buttonLoading" type="primary" @click="handleRead">定时回读</el-button>-->
+          </div>
+          <el-divider border-style="double"/>
+          <el-table :data="powerScheduleList">
+            <el-table-column label="电源类型" align="center" prop="powerType">
+              <template #default="scope">
+                <dict-tag :options="smsb_multi_card_type" :value="scope.row.powerType"/>
+              </template>
+            </el-table-column>
+            <el-table-column label="开始日期" align="center" prop="startDate"/>
+            <el-table-column label="结束日期" align="center" prop="endDate"/>
+            <el-table-column label="亮屏时间" align="center" prop="powerOnTime"/>
+            <el-table-column label="息屏时间" align="center" prop="powerOffTime"/>
+            <el-table-column label="状态" align="center" prop="status">
+              <template #default="scope">
+                <dict-tag :options="smsb_multi_card_status" :value="scope.row.status"/>
+              </template>
+            </el-table-column>
+            <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+              <template #default="scope">
+                <el-tooltip content="修改" placement="top">
+                  <el-button link type="primary" icon="Edit" @click="handleUpdateSchedule(scope.row)"></el-button>
+                </el-tooltip>
+                <el-tooltip content="删除" placement="top">
+                  <el-button link type="primary" icon="Delete" @click="handleDeleteSchedule(scope.row)"></el-button>
+                </el-tooltip>
+              </template>
+            </el-table-column>
+          </el-table>
         </el-tab-pane>
       </el-tabs>
       <template #footer>
@@ -360,7 +395,7 @@
     </el-dialog>
     <!--亮度调节弹窗-->
     <el-dialog v-model="brightDialog.visible" :title="brightDialog.title" width="700px" append-to-body>
-      <el-slider style="margin: 20px" v-model="brightnessValue" :min="0" :max="255" :step="1"  />
+      <el-slider style="margin: 20px" v-model="brightnessValue" :min="0" :max="255" :step="1"/>
       <template #footer>
         <div class="dialog-footer">
           <el-button :loading="buttonLoading" type="primary" @click="brightSubmit">确 定</el-button>
@@ -368,6 +403,41 @@
         </div>
       </template>
     </el-dialog>
+    <!--电源开关弹窗-->
+    <el-dialog v-model="powerDialog.visible" :title="powerDialog.title" width="600px" append-to-body>
+      <el-form ref="powerFormRef" :model="powerForm" :rules="powerRules" label-width="70px">
+        <el-form-item label="电源类型" prop="powerType">
+          <el-select v-model="powerForm.powerType" placeholder="请选择电源类型" style="width: 150px">
+            <el-option v-for="dict in smsb_multi_card_type" :key="dict.value" :label="dict.label"
+                       :value="dict.value"/>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="日期范围" prop="dateRange">
+          <el-date-picker v-model="powerForm.dateRange" value-format="YYYY-MM-DD" type="daterange" range-separator="-"
+                          start-placeholder="开始日期" end-placeholder="结束日期" style="width: 100px"
+                          :default-time="[new Date(2025, 1, 1, 0, 0, 0), new Date(2025, 1, 1, 23, 59, 59)]"/>
+
+        </el-form-item>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="亮屏时间" prop="powerOnTime">
+              <el-time-picker clearable v-model="powerForm.powerOnTime" value-format="HH:mm:ss" placeholder="请选择亮屏时间"/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="息屏时间" prop="powerOffTime">
+              <el-time-picker clearable v-model="powerForm.powerOffTime" value-format="HH:mm:ss" placeholder="请选择息屏时间"/>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button :loading="buttonLoading" type="primary" @click="submitPowerForm">确 定</el-button>
+          <el-button @click="powerCancel">取 消</el-button>
+        </div>
+      </template>
+    </el-dialog>
   </div>
 </template>
 
@@ -382,6 +452,7 @@ import {
   getDeviceRunInfo,
   getDeviceScreenshot,
   listDevice,
+  powerSet,
   reboot,
   restartApp,
   shutdown,
@@ -402,10 +473,17 @@ import {DeviceErrorRecordQuery, DeviceErrorRecordVO} from '@/api/smsb/device/err
 import {listDeviceErrorRecord} from '@/api/smsb/device/errorRecord';
 import {storeToRefs} from 'pinia';
 import useScreenshotStore from '@/store/modules/screenshot';
+import {DevicePowerScheduleForm, DevicePowerScheduleVO} from "@/api/smsb/device/device_power_schedule_type";
+import {
+  addDevicePowerSchedule, delDevicePowerSchedule,
+  getDevicePowerSchedule,
+  listPowerScheduleByDevice, updateDevicePowerSchedule
+} from "@/api/smsb/device/device_power_schedule";
 
 const screenshotStore = storeToRefs(useScreenshotStore());
 const screenshotImageUrl = ref<string>();
 const alarmList = ref<DeviceErrorRecordVO[]>([]);
+const powerScheduleList = ref<DevicePowerScheduleVO[]>([]);
 const {proxy} = getCurrentInstance() as ComponentInternalInstance;
 const {
   sys_device_online,
@@ -431,6 +509,7 @@ const multiple = ref(true);
 const total = ref(0);
 const queryFormRef = ref<ElFormInstance>();
 const deviceFormRef = ref<ElFormInstance>();
+const powerFormRef = ref<ElFormInstance>();
 const deviceId = ref<string | number>();
 const totalNum = ref(0);
 const alarmTotal = ref(0);
@@ -440,6 +519,14 @@ const streamDeviceId = ref<string | number>();
 const initNum = ref(0);
 const volumeValue = ref(0);
 const brightnessValue = ref(0);
+const powerForm = ref<DevicePowerScheduleForm>({
+  id: null,
+  powerType: "1",
+  dateRange: null,
+  powerOnTime: null,
+  powerOffTime: null,
+  deviceId: null
+});
 const deviceRunInfo = reactive<DeviceRunInfoVO>({
   deviceBase: undefined,
   id: undefined,
@@ -476,6 +563,10 @@ const brightDialog = reactive<DialogOption>({
   visible: false,
   title: ''
 });
+const powerDialog = reactive<DialogOption>({
+  visible: false,
+  title: ''
+});
 // 播放器实例引用
 const flvPlayer = ref<flvjs.Player | null>(null);
 const flvPlayerRef = ref<HTMLVideoElement | null>(null);
@@ -548,9 +639,21 @@ const dialogData = reactive<DialogPageData<DeviceErrorRecordQuery>>({
   }
 });
 
-const { queryParams, form, rules } = toRefs(data);
-const { dialogQueryParams } = toRefs(dialogData);
-
+const {queryParams, form, rules} = toRefs(data);
+const {dialogQueryParams} = toRefs(dialogData);
+const submitPowerForm = async () => {
+  buttonLoading.value = true;
+  if (powerForm.value.id){
+    await updateDevicePowerSchedule(powerForm.value).finally(() => (buttonLoading.value = false));
+  }else {
+    await addDevicePowerSchedule(powerForm.value).finally(() => (buttonLoading.value = false));
+  }
+  await getPowerScheduleList();
+  powerDialog.visible = false;
+};
+const powerCancel = () => {
+  powerDialog.visible = false;
+};
 /** 查询设备列表 */
 const getList = async () => {
   loading.value = true;
@@ -594,6 +697,41 @@ const brightCancel = () => {
   brightDialog.visible = false;
   buttonLoading.value = false;
 }
+const handleSchedule = async () => {
+  const deviceId = deviceRunInfo.deviceId;
+  powerForm.value.dateRange = [];
+  powerForm.value.powerOffTime = null;
+  powerForm.value.powerOnTime = null;
+  powerForm.value.deviceId = deviceId;
+  powerDialog.visible = true;
+  powerDialog.title = '定时设置';
+}
+const handleUpdateSchedule = async (row?: DevicePowerScheduleVO) => {
+  const _id = row?.id
+  powerForm.value.dateRange = [];
+  powerForm.value.powerOffTime = null;
+  powerForm.value.powerOnTime = null;
+  const res = await getDevicePowerSchedule(_id);
+  Object.assign(powerForm.value, res.data);
+  powerForm.value.dateRange.push(res.data.startDate);
+  powerForm.value.dateRange.push(res.data.endDate);
+  powerDialog.visible = true;
+  powerDialog.title = "定时设置";
+}
+const handleDeleteSchedule = async (row?: DevicePowerScheduleVO) => {
+  const _ids = row?.id
+  await proxy?.$modal.confirm('是否确认删除定时配置ID为"' + _ids + '"的数据项?').finally(() => loading.value = false);
+  await delDevicePowerSchedule(_ids);
+  proxy?.$modal.msgSuccess("删除成功");
+  await getPowerScheduleList();
+}
+const handlePower = async (type: string) => {
+  buttonLoading.value = true;
+  const deviceId = deviceRunInfo.deviceId;
+  await powerSet(deviceId, type).finally(() => buttonLoading.value = false);
+  buttonLoading.value = false;
+  proxy?.$modal.msgSuccess('命令下发成功');
+}
 const handleVoice = () => {
   // console.log("volume num = " + deviceRunInfo.volume)
   voiceDialog.visible = true;
@@ -843,7 +981,17 @@ const handleClickTab = (tab: TabsPaneContext, event: Event) => {
   if (tab.props.name === 'alarm') {
     getAlarmList();
   }
+  if (tab.props.name === 'power') {
+    getPowerScheduleList();
+  }
 };
+
+const getPowerScheduleList = async () => {
+  const deviceId = deviceRunInfo.deviceId;
+  const res = await listPowerScheduleByDevice(deviceId);
+  powerScheduleList.value = res.data;
+};
+
 // 组件卸载前清理
 onBeforeUnmount(() => {
   destroyPlayer();