浏览代码

1、增加播放清单
2、增加播放时序
3、增加任务中心

lihao16 6 月之前
父节点
当前提交
fa5a3d5aba
共有 43 个文件被更改,包括 2253 次插入255 次删除
  1. 106 0
      smsb-modules/smsb-device/src/main/java/com/inspur/device/controller/SmsbDeviceTaskController.java
  2. 68 0
      smsb-modules/smsb-device/src/main/java/com/inspur/device/domain/SmsbDeviceTask.java
  3. 53 0
      smsb-modules/smsb-device/src/main/java/com/inspur/device/domain/SmsbDeviceTaskDetail.java
  4. 61 0
      smsb-modules/smsb-device/src/main/java/com/inspur/device/domain/bo/SmsbDeviceTaskBo.java
  5. 36 0
      smsb-modules/smsb-device/src/main/java/com/inspur/device/domain/bo/SmsbDeviceTaskDetailBo.java
  6. 20 0
      smsb-modules/smsb-device/src/main/java/com/inspur/device/domain/constants/DeviceTaskConstants.java
  7. 2 0
      smsb-modules/smsb-device/src/main/java/com/inspur/device/domain/constants/ResultCodeEnum.java
  8. 49 0
      smsb-modules/smsb-device/src/main/java/com/inspur/device/domain/vo/SmsbDeviceTaskDetailVo.java
  9. 75 0
      smsb-modules/smsb-device/src/main/java/com/inspur/device/domain/vo/SmsbDeviceTaskVo.java
  10. 15 0
      smsb-modules/smsb-device/src/main/java/com/inspur/device/mapper/SmsbDeviceTaskDetailMapper.java
  11. 15 0
      smsb-modules/smsb-device/src/main/java/com/inspur/device/mapper/SmsbDeviceTaskMapper.java
  12. 77 0
      smsb-modules/smsb-device/src/main/java/com/inspur/device/service/ISmsbDeviceTaskService.java
  13. 172 0
      smsb-modules/smsb-device/src/main/java/com/inspur/device/service/impl/SmsbDeviceTaskServiceImpl.java
  14. 1 1
      smsb-modules/smsb-device/src/main/resources/mapper/device/SmsbDeviceMapper.xml
  15. 19 9
      smsb-modules/smsb-source/src/main/java/com/inspur/source/controller/SmsbFrontController.java
  16. 25 1
      smsb-modules/smsb-source/src/main/java/com/inspur/source/controller/SmsbItemPushController.java
  17. 32 39
      smsb-modules/smsb-source/src/main/java/com/inspur/source/controller/SmsbItemPushDeviceController.java
  18. 57 0
      smsb-modules/smsb-source/src/main/java/com/inspur/source/domain/SmsbItemPushPlayline.java
  19. 83 0
      smsb-modules/smsb-source/src/main/java/com/inspur/source/domain/SmsbItemPushPlaylist.java
  20. 1 1
      smsb-modules/smsb-source/src/main/java/com/inspur/source/domain/bo/SmsbItemPushBo.java
  21. 56 0
      smsb-modules/smsb-source/src/main/java/com/inspur/source/domain/bo/SmsbItemPushPlaylineBo.java
  22. 74 0
      smsb-modules/smsb-source/src/main/java/com/inspur/source/domain/bo/SmsbItemPushPlaylistBo.java
  23. 5 1
      smsb-modules/smsb-source/src/main/java/com/inspur/source/domain/vo/FrontPushInfoVo.java
  24. 22 0
      smsb-modules/smsb-source/src/main/java/com/inspur/source/domain/vo/ResponseBaseBean.java
  25. 68 0
      smsb-modules/smsb-source/src/main/java/com/inspur/source/domain/vo/SmsbItemPushPlaylineVo.java
  26. 85 0
      smsb-modules/smsb-source/src/main/java/com/inspur/source/domain/vo/SmsbItemPushPlaylistVo.java
  27. 30 0
      smsb-modules/smsb-source/src/main/java/com/inspur/source/domain/vo/ValidatePushTimeVo.java
  28. 7 0
      smsb-modules/smsb-source/src/main/java/com/inspur/source/mapper/SmsbItemPushMapper.java
  29. 28 0
      smsb-modules/smsb-source/src/main/java/com/inspur/source/mapper/SmsbItemPushPlaylineMapper.java
  30. 26 0
      smsb-modules/smsb-source/src/main/java/com/inspur/source/mapper/SmsbItemPushPlaylistMapper.java
  31. 18 14
      smsb-modules/smsb-source/src/main/java/com/inspur/source/service/ISmsbItemPushDeviceService.java
  32. 17 2
      smsb-modules/smsb-source/src/main/java/com/inspur/source/service/ISmsbItemPushService.java
  33. 36 31
      smsb-modules/smsb-source/src/main/java/com/inspur/source/service/impl/SmsbItemPushDeviceServiceImpl.java
  34. 338 143
      smsb-modules/smsb-source/src/main/java/com/inspur/source/service/impl/SmsbItemPushServiceImpl.java
  35. 11 0
      smsb-modules/smsb-source/src/main/resources/mapper/SmsbItemPushPlaylineMapper.xml
  36. 18 0
      smsb-modules/smsb-source/src/main/resources/mapper/SmsbItemPushPlaylistMapper.xml
  37. 63 0
      smsb-plus-ui/src/api/smsb/device/device_task.ts
  38. 101 0
      smsb-plus-ui/src/api/smsb/device/device_task_type.ts
  39. 8 0
      smsb-plus-ui/src/api/smsb/source/item_push.ts
  40. 1 1
      smsb-plus-ui/src/views/smsb/device/index.vue
  41. 250 0
      smsb-plus-ui/src/views/smsb/deviceTask/index.vue
  42. 24 12
      smsb-plus-ui/src/views/smsb/itemPush/index.vue
  43. 0 0
      upload/smsb/upload/.gitkeep

+ 106 - 0
smsb-modules/smsb-device/src/main/java/com/inspur/device/controller/SmsbDeviceTaskController.java

@@ -0,0 +1,106 @@
+package com.inspur.device.controller;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import com.inspur.device.domain.bo.SmsbDeviceTaskBo;
+import com.inspur.device.domain.vo.SmsbDeviceTaskVo;
+import com.inspur.device.service.ISmsbDeviceTaskService;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.constraints.NotEmpty;
+import jakarta.validation.constraints.NotNull;
+import lombok.RequiredArgsConstructor;
+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.excel.utils.ExcelUtil;
+import org.dromara.common.idempotent.annotation.RepeatSubmit;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.web.core.BaseController;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+/**
+ * 设备任务中心
+ *
+ * @author Hao Li
+ * @date 2025-05-12
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/smsb/device/task")
+public class SmsbDeviceTaskController extends BaseController {
+
+    private final ISmsbDeviceTaskService smsbDeviceTaskService;
+
+    /**
+     * 查询设备任务中心列表
+     */
+    @SaCheckPermission("device:task:list")
+    @GetMapping("/list")
+    public TableDataInfo<SmsbDeviceTaskVo> list(SmsbDeviceTaskBo bo, PageQuery pageQuery) {
+        return smsbDeviceTaskService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 导出设备任务中心列表
+     */
+    @SaCheckPermission("device:task:export")
+    @Log(title = "设备任务中心", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(SmsbDeviceTaskBo bo, HttpServletResponse response) {
+        List<SmsbDeviceTaskVo> list = smsbDeviceTaskService.queryList(bo);
+        ExcelUtil.exportExcel(list, "设备任务中心", SmsbDeviceTaskVo.class, response);
+    }
+
+    /**
+     * 获取设备任务中心详细信息
+     *
+     * @param id 主键
+     */
+    @SaCheckPermission("device:task:query")
+    @GetMapping("/{id}")
+    public R<SmsbDeviceTaskVo> getInfo(@NotNull(message = "主键不能为空")
+                                       @PathVariable Long id) {
+        return R.ok(smsbDeviceTaskService.queryById(id));
+    }
+
+    /**
+     * 新增设备任务中心
+     */
+    @SaCheckPermission("device:task:add")
+    @Log(title = "设备任务中心", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping()
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody SmsbDeviceTaskBo bo) {
+        return toAjax(smsbDeviceTaskService.insertByBo(bo));
+    }
+
+    /**
+     * 修改设备任务中心
+     */
+    @SaCheckPermission("device:task:edit")
+    @Log(title = "设备任务中心", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping()
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody SmsbDeviceTaskBo bo) {
+        return toAjax(smsbDeviceTaskService.updateByBo(bo));
+    }
+
+    /**
+     * 删除设备任务中心
+     *
+     * @param ids 主键串
+     */
+    @SaCheckPermission("device:task:remove")
+    @Log(title = "设备任务中心", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public R<Void> remove(@NotEmpty(message = "主键不能为空")
+                          @PathVariable Long[] ids) {
+        return toAjax(smsbDeviceTaskService.deleteWithValidByIds(List.of(ids), true));
+    }
+}

+ 68 - 0
smsb-modules/smsb-device/src/main/java/com/inspur/device/domain/SmsbDeviceTask.java

@@ -0,0 +1,68 @@
+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_task
+ *
+ * @author Hao Li
+ * @date 2025-05-12
+ */
+@Data
+@TableName("smsb_device_task")
+public class SmsbDeviceTask {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 唯一标识
+     */
+    private String identifier;
+
+    /**
+     * 设备ID
+     */
+    private Long deviceId;
+
+    /**
+     * 任务类型
+     */
+    private Integer taskType;
+
+    /**
+     * 任务参数
+     */
+    private String taskParam;
+
+    /**
+     * 是否完成 0-否 1-是
+     */
+    private Integer isEnd;
+
+    /**
+     * 租户编号
+     */
+    private String tenantId;
+
+    /**
+     * 创建时间
+     */
+    @TableField(fill = FieldFill.INSERT)
+    private Date createTime;
+
+
+}

+ 53 - 0
smsb-modules/smsb-device/src/main/java/com/inspur/device/domain/SmsbDeviceTaskDetail.java

@@ -0,0 +1,53 @@
+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_task_detail
+ *
+ * @author Hao Li
+ * @date 2025-05-12
+ */
+@Data
+@TableName("smsb_device_task_detail")
+public class SmsbDeviceTaskDetail {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 任务ID
+     */
+    private Long taskId;
+
+    /**
+     * 任务状态
+     */
+    private Integer taskStatus;
+
+    /**
+     * 租户编号
+     */
+    private String tenantId;
+
+    /**
+     * 创建时间
+     */
+    @TableField(fill = FieldFill.INSERT)
+    private Date createTime;
+
+
+}

+ 61 - 0
smsb-modules/smsb-device/src/main/java/com/inspur/device/domain/bo/SmsbDeviceTaskBo.java

@@ -0,0 +1,61 @@
+package com.inspur.device.domain.bo;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.inspur.device.domain.SmsbDeviceTask;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+
+import java.util.Date;
+
+/**
+ * 设备任务中心业务对象 smsb_device_task
+ *
+ * @author Hao Li
+ * @date 2025-05-12
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = SmsbDeviceTask.class, reverseConvertGenerate = false)
+public class SmsbDeviceTaskBo extends BaseEntity {
+
+    /**
+     * 主键ID
+     */
+    private Long id;
+
+    /**
+     * 唯一标识
+     */
+    private String identifier;
+
+    /**
+     * 设备ID
+     */
+    private Long deviceId;
+
+    /**
+     * 任务类型
+     */
+    private Integer taskType;
+
+    /**
+     * 任务参数
+     */
+    private String taskParam;
+
+    /**
+     * 是否完成 0-否 1-是
+     */
+    private Integer isEnd;
+
+    /**
+     * 创建时间
+     */
+    @TableField(fill = FieldFill.INSERT)
+    private Date createTime;
+
+
+}

+ 36 - 0
smsb-modules/smsb-device/src/main/java/com/inspur/device/domain/bo/SmsbDeviceTaskDetailBo.java

@@ -0,0 +1,36 @@
+package com.inspur.device.domain.bo;
+
+import com.inspur.device.domain.SmsbDeviceTaskDetail;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+
+/**
+ * 设备任务详情业务对象 smsb_device_task_detail
+ *
+ * @author Lion Li
+ * @date 2025-05-12
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = SmsbDeviceTaskDetail.class, reverseConvertGenerate = false)
+public class SmsbDeviceTaskDetailBo extends BaseEntity {
+
+    /**
+     * 主键ID
+     */
+    private Long id;
+
+    /**
+     * 任务ID
+     */
+    private Long taskId;
+
+    /**
+     * 任务状态
+     */
+    private Integer taskStatus;
+
+
+}

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

@@ -0,0 +1,20 @@
+package com.inspur.device.domain.constants;
+
+/**
+ * 设备任务常量类
+ * @author lihao16
+ */
+public class DeviceTaskConstants {
+
+    /** 设备任务类型 begin */
+
+    /** 设备时序更新 */
+    public static final Integer DEVICE_TASK_PLAY_LINE_UPDATE = 1001;
+
+    /** 设备任务类型 end */
+
+    /** 设备任务状态 begin */
+    private static final Integer DEVICE_TASK_STATUS_INIT = 1001;
+
+    /** 设备任务状态 end */
+}

+ 2 - 0
smsb-modules/smsb-device/src/main/java/com/inspur/device/domain/constants/ResultCodeEnum.java

@@ -36,6 +36,8 @@ public enum ResultCodeEnum {
     MEDIA_EMPTY_INVALID("1002", "data empty or not a valid json"),
     MEDIA_UNKNOWN_CP("1003", "unknown appId or appSecret"),
     MEDIA_UNKNOWN_COMMAND("1004", "unknown command"),
+    PUSH_LEVEL_LOW("1005", "设备播放内容等级高于当前下发等级"),
+    PUSH_TIME_CLASH("1006", "设备播放内容当前时间段存在冲突"),
 
     MEDIA_NOT_SET("2001", "data property not set"),
     MEDIA_IS_NULL("2002", "operate data is null"),

+ 49 - 0
smsb-modules/smsb-device/src/main/java/com/inspur/device/domain/vo/SmsbDeviceTaskDetailVo.java

@@ -0,0 +1,49 @@
+package com.inspur.device.domain.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.inspur.device.domain.SmsbDeviceTaskDetail;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+
+/**
+ * 设备任务详情视图对象 smsb_device_task_detail
+ *
+ * @author Hao Li
+ * @date 2025-05-12
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = SmsbDeviceTaskDetail.class)
+public class SmsbDeviceTaskDetailVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @ExcelProperty(value = "主键ID")
+    private Long id;
+
+    /**
+     * 任务ID
+     */
+    @ExcelProperty(value = "任务ID")
+    private Long taskId;
+
+    /**
+     * 任务状态
+     */
+    @ExcelProperty(value = "任务状态")
+    private Integer taskStatus;
+
+    private Date createTime;
+
+
+}

+ 75 - 0
smsb-modules/smsb-device/src/main/java/com/inspur/device/domain/vo/SmsbDeviceTaskVo.java

@@ -0,0 +1,75 @@
+package com.inspur.device.domain.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.inspur.device.domain.SmsbDeviceTask;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+
+/**
+ * 设备任务中心视图对象 smsb_device_task
+ *
+ * @author Hao Li
+ * @date 2025-05-12
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = SmsbDeviceTask.class)
+public class SmsbDeviceTaskVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @ExcelProperty(value = "主键ID")
+    private Long id;
+
+    /**
+     * 唯一标识
+     */
+    @ExcelProperty(value = "唯一标识")
+    private String identifier;
+
+    /**
+     * 设备ID
+     */
+    @ExcelProperty(value = "设备ID")
+    private Long deviceId;
+
+    private String deviceName;
+
+    /**
+     * 任务类型
+     */
+    @ExcelProperty(value = "任务类型")
+    private Integer taskType;
+
+    /**
+     * 任务参数
+     */
+    @ExcelProperty(value = "任务参数")
+    private String taskParam;
+
+    /**
+     * 是否完成 0-否 1-是
+     */
+    @ExcelProperty(value = "是否完成 0-否 1-是")
+    private Integer isEnd;
+
+    /**
+     * 创建时间
+     */
+    @ExcelProperty(value = "创建时间")
+    private Date createTime;
+
+    private String tenantId;
+
+
+}

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

@@ -0,0 +1,15 @@
+package com.inspur.device.mapper;
+
+import com.inspur.device.domain.SmsbDeviceTaskDetail;
+import com.inspur.device.domain.vo.SmsbDeviceTaskDetailVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 设备任务详情Mapper接口
+ *
+ * @author Lion Li
+ * @date 2025-05-12
+ */
+public interface SmsbDeviceTaskDetailMapper extends BaseMapperPlus<SmsbDeviceTaskDetail, SmsbDeviceTaskDetailVo> {
+
+}

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

@@ -0,0 +1,15 @@
+package com.inspur.device.mapper;
+
+import com.inspur.device.domain.SmsbDeviceTask;
+import com.inspur.device.domain.vo.SmsbDeviceTaskVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 设备任务中心Mapper接口
+ *
+ * @author Hao Li
+ * @date 2025-05-12
+ */
+public interface SmsbDeviceTaskMapper extends BaseMapperPlus<SmsbDeviceTask, SmsbDeviceTaskVo> {
+
+}

+ 77 - 0
smsb-modules/smsb-device/src/main/java/com/inspur/device/service/ISmsbDeviceTaskService.java

@@ -0,0 +1,77 @@
+package com.inspur.device.service;
+
+import com.inspur.device.domain.bo.SmsbDeviceTaskBo;
+import com.inspur.device.domain.vo.SmsbDeviceTaskVo;
+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-12
+ */
+public interface ISmsbDeviceTaskService {
+
+    /**
+     * 查询设备任务中心
+     *
+     * @param id 主键
+     * @return 设备任务中心
+     */
+    SmsbDeviceTaskVo queryById(Long id);
+
+    /**
+     * 分页查询设备任务中心列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 设备任务中心分页列表
+     */
+    TableDataInfo<SmsbDeviceTaskVo> queryPageList(SmsbDeviceTaskBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的设备任务中心列表
+     *
+     * @param bo 查询条件
+     * @return 设备任务中心列表
+     */
+    List<SmsbDeviceTaskVo> queryList(SmsbDeviceTaskBo bo);
+
+    /**
+     * 新增设备任务中心
+     *
+     * @param bo 设备任务中心
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(SmsbDeviceTaskBo bo);
+
+    /**
+     * 修改设备任务中心
+     *
+     * @param bo 设备任务中心
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(SmsbDeviceTaskBo bo);
+
+    /**
+     * 校验并批量删除设备任务中心信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+
+    /**
+     * 获取设备任务
+     * @param identifier
+     * @param taskType
+     * @return
+     */
+    R<SmsbDeviceTaskVo> getDeviceTask(String identifier, Integer taskType);
+}

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

@@ -0,0 +1,172 @@
+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.SmsbDeviceTask;
+import com.inspur.device.domain.SmsbDeviceTaskDetail;
+import com.inspur.device.domain.bo.SmsbDeviceTaskBo;
+import com.inspur.device.domain.constants.DeviceTaskConstants;
+import com.inspur.device.domain.vo.SmsbDeviceTaskVo;
+import com.inspur.device.domain.vo.SmsbDeviceVo;
+import com.inspur.device.mapper.SmsbDeviceTaskDetailMapper;
+import com.inspur.device.mapper.SmsbDeviceTaskMapper;
+import com.inspur.device.service.ISmsbDeviceService;
+import com.inspur.device.service.ISmsbDeviceTaskService;
+import lombok.RequiredArgsConstructor;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.springframework.stereotype.Service;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 设备任务中心Service业务层处理
+ *
+ * @author Hao Li
+ * @date 2025-05-12
+ */
+@RequiredArgsConstructor
+@Service
+public class SmsbDeviceTaskServiceImpl implements ISmsbDeviceTaskService {
+
+    private final SmsbDeviceTaskMapper baseMapper;
+
+    private final ISmsbDeviceService smsbDeviceService;
+
+    private final SmsbDeviceTaskDetailMapper smsbDeviceTaskDetailMapper;
+
+    /**
+     * 查询设备任务中心
+     *
+     * @param id 主键
+     * @return 设备任务中心
+     */
+    @Override
+    public SmsbDeviceTaskVo queryById(Long id) {
+        return baseMapper.selectVoById(id);
+    }
+
+    @Override
+    public R<SmsbDeviceTaskVo> getDeviceTask(String identifier, Integer taskType) {
+        LambdaQueryWrapper<SmsbDeviceTask> lqw = Wrappers.lambdaQuery();
+        lqw.eq(StringUtils.isNotBlank(identifier), SmsbDeviceTask::getIdentifier, identifier);
+        lqw.eq(taskType != null, SmsbDeviceTask::getTaskType, taskType);
+        lqw.orderByDesc(SmsbDeviceTask::getCreateTime);
+        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);
+    }
+
+    /**
+     * 分页查询设备任务中心列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 设备任务中心分页列表
+     */
+    @Override
+    public TableDataInfo<SmsbDeviceTaskVo> queryPageList(SmsbDeviceTaskBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<SmsbDeviceTask> lqw = buildQueryWrapper(bo);
+        Page<SmsbDeviceTaskVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        //组装结果
+        if (!result.getRecords().isEmpty()) {
+            result.getRecords().forEach(n -> {
+                // 通过缓存获取设备信息
+                SmsbDeviceVo smsbDeviceVo = smsbDeviceService.getDeviceCacheById(n.getDeviceId());
+                if (smsbDeviceVo != null) {
+                    n.setDeviceName(smsbDeviceVo.getName());
+                }
+            });
+        }
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的设备任务中心列表
+     *
+     * @param bo 查询条件
+     * @return 设备任务中心列表
+     */
+    @Override
+    public List<SmsbDeviceTaskVo> queryList(SmsbDeviceTaskBo bo) {
+        LambdaQueryWrapper<SmsbDeviceTask> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<SmsbDeviceTask> buildQueryWrapper(SmsbDeviceTaskBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<SmsbDeviceTask> lqw = Wrappers.lambdaQuery();
+        lqw.eq(StringUtils.isNotBlank(bo.getIdentifier()), SmsbDeviceTask::getIdentifier, bo.getIdentifier());
+        lqw.eq(bo.getDeviceId() != null, SmsbDeviceTask::getDeviceId, bo.getDeviceId());
+        lqw.eq(bo.getTaskType() != null, SmsbDeviceTask::getTaskType, bo.getTaskType());
+        lqw.eq(bo.getIsEnd() != null, SmsbDeviceTask::getIsEnd, bo.getIsEnd());
+        return lqw;
+    }
+
+    /**
+     * 新增设备任务中心
+     *
+     * @param bo 设备任务中心
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(SmsbDeviceTaskBo bo) {
+        SmsbDeviceTask add = MapstructUtils.convert(bo, SmsbDeviceTask.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setId(add.getId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改设备任务中心
+     *
+     * @param bo 设备任务中心
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(SmsbDeviceTaskBo bo) {
+        SmsbDeviceTask update = MapstructUtils.convert(bo, SmsbDeviceTask.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(SmsbDeviceTask entity) {
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除设备任务中心信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if (isValid) {
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+}

+ 1 - 1
smsb-modules/smsb-device/src/main/resources/mapper/device/SmsbDeviceMapper.xml

@@ -20,7 +20,7 @@
     <select id="queryDeviceVoByPushId" parameterType="Long" resultType="com.inspur.device.domain.vo.SmsbDeviceVo">
         SELECT id, NAME
         FROM smsb_device
-        WHERE id IN (SELECT device_id FROM smsb_item_push_device WHERE push_id = #{pushId})
+        WHERE id IN (SELECT distinct device_id FROM smsb_item_push_playlist WHERE push_id = #{pushId})
     </select>
 
     <select id="queryPageListByTenantId" resultType="com.inspur.device.domain.vo.SmsbDeviceVo">

+ 19 - 9
smsb-modules/smsb-source/src/main/java/com/inspur/source/controller/SmsbFrontController.java

@@ -3,11 +3,9 @@ package com.inspur.source.controller;
 import cn.dev33.satoken.annotation.SaIgnore;
 import com.inspur.device.domain.bo.HttpHeartbeatReq;
 import com.inspur.device.domain.vo.HttpHeartbeatRspVo;
+import com.inspur.device.domain.vo.SmsbDeviceTaskVo;
 import com.inspur.device.domain.vo.SmsbOtaRecordVo;
-import com.inspur.device.service.ISmsbDeviceAuthService;
-import com.inspur.device.service.ISmsbDeviceLoginService;
-import com.inspur.device.service.ISmsbDeviceService;
-import com.inspur.device.service.ISmsbOtaRecordService;
+import com.inspur.device.service.*;
 import com.inspur.source.domain.vo.FrontPushInfoVo;
 import com.inspur.source.service.ISmsbItemPushService;
 import jakarta.validation.constraints.NotNull;
@@ -18,6 +16,8 @@ import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 
+import java.util.List;
+
 /**
  * 前端设备接口
  *
@@ -30,18 +30,16 @@ import org.springframework.web.multipart.MultipartFile;
 public class SmsbFrontController {
 
     private final ISmsbItemPushService smsbItemPushService;
-
     @Autowired
     private ISmsbOtaRecordService iSmsbOtaRecordService;
-
     @Autowired
     private ISmsbDeviceService smsbDeviceService;
-
     @Autowired
     private ISmsbDeviceLoginService smsbDeviceLoginService;
-
     @Autowired
     private ISmsbDeviceAuthService smsbDeviceAuthService;
+    @Autowired
+    private ISmsbDeviceTaskService smsbDeviceTaskService;
 
     /**
      * 根据设备identifier 获取该设备最新内容下发记录
@@ -50,7 +48,7 @@ public class SmsbFrontController {
      */
     @SaIgnore
     @GetMapping("/push/{identifier}")
-    public R<FrontPushInfoVo> getItemPushInfo(@NotNull(message = "identifier不能为空") @PathVariable String identifier) {
+    public R<List<FrontPushInfoVo>> getItemPushInfo(@NotNull(message = "identifier不能为空") @PathVariable String identifier) {
         return smsbItemPushService.getItemPushInfo(identifier);
     }
 
@@ -127,4 +125,16 @@ public class SmsbFrontController {
         return smsbDeviceAuthService.deviceAuth(requestParam);
     }
 
+    /**
+     * 前端设备登录接口
+     *
+     * @param identifier
+     * @param taskType
+     */
+    @SaIgnore
+    @GetMapping("/task")
+    public R<SmsbDeviceTaskVo> getDeviceTask(@RequestParam("identifier") String identifier,@RequestParam("taskType") Integer taskType) {
+        return smsbDeviceTaskService.getDeviceTask(identifier,taskType);
+    }
+
 }

+ 25 - 1
smsb-modules/smsb-source/src/main/java/com/inspur/source/controller/SmsbItemPushController.java

@@ -2,8 +2,10 @@ package com.inspur.source.controller;
 
 import cn.dev33.satoken.annotation.SaCheckPermission;
 import cn.dev33.satoken.annotation.SaIgnore;
+import com.inspur.source.domain.SmsbItemPush;
 import com.inspur.source.domain.bo.SmsbItemPushBo;
 import com.inspur.source.domain.vo.PushStatisticsVo;
+import com.inspur.source.domain.vo.ResponseBaseBean;
 import com.inspur.source.domain.vo.SmsbItemPushReviewVo;
 import com.inspur.source.domain.vo.SmsbItemPushVo;
 import com.inspur.source.service.ISmsbItemPushService;
@@ -102,7 +104,29 @@ public class SmsbItemPushController extends BaseController {
     @RepeatSubmit()
     @PostMapping()
     public R<Void> add(@Validated(AddGroup.class) @RequestBody SmsbItemPushBo bo) {
-        return toAjax(smsbItemPushService.insertByBo(bo));
+        return smsbItemPushService.insertByBo(bo);
+    }
+
+    /**
+     * 新增内容发布
+     */
+    @RepeatSubmit()
+    @PostMapping("/validate/time")
+    public R<ResponseBaseBean> validateTime(@Validated(AddGroup.class) @RequestBody SmsbItemPushBo bo) {
+        return smsbItemPushService.validateTime(bo);
+    }
+
+    /**
+     * 新增内容发布
+     */
+    @SaIgnore
+    @RepeatSubmit()
+    @GetMapping("/update/line/{pushId}")
+    public R<Void> updateLine(@PathVariable("pushId") Long pushId) {
+        SmsbItemPush smsbItemPush = new SmsbItemPush();
+        smsbItemPush.setId(pushId);
+        smsbItemPushService.updatePlayLine(smsbItemPush);
+        return R.ok();
     }
 
     /**

+ 32 - 39
smsb-modules/smsb-source/src/main/java/com/inspur/source/controller/SmsbItemPushDeviceController.java

@@ -1,26 +1,17 @@
 package com.inspur.source.controller;
 
-import java.util.List;
-
+import com.inspur.source.domain.bo.SmsbItemPushPlaylistBo;
+import com.inspur.source.domain.vo.SmsbItemPushPlaylistVo;
+import com.inspur.source.service.ISmsbItemPushDeviceService;
 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.source.domain.vo.SmsbItemPushDeviceVo;
-import com.inspur.source.domain.bo.SmsbItemPushDeviceBo;
-import com.inspur.source.service.ISmsbItemPushDeviceService;
-import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.web.core.BaseController;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
 
 /**
  * 内容发布设备
@@ -39,22 +30,24 @@ public class SmsbItemPushDeviceController extends BaseController {
     /**
      * 查询内容发布设备列表
      */
-    @GetMapping("/list")
-    public TableDataInfo<SmsbItemPushDeviceVo> list(SmsbItemPushDeviceBo bo, PageQuery pageQuery) {
-        return smsbItemPushDeviceService.queryPageList(bo, pageQuery);
+    @GetMapping("/list/v2")
+    public R<List<SmsbItemPushPlaylistVo>> getPushDevicelist(SmsbItemPushPlaylistBo bo) {
+        return R.ok(smsbItemPushDeviceService.getPushDeviceList(bo));
     }
 
     /**
      * 查询内容发布设备列表
-     */
-    @GetMapping("/list/v2")
-    public TableDataInfo<SmsbItemPushDeviceVo> listV2(SmsbItemPushDeviceBo bo, PageQuery pageQuery) {
-        return smsbItemPushDeviceService.queryPageListV2(bo, pageQuery);
+     *//*
+    @GetMapping("/list")
+    public TableDataInfo<SmsbItemPushDeviceVo> list(SmsbItemPushDeviceBo bo, PageQuery pageQuery) {
+        return smsbItemPushDeviceService.queryPageList(bo, pageQuery);
     }
 
-    /**
+
+
+    *//**
      * 导出内容发布设备列表
-     */
+     *//*
     @Log(title = "内容发布设备", businessType = BusinessType.EXPORT)
     @PostMapping("/export")
     public void export(SmsbItemPushDeviceBo bo, HttpServletResponse response) {
@@ -62,20 +55,20 @@ public class SmsbItemPushDeviceController extends BaseController {
         ExcelUtil.exportExcel(list, "内容发布设备", SmsbItemPushDeviceVo.class, response);
     }
 
-    /**
+    *//**
      * 获取内容发布设备详细信息
      *
      * @param id 主键
-     */
+     *//*
     @GetMapping("/{id}")
     public R<SmsbItemPushDeviceVo> getInfo(@NotNull(message = "主键不能为空")
                                            @PathVariable Long id) {
         return R.ok(smsbItemPushDeviceService.queryById(id));
     }
 
-    /**
+    *//**
      * 新增内容发布设备
-     */
+     *//*
     @Log(title = "内容发布设备", businessType = BusinessType.INSERT)
     @RepeatSubmit()
     @PostMapping()
@@ -83,9 +76,9 @@ public class SmsbItemPushDeviceController extends BaseController {
         return toAjax(smsbItemPushDeviceService.insertByBo(bo));
     }
 
-    /**
+    *//**
      * 修改内容发布设备
-     */
+     *//*
     @Log(title = "内容发布设备", businessType = BusinessType.UPDATE)
     @RepeatSubmit()
     @PutMapping()
@@ -93,11 +86,11 @@ public class SmsbItemPushDeviceController extends BaseController {
         return toAjax(smsbItemPushDeviceService.updateByBo(bo));
     }
 
-    /**
+    *//**
      * 删除内容发布设备
      *
      * @param ids 主键串
-     */
+     *//*
     @Log(title = "内容发布设备", businessType = BusinessType.DELETE)
     @DeleteMapping("/{ids}")
     public R<Void> remove(@NotEmpty(message = "主键不能为空")
@@ -105,14 +98,14 @@ public class SmsbItemPushDeviceController extends BaseController {
         return toAjax(smsbItemPushDeviceService.deleteWithValidByIds(List.of(ids), true));
     }
 
-    /**
+    *//**
      * 内容发布设备下架
      *
      * @param bo
-     */
+     *//*
     @Log(title = "内容发布下架", businessType = BusinessType.DELETE)
     @DeleteMapping("/remove")
     public R<Void> pushRemoveDevice(@RequestBody SmsbItemPushDeviceBo bo) {
         return smsbItemPushDeviceService.pushRemoveDevice(bo);
-    }
+    }*/
 }

+ 57 - 0
smsb-modules/smsb-source/src/main/java/com/inspur/source/domain/SmsbItemPushPlayline.java

@@ -0,0 +1,57 @@
+package com.inspur.source.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_item_push_playline
+ *
+ * @author Hao Li
+ * @date 2025-05-09
+ */
+@Data
+@TableName("smsb_item_push_playline")
+public class SmsbItemPushPlayline {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 开始时间
+     */
+    private Date startTime;
+
+    /**
+     * 结束时间
+     */
+    private Date endTime;
+
+    /**
+     * 播单ID
+     */
+    private Long pushId;
+
+    /**
+     * 设备ID
+     */
+    private Long deviceId;
+
+    /**
+     * 创建时间
+     */
+    @TableField(fill = FieldFill.INSERT)
+    private Date createTime;
+
+}

+ 83 - 0
smsb-modules/smsb-source/src/main/java/com/inspur/source/domain/SmsbItemPushPlaylist.java

@@ -0,0 +1,83 @@
+package com.inspur.source.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_item_push_playlist
+ *
+ * @author Hao Li
+ * @date 2025-05-09
+ */
+@Data
+@TableName("smsb_item_push_playlist")
+public class SmsbItemPushPlaylist {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 发布ID
+     */
+    private Long pushId;
+
+    /**
+     * 设备ID
+     */
+    private Long deviceId;
+
+    /**
+     * 发布顺序
+     */
+    private Integer sortNum;
+
+    /**
+     * 发布状态
+     */
+    private Integer pushState;
+
+    /**
+     * 开始日期
+     */
+    private String startDate;
+
+    /**
+     * 结束日期
+     */
+    private String endDate;
+
+    /**
+     * 开始日期
+     */
+    private String startTime;
+
+    /**
+     * 结束日期
+     */
+    private String endTime;
+
+    /**
+     * 每周
+     */
+    private String weekDays;
+
+    /**
+     * 创建时间
+     */
+    @TableField(fill = FieldFill.INSERT)
+    private Date createTime;
+
+
+}

+ 1 - 1
smsb-modules/smsb-source/src/main/java/com/inspur/source/domain/bo/SmsbItemPushBo.java

@@ -31,7 +31,7 @@ public class SmsbItemPushBo extends BaseEntity {
     private String name;
 
     /**
-     * 优先级 1-垫片 2-常规 3-紧急
+     * 优先级 100-垫片 200-常规 300-紧急
      */
     private Integer level;
 

+ 56 - 0
smsb-modules/smsb-source/src/main/java/com/inspur/source/domain/bo/SmsbItemPushPlaylineBo.java

@@ -0,0 +1,56 @@
+package com.inspur.source.domain.bo;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.inspur.source.domain.SmsbItemPushPlayline;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+
+import java.util.Date;
+
+/**
+ * 节目播放时序业务对象 smsb_item_push_playline
+ *
+ * @author Hao Li
+ * @date 2025-05-09
+ */
+@Data
+@AutoMapper(target = SmsbItemPushPlayline.class, reverseConvertGenerate = false)
+public class SmsbItemPushPlaylineBo  {
+
+    /**
+     * 主键ID
+     */
+    private Long id;
+
+    /**
+     * 开始时间
+     */
+    private Date startTime;
+
+    /**
+     * 结束时间
+     */
+    private Date endTime;
+
+    /**
+     * 播单ID
+     */
+    private Long pushId;
+
+    /**
+     * 设备ID
+     */
+    private Long deviceId;
+
+    /**
+     * 创建时间
+     */
+    @TableField(fill = FieldFill.INSERT)
+    private Date createTime;
+
+
+
+}

+ 74 - 0
smsb-modules/smsb-source/src/main/java/com/inspur/source/domain/bo/SmsbItemPushPlaylistBo.java

@@ -0,0 +1,74 @@
+package com.inspur.source.domain.bo;
+
+import com.inspur.source.domain.SmsbItemPushPlaylist;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+
+import java.util.Date;
+
+/**
+ * 节目播放单业务对象 smsb_item_push_playlist
+ *
+ * @author Hao Li
+ * @date 2025-05-09
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = SmsbItemPushPlaylist.class, reverseConvertGenerate = false)
+public class SmsbItemPushPlaylistBo extends BaseEntity {
+
+    private Long id;
+
+    /**
+     * 发布ID
+     */
+    private Long pushId;
+
+    /**
+     * 设备ID
+     */
+    private Long deviceId;
+
+    /**
+     * 发布顺序
+     */
+    private Integer sortNum;
+
+    /**
+     * 发布状态
+     */
+    private Integer pushState;
+
+    /**
+     * 开始日期
+     */
+    private String startDate;
+
+    /**
+     * 结束日期
+     */
+    private String endDate;
+
+    /**
+     * 开始日期
+     */
+    private String startTime;
+
+    /**
+     * 结束日期
+     */
+    private String endTime;
+
+    /**
+     * 每周
+     */
+    private String weekDays;
+
+    /**
+     * 创建时间
+     */
+    private Date createTime;
+
+}

+ 5 - 1
smsb-modules/smsb-source/src/main/java/com/inspur/source/domain/vo/FrontPushInfoVo.java

@@ -40,7 +40,11 @@ public class FrontPushInfoVo {
     /**
      * 时间段
      */
-    private List<SmsbItemPushTimeRangeBo> timeRange;
+    // private List<SmsbItemPushTimeRangeBo> timeRange;
+
+    private String startTime;
+
+    private String endTime;
 
     /**
      * 周

+ 22 - 0
smsb-modules/smsb-source/src/main/java/com/inspur/source/domain/vo/ResponseBaseBean.java

@@ -0,0 +1,22 @@
+package com.inspur.source.domain.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 接口返回 定义new
+ * @author lihao16
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class ResponseBaseBean<T> {
+
+    private Integer code;
+
+    private String msg;
+
+    private T data;
+
+}

+ 68 - 0
smsb-modules/smsb-source/src/main/java/com/inspur/source/domain/vo/SmsbItemPushPlaylineVo.java

@@ -0,0 +1,68 @@
+package com.inspur.source.domain.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.inspur.source.domain.SmsbItemPushPlayline;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+
+/**
+ * 节目播放时序视图对象 smsb_item_push_playline
+ *
+ * @author Hao Li
+ * @date 2025-05-09
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = SmsbItemPushPlayline.class)
+public class SmsbItemPushPlaylineVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @ExcelProperty(value = "主键ID")
+    private Long id;
+
+    /**
+     * 开始时间
+     */
+    @ExcelProperty(value = "开始时间")
+    private Date startTime;
+
+    /**
+     * 结束时间
+     */
+    @ExcelProperty(value = "结束时间")
+    private Date endTime;
+
+    /**
+     * 播单ID
+     */
+    @ExcelProperty(value = "播单ID")
+    private Long pushId;
+
+    /**
+     * 设备ID
+     */
+    @ExcelProperty(value = "设备ID")
+    private Long deviceId;
+
+    /**
+     * 创建时间
+     */
+    @ExcelProperty(value = "创建时间")
+    private Date createTime;
+
+    /** 标识符 0-开始 1-结束 */
+    private Integer startFlag;
+
+
+}

+ 85 - 0
smsb-modules/smsb-source/src/main/java/com/inspur/source/domain/vo/SmsbItemPushPlaylistVo.java

@@ -0,0 +1,85 @@
+package com.inspur.source.domain.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.inspur.source.domain.SmsbItemPushPlaylist;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+
+/**
+ * 节目播放单视图对象 smsb_item_push_playlist
+ *
+ * @author Hao Li
+ * @date 2025-05-09
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = SmsbItemPushPlaylist.class)
+public class SmsbItemPushPlaylistVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    private Long id;
+
+    /**
+     * 发布ID
+     */
+    private Long pushId;
+
+    /**
+     * 设备ID
+     */
+    private Long deviceId;
+
+    private String deviceName;
+
+    /**
+     * 发布顺序
+     */
+    private Integer sortNum;
+
+    /**
+     * 发布状态
+     */
+    private Integer pushState;
+
+    /**
+     * 开始日期
+     */
+    private String startDate;
+
+    /**
+     * 结束日期
+     */
+    private String endDate;
+
+    /**
+     * 开始日期
+     */
+    private String startTime;
+
+    /**
+     * 结束日期
+     */
+    private String endTime;
+
+    /**
+     * 每周
+     */
+    private String weekDays;
+
+    /**
+     * 创建时间
+     */
+    private Date createTime;
+
+
+}

+ 30 - 0
smsb-modules/smsb-source/src/main/java/com/inspur/source/domain/vo/ValidatePushTimeVo.java

@@ -0,0 +1,30 @@
+package com.inspur.source.domain.vo;
+
+import lombok.Data;
+
+/**
+ * 内容发布 校验播单时间冲突结果返回
+ * @author lihao16
+ */
+@Data
+public class ValidatePushTimeVo {
+
+    /** 冲突设备 */
+    private String deviceName;
+
+    /** 新发布时间 */
+    private String newPushTime;
+
+    /** 冲突播单名称*/
+    private String clashPushName;
+
+    /** 冲突播单等级 */
+    private Integer clashPushLevel;
+
+    /** 冲突播单时间 */
+    private String clashPushTime;
+
+    /** 冲突时间 */
+    private String clashTime;
+
+}

+ 7 - 0
smsb-modules/smsb-source/src/main/java/com/inspur/source/mapper/SmsbItemPushMapper.java

@@ -49,4 +49,11 @@ public interface SmsbItemPushMapper extends BaseMapperPlus<SmsbItemPush, SmsbIte
      */
     @InterceptorIgnore(tenantLine = "true", dataPermission = "false")
     Page<SmsbItemPushVo> selectFlowFinishList(@Param("page") Page<SmsbItemPush> page, @Param("bo") SmsbItemPushBo bo);
+
+    /**
+     * 节目下发 - 查询设备在播节目
+     * @param deviceId
+     * @return
+     */
+    // SmsbItemPushVo selectDeviceNowPlayPush(@Param("deviceId") String deviceId);
 }

+ 28 - 0
smsb-modules/smsb-source/src/main/java/com/inspur/source/mapper/SmsbItemPushPlaylineMapper.java

@@ -0,0 +1,28 @@
+package com.inspur.source.mapper;
+
+import com.inspur.source.domain.SmsbItemPushPlayline;
+import com.inspur.source.domain.vo.SmsbItemPushPlaylineVo;
+import org.apache.ibatis.annotations.Param;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+import java.util.List;
+
+/**
+ * 节目播放时序Mapper接口
+ *
+ * @author Hao Li
+ * @date 2025-05-09
+ */
+public interface SmsbItemPushPlaylineMapper extends BaseMapperPlus<SmsbItemPushPlayline, SmsbItemPushPlaylineVo> {
+
+    /**
+     * 查询某个设备在某个时间段内的所有节点
+     * @param startTime
+     * @param endTime
+     * @param deviceId
+     * @return
+     */
+    List<SmsbItemPushPlaylineVo> selectExistTimeNodes(@Param("startTime") String startTime, @Param("endTime") String endTime,
+                                                      @Param("deviceId") Long deviceId);
+
+}

+ 26 - 0
smsb-modules/smsb-source/src/main/java/com/inspur/source/mapper/SmsbItemPushPlaylistMapper.java

@@ -0,0 +1,26 @@
+package com.inspur.source.mapper;
+
+import com.inspur.source.domain.SmsbItemPushPlaylist;
+import com.inspur.source.domain.vo.SmsbItemPushPlaylistVo;
+import org.apache.ibatis.annotations.Param;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+import java.util.List;
+
+/**
+ * 节目播放单Mapper接口
+ *
+ * @author Hao Li
+ * @date 2025-05-09
+ */
+public interface SmsbItemPushPlaylistMapper extends BaseMapperPlus<SmsbItemPushPlaylist, SmsbItemPushPlaylistVo> {
+
+    /**
+     * 根据推送id查询节目播放单设备列表
+     *
+     * @param pushId
+     * @return
+     */
+    List<SmsbItemPushPlaylistVo> selectDeviceListByPushId(@Param("pushId") Long pushId);
+
+}

+ 18 - 14
smsb-modules/smsb-source/src/main/java/com/inspur/source/service/ISmsbItemPushDeviceService.java

@@ -1,12 +1,8 @@
 package com.inspur.source.service;
 
-import com.inspur.source.domain.bo.SmsbItemPushDeviceBo;
-import com.inspur.source.domain.vo.SmsbItemPushDeviceVo;
-import org.dromara.common.core.domain.R;
-import org.dromara.common.mybatis.core.page.PageQuery;
-import org.dromara.common.mybatis.core.page.TableDataInfo;
+import com.inspur.source.domain.bo.SmsbItemPushPlaylistBo;
+import com.inspur.source.domain.vo.SmsbItemPushPlaylistVo;
 
-import java.util.Collection;
 import java.util.List;
 
 /**
@@ -17,13 +13,21 @@ import java.util.List;
  */
 public interface ISmsbItemPushDeviceService {
 
+    /**
+     * 查询内容发布设备列表
+     *
+     * @param bo 查询条件
+     * @return 内容发布设备列表
+     */
+    List<SmsbItemPushPlaylistVo> getPushDeviceList(SmsbItemPushPlaylistBo bo);
+
     /**
      * 查询内容发布设备
      *
      * @param id 主键
      * @return 内容发布设备
      */
-    SmsbItemPushDeviceVo queryById(Long id);
+    // SmsbItemPushDeviceVo queryById(Long id);
 
     /**
      * 分页查询内容发布设备列表
@@ -32,7 +36,7 @@ public interface ISmsbItemPushDeviceService {
      * @param pageQuery 分页参数
      * @return 内容发布设备分页列表
      */
-    TableDataInfo<SmsbItemPushDeviceVo> queryPageList(SmsbItemPushDeviceBo bo, PageQuery pageQuery);
+    // TableDataInfo<SmsbItemPushDeviceVo> queryPageList(SmsbItemPushDeviceBo bo, PageQuery pageQuery);
 
     /**
      * 查询符合条件的内容发布设备列表
@@ -40,9 +44,9 @@ public interface ISmsbItemPushDeviceService {
      * @param bo 查询条件
      * @return 内容发布设备列表
      */
-    List<SmsbItemPushDeviceVo> queryList(SmsbItemPushDeviceBo bo);
+    // List<SmsbItemPushDeviceVo> queryList(SmsbItemPushDeviceBo bo);
+
 
-    TableDataInfo<SmsbItemPushDeviceVo> queryPageListV2(SmsbItemPushDeviceBo bo,PageQuery pageQuery);
 
 
     /**
@@ -51,7 +55,7 @@ public interface ISmsbItemPushDeviceService {
      * @param bo 内容发布设备
      * @return 是否新增成功
      */
-    Boolean insertByBo(SmsbItemPushDeviceBo bo);
+    // Boolean insertByBo(SmsbItemPushDeviceBo bo);
 
     /**
      * 修改内容发布设备
@@ -59,7 +63,7 @@ public interface ISmsbItemPushDeviceService {
      * @param bo 内容发布设备
      * @return 是否修改成功
      */
-    Boolean updateByBo(SmsbItemPushDeviceBo bo);
+    // Boolean updateByBo(SmsbItemPushDeviceBo bo);
 
     /**
      * 校验并批量删除内容发布设备信息
@@ -68,12 +72,12 @@ public interface ISmsbItemPushDeviceService {
      * @param isValid 是否进行有效性校验
      * @return 是否删除成功
      */
-    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+    // Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
 
     /**
      * 内容发布下架
      * @param bo
      * @return
      */
-    public R<Void> pushRemoveDevice(SmsbItemPushDeviceBo bo);
+    // public R<Void> pushRemoveDevice(SmsbItemPushDeviceBo bo);
 }

+ 17 - 2
smsb-modules/smsb-source/src/main/java/com/inspur/source/service/ISmsbItemPushService.java

@@ -1,5 +1,6 @@
 package com.inspur.source.service;
 
+import com.inspur.source.domain.SmsbItemPush;
 import com.inspur.source.domain.vo.*;
 import com.inspur.source.domain.bo.SmsbItemPushBo;
 import org.dromara.common.core.domain.R;
@@ -50,7 +51,7 @@ public interface ISmsbItemPushService {
      * @param bo 内容发布
      * @return 是否新增成功
      */
-    Boolean insertByBo(SmsbItemPushBo bo);
+    R<Void> insertByBo(SmsbItemPushBo bo);
 
     /**
      * 修改内容发布
@@ -80,7 +81,7 @@ public interface ISmsbItemPushService {
      * @param identifier
      * @return
      */
-    R<FrontPushInfoVo> getItemPushInfo(String identifier);
+    R<List<FrontPushInfoVo>> getItemPushInfo(String identifier);
 
     /**
      * 更新下发结果
@@ -127,4 +128,18 @@ public interface ISmsbItemPushService {
      * @return 结果
      */
     boolean terminationTask(TerminationBo terminationBo);
+
+    /**
+     * 新增发布校验时间冲突
+     * @param bo
+     * @return
+     */
+    R<ResponseBaseBean> validateTime(SmsbItemPushBo bo);
+
+    /**
+     * 更新时间时序
+     * @param smsbItemPush
+     * @return
+     */
+    void updatePlayLine(SmsbItemPush smsbItemPush);
 }

+ 36 - 31
smsb-modules/smsb-source/src/main/java/com/inspur/source/service/impl/SmsbItemPushDeviceServiceImpl.java

@@ -12,8 +12,11 @@ import com.inspur.netty.message.push.PushMessageType;
 import com.inspur.netty.util.PushMsgUtil;
 import com.inspur.source.domain.SmsbItemPushDevice;
 import com.inspur.source.domain.bo.SmsbItemPushDeviceBo;
+import com.inspur.source.domain.bo.SmsbItemPushPlaylistBo;
 import com.inspur.source.domain.vo.SmsbItemPushDeviceVo;
+import com.inspur.source.domain.vo.SmsbItemPushPlaylistVo;
 import com.inspur.source.mapper.SmsbItemPushDeviceMapper;
+import com.inspur.source.mapper.SmsbItemPushPlaylistMapper;
 import com.inspur.source.service.ISmsbItemPushDeviceService;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
@@ -25,9 +28,8 @@ import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * 内容发布设备Service业务层处理
@@ -40,10 +42,7 @@ import java.util.Map;
 @Slf4j
 public class SmsbItemPushDeviceServiceImpl implements ISmsbItemPushDeviceService {
 
-    private final SmsbItemPushDeviceMapper baseMapper;
-
-    @Autowired
-    private ISmsbDeviceService smsbDeviceService;
+    private final SmsbItemPushPlaylistMapper smsbItemPushPlaylistMapper;
 
     /**
      * 查询内容发布设备
@@ -51,29 +50,35 @@ public class SmsbItemPushDeviceServiceImpl implements ISmsbItemPushDeviceService
      * @param id 主键
      * @return 内容发布设备
      */
-    @Override
+    /*@Override
     public SmsbItemPushDeviceVo queryById(Long id) {
         return baseMapper.selectVoById(id);
-    }
+    }*/
 
     /**
      * 分页查询内容发布设备列表
      *
      * @param bo        查询条件
-     * @param pageQuery 分页参数
      * @return 内容发布设备分页列表
      */
-    @Override
+    /*@Override
     public TableDataInfo<SmsbItemPushDeviceVo> queryPageList(SmsbItemPushDeviceBo bo, PageQuery pageQuery) {
         LambdaQueryWrapper<SmsbItemPushDevice> lqw = buildQueryWrapper(bo);
         Page<SmsbItemPushDeviceVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
         return TableDataInfo.build(result);
-    }
+    }*/
 
     @Override
-    public TableDataInfo<SmsbItemPushDeviceVo> queryPageListV2(SmsbItemPushDeviceBo bo,PageQuery pageQuery) {
-        Page<SmsbItemPushDeviceVo> result = baseMapper.selectVoListV2(bo.getPushId(),pageQuery.build());
-        return TableDataInfo.build(result);
+    public List<SmsbItemPushPlaylistVo> getPushDeviceList(SmsbItemPushPlaylistBo bo) {
+        List<SmsbItemPushPlaylistVo> results = smsbItemPushPlaylistMapper.selectDeviceListByPushId(bo.getPushId());
+        if (CollectionUtil.isEmpty(results)) {
+            return results;
+        }
+        // 更具设备ID进行去重
+        List<SmsbItemPushPlaylistVo> distinctResults = results.stream()
+            .collect(Collectors.collectingAndThen(Collectors.toCollection(() ->
+                new TreeSet<>(Comparator.comparing(SmsbItemPushPlaylistVo::getDeviceId))), ArrayList::new));
+        return distinctResults;
     }
 
     /**
@@ -82,15 +87,15 @@ public class SmsbItemPushDeviceServiceImpl implements ISmsbItemPushDeviceService
      * @param bo 查询条件
      * @return 内容发布设备列表
      */
-    @Override
+    /*@Override
     public List<SmsbItemPushDeviceVo> queryList(SmsbItemPushDeviceBo bo) {
         LambdaQueryWrapper<SmsbItemPushDevice> lqw = buildQueryWrapper(bo);
         return baseMapper.selectVoList(lqw);
-    }
+    }*/
 
 
 
-    private LambdaQueryWrapper<SmsbItemPushDevice> buildQueryWrapper(SmsbItemPushDeviceBo bo) {
+    /*private LambdaQueryWrapper<SmsbItemPushDevice> buildQueryWrapper(SmsbItemPushDeviceBo bo) {
         Map<String, Object> params = bo.getParams();
         LambdaQueryWrapper<SmsbItemPushDevice> lqw = Wrappers.lambdaQuery();
         lqw.eq(bo.getPushId() != null, SmsbItemPushDevice::getPushId, bo.getPushId());
@@ -98,7 +103,7 @@ public class SmsbItemPushDeviceServiceImpl implements ISmsbItemPushDeviceService
         lqw.eq(bo.getSortNum() != null, SmsbItemPushDevice::getSortNum, bo.getSortNum());
         lqw.eq(bo.getPushState() != null, SmsbItemPushDevice::getPushState, bo.getPushState());
         return lqw;
-    }
+    }*/
 
     /**
      * 新增内容发布设备
@@ -106,7 +111,7 @@ public class SmsbItemPushDeviceServiceImpl implements ISmsbItemPushDeviceService
      * @param bo 内容发布设备
      * @return 是否新增成功
      */
-    @Override
+    /*@Override
     public Boolean insertByBo(SmsbItemPushDeviceBo bo) {
         SmsbItemPushDevice add = MapstructUtils.convert(bo, SmsbItemPushDevice.class);
         validEntityBeforeSave(add);
@@ -115,7 +120,7 @@ public class SmsbItemPushDeviceServiceImpl implements ISmsbItemPushDeviceService
             bo.setId(add.getId());
         }
         return flag;
-    }
+    }*/
 
     /**
      * 修改内容发布设备
@@ -123,19 +128,19 @@ public class SmsbItemPushDeviceServiceImpl implements ISmsbItemPushDeviceService
      * @param bo 内容发布设备
      * @return 是否修改成功
      */
-    @Override
+    /*@Override
     public Boolean updateByBo(SmsbItemPushDeviceBo bo) {
         SmsbItemPushDevice update = MapstructUtils.convert(bo, SmsbItemPushDevice.class);
         validEntityBeforeSave(update);
         return baseMapper.updateById(update) > 0;
     }
-
+*/
     /**
      * 保存前的数据校验
      */
-    private void validEntityBeforeSave(SmsbItemPushDevice entity) {
+    /*private void validEntityBeforeSave(SmsbItemPushDevice entity) {
         //TODO 做一些数据校验,如唯一约束
-    }
+    }*/
 
     /**
      * 校验并批量删除内容发布设备信息
@@ -144,15 +149,15 @@ public class SmsbItemPushDeviceServiceImpl implements ISmsbItemPushDeviceService
      * @param isValid 是否进行有效性校验
      * @return 是否删除成功
      */
-    @Override
+    /*@Override
     public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
         if (isValid) {
             //TODO 做一些业务上的校验,判断是否需要校验
         }
         return baseMapper.deleteByIds(ids) > 0;
-    }
+    }*/
 
-    @Override
+    /*@Override
     public R<Void> pushRemoveDevice(SmsbItemPushDeviceBo bo) {
         if (CollectionUtil.isEmpty(bo.getDeviceIds())) {
             return R.fail(Integer.parseInt(ResultCodeEnum.DEVICE_IDS_IS_NULL.getValue()), ResultCodeEnum.DEVICE_IDS_IS_NULL.getMessage());
@@ -168,9 +173,9 @@ public class SmsbItemPushDeviceServiceImpl implements ISmsbItemPushDeviceService
             pushRemoveMessage(deviceId, bo.getPushId());
         }
         return R.ok();
-    }
+    }*/
 
-    private void pushRemoveMessage(Long deviceId, Long pushId) {
+    /*private void pushRemoveMessage(Long deviceId, Long pushId) {
         SmsbDeviceVo deviceVo = smsbDeviceService.getDeviceCacheById(deviceId);
         if (null == deviceVo) {
             return;
@@ -179,5 +184,5 @@ public class SmsbItemPushDeviceServiceImpl implements ISmsbItemPushDeviceService
         String nettyMessage = PushMessageType.CONTENT_REMOVE.getValue() + "/" + pushId;
         boolean pushResult = PushMsgUtil.sendV2(identifier, nettyMessage);
         log.info("push content remove identifier: {}, result:{}", identifier, pushResult);
-    }
+    }*/
 }

+ 338 - 143
smsb-modules/smsb-source/src/main/java/com/inspur/source/service/impl/SmsbItemPushServiceImpl.java

@@ -2,14 +2,21 @@ package com.inspur.source.service.impl;
 
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.date.DateField;
+import cn.hutool.core.date.DatePattern;
+import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
 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.SmsbDevice;
+import com.inspur.device.domain.SmsbDeviceTask;
+import com.inspur.device.domain.constants.DeviceTaskConstants;
+import com.inspur.device.domain.constants.ResultCodeEnum;
 import com.inspur.device.domain.vo.SmsbDeviceVo;
 import com.inspur.device.mapper.SmsbDeviceMapper;
+import com.inspur.device.mapper.SmsbDeviceTaskMapper;
 import com.inspur.device.service.ISmsbDeviceService;
 import com.inspur.netty.message.push.PushMessageType;
 import com.inspur.netty.util.PushMsgUtil;
@@ -21,6 +28,7 @@ import com.inspur.source.mapper.*;
 import com.inspur.source.service.ISmsbItemPushService;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.core.constant.HttpStatus;
 import org.dromara.common.core.domain.R;
 import org.dromara.common.core.domain.event.ProcessEvent;
 import org.dromara.common.core.domain.event.ProcessTaskEvent;
@@ -85,16 +93,19 @@ public class SmsbItemPushServiceImpl implements ISmsbItemPushService {
 
     private final SmsbItemPushMapper baseMapper;
     private final SmsbItemPushTimeMapper itemPushTimeMapper;
-    private final SmsbItemPushDeviceMapper itemPushDeviceMapper;
     private final SmsbItemPushRelMapper itemPushRelMapper;
     private final SmsbItemFileRelMapper itemFileRelMapper;
     private final SmsbItemSplitScreenMapper itemSplitScreenMapper;
     private final SmsbItemMapper itemMapper;
+    private final SmsbItemPushPlaylistMapper smsbItemPushPlaylistMapper;
+    private final SmsbItemPushPlaylineMapper smsbItemPushPlaylineMapper;
     @Autowired
     private ISmsbDeviceService smsbDeviceService;
     @Autowired
     private SmsbDeviceMapper smsbDeviceMapper;
     @Autowired
+    private SmsbDeviceTaskMapper smsbDeviceTaskMapper;
+    @Autowired
     private IActTaskService actTaskService;
     @Autowired
     private FlowProcessEventHandler flowProcessEventHandler;
@@ -137,15 +148,15 @@ public class SmsbItemPushServiceImpl implements ISmsbItemPushService {
             reviewVo.setResourceList(sourceList);
         }
 
-        List<SmsbItemPushTimeVo> pushTimeList = itemPushTimeMapper.selectVoList(new LambdaQueryWrapper<SmsbItemPushTime>()
-            .eq(SmsbItemPushTime::getPushId, pushId));
-        String dateStart = pushTimeList.get(0).getStartDate();
-        String dateEnd = pushTimeList.get(0).getEndDate();
+        List<SmsbItemPushPlaylistVo> pushPlaylistVos = smsbItemPushPlaylistMapper.selectVoList(new LambdaQueryWrapper<SmsbItemPushPlaylist>()
+            .eq(SmsbItemPushPlaylist::getPushId, pushId));
+        String dateStart = pushPlaylistVos.get(0).getStartDate();
+        String dateEnd = pushPlaylistVos.get(0).getEndDate();
         List<SmsbItemPushTimeRangeBo> timeRangeList = new ArrayList<>();
-        for (SmsbItemPushTimeVo pushTime : pushTimeList) {
+        for (SmsbItemPushPlaylistVo pushTime : pushPlaylistVos) {
             SmsbItemPushTimeRangeBo timeRange = new SmsbItemPushTimeRangeBo();
-            timeRange.setStart(dateStart + " " + pushTime.getTimeStart());
-            timeRange.setEnd(dateEnd + " " + pushTime.getTimeEnd());
+            timeRange.setStart(dateStart + " " + pushTime.getStartTime());
+            timeRange.setEnd(dateEnd + " " + pushTime.getEndTime());
             timeRangeList.add(timeRange);
         }
         reviewVo.setTimeList(timeRangeList);
@@ -192,6 +203,36 @@ public class SmsbItemPushServiceImpl implements ISmsbItemPushService {
         return lqw;
     }
 
+    @Override
+    public R<ResponseBaseBean> validateTime(SmsbItemPushBo bo) {
+
+        ResponseBaseBean result = new ResponseBaseBean();
+        result.setCode(HttpStatus.SUCCESS);
+        List<ValidatePushTimeVo> validatePushTimeVos = new ArrayList<>();
+        result.setData(validatePushTimeVos);
+        // 遍历每个设备
+        List<String> deviceIds = bo.getDeviceIds();
+        for (String deviceId : deviceIds) {
+            // 1、判断日期是否与时序冲突
+            String startDateStr = bo.getDateRange().get(0) + " 00:00:00";
+            String endDateStr = bo.getDateRange().get(1) + " 23:59:59";
+            List<SmsbItemPushPlaylineVo> exitsTimeNodes = smsbItemPushPlaylineMapper.selectExistTimeNodes(startDateStr,endDateStr,Long.parseLong(deviceId));
+            // exitsTimeNodes 为空说明没冲突
+            if (CollectionUtil.isEmpty(exitsTimeNodes)) {
+                continue;
+            }
+            ValidatePushTimeVo validateVo = new ValidatePushTimeVo();
+            validateVo.setDeviceName(smsbDeviceService.getDeviceCacheById(Long.parseLong(deviceId)).getName());
+            validatePushTimeVos.add(validateVo);
+        }
+        if (!CollectionUtil.isEmpty(validatePushTimeVos)) {
+            result.setCode(Integer.parseInt(ResultCodeEnum.PUSH_TIME_CLASH.getValue()));
+            result.setData(validatePushTimeVos);
+        }
+
+        return R.ok(result);
+    }
+
     /**
      * 新增内容发布
      *
@@ -200,30 +241,53 @@ public class SmsbItemPushServiceImpl implements ISmsbItemPushService {
      */
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public Boolean insertByBo(SmsbItemPushBo bo) {
+    public R<Void> insertByBo(SmsbItemPushBo bo) {
         SmsbItemPush add = MapstructUtils.convert(bo, SmsbItemPush.class);
         add.setStatus(BusinessStatusEnum.DRAFT.getStatus());
         add.setCreateUser(LoginHelper.getLoginUser().getUsername());
-        validEntityBeforeSave(add);
-        Date startDate = DateUtils.parseDate(bo.getDateRange().get(0));
-        Date endDate = DateUtils.parseDate(bo.getDateRange().get(1));
+        Date startDate = DateUtils.parseDate(bo.getDateRange().get(0) + " 00:00:00");
+        Date endDate = DateUtils.parseDate(bo.getDateRange().get(1) + " 23:59:59");
         add.setStartDate(startDate);
         add.setEndDate(endDate);
         boolean flag = baseMapper.insert(add) > 0;
         if (!flag) {
-            return flag;
+            R.fail(ResultCodeEnum.INTERNAL_SERVER_ERROR);
         }
         bo.setId(add.getId());
-        // 保存内容时间排期
-        addItemPushTime(bo);
-        // 保存发布设备
-        addItemPushDevice(bo);
-        // 轮播组 分屏组
+        // 保存设备内容播放单
+        saveItemPushPlaylist(bo);
+        // 轮播组 分屏组关联保存
         if (bo.getItemType() == 1 || bo.getItemType() == 2) {
             addItemPushRel(bo.getId(), bo.getItemIds());
         }
         submitReview(add.getId());
-        return flag;
+        return R.ok();
+    }
+
+    private void saveItemPushPlaylist(SmsbItemPushBo bo) {
+        List<String> deviceIds = bo.getDeviceIds();
+        if (CollectionUtil.isEmpty(deviceIds)) {
+            return;
+        }
+        Integer sortNum = 0;
+        for (String deviceId : deviceIds) {
+            List<SmsbItemPushPlaylist> pushPlaylist = new ArrayList<>();
+            sortNum++;
+            for (SmsbItemPushTimeRangeBo smsbItemPushTimeRangeBo : bo.getTimeRange()) {
+                SmsbItemPushPlaylist onePlayList = new SmsbItemPushPlaylist();
+                onePlayList.setPushId(bo.getId());
+                onePlayList.setDeviceId(Long.parseLong(deviceId));
+                onePlayList.setSortNum(sortNum);
+                onePlayList.setPushState(1);
+                onePlayList.setStartTime(getHourTimeStrByUTC(smsbItemPushTimeRangeBo.getStart()));
+                onePlayList.setEndTime(getHourTimeStrByUTC(smsbItemPushTimeRangeBo.getEnd()));
+                onePlayList.setStartDate(bo.getDateRange().get(0));
+                onePlayList.setEndDate(bo.getDateRange().get(1));
+                onePlayList.setWeekDays(String.join(",", bo.getWeekDays()));
+                pushPlaylist.add(onePlayList);
+            }
+            smsbItemPushPlaylistMapper.insertBatch(pushPlaylist);
+        }
     }
 
     @Override
@@ -276,34 +340,244 @@ public class SmsbItemPushServiceImpl implements ISmsbItemPushService {
         }
         // 更新内容发布状态
         baseMapper.updateById(smsbItemPush);
-        // 如果是finnish 发布netty消息 推送长连接消息 记录每个设备的下发状态
+        // 如果是finnish
         if (status.equals(BusinessStatusEnum.FINISH.getStatus())) {
-            List<Long> deviceIds = itemPushDeviceMapper.selectList(new LambdaQueryWrapper<SmsbItemPushDevice>()
-                .eq(SmsbItemPushDevice::getPushId, smsbItemPush.getId())).stream().map(SmsbItemPushDevice::getDeviceId).collect(Collectors.toList());
-            List<String> deviceIdsAsString = deviceIds.stream().map(String::valueOf).collect(Collectors.toList());
-            pushNettyMsg(deviceIdsAsString, smsbItemPush.getId());
+            // 新发布的播单内容
+            List<SmsbItemPushPlaylistVo> smsbItemPushPlaylists = smsbItemPushPlaylistMapper.selectDeviceListByPushId(smsbItemPush.getId());
+            if (CollectionUtil.isEmpty(smsbItemPushPlaylists)) {
+                return;
+            }
+            // 获取所有设备ID
+            List<Long> deviceIds = smsbItemPushPlaylists.stream().map(SmsbItemPushPlaylistVo::getDeviceId).collect(Collectors.toList()).stream().distinct().collect(Collectors.toList());
+            // 1-更新时序
+            updatePlayLine(smsbItemPush);
+            // 2-任务中心创建任务
+            createDeviceTask(deviceIds,smsbItemPush);
+            // 3-发送长连接
+            pushNettyMsg(deviceIds);
         }
     }
 
-    @EventListener(condition = "#processTaskEvent.key.startsWith('review')")
-    public void processTaskHandler(ProcessTaskEvent processTaskEvent) {
-        log.info("processTaskHandler : 当前任务执行了{}", processTaskEvent.toString());
+    private void createDeviceTask(List<Long> deviceIds,SmsbItemPush smsbItemPush) {
+        if (CollectionUtil.isEmpty(deviceIds)) {
+            return;
+        }
+        List<SmsbDeviceTask> insertList = new ArrayList<>();
+        for (Long deviceId : deviceIds) {
+            SmsbDeviceVo smsbDeviceVo = smsbDeviceService.getDeviceCacheById(deviceId);
+            // 创建任务
+            SmsbDeviceTask deviceTask = new SmsbDeviceTask();
+            deviceTask.setIdentifier(smsbDeviceVo.getIdentifier());
+            deviceTask.setDeviceId(smsbDeviceVo.getId());
+            deviceTask.setTaskType(DeviceTaskConstants.DEVICE_TASK_PLAY_LINE_UPDATE);
+            deviceTask.setTaskParam(smsbItemPush.getId().toString());
+            deviceTask.setIsEnd(0);
+            insertList.add(deviceTask);
+        }
+        smsbDeviceTaskMapper.insertBatch(insertList);
     }
 
-    private void pushNettyMsg(List<String> deviceIds, Long pushId) {
-        List<SmsbDevice> smsbDevices = smsbDeviceMapper.selectByIds(deviceIds);
-        for (SmsbDevice smsbDevice : smsbDevices) {
-            // 1 redis 缓存预加载
-            cachePushInfo(smsbDevice.getIdentifier());
-            // 2 发送长连接消息
-            String nettyMessage = PushMessageType.CONTENT_UPDATE.getValue() + "/" + pushId;
-            boolean pushResult = PushMsgUtil.sendV2(smsbDevice.getIdentifier(), nettyMessage);
-            log.info("push content update identifier: {}, result:{}", smsbDevice.getIdentifier(), pushResult);
-            // 3 下发成功  更新设备下发状态
-            if (pushResult) {
-                itemPushDeviceMapper.updateDevicePushStatus(pushId, smsbDevice.getId(), 2);
+    private void pushNettyMsg(List<Long> deviceIds) {
+        if (CollectionUtil.isEmpty(deviceIds)) {
+            return;
+        }
+        for (Long deviceId : deviceIds) {
+            // 发送长连接消息
+            String nettyMessage = PushMessageType.CONTENT_UPDATE.getValue();
+            SmsbDeviceVo smsbDeviceVo = smsbDeviceService.getDeviceCacheById(deviceId);
+            boolean pushResult = PushMsgUtil.sendV2(smsbDeviceVo.getIdentifier(), nettyMessage);
+            log.info("push content update identifier: {}, result:{}", smsbDeviceVo.getIdentifier(), pushResult);
+        }
+    }
+
+    @Override
+    public void updatePlayLine(SmsbItemPush smsbItemPush) {
+        Long pushId = smsbItemPush.getId();
+        List<SmsbItemPushPlaylistVo> smsbItemPushPlaylists = smsbItemPushPlaylistMapper.selectDeviceListByPushId(pushId);
+        if (CollectionUtil.isEmpty(smsbItemPushPlaylists)) {
+            return;
+        }
+        // 获取所有设备ID
+        List<Long> deviceIds = smsbItemPushPlaylists.stream().map(SmsbItemPushPlaylistVo::getDeviceId).collect(Collectors.toList()).stream().distinct().collect(Collectors.toList());
+        // 根据一个设备 获取当前发布所有的日期节点
+        List<SmsbItemPushTimeRangeBo> timeRanges = getNewPushAllTimeRanges(smsbItemPushPlaylists,deviceIds.get(0));
+
+        // 获取第一个节点和最后一个节点
+        String firstNode = timeRanges.get(0).getStart();
+        String lastNode = timeRanges.get(timeRanges.size() - 1).getEnd();
+
+        for (Long deviceId : deviceIds) {
+            // 判断整个时间段内是否存在时间点
+            List<SmsbItemPushPlaylineVo> existTimeNodes = smsbItemPushPlaylineMapper.selectExistTimeNodes(firstNode, lastNode,deviceId);
+            // 没有则新增
+            if (CollectionUtil.isEmpty(existTimeNodes)) {
+                List<SmsbItemPushPlayline> allInsert = new ArrayList<>();
+                for (SmsbItemPushTimeRangeBo timeRange : timeRanges) {
+                    SmsbItemPushPlayline oneInsert = new SmsbItemPushPlayline();
+                    oneInsert.setStartTime(DateUtils.parseDate(timeRange.getStart()));
+                    oneInsert.setEndTime(DateUtils.parseDate(timeRange.getEnd()));
+                    oneInsert.setPushId(pushId);
+                    oneInsert.setDeviceId(deviceId);
+                    allInsert.add(oneInsert);
+                }
+                smsbItemPushPlaylineMapper.insertBatch(allInsert);
+                continue;
             }
+            // 如果存在 则进行更新
+            // 对新增的每一天进行遍历
+            List<SmsbItemPushPlayline> needAdd = new ArrayList<>();
+            List<SmsbItemPushPlaylineVo> needRemove = new ArrayList<>();
+            for (SmsbItemPushTimeRangeBo timeRange : timeRanges) {
+                String oneStart = timeRange.getStart();
+                String oneEnd = timeRange.getEnd();
+                // 当前时间的日期
+                String newDate = DateUtils.parseDateToStr(DatePattern.NORM_DATE_PATTERN, DateUtils.parseDate(oneStart));
+                // 对存在的进行遍历 判断时间短是否冲突
+                for (SmsbItemPushPlaylineVo existTimeNode : existTimeNodes) {
+                    String existDate = DateUtils.parseDateToStr(DatePattern.NORM_DATE_PATTERN, existTimeNode.getStartTime());
+                    // 不是同一个日期,不进行判断
+                    if (!newDate.equals(existDate)) {
+                        continue;
+                    }
+                    SmsbItemPushPlayline oneNeedAdd = new SmsbItemPushPlayline();
+                    // 共计六种情况
+                    // 1、无时间冲突 新发布完全早于老发布 或者完全晚于老发布
+                    if (DateUtils.parseDate(oneStart).after(existTimeNode.getEndTime()) || DateUtils.parseDate(oneEnd).before(existTimeNode.getStartTime())) {
+                        // 直接插入
+                        oneNeedAdd.setPushId(pushId);
+                        oneNeedAdd.setDeviceId(deviceId);
+                        oneNeedAdd.setStartTime(DateUtils.parseDate(oneStart));
+                        oneNeedAdd.setEndTime(DateUtils.parseDate(oneEnd));
+                        needAdd.add(oneNeedAdd);
+                    }
+                    // 开始时间向前偏移100毫秒
+                    Date existStartOffset = DateUtil.offset(existTimeNode.getStartTime(), DateField.MILLISECOND, 100);
+                    // 结束时间向后偏移100毫秒
+                    Date existEndOffset = DateUtil.offset(existTimeNode.getEndTime(), DateField.MILLISECOND, -100);
+                    // 2、新发布结束与老发布开始冲突
+                    if (DateUtils.parseDate(oneStart).before(existStartOffset)
+                        && DateUtils.parseDate(oneEnd).after(existStartOffset)
+                        && DateUtils.parseDate(oneEnd).before(existEndOffset)) {
+                        // 删除原有时间
+                        needRemove.add(existTimeNode);
+                        // 拆分成两个
+                        oneNeedAdd.setPushId(pushId);
+                        oneNeedAdd.setDeviceId(deviceId);
+                        oneNeedAdd.setStartTime(DateUtils.parseDate(oneStart));
+                        oneNeedAdd.setEndTime(DateUtils.parseDate(oneEnd));
+                        needAdd.add(oneNeedAdd);
+                        SmsbItemPushPlayline oneNeedAdd2 = new SmsbItemPushPlayline();
+                        oneNeedAdd2.setPushId(existTimeNode.getPushId());
+                        oneNeedAdd2.setDeviceId(deviceId);
+                        oneNeedAdd2.setStartTime(DateUtils.parseDate(oneEnd));
+                        oneNeedAdd2.setEndTime(existTimeNode.getEndTime());
+                        needAdd.add(oneNeedAdd2);
+                    }
+                    // 3、新发布与老发布冲突 老发布完全包含新发布
+                    if (DateUtils.parseDate(oneStart).after(existStartOffset)
+                        && DateUtils.parseDate(oneEnd).before(existEndOffset)) {
+                        // 删除原有时间
+                        needRemove.add(existTimeNode);
+                        // 拆分成3个
+                        oneNeedAdd.setPushId(existTimeNode.getPushId());
+                        oneNeedAdd.setDeviceId(deviceId);
+                        oneNeedAdd.setStartTime(existTimeNode.getStartTime());
+                        oneNeedAdd.setEndTime(DateUtils.parseDate(oneStart));
+                        needAdd.add(oneNeedAdd);
+                        SmsbItemPushPlayline oneNeedAdd2 = new SmsbItemPushPlayline();
+                        oneNeedAdd2.setPushId(pushId);
+                        oneNeedAdd2.setDeviceId(deviceId);
+                        oneNeedAdd2.setStartTime(DateUtils.parseDate(oneStart));
+                        oneNeedAdd2.setEndTime(DateUtils.parseDate(oneEnd));
+                        needAdd.add(oneNeedAdd2);
+                        SmsbItemPushPlayline oneNeedAdd3 = new SmsbItemPushPlayline();
+                        oneNeedAdd3.setPushId(existTimeNode.getPushId());
+                        oneNeedAdd3.setDeviceId(deviceId);
+                        oneNeedAdd3.setStartTime(DateUtils.parseDate(oneEnd));
+                        oneNeedAdd3.setEndTime(existTimeNode.getEndTime());
+                        needAdd.add(oneNeedAdd3);
+                    }
+                    // 4、新发布开始与老发布结束冲突
+                    if (DateUtils.parseDate(oneStart).after(existStartOffset)
+                        && DateUtils.parseDate(oneStart).before(existEndOffset)
+                        && DateUtils.parseDate(oneEnd).after(existEndOffset)) {
+                        // 删除原有时间
+                        needRemove.add(existTimeNode);
+                        // 拆分成2个
+                        oneNeedAdd.setPushId(existTimeNode.getPushId());
+                        oneNeedAdd.setDeviceId(deviceId);
+                        oneNeedAdd.setStartTime(existTimeNode.getStartTime());
+                        oneNeedAdd.setEndTime(DateUtils.parseDate(oneStart));
+                        needAdd.add(oneNeedAdd);
+                        SmsbItemPushPlayline oneNeedAdd2 = new SmsbItemPushPlayline();
+                        oneNeedAdd2.setPushId(pushId);
+                        oneNeedAdd2.setDeviceId(deviceId);
+                        oneNeedAdd2.setStartTime(DateUtils.parseDate(oneStart));
+                        oneNeedAdd2.setEndTime(DateUtils.parseDate(oneEnd));
+                        needAdd.add(oneNeedAdd2);
+                    }
+                    // 5、 新发布完全覆盖老发布
+                    if (DateUtils.parseDate(oneStart).before(existStartOffset) && DateUtils.parseDate(oneEnd).after(existEndOffset)) {
+                        // 删除原有时间
+                        needRemove.add(existTimeNode);
+                        // 直接插入
+                        oneNeedAdd.setPushId(pushId);
+                        oneNeedAdd.setDeviceId(deviceId);
+                        oneNeedAdd.setStartTime(DateUtils.parseDate(oneStart));
+                        oneNeedAdd.setEndTime(DateUtils.parseDate(oneEnd));
+                        needAdd.add(oneNeedAdd);
+                    }
+                }
+
+            }
+            // 需要删除的Ids
+            if (CollectionUtil.isNotEmpty(needRemove)) {
+                List<Long> needRemoveIds = needRemove.stream().map(SmsbItemPushPlaylineVo::getId).collect(Collectors.toList());
+                smsbItemPushPlaylineMapper.deleteByIds(needRemoveIds);
+            }
+            // 需要新增的
+            if (CollectionUtil.isNotEmpty(needAdd)) {
+                // 对需要新增的根据startTime进行去重
+                List<SmsbItemPushPlayline> needAddDistinct = needAdd.stream().collect(
+                    Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(SmsbItemPushPlayline::getStartTime))),
+                        ArrayList::new));
+                smsbItemPushPlaylineMapper.insertBatch(needAddDistinct);
+            }
+
         }
+
+    }
+
+    private List<SmsbItemPushTimeRangeBo> getNewPushAllTimeRanges(List<SmsbItemPushPlaylistVo> smsbItemPushPlaylists,Long deviceId) {
+        List<SmsbItemPushPlaylistVo> oneDevicePlayList = smsbItemPushPlaylists.stream()
+            .filter(item -> item.getDeviceId().equals(deviceId)).collect(Collectors.toList());
+        List<SmsbItemPushTimeRangeBo> dateNodes = new ArrayList<>();
+        LocalDate startDate = LocalDate.parse(smsbItemPushPlaylists.get(0).getStartDate());
+        LocalDate endDate = LocalDate.parse(smsbItemPushPlaylists.get(0).getEndDate());
+
+        // 定义日期格式
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+        // 使用 Stream API // 将 LocalDate 转换为字符串
+        startDate.datesUntil(endDate.plusDays(1)).map(date -> date.format(formatter));
+        // 或者使用传统的 while 循环
+        LocalDate currentDate = startDate;
+        while (!currentDate.isAfter(endDate)) {
+            // 转换为字符串
+            String dateStr = currentDate.format(formatter);
+            for (SmsbItemPushPlaylistVo oneDeviceVo : oneDevicePlayList) {
+                SmsbItemPushTimeRangeBo oneRange = new SmsbItemPushTimeRangeBo();
+                oneRange.setStart(dateStr + " " + oneDeviceVo.getStartTime());
+                oneRange.setEnd(dateStr + " " + oneDeviceVo.getEndTime());
+                dateNodes.add(oneRange);
+            }
+            currentDate = currentDate.plusDays(1);
+        }
+        return dateNodes;
+    }
+
+    @EventListener(condition = "#processTaskEvent.key.startsWith('review')")
+    public void processTaskHandler(ProcessTaskEvent processTaskEvent) {
+        // log.info("processTaskHandler : 当前任务执行了{}", processTaskEvent.toString());
     }
 
     private void addItemPushRel(Long id, List<Long> itemIds) {
@@ -320,48 +594,6 @@ public class SmsbItemPushServiceImpl implements ISmsbItemPushService {
         itemPushRelMapper.insertBatch(itemPushRelList);
     }
 
-    private void addItemPushDevice(SmsbItemPushBo bo) {
-        List<String> deviceIds = bo.getDeviceIds();
-        if (CollectionUtil.isEmpty(deviceIds)) {
-            throw new ServiceException("发布设备不能为空");
-        }
-        List<SmsbItemPushDevice> itemPushDeviceList = new ArrayList<>();
-        Integer sortNum = 0;
-        for (String deviceId : deviceIds) {
-            sortNum++;
-            SmsbItemPushDevice itemPushDevice = new SmsbItemPushDevice();
-            itemPushDevice.setPushId(bo.getId());
-            itemPushDevice.setDeviceId(Long.parseLong(deviceId));
-            itemPushDevice.setPushState(1);
-            itemPushDevice.setSortNum(sortNum);
-            itemPushDeviceList.add(itemPushDevice);
-        }
-        itemPushDeviceMapper.insertBatch(itemPushDeviceList);
-    }
-
-    private void addItemPushTime(SmsbItemPushBo bo) {
-        List<SmsbItemPushTimeRangeBo> timeRange = bo.getTimeRange();
-        if (CollectionUtil.isEmpty(timeRange)) {
-            throw new ServiceException("内容时间排期不能为空");
-        }
-        List<String> weekDays = bo.getWeekDays();
-        if (CollectionUtil.isEmpty(weekDays)) {
-            throw new ServiceException("内容每周日期不能为空");
-        }
-        List<SmsbItemPushTime> itemPushTimeList = new ArrayList<>();
-        for (SmsbItemPushTimeRangeBo smsbItemPushTimeRangeBo : timeRange) {
-            SmsbItemPushTime itemPushTime = new SmsbItemPushTime();
-            itemPushTime.setPushId(bo.getId());
-            itemPushTime.setTimeStart(getHourTimeStrByUTC(smsbItemPushTimeRangeBo.getStart()));
-            itemPushTime.setTimeEnd(getHourTimeStrByUTC(smsbItemPushTimeRangeBo.getEnd()));
-            itemPushTime.setStartDate(bo.getDateRange().get(0));
-            itemPushTime.setEndDate(bo.getDateRange().get(1));
-            itemPushTime.setWeekDays(String.join(",", weekDays));
-            itemPushTimeList.add(itemPushTime);
-        }
-        itemPushTimeMapper.insertBatch(itemPushTimeList);
-    }
-
     private String getHourTimeStrByUTC(String utcTime) {
         OffsetDateTime offsetDateTime = OffsetDateTime.parse(utcTime);
         OffsetDateTime beijingTime = offsetDateTime.withOffsetSameInstant(ZoneOffset.of("+08:00"));
@@ -380,17 +612,9 @@ public class SmsbItemPushServiceImpl implements ISmsbItemPushService {
     @Override
     public Boolean updateByBo(SmsbItemPushBo bo) {
         SmsbItemPush update = MapstructUtils.convert(bo, SmsbItemPush.class);
-        validEntityBeforeSave(update);
-        pushNettyMsg(bo.getDeviceIds(), bo.getId());
         return baseMapper.updateById(update) > 0;
     }
 
-    /**
-     * 保存前的数据校验
-     */
-    private void validEntityBeforeSave(SmsbItemPush entity) {
-
-    }
 
     /**
      * 校验并批量删除内容发布信息
@@ -413,69 +637,47 @@ public class SmsbItemPushServiceImpl implements ISmsbItemPushService {
     }
 
     @Override
-    public R<FrontPushInfoVo> getItemPushInfo(String identifier) {
+    public R<List<FrontPushInfoVo>> getItemPushInfo(String identifier) {
         if (StringUtils.isEmpty(identifier)) {
             return R.fail(HttpApiResult.PARAM_IS_NULL.getCode(), HttpApiResult.PARAM_IS_NULL.getInfo());
         }
-        FrontPushInfoVo result = getItemPushInfoByCache(identifier);
+        List<FrontPushInfoVo> result = generatePushInfo(identifier);
         return R.ok(result);
     }
 
-    // @Cacheable(cacheNames = "global:msr:device:push", key = "#identifier")
-    public FrontPushInfoVo getItemPushInfoByCache(String identifier) {
-        FrontPushInfoVo redisValue = RedisUtils.getCacheObject(PUSH_CONTENT_INFO_KEY + identifier);
-        if (null != redisValue) {
-            return redisValue;
-        }
-        return generatePushInfo(identifier);
-    }
-
-    // @CachePut(cacheNames = "global:msr:device:push", key = "#identifier")
-    public FrontPushInfoVo cachePushInfo(String identifier) {
-        FrontPushInfoVo redisValue = generatePushInfo(identifier);
-        RedisUtils.setCacheObject(PUSH_CONTENT_INFO_KEY + identifier,redisValue, Duration.ofSeconds(60));
-        return generatePushInfo(identifier);
-    }
-
-    public FrontPushInfoVo generatePushInfo(String identifier) {
-        FrontPushInfoVo result = new FrontPushInfoVo();
+    public List<FrontPushInfoVo> generatePushInfo(String identifier) {
+        List<FrontPushInfoVo> result = new ArrayList<>();
         SmsbDeviceVo deviceVo = smsbDeviceService.getDeviceByIdentifier(identifier);
-        // 根据设备ID查询当前设备最新的内容下发
-        Long deviceId = deviceVo.getId();
-        result.setDeviceId(deviceId);
-        result.setWidth(deviceVo.getWidth());
-        result.setHeight(deviceVo.getHeight());
-        // 根据等级倒序100垫片 200常规 300紧急 时间范围内的节目列表
-        List<SmsbItemPushVo> smsbItemPushVoList = baseMapper.selectFrontOnePushByDeviceId(deviceId);
-        if (CollectionUtil.isEmpty(smsbItemPushVoList)) {
-            return result;
+        // 查询当前设备三天的时序
+        Date startDate = DateUtil.beginOfDay(new Date());
+        Date endDate = DateUtil.endOfDay(DateUtil.offsetDay(startDate, 2));
+        List<SmsbItemPushPlaylineVo> devicePlaylineList = smsbItemPushPlaylineMapper.selectExistTimeNodes(DateUtil.formatDateTime(startDate),
+            DateUtil.formatDateTime(endDate), deviceVo.getId());
+        for (SmsbItemPushPlaylineVo devicePlayline : devicePlaylineList) {
+            FrontPushInfoVo oneLineResult = new FrontPushInfoVo();
+            buildPushItemInfo(oneLineResult, devicePlayline);
+            oneLineResult.setDeviceId(deviceVo.getId());
+            oneLineResult.setWidth(deviceVo.getWidth());
+            oneLineResult.setHeight(deviceVo.getHeight());
+            result.add(oneLineResult);
         }
-        buildPushItemInfo(result, smsbItemPushVoList.get(0));
+
         return result;
     }
 
-    private void buildPushItemInfo(FrontPushInfoVo result, SmsbItemPushVo smsbItemPushVo) {
+    private void buildPushItemInfo(FrontPushInfoVo result, SmsbItemPushPlaylineVo devicePlayline) {
         FrontItemInfoVO itemInfoVO = new FrontItemInfoVO();
         // pushId - 内容下发基础信息
-        Long pushId = smsbItemPushVo.getId();
+        Long pushId = devicePlayline.getPushId();
         result.setPushId(pushId);
+        SmsbItemPushVo smsbItemPushVo = baseMapper.selectVoById(pushId);
         result.setPushName(smsbItemPushVo.getName());
         itemInfoVO.setLevel(smsbItemPushVo.getLevel());
-        // 时间排期
-        List<SmsbItemPushTimeVo> pushTimeList = itemPushTimeMapper.selectVoList(new LambdaQueryWrapper<SmsbItemPushTime>()
-            .eq(SmsbItemPushTime::getPushId, pushId));
-        String dateStart = pushTimeList.get(0).getStartDate();
-        String dateEnd = pushTimeList.get(0).getEndDate();
-        List<SmsbItemPushTimeRangeBo> timeRangeList = new ArrayList<>();
-        for (SmsbItemPushTimeVo pushTime : pushTimeList) {
-            SmsbItemPushTimeRangeBo timeRange = new SmsbItemPushTimeRangeBo();
-            timeRange.setStart(dateStart + " " + pushTime.getTimeStart());
-            timeRange.setEnd(dateEnd + " " + pushTime.getTimeEnd());
-            timeRangeList.add(timeRange);
-        }
-        result.setTimeRange(timeRangeList);
+
+        result.setStartTime(DateUtil.formatDateTime(devicePlayline.getStartTime()));
+        result.setEndTime(DateUtil.formatDateTime(devicePlayline.getEndTime()));
         // weekDays
-        result.setWeekDays(pushTimeList.get(0).getWeekDays());
+        // result.setWeekDays(pushTimeList.get(0).getWeekDays());
         // 根据pushId 查询出最新的一个节目
         SmsbItemPushRel itemPushRel = itemPushRelMapper.selectOne(new LambdaQueryWrapper<SmsbItemPushRel>()
             .eq(SmsbItemPushRel::getPushId, pushId).orderByDesc(SmsbItemPushRel::getCreateTime));
@@ -513,17 +715,10 @@ public class SmsbItemPushServiceImpl implements ISmsbItemPushService {
         // 根据identifier 查询设备信息
         SmsbDeviceVo smsbDeviceVo = smsbDeviceService.getDeviceByIdentifier(identifier);
         Long deviceId = smsbDeviceVo.getId();
-        updateDevicePushState(pushId, deviceId, 3);
+        // updateDevicePushState(pushId, deviceId, 3);
         return R.ok();
     }
 
-    private void updateDevicePushState(Long pushId, Long deviceId, Integer state) {
-        SmsbItemPushDevice updateBean = new SmsbItemPushDevice();
-        updateBean.setPushState(state);
-        itemPushDeviceMapper.update(updateBean, new LambdaQueryWrapper<SmsbItemPushDevice>()
-            .eq(SmsbItemPushDevice::getPushId, pushId).eq(SmsbItemPushDevice::getDeviceId, deviceId));
-    }
-
     private List<FrontItemSourceVO> getItemSourceListByPushId(Long pushId) {
         // 根据pushId 查询关联的轮播组
         List<FrontItemSourceVO> fileRelList = itemFileRelMapper.selectVoListByPushId(pushId);

+ 11 - 0
smsb-modules/smsb-source/src/main/resources/mapper/SmsbItemPushPlaylineMapper.xml

@@ -0,0 +1,11 @@
+<?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.source.mapper.SmsbItemPushPlaylineMapper">
+
+    <select id="selectExistTimeNodes" resultType="com.inspur.source.domain.vo.SmsbItemPushPlaylineVo">
+        SELECT * from smsb_item_push_playline where device_id = #{deviceId} and start_time <![CDATA[ >= ]]> #{startTime} and end_time <![CDATA[ <= ]]> #{endTime}
+    </select>
+
+</mapper>

+ 18 - 0
smsb-modules/smsb-source/src/main/resources/mapper/SmsbItemPushPlaylistMapper.xml

@@ -0,0 +1,18 @@
+<?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.source.mapper.SmsbItemPushPlaylistMapper">
+
+    <select id="selectDeviceListByPushId" resultType="com.inspur.source.domain.vo.SmsbItemPushPlaylistVo">
+        SELECT
+            sipp.*,
+            sd.NAME AS deviceName
+        FROM
+            smsb_item_push_playlist sipp
+                LEFT JOIN smsb_device sd ON sipp.device_id = sd.id
+        WHERE
+            sipp.push_id = #{pushId}
+    </select>
+
+</mapper>

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

@@ -0,0 +1,63 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import { DeviceTaskVO, DeviceTaskForm, DeviceTaskQuery } from '@/api/device/device_task_type';
+
+/**
+ * 查询设备任务中心列表
+ * @param query
+ * @returns {*}
+ */
+
+export const listDeviceTask = (query?: DeviceTaskQuery): AxiosPromise<DeviceTaskVO[]> => {
+  return request({
+    url: '/smsb/device/task/list',
+    method: 'get',
+    params: query
+  });
+};
+
+/**
+ * 查询设备任务中心详细
+ * @param id
+ */
+export const getDeviceTask = (id: string | number): AxiosPromise<DeviceTaskVO> => {
+  return request({
+    url: '/smsb/device/task/' + id,
+    method: 'get'
+  });
+};
+
+/**
+ * 新增设备任务中心
+ * @param data
+ */
+export const addDeviceTask = (data: DeviceTaskForm) => {
+  return request({
+    url: '/smsb/device/task',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 修改设备任务中心
+ * @param data
+ */
+export const updateDeviceTask = (data: DeviceTaskForm) => {
+  return request({
+    url: '/smsb/device/task',
+    method: 'put',
+    data: data
+  });
+};
+
+/**
+ * 删除设备任务中心
+ * @param id
+ */
+export const delDeviceTask = (id: string | number | Array<string | number>) => {
+  return request({
+    url: '/smsb/device/task/' + id,
+    method: 'delete'
+  });
+};

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

@@ -0,0 +1,101 @@
+export interface DeviceTaskVO {
+  /**
+   * 主键ID
+   */
+  id: string | number;
+
+  /**
+   * 唯一标识
+   */
+  identifier: string | number;
+
+  /**
+   * 设备ID
+   */
+  deviceId: string | number;
+
+  /**
+   * 任务类型
+   */
+  taskType: number;
+
+  /**
+   * 任务参数
+   */
+  taskParam: string;
+
+  /**
+   * 是否完成 0-否 1-是
+   */
+  isEnd: number;
+
+  /**
+   * 创建时间
+   */
+  createTime: string;
+
+}
+
+export interface DeviceTaskForm extends BaseEntity {
+  /**
+   * 主键ID
+   */
+  id?: string | number;
+
+  /**
+   * 唯一标识
+   */
+  identifier?: string | number;
+
+  /**
+   * 设备ID
+   */
+  deviceId?: string | number;
+
+  /**
+   * 任务类型
+   */
+  taskType?: number;
+
+  /**
+   * 任务参数
+   */
+  taskParam?: string;
+
+  /**
+   * 是否完成 0-否 1-是
+   */
+  isEnd?: number;
+
+}
+
+export interface DeviceTaskQuery extends PageQuery {
+
+  /**
+   * 唯一标识
+   */
+  identifier?: string | number;
+
+  /**
+   * 设备ID
+   */
+  deviceId?: string | number;
+
+  /**
+   * 任务类型
+   */
+  taskType?: number;
+
+  /**
+   * 是否完成 0-否 1-是
+   */
+  isEnd?: number;
+
+  /**
+   * 日期范围参数
+   */
+  params?: any;
+}
+
+
+

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

@@ -66,6 +66,14 @@ export const updateItemPush = (data: ItemPushForm) => {
   });
 };
 
+export const validateTime = (data: ItemPushForm) => {
+  return request({
+    url: '/source/itemPush/validate/time',
+    method: 'post',
+    data: data
+  });
+}
+
 /**
  * 删除内容发布
  * @param id

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

@@ -270,7 +270,7 @@
           <div style="margin-top: 20px">
             <span>版本CODE:{{ deviceRunInfo.versionCode }}</span>
             <span style="margin-left: 50px">应用版本:{{ deviceRunInfo.versionName }}</span>
-            <span style="margin-left: 50px">状态时间:{{ deviceRunInfo.versionName }}</span>
+            <span style="margin-left: 50px">状态时间:{{ deviceRunInfo.createTime }}</span>
             <br />
           </div>
         </el-tab-pane>

+ 250 - 0
smsb-plus-ui/src/views/smsb/deviceTask/index.vue

@@ -0,0 +1,250 @@
+<template>
+  <div class="p-2">
+    <transition :enter-active-class="proxy?.animate.searchAnimate.enter"
+                :leave-active-class="proxy?.animate.searchAnimate.leave">
+      <div v-show="showSearch" class="mb-[10px]">
+        <el-card shadow="hover" :style="{ marginTop: '10px', height: '60px' }">
+          <el-form ref="queryFormRef" :model="queryParams" :inline="true">
+            <el-form-item label="唯一标识" prop="identifier">
+              <el-input v-model="queryParams.identifier" placeholder="请输入唯一标识" clearable @keyup.enter="handleQuery"/>
+            </el-form-item>
+            <el-form-item>
+              <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
+              <el-button icon="Refresh" @click="resetQuery">重置</el-button>
+            </el-form-item>
+          </el-form>
+        </el-card>
+      </div>
+    </transition>
+
+    <el-card shadow="never">
+      <!--      <template #header>
+              <el-row :gutter="10" class="mb8">
+                <el-col :span="1.5">
+                  <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['device:deviceTask:add']">新增</el-button>
+                </el-col>
+                <el-col :span="1.5">
+                  <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['device:deviceTask:edit']">修改</el-button>
+                </el-col>
+                <el-col :span="1.5">
+                  <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['device:deviceTask:remove']">删除</el-button>
+                </el-col>
+                <el-col :span="1.5">
+                  <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['device:deviceTask:export']">导出</el-button>
+                </el-col>
+                <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+              </el-row>
+            </template>-->
+      <div class="table-content">
+        <el-table v-loading="loading" :data="deviceTaskList" @selection-change="handleSelectionChange">
+          <!--        <el-table-column type="selection" width="55" align="center" />-->
+          <el-table-column label="" align="left" v-if="true" width="10"/>
+          <el-table-column label="任务ID" align="left" prop="id" v-if="true" width="180"/>
+          <el-table-column label="设备ID" align="left" prop="deviceId" width="180"/>
+          <el-table-column label="设备名称" align="left" prop="deviceName"/>
+          <el-table-column label="唯一标识" align="left" prop="identifier" width="220"/>
+          <el-table-column label="任务类型" align="center" prop="taskType" width="150">
+            <template #default="scope">
+              <dict-tag :options="smsb_device_task_type" :value="scope.row.taskType"/>
+            </template>
+          </el-table-column>
+          <el-table-column label="是否完成" align="center" prop="isEnd" width="150">
+            <template #default="scope">
+              <dict-tag :options="smsb_device_task_end" :value="scope.row.isEnd"/>
+            </template>
+          </el-table-column>
+          <el-table-column label="任务参数" align="left" prop="taskParam"/>
+          <el-table-column label="创建时间" align="left" prop="createTime" width="160"/>
+          <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="120">
+            <template #default="scope">
+              <el-tooltip content="详情" placement="top">
+                <el-button link type="primary" icon="InfoFilled" @click="handleUpdate(scope.row)"
+                           v-hasPermi="['device:deviceTask:edit']"></el-button>
+              </el-tooltip>
+              <el-tooltip content="删除" placement="top">
+                <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)"
+                           v-hasPermi="['device:deviceTask:remove']"></el-button>
+              </el-tooltip>
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+
+      <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum"
+                  v-model:limit="queryParams.pageSize" @pagination="getList"/>
+    </el-card>
+    <!-- 添加或修改设备任务中心对话框 -->
+    <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
+      <el-form ref="deviceTaskFormRef" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="唯一标识" prop="identifier">
+          <el-input v-model="form.identifier" placeholder="请输入唯一标识"/>
+        </el-form-item>
+        <el-form-item label="设备ID" prop="deviceId">
+          <el-input v-model="form.deviceId" placeholder="请输入设备ID"/>
+        </el-form-item>
+        <el-form-item label="任务参数" prop="taskParam">
+          <el-input v-model="form.taskParam" placeholder="请输入任务参数"/>
+        </el-form-item>
+        <el-form-item label="是否完成 0-否 1-是" prop="isEnd">
+          <el-input v-model="form.isEnd" placeholder="请输入是否完成 0-否 1-是"/>
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
+          <el-button @click="cancel">取 消</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup name="DeviceTask" lang="ts">
+import {
+  addDeviceTask,
+  delDeviceTask,
+  getDeviceTask,
+  listDeviceTask,
+  updateDeviceTask
+} from '@/api/smsb/device/device_task';
+import {DeviceTaskForm, DeviceTaskQuery, DeviceTaskVO} from '@/api/smsb/device/device_task_type';
+
+const {proxy} = getCurrentInstance() as ComponentInternalInstance;
+const {smsb_device_task_type, smsb_device_task_end} = toRefs<any>(
+  proxy?.useDict('smsb_device_task_type', 'smsb_device_task_end')
+);
+const deviceTaskList = ref<DeviceTaskVO[]>([]);
+const buttonLoading = ref(false);
+const loading = ref(true);
+const showSearch = ref(true);
+const ids = ref<Array<string | number>>([]);
+const single = ref(true);
+const multiple = ref(true);
+const total = ref(0);
+
+const queryFormRef = ref<ElFormInstance>();
+const deviceTaskFormRef = ref<ElFormInstance>();
+
+const dialog = reactive<DialogOption>({
+  visible: false,
+  title: ''
+});
+
+const initFormData: DeviceTaskForm = {
+  id: undefined,
+  identifier: undefined,
+  deviceId: undefined,
+  taskType: undefined,
+  taskParam: undefined,
+  isEnd: undefined,
+}
+const data = reactive<PageData<DeviceTaskForm, DeviceTaskQuery>>({
+  form: {...initFormData},
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
+    identifier: undefined,
+    deviceId: undefined,
+    taskType: undefined,
+    isEnd: undefined,
+    params: {}
+  },
+  rules: {}
+});
+
+const {queryParams, form, rules} = toRefs(data);
+
+/** 查询设备任务中心列表 */
+const getList = async () => {
+  loading.value = true;
+  const res = await listDeviceTask(queryParams.value);
+  deviceTaskList.value = res.rows;
+  total.value = res.total;
+  loading.value = false;
+}
+
+/** 取消按钮 */
+const cancel = () => {
+  reset();
+  dialog.visible = false;
+}
+
+/** 表单重置 */
+const reset = () => {
+  form.value = {...initFormData};
+  deviceTaskFormRef.value?.resetFields();
+}
+
+/** 搜索按钮操作 */
+const handleQuery = () => {
+  queryParams.value.pageNum = 1;
+  getList();
+}
+
+/** 重置按钮操作 */
+const resetQuery = () => {
+  queryFormRef.value?.resetFields();
+  handleQuery();
+}
+
+/** 多选框选中数据 */
+const handleSelectionChange = (selection: DeviceTaskVO[]) => {
+  ids.value = selection.map(item => item.id);
+  single.value = selection.length != 1;
+  multiple.value = !selection.length;
+}
+
+/** 新增按钮操作 */
+const handleAdd = () => {
+  reset();
+  dialog.visible = true;
+  dialog.title = "添加设备任务中心";
+}
+
+/** 修改按钮操作 */
+const handleUpdate = async (row?: DeviceTaskVO) => {
+  reset();
+  const _id = row?.id || ids.value[0]
+  const res = await getDeviceTask(_id);
+  Object.assign(form.value, res.data);
+  dialog.visible = true;
+  dialog.title = "修改设备任务中心";
+}
+
+/** 提交按钮 */
+const submitForm = () => {
+  deviceTaskFormRef.value?.validate(async (valid: boolean) => {
+    if (valid) {
+      buttonLoading.value = true;
+      if (form.value.id) {
+        await updateDeviceTask(form.value).finally(() => buttonLoading.value = false);
+      } else {
+        await addDeviceTask(form.value).finally(() => buttonLoading.value = false);
+      }
+      proxy?.$modal.msgSuccess("操作成功");
+      dialog.visible = false;
+      await getList();
+    }
+  });
+}
+
+/** 删除按钮操作 */
+const handleDelete = async (row?: DeviceTaskVO) => {
+  const _ids = row?.id || ids.value;
+  await proxy?.$modal.confirm('是否确认删除设备任务中心编号为"' + _ids + '"的数据项?').finally(() => loading.value = false);
+  await delDeviceTask(_ids);
+  proxy?.$modal.msgSuccess("删除成功");
+  await getList();
+}
+
+/** 导出按钮操作 */
+const handleExport = () => {
+  proxy?.download('device/deviceTask/export', {
+    ...queryParams.value
+  }, `deviceTask_${new Date().getTime()}.xlsx`)
+}
+
+onMounted(() => {
+  getList();
+});
+</script>

+ 24 - 12
smsb-plus-ui/src/views/smsb/itemPush/index.vue

@@ -116,18 +116,19 @@
             </el-tooltip> -->
               <el-tooltip content="删除" placement="top">
                 <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)"
-                  v-hasPermi="['source:itemPush:remove']"></el-button>
+                           v-hasPermi="['source:itemPush:remove']"></el-button>
               </el-tooltip>
-              <!--            <el-tooltip content="提交审核" placement="top">
-                          <el-button link type="primary" icon="Top" @click="handleReview(scope.row)" v-hasPermi="['source:minioData:add']"></el-button>
-                        </el-tooltip>-->
+<!--              <el-tooltip content="提交审核" placement="top">
+                <el-button link type="primary" icon="Top" @click="handleReview(scope.row)"
+                           v-hasPermi="['source:minioData:add']"></el-button>
+              </el-tooltip>-->
               <el-tooltip content="下发详情" placement="top">
                 <el-button link type="primary" icon="List" @click="handleDevice(scope.row)"
-                  v-hasPermi="['source:itemPush:edit']"></el-button>
+                           v-hasPermi="['source:itemPush:edit']"></el-button>
               </el-tooltip>
               <el-tooltip content="下架" placement="top">
                 <el-button link type="primary" icon="Bottom" v-if="scope.row.status == 'finish'"
-                  @click="handleRemoveItem(scope.row)" v-hasPermi="['source:itemPush:edit']"></el-button>
+                           @click="handleRemoveItem(scope.row)" v-hasPermi="['source:itemPush:edit']"></el-button>
               </el-tooltip>
             </template>
           </el-table-column>
@@ -297,7 +298,8 @@ import {
   listItemPush,
   pushStatistics,
   reviewItemPush,
-  updateItemPush
+  updateItemPush,
+  validateTime,
 } from '@/api/smsb/source/item_push';
 import {ItemPushForm, ItemPushQuery, ItemPushVO} from '@/api/smsb/source/item_push_type';
 import {DeviceQuery, DeviceVO} from '@/api/smsb/device/device_type';
@@ -438,7 +440,9 @@ const getItemList = async () => {
 const addTimePeriod = () => {
   const now = new Date();
   now.setHours(0, 0, 0, 0);
-  form.value.timeRange.push({ start: new Date(now), end: new Date(now) });
+  const end = new Date();
+  end.setHours(23, 59, 59, 0);
+  form.value.timeRange.push({start: new Date(now), end: new Date(end)});
 };
 
 const removeTimePeriod = (index: number) => {
@@ -470,7 +474,7 @@ const handleDevice = async (row?: ItemPushVO) => {
   deviceDialog.title = '发布详情';
   deviceDialog.visible = true;
   dialogQueryParams.value.pushId = pushId;
-  dialogQueryParams.value.pageSize = 1000;
+  // dialogQueryParams.value.pageSize = 1000;
   pushDeviceList.value = [];
   const pushInfo = await getItemPush(pushId);
   Object.assign(form.value, pushInfo.data);
@@ -513,8 +517,7 @@ const getItemDeviceList = async (pushId: number | string) => {
   deviceLoading.value = true;
   dialogQueryParams.value.pushId = pushId;
   const res = await listItemPushDeviceV2(dialogQueryParams.value);
-  pushDeviceList.value = res.rows;
-  deviceTotal.value = res.total;
+  pushDeviceList.value = res.data;
   deviceLoading.value = false;
 };
 
@@ -580,7 +583,16 @@ const submitForm = () => {
       if (form.value.id) {
         await updateItemPush(form.value).finally(() => (buttonLoading.value = false));
       } else {
-        await addItemPush(form.value).finally(() => (buttonLoading.value = false));
+        // 校验时间冲突
+        const resTime = await validateTime(form.value);
+        if (resTime.data.code !== 200) {
+          await proxy?.$modal.confirm("排期时间存在冲突,是否覆盖之前排期").finally(() => (buttonLoading.value = false));
+          console.log(resTime.data)
+          await addItemPush(form.value).finally(() => (buttonLoading.value = false));
+        } else {
+          console.log(form.value)
+          await addItemPush(form.value).finally(() => (buttonLoading.value = false));
+        }
       }
       proxy?.$modal.msgSuccess('操作成功');
       dialog.visible = false;

+ 0 - 0
upload/smsb/upload/.gitkeep