mqtt 模块添加

This commit is contained in:
yuhaiming
2026-06-04 11:24:08 +08:00
parent ccfecae584
commit 1ab8c28c36
48 changed files with 1200 additions and 10174 deletions

View File

@@ -1,31 +1,22 @@
package org.dromara.app.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.crypto.digest.BCrypt;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.app.domain.bo.AppDeviceBo;
import org.dromara.app.domain.bo.AppScheduleBo;
import org.dromara.app.domain.vo.AppDeviceVo;
import org.dromara.app.domain.vo.AppScheduleDetailVo;
import org.dromara.app.domain.vo.AppScheduleVo;
import org.dromara.app.domain.vo.AppSchedulingDeviceVo;
import org.dromara.app.service.IAppDeviceService;
import org.dromara.app.service.IAppScheduleDetailService;
import org.dromara.app.service.IAppScheduleService;
import org.dromara.app.service.IAppSchedulingDeviceService;
import org.dromara.app.service.impl.AppScheduleDetailServiceImpl;
import org.dromara.app.domain.AppDevice;
import org.dromara.app.domain.bo.*;
import org.dromara.app.domain.vo.*;
import org.dromara.app.service.*;
import org.dromara.app.service.impl.AppScheduleServiceImpl;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.domain.model.ForgotLoginBody;
import org.dromara.common.core.domain.model.LoginUser;
import org.dromara.common.core.enums.LoginType;
import org.dromara.common.core.exception.user.UserException;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.core.validate.AddGroup;
@@ -39,7 +30,6 @@ import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.helper.DataPermissionHelper;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.tenant.helper.TenantHelper;
import org.dromara.common.web.core.BaseController;
import org.dromara.system.domain.bo.SysUserBo;
import org.dromara.system.domain.vo.SysUserVo;
@@ -48,9 +38,9 @@ import org.dromara.system.service.ISysUserService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.text.SimpleDateFormat;
import java.util.*;
@Slf4j
@RequiredArgsConstructor
@@ -65,6 +55,8 @@ public class AppController extends BaseController {
private final AppScheduleServiceImpl appScheduleServiceimpl;
private final IAppSchedulingDeviceService appSchedulingDeviceService;
private final ISysUserService userService;
private final IAppWateringLogService wateringLogService;
private final IAppWateringLogService appWateringLogService;
/**
*查询设备
@@ -73,6 +65,8 @@ public class AppController extends BaseController {
@GetMapping("/deviceList")
public TableDataInfo<AppDeviceVo> list(AppDeviceBo bo, PageQuery pageQuery) {
bo.setUserId(LoginHelper.getUserId());
pageQuery.setOrderByColumn("createTime");
pageQuery.setIsAsc("desc");
return appDeviceService.queryPageList(bo, pageQuery);
}
@@ -137,40 +131,175 @@ public class AppController extends BaseController {
}
/**
* 手动开启关闭设备
*
*/
// @SaCheckRole("appadmin")
@RepeatSubmit()
@PutMapping("/switchDevice")
public R<Void> switchDevice(@RequestBody String body) {
Map<String,String> map = JsonUtils.parseObject(body, Map.class);
try {
Long id = Long.valueOf(map.get("id"));
String status = map.get("workStatus");
String startTime = map.get("startTime");
int durationMin = Integer.valueOf(map.get("durationMin"));
//更新设备工作状态
AppDeviceBo appDeviceBo = new AppDeviceBo();
appDeviceBo.setId(id);
appDeviceBo.setWorkStatus(status);
Boolean flag = appDeviceService.updateByBo(appDeviceBo);
if (flag){
//todo 给设备发送开始浇水信息
// 记录信息到历史表
AppWateringLogBo appWateringLog = new AppWateringLogBo();
appWateringLog.setDeviceId(id);
appWateringLog.setUserId(LoginHelper.getUserId());
appWateringLog.setDurationMin(durationMin+"");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
if (StringUtils.isNotEmpty(startTime)){
Date date = sdf.parse(startTime);
appWateringLog.setStartTime(date);
long time = date.getTime()+durationMin*60000L;
Date endTime = new Date(time);
appWateringLog.setEndTime(endTime);
}
appWateringLog.setTriggerType("1");
appWateringLog.setCreateTime(new Date());
appWateringLog.setScheduleId(1L);
wateringLogService.insertByBo(appWateringLog);
}
return toAjax(flag);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 排程关联设备查询
* @param
* @return
*/
@GetMapping("/scheduleDeviceList")
public List<AppDeviceVo> scheduleDeviceList(AppDeviceBo appDeviceBo, AppScheduleBo appScheduleBo) {
@GetMapping("/scheduleDeviceList/{scheduleId}")
public R<Map<String,Object>> scheduleDeviceList( @PathVariable Long scheduleId) {
Map retMap = new HashMap();
//所有设备列表
AppDeviceBo appDeviceBo = new AppDeviceBo();
appDeviceBo.setUserId(LoginHelper.getUserId());
List<AppDeviceVo> appDeviceVos = appDeviceService.queryList(appDeviceBo);
List<AppDeviceVo> AppDeviceVoList = new ArrayList();
List<AppDeviceVo> appDeviceVoList = new ArrayList();
AppSchedulingDeviceBo schedulingDeviceBo = new AppSchedulingDeviceBo();
schedulingDeviceBo.setScheduleId(scheduleId);
for (AppDeviceVo appDeviceVo:appDeviceVos){
//查询设备日程冲突
List list = appScheduleServiceimpl.checkConflict(appDeviceVo.getId(), appScheduleBo);
if (list.size()==0){
AppDeviceVoList.add(appDeviceVo);
List<AppSchedulingDeviceVo> appSchedulingDeviceVos = appSchedulingDeviceService.queryByDeviveId(appDeviceVo.getId());
if(appSchedulingDeviceVos.size() == 0){
appDeviceVoList.add(appDeviceVo);
}
}
return AppDeviceVoList;
retMap.put("deviceList", appDeviceVoList);
// if (appDeviceVoList.size()==0){
// retMap.put("deviceList", appDeviceVos);
// }
return R.ok(retMap);
/** //排程信息
AppScheduleVo appScheduleVo = appScheduleService.queryById(scheduleId);
if (ObjectUtil.isNotNull(appScheduleVo)&&"1".equals(appScheduleVo.getStatus())){
for (AppDeviceVo appDeviceVo:appDeviceVos){
//查询设备日程冲突
List list = appScheduleServiceimpl.checkConflict(appDeviceVo.getId(), appScheduleVo);
if (list.size()==0){
AppDeviceVoList.add(appDeviceVo);
}
// retMap.put("conflict", list);
}
retMap.put("devicelist", AppDeviceVoList);
}else {
retMap.put("devicelist", appDeviceVos);
// retMap.put("conflict", new ArrayList<>());
return R.ok(retMap);
}
return R.ok(retMap); **/
}
/**
*绑定排程跟设备
*/
@RepeatSubmit()
@PostMapping("/addScheduleDevice")
public R<Void> addScheduleDevice( @RequestBody String body) {
try {
Map<String, Object> map = JsonUtils.parseObject(body, Map.class);
Long scheduleId = Long.valueOf(map.get("scheduleId").toString());
List<String> deviceIds= (List<String>) map.get("deviceIds");
for (String deviceId:deviceIds){
AppSchedulingDeviceBo schedulingDeviceBo = new AppSchedulingDeviceBo();
schedulingDeviceBo.setDeviceId(Long.valueOf(deviceId));
schedulingDeviceBo.setScheduleId(scheduleId);
appSchedulingDeviceService.insertByBo(schedulingDeviceBo);
}
return R.ok();
} catch (RuntimeException e) {
throw new RuntimeException(e);
}
}
/**
* 删除排程与设备绑定
* @param scheduleId,deviceId
* @return
*/
@Log(title = "排程与设备关联", businessType = BusinessType.DELETE)
@DeleteMapping("/deleteScheduleDevice")
public R<Void> deleteScheduleDevice(@NotEmpty(message = "主键不能为空")
@RequestParam String scheduleId, @RequestParam String deviceId) {
return toAjax(appSchedulingDeviceService.deleteWithValidByschedulingIds2Ids(Long.valueOf(scheduleId),Long.valueOf(deviceId)));
}
/**
* 查询排程列表
*/
@GetMapping("/schedulelist")
public TableDataInfo<AppScheduleVo> schedulelist(AppScheduleBo bo, PageQuery pageQuery) {
bo.setUserId(LoginHelper.getUserId());
pageQuery.setOrderByColumn("createTime");
pageQuery.setIsAsc("desc");
return appScheduleService.queryPageList(bo, pageQuery);
}
/**
* 新增排程
*
*/
@SaCheckPermission("app:schedule:add")
@Log(title = "日程排列", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping("/addschedule")
public R<Void> addSchedule(@Validated(AddGroup.class) @RequestBody AppScheduleBo bo) {
public R<AppScheduleVo> addSchedule(@Validated(AddGroup.class) @RequestBody AppScheduleBo bo) {
try {
return toAjax(appScheduleService.insertByBo(bo));
bo.setCreateTime(new Date());
AppScheduleVo appScheduleVo = appScheduleService.insertByBo(bo);
if (ObjectUtil.isNotNull(appScheduleVo)){
return R.ok(appScheduleVo);
}
return R.fail();
// return toAjax(appScheduleService.insertByBo(bo));
} catch (RuntimeException e) {
throw new RuntimeException(e);
}
@@ -186,27 +315,71 @@ public class AppController extends BaseController {
public R<AppScheduleVo> getScheduleInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
AppScheduleVo appScheduleVo = appScheduleService.queryById(id);
if (ObjectUtil.isNotNull(appScheduleVo)){
List<AppScheduleDetailVo> list = appScheduleDetailService.queryByScheduleIdByStatus(appScheduleVo.getId());
List<AppScheduleDetailVo> list = appScheduleDetailService.queryByScheduleId(appScheduleVo.getId());
AppSchedulingDeviceBo appSchedulingDeviceBo = new AppSchedulingDeviceBo();
appSchedulingDeviceBo.setScheduleId(appScheduleVo.getId());
List<AppSchedulingDeviceVo> appSchedulingDeviceVos = appSchedulingDeviceService.queryList(appSchedulingDeviceBo);
List deviceList = new ArrayList();
for (AppSchedulingDeviceVo appSchedulingDeviceVo:appSchedulingDeviceVos){
AppDeviceVo appDeviceVo = appDeviceService.queryById(appSchedulingDeviceVo.getDeviceId());
deviceList.add(appDeviceVo);
}
List detailList = new ArrayList();
appScheduleVo.setDetails(list);
for (AppScheduleDetailVo detail:list){
List timeSlots = new ArrayList();
JSONArray mapArray = JSONUtil.parseArray(detail.getTimeData());
for (Object timeSlot:mapArray){
timeSlots.add(timeSlot);
}
return R.ok(appScheduleVo);
Map map = new HashMap();
map.put("id",detail.getId() );
map.put("weekday",detail.getWeekday() );
map.put("timeData",timeSlots );
map.put("triggerType",detail.getTriggerType() );
map.put("status",detail.getStatus() );
detailList.add(map);
}
appScheduleVo.setDetails(detailList);
appScheduleVo.setDeviceIds(deviceList);
return R.ok(appScheduleVo);
}
return R.fail(appScheduleVo);
}
/**
* 修改排程状态
* @param
* @return
*/
@PutMapping("/editScheduleStatus")
public R<Void> editScheduleStatus(@NotNull(message = "主键不能为空")
@RequestBody AppScheduleBo bo) {
return toAjax(appScheduleService.updateStatusByBo(bo));
}
/**
* 修改日程排列
*/
@SaCheckPermission("app:schedule:edit")
@Log(title = "日程排列", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping("/updataschedule")
public R<Void> editSchedule(@Validated(EditGroup.class) @RequestBody AppScheduleBo bo) {
List list = appScheduleService.updateByBo(bo);
if (list.size()==0){
return R.ok();
public R<Object> editSchedule(@Validated(EditGroup.class) @RequestBody AppScheduleBo bo) {
Map<String, Object> map = appScheduleService.updateByBo(bo);
if (Boolean.valueOf(map.get("flag").toString())){
return R.ok(map.get("appSchedule"));
}else {
return R.fail(list.toString());
return R.fail();
}
}
@@ -217,7 +390,6 @@ public class AppController extends BaseController {
*
* @param ids 主键串
*/
@SaCheckPermission("app:schedule:remove")
@Log(title = "日程排列", businessType = BusinessType.DELETE)
@DeleteMapping("/deleteschedule/{ids}")
public R<Void> removeSchedule(@NotEmpty(message = "主键不能为空")
@@ -225,6 +397,85 @@ public class AppController extends BaseController {
return toAjax(appScheduleService.deleteWithValidByIds(List.of(ids), true));
}
/**
* 历史
* 查询浇水记录列表
*/
@GetMapping("/waterLogList")
public TableDataInfo<AppWateringLogVo> list(AppWateringLogBo bo, PageQuery pageQuery) {
bo.setUserId(LoginHelper.getUserId());
pageQuery.setOrderByColumn("createTime");
pageQuery.setIsAsc("desc");
TableDataInfo<AppWateringLogVo> appWateringLogVoTableDataInfo = appWateringLogService.queryPageList(bo, pageQuery);
AppDeviceBo appDeviceBo = new AppDeviceBo();
appDeviceBo.setUserId(LoginHelper.getUserId());
List<AppDeviceVo> appDeviceVos = appDeviceService.queryList(appDeviceBo);
List l = new ArrayList<>();
for (AppWateringLogVo vo : appWateringLogVoTableDataInfo.getRows()){
for(AppDeviceVo appDeviceVo:appDeviceVos){
if (appDeviceVo.getId().equals(vo.getDeviceId())){
vo.setDeviceName(appDeviceVo.getDeviceName());
vo.setDeviceNo(appDeviceVo.getDeviceNo());
}
}
// AppDeviceVo appDeviceVo = appDeviceService.queryById(vo.getDeviceId());
vo.setTriggerType(vo.getTriggerType().equals("0")?"排程":"手动");
l.add(vo);
}
appWateringLogVoTableDataInfo.setRows(l);
return appWateringLogVoTableDataInfo;
}
/**
* 删除浇水记录
*
* @param ids 主键串
*/
@Log(title = "浇水记录", businessType = BusinessType.DELETE)
@DeleteMapping("/waterLog/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(appWateringLogService.deleteWithValidByIds(List.of(ids), true));
}
/**
* 数据统计
*/
@GetMapping("/dataStatistics")
public R<Map> dataStatistics() {
Map map = new HashMap();
try {
Long userId = LoginHelper.getUserId();
//总浇水次数
Long count = appWateringLogService.queryCount(userId);
//本月浇水次数
Long monCount = appWateringLogService.queryByMonCount(userId);
//本周浇水次数
Long weekCount = appWateringLogService.queryByWeekCount(userId);
//排程浇水次数
Long schedule = appWateringLogService.queryByTriggerTypeCount(userId, "0");
//手动浇水次数
Long manualNum = appWateringLogService.queryByTriggerTypeCount(userId, "1");
//总浇水时间
Long allTime = appWateringLogService.queryByTotalWateringTime(userId);
//平均浇水时间
Long averageTime = allTime/count;
map.put("count",count);
map.put("monCount",monCount);
map.put("weekCount",weekCount);
map.put("schedule",schedule);
map.put("manualNum",manualNum);
map.put("allTime",allTime);
map.put("averageTime",averageTime);
return R.ok(map);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 获取用户信息
@@ -290,12 +541,12 @@ public class AppController extends BaseController {
if(Validator.isEmail(bo.getUserName())){
boolean checkPhoneFlag = userService.checkEmailUnique(bo);
if (checkPhoneFlag){
if (!checkPhoneFlag){
throw new UserException("user.email.not.username");
}
}else if (Validator.isMobile(bo.getUserName())){
boolean checkPhoneFlag = userService.checkPhoneUnique(bo);
if (checkPhoneFlag){
if (!checkPhoneFlag){
throw new UserException("user.mobile.phone.number.not.username");
}
}

View File

@@ -55,6 +55,11 @@ public class AppDevice extends BaseEntity {
*/
private String status;
/**
* 工作状态 1-工作中 0-休息
*/
private String workStatus;
/**
* 电量
*/
@@ -98,8 +103,8 @@ public class AppDevice extends BaseEntity {
/**
* 删除标志0代表存在 1代表删除
*/
@TableLogic
private String delFlag;
//@TableLogic
//private String delFlag;
/**
* 到期时间

View File

@@ -47,8 +47,8 @@ public class AppSchedule extends BaseEntity {
private String status;
private Date createdTime;
private Date createTime;
private List<AppScheduleDetail> details;
//private List<AppScheduleDetail> details;
}

View File

@@ -1,16 +1,17 @@
package org.dromara.app.domain;
import cn.hutool.json.JSON;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.io.Serial;
import java.util.List;
import java.util.Map;
/**
* 排程详情对象 app_schedule_detail
@@ -20,7 +21,7 @@ import java.io.Serial;
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("app_schedule_detail")
@TableName(value ="app_schedule_detail")
public class AppScheduleDetail extends BaseEntity {
@Serial
@@ -45,12 +46,16 @@ public class AppScheduleDetail extends BaseEntity {
/**
* 开始时间
*/
private LocalTime startTime;
private String timeData;
private String endTime;
/**
* 持续时间(分钟)
*/
private Integer durationMin;
@TableField(value = "duration_min", typeHandler = JacksonTypeHandler.class)
private String durationMin;
/**
* 浇水区域
@@ -62,5 +67,7 @@ public class AppScheduleDetail extends BaseEntity {
*/
private String triggerType;
private String status;
}

View File

@@ -24,7 +24,7 @@ public class AppSchedulingDevice extends BaseEntity {
/**
* 排程id
*/
private Long schedulingId;
private Long scheduleId;
/**
* 设备id

View File

@@ -39,6 +39,8 @@ public class AppWateringLog extends BaseEntity {
*/
private Long deviceId;
private String deviceNo;
/**
* 关联排程
*/
@@ -72,7 +74,7 @@ public class AppWateringLog extends BaseEntity {
/**
* 创建时间
*/
private Date createdTime;
private Date createTime;
}

View File

@@ -54,6 +54,10 @@ public class AppDeviceBo extends BaseEntity {
* 状态 1-工作中 0-离线 2-待机 3-故障
*/
private String status;
/**
* 工作状态 1-工作中 0-休息
*/
private String workStatus;
/**
* 电量

View File

@@ -1,5 +1,6 @@
package org.dromara.app.domain.bo;
import cn.hutool.json.JSON;
import org.dromara.app.domain.AppSchedule;
import org.dromara.app.domain.AppScheduleDetail;
import org.dromara.common.mybatis.core.domain.BaseEntity;
@@ -13,6 +14,7 @@ import jakarta.validation.constraints.*;
import java.time.LocalTime;
import java.util.Date;
import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonFormat;
@@ -56,23 +58,30 @@ public class AppScheduleBo extends BaseEntity {
// 内部类
@Data
public static class AppScheduleDetail extends org.dromara.app.domain.AppScheduleDetail {
public static class AppScheduleDetail {
private Long id;
@NotNull(message = "星期不能为空")
@Min(1) @Max(7)
private Integer weekday;
@NotNull(message = "开始时间不能为空")
private LocalTime startTime;
@NotNull(message = "持续时间不能为空")
//@Min(1) @Max(120)
private Integer durationMin;
private List<TimeSlot> timeData;
//@NotNull(message = "浇水区域不能为空")
private Integer zones; // 位掩码
private String triggerType = "0";
private String status = "0";
}
@Data
public static class TimeSlot {
private String startTime;
private Integer durationMin;
}

View File

@@ -1,5 +1,6 @@
package org.dromara.app.domain.bo;
import cn.hutool.json.JSON;
import org.dromara.app.domain.AppScheduleDetail;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import org.dromara.common.core.validate.AddGroup;
@@ -11,6 +12,9 @@ import jakarta.validation.constraints.*;
import java.time.LocalTime;
import java.util.Date;
import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonFormat;
/**
@@ -43,7 +47,9 @@ public class AppScheduleDetailBo extends BaseEntity {
/**
* 开始时间
*/
private LocalTime startTime;
private String timeData;
private String endTime;
/**
* 持续时间(分钟)

View File

@@ -24,7 +24,7 @@ public class AppSchedulingDeviceBo extends BaseEntity {
* 排程id
*/
@NotNull(message = "排程id不能为空", groups = { AddGroup.class, EditGroup.class })
private Long schedulingId;
private Long scheduleId;
/**
* 设备id

View File

@@ -38,6 +38,8 @@ public class AppWateringLogBo extends BaseEntity {
*/
private Long deviceId;
private String deviceNo;
/**
* 关联排程
*/
@@ -71,7 +73,7 @@ public class AppWateringLogBo extends BaseEntity {
/**
* 创建时间
*/
private Date createdTime;
private Date createTime;
}

View File

@@ -66,7 +66,10 @@ public class AppDeviceVo implements Serializable {
*/
@ExcelProperty(value = "状态 1-工作中 0-离线 2-待机 3-故障")
private String status;
/**
* 工作状态 1-工作中 0-休息
*/
private String workStatus;
/**
* 电量
*/

View File

@@ -2,6 +2,8 @@ package org.dromara.app.domain.vo;
import java.time.LocalTime;
import java.util.Date;
import cn.hutool.json.JSON;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.dromara.app.domain.AppScheduleDetail;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
@@ -14,7 +16,8 @@ import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
@@ -53,13 +56,14 @@ public class AppScheduleDetailVo implements Serializable {
* 开始时间
*/
@ExcelProperty(value = "开始时间")
private LocalTime startTime;
private String timeData;
private String endTime;
/**
* 持续时间(分钟)
*/
@ExcelProperty(value = "持续时间(分钟)")
private Integer durationMin;
private String durationMin;
/**
* 浇水区域
@@ -73,5 +77,12 @@ public class AppScheduleDetailVo implements Serializable {
@ExcelProperty(value = "方式 0-排程 1-手动 ")
private String triggerType;
private String status;
@Data
public static class TimeSlot {
private String startTime;
private Integer durationMin;
}
}

View File

@@ -53,7 +53,7 @@ public class AppScheduleVo implements Serializable {
/**
* 设备ids
*/
private List<Long> deviceIds;
private List deviceIds;
/**
* 状态 0-关闭 1 开启
*/

View File

@@ -1,5 +1,6 @@
package org.dromara.app.domain.vo;
import org.dromara.app.domain.AppSchedule;
import org.dromara.app.domain.AppSchedulingDevice;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
@@ -32,7 +33,7 @@ public class AppSchedulingDeviceVo implements Serializable {
* 排程id
*/
@ExcelProperty(value = "排程id")
private Long schedulingId;
private Long scheduleId;
/**
* 设备id
@@ -40,5 +41,6 @@ public class AppSchedulingDeviceVo implements Serializable {
@ExcelProperty(value = "设备id")
private Long deviceId;
private AppScheduleVo schedule;
}

View File

@@ -48,6 +48,7 @@ public class AppWateringLogVo implements Serializable {
@ExcelProperty(value = "设备ID")
private Long deviceId;
private String deviceNo;
/**
* 关联排程
*/
@@ -83,12 +84,13 @@ public class AppWateringLogVo implements Serializable {
*/
@ExcelProperty(value = "0-排程 1-手动")
private String triggerType;
private String deviceName;
/**
* 创建时间
*/
@ExcelProperty(value = "创建时间")
private Date createdTime;
private Date createTime;
}

View File

@@ -0,0 +1,26 @@
package org.dromara.app.handler;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@Slf4j
@Component
@RequiredArgsConstructor
public class DeviceDataHandler {
public void handle(String deviceId, String payload) {
try {
// DeviceDataDTO dto = JsonUtils.parseObject(payload, DeviceDataDTO.class);
// dto.setDeviceId(deviceId);
// dto.setReportTime(LocalDateTime.now());
// deviceDataService.saveDeviceData(dto);
log.info("[MQTT] 设备数据入库 deviceId={}", deviceId);
} catch (Exception e) {
log.error("[MQTT] 设备数据解析失败 deviceId={} payload={}", deviceId, payload, e);
}
}
}

View File

@@ -0,0 +1,29 @@
package org.dromara.app.handler;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.json.utils.JsonUtils;
import org.springframework.stereotype.Component;
import java.util.Map;
//设备在线状态
@Slf4j
@Component
@RequiredArgsConstructor
public class DeviceStatusHandler {
public void handle(String deviceNo, String payload) {
try {
Map<String,Object> dto = JsonUtils.parseObject(payload, Map.class);
// 更新设备在线状态
// log.info("[MQTT] 设备状态更新 deviceId={} status={}", deviceId, dto.getStatus());
} catch (Exception e) {
log.error("[MQTT] 设备状态处理失败 deviceId={}", deviceNo, e);
}
}
}

View File

@@ -0,0 +1,26 @@
package org.dromara.app.handler;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.json.utils.JsonUtils;
import org.springframework.stereotype.Component;
import java.util.Map;
//设备推送异常告警入库
@Slf4j
@Component
@RequiredArgsConstructor
public class ErromesHandler {
public void handle(String deviceNo, String payload) {
try {
Map<String,Object> dto = JsonUtils.parseObject(payload, Map.class);
log.info("[MQTT] 设备状态发送异常 deviceNo={}", deviceNo);
} catch (Exception e) {
log.error("[MQTT] 设备状态处理失败 deviceNo={}", deviceNo, e);
}
}
}

View File

@@ -1,5 +1,7 @@
package org.dromara.app.mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.dromara.app.domain.AppWateringLog;
import org.dromara.app.domain.vo.AppWateringLogVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
@@ -12,4 +14,26 @@ import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
*/
public interface AppWateringLogMapper extends BaseMapperPlus<AppWateringLog, AppWateringLogVo> {
@Select("SELECT count(id) FROM app_watering_log\n" +
"WHERE user_id=${userId} AND YEAR(create_time) = YEAR(CURDATE()) AND MONTH(create_time) = MONTH(CURDATE());")
Long selectByMonCout(@Param("userId") Long userId);
@Select("SELECT COUNT(id) \n" +
"FROM app_watering_log \n" +
"WHERE user_id=${userId} AND WEEK(create_time) = WEEK(CURDATE());")
Long selectByWeekCount(@Param("userId") Long userId);
@Select("SELECT COUNT(id) \n" +
"FROM app_watering_log \n" +
"WHERE user_id=${userId} AND trigger_type =${triggerType}")
Long selectByTriggerTypeCount(Long userId, String triggerType);
@Select("SELECT SUM(duration_min)\n" +
"FROM app_watering_log \n" +
"WHERE user_id=${userId}")
Long selectByTotalWateringTime(Long userId);
}

View File

@@ -0,0 +1,42 @@
package org.dromara.app.mqtt;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.app.handler.DeviceDataHandler;
import org.dromara.app.handler.DeviceStatusHandler;
import org.dromara.app.handler.ErromesHandler;
import org.springframework.stereotype.Component;
@Slf4j
@Component
@RequiredArgsConstructor
public class MqttMessageDispatcher {
private final DeviceDataHandler dataHandler;
private final DeviceStatusHandler statusHandler;
private final ErromesHandler erroHandler;
// 路由规则:匹配 topic 分发到对应 Handler
private static final String DATA_PATTERN = "/water/([^/]+)/data";
private static final String STATUS_PATTERN = "/water/([^/]+)/status";
private static final String ERROMES_PATTERN = "/water/([^/]+)/erromes";
public void dispatch(String topic, String payload) {
log.debug("[MQTT] 收到消息 topic={} 内容: {}", topic,payload);
if (topic.matches(DATA_PATTERN)) {
String deviceNo = extract(topic, DATA_PATTERN);
dataHandler.handle(deviceNo, payload);
} else if (topic.matches(STATUS_PATTERN)) {
String deviceNo = extract(topic, STATUS_PATTERN);
statusHandler.handle(deviceNo, payload);
}else if (topic.matches(ERROMES_PATTERN)) {
String deviceNo = extract(topic, STATUS_PATTERN);
erroHandler.handle(deviceNo, payload);
} else {
log.warn("[MQTT] 未知 topic: {} 内容: {}", topic,payload);
}
}
private String extract(String topic, String pattern) {
return topic.replaceAll(pattern, "$1");
}
}

View File

@@ -66,5 +66,5 @@ public interface IAppScheduleDetailService {
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
List<AppScheduleDetailVo> queryByScheduleId(Long id);
List<AppScheduleDetailVo> queryByScheduleIdByStatus(Long id);
}

View File

@@ -1,12 +1,16 @@
package org.dromara.app.service;
import jakarta.validation.constraints.NotNull;
import org.dromara.app.domain.vo.AppDeviceVo;
import org.dromara.app.domain.vo.AppScheduleVo;
import org.dromara.app.domain.bo.AppScheduleBo;
import org.dromara.app.domain.vo.AppSchedulingDeviceVo;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* 日程排列Service接口
@@ -47,7 +51,7 @@ public interface IAppScheduleService {
* @param bo 日程排列
* @return 是否新增成功
*/
Boolean insertByBo(AppScheduleBo bo);
AppScheduleVo insertByBo(AppScheduleBo bo);
/**
* 修改日程排列
@@ -55,7 +59,7 @@ public interface IAppScheduleService {
* @param bo 日程排列
* @return 是否修改成功
*/
List updateByBo(AppScheduleBo bo);
Map<String,Object> updateByBo(AppScheduleBo bo);
/**
* 校验并批量删除日程排列信息
@@ -65,4 +69,6 @@ public interface IAppScheduleService {
* @return 是否删除成功
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
Boolean updateStatusByBo(@NotNull(message = "主键不能为空") AppScheduleBo bo);
}

View File

@@ -1,5 +1,6 @@
package org.dromara.app.service;
import jakarta.validation.constraints.NotEmpty;
import org.dromara.app.domain.vo.AppSchedulingDeviceVo;
import org.dromara.app.domain.bo.AppSchedulingDeviceBo;
import org.dromara.common.mybatis.core.page.TableDataInfo;
@@ -65,4 +66,17 @@ public interface IAppSchedulingDeviceService {
* @return 是否删除成功
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
/**
* 查找某一设备的所有日程
* @param deviceId
* @return
*/
List<AppSchedulingDeviceVo> findByDeviceId(Long deviceId);
Boolean deleteWithValidByschedulingIds2Ids(@NotEmpty(message = "主键不能为空") Long schedulingId, Long deviceId);
AppSchedulingDeviceVo queryById2DeviveId(Long scheduleId, Long id);
List<AppSchedulingDeviceVo> queryByDeviveId(Long id);
}

View File

@@ -65,4 +65,16 @@ public interface IAppWateringLogService {
* @return 是否删除成功
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
Long queryCount(Long userId);
Long queryByMonCount(Long userId);
Long queryByWeekCount(Long userId);
Long queryByTriggerTypeCount(Long userId, String triggerType);
Long queryByTotalWateringTime(Long userId);
}

View File

@@ -1,5 +1,8 @@
package org.dromara.app.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.dromara.app.domain.AppSchedulingDevice;
import org.dromara.app.mapper.AppSchedulingDeviceMapper;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.annotation.DataColumn;
@@ -11,12 +14,14 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.satoken.utils.LoginHelper;
import org.springframework.stereotype.Service;
import org.dromara.app.domain.bo.AppDeviceBo;
import org.dromara.app.domain.vo.AppDeviceVo;
import org.dromara.app.domain.AppDevice;
import org.dromara.app.mapper.AppDeviceMapper;
import org.dromara.app.service.IAppDeviceService;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Map;
@@ -35,6 +40,7 @@ Service业务层处理
public class AppDeviceServiceImpl implements IAppDeviceService {
private final AppDeviceMapper baseMapper;
private final AppSchedulingDeviceMapper schedulingDeviceMapper;
/**
* 查询设备信息
@@ -150,10 +156,18 @@ public class AppDeviceServiceImpl implements IAppDeviceService {
* @return 是否删除成功
*/
@Override
@Transactional
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteByIds(ids) > 0;
boolean flag = baseMapper.deleteByIds(ids) > 0;
if (flag){
for (Long id :ids){
schedulingDeviceMapper.delete(new QueryWrapper<AppSchedulingDevice>().eq("device_id",id));
}
}
return flag;
}
}

View File

@@ -1,5 +1,7 @@
package org.dromara.app.service.impl;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
@@ -76,8 +78,8 @@ public class AppScheduleDetailServiceImpl implements IAppScheduleDetailService {
lqw.orderByAsc(AppScheduleDetail::getId);
lqw.eq(bo.getScheduleId() != null, AppScheduleDetail::getScheduleId, bo.getScheduleId());
lqw.eq(StringUtils.isNotBlank(bo.getWeekday()), AppScheduleDetail::getWeekday, bo.getWeekday());
lqw.eq(bo.getStartTime() != null, AppScheduleDetail::getStartTime, bo.getStartTime());
lqw.eq(StringUtils.isNotBlank(bo.getDurationMin()), AppScheduleDetail::getDurationMin, bo.getDurationMin());
lqw.eq(bo.getTimeData() != null, AppScheduleDetail::getTimeData, bo.getTimeData());
lqw.eq(ObjectUtil.isNotNull(bo.getDurationMin()), AppScheduleDetail::getDurationMin, bo.getDurationMin());
lqw.eq(StringUtils.isNotBlank(bo.getZones()), AppScheduleDetail::getZones, bo.getZones());
lqw.eq(StringUtils.isNotBlank(bo.getTriggerType()), AppScheduleDetail::getTriggerType, bo.getTriggerType());
return lqw;
@@ -136,7 +138,8 @@ public class AppScheduleDetailServiceImpl implements IAppScheduleDetailService {
}
@Override
public List<AppScheduleDetailVo> queryByScheduleId(Long id) {
return List.of();
public List<AppScheduleDetailVo> queryByScheduleIdByStatus(Long id) {
return baseMapper.selectVoList(new QueryWrapper<AppScheduleDetail>().eq("schedule_id",id));
}
}

View File

@@ -3,10 +3,14 @@ package org.dromara.app.service.impl;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.dromara.app.domain.AppSchedulingDevice;
import org.dromara.app.domain.vo.AppDeviceVo;
import org.dromara.app.domain.vo.AppScheduleDetailVo;
import org.dromara.app.domain.vo.AppSchedulingDeviceVo;
import org.dromara.app.mapper.AppScheduleDetailMapper;
import org.dromara.app.mapper.AppSchedulingDeviceMapper;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.json.utils.JsonUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -14,6 +18,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.satoken.utils.LoginHelper;
import org.springframework.stereotype.Service;
import org.dromara.app.domain.bo.AppScheduleBo;
import org.dromara.app.domain.vo.AppScheduleVo;
@@ -24,6 +29,7 @@ import org.dromara.app.service.IAppScheduleService;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.*;
/**
@@ -84,6 +90,7 @@ public class AppScheduleServiceImpl implements IAppScheduleService {
lqw.orderByAsc(AppSchedule::getId);
lqw.like(StringUtils.isNotBlank(bo.getName()), AppSchedule::getName, bo.getName());
lqw.eq(StringUtils.isNotBlank(bo.getStatus()), AppSchedule::getStatus, bo.getStatus());
lqw.eq(bo.getUserId() != null, AppSchedule::getUserId, bo.getUserId());
return lqw;
}
@@ -95,37 +102,54 @@ public class AppScheduleServiceImpl implements IAppScheduleService {
*/
@Override
@Transactional
public Boolean insertByBo(AppScheduleBo bo) {
public AppScheduleVo insertByBo(AppScheduleBo bo) {
AppSchedule add = MapstructUtils.convert(bo, AppSchedule.class);
add.setUserId(LoginHelper.getUserId());
validEntityBeforeSave(add);
//创建排程
boolean flag = baseMapper.insert(add) > 0;
//创建详情
for (AppScheduleBo.AppScheduleDetail item:bo.getDetails()){
AppScheduleDetail detail = new AppScheduleDetail();
detail.setWeekday(item.getWeekday());
detail.setStartTime(item.getStartTime());
detail.setDurationMin(item.getDurationMin());
detail.setZones(item.getZones());
detail.setTriggerType(item.getTriggerType());
scheduleDetailMapper.insert(detail);
}
//绑定设备
for (Long deviceId:bo.getDeviceIds()){
//查询设备日程冲突
List list = checkConflict(deviceId, bo);
if (list.size()!=0){
return false;
if (flag){
AppScheduleVo vo = MapstructUtils.convert(add, AppScheduleVo.class);
List list = new ArrayList<>();
//创建详情
for (AppScheduleBo.AppScheduleDetail item:bo.getDetails()){
AppScheduleDetail detail = new AppScheduleDetail();
detail.setScheduleId(add.getId());
detail.setWeekday(item.getWeekday());
if (ObjectUtil.isNotNull(item.getTimeData())){
detail.setTimeData(JsonUtils.toJsonString(item.getTimeData()));
// detail.setEndTime(item.getStartTime().plusMinutes(item.getDurationMin()));
}
detail.setZones(item.getZones());
detail.setTriggerType(item.getTriggerType());
detail.setStatus(item.getStatus());
scheduleDetailMapper.insert(detail);
List timeSlots = new ArrayList();
for (AppScheduleBo.TimeSlot timeSlot:item.getTimeData()){
timeSlots.add(timeSlot);
}
Map map = new HashMap();
map.put("id",detail.getId() );
map.put("weekday",detail.getWeekday() );
map.put("timeData",timeSlots );
map.put("triggerType",detail.getTriggerType() );
map.put("status",detail.getStatus() );
map.put("createTime",detail.getCreateTime() );
list.add(map);
}
//没冲突设备绑定日程
AppSchedulingDevice appSchedulingDevice = new AppSchedulingDevice();
appSchedulingDevice.setDeviceId(deviceId);
appSchedulingDevice.setSchedulingId(add.getId());
appSchedulingDevice.setCreateTime(new Date());
schedulingDeviceMapper.insert(appSchedulingDevice);
vo.setDetails(list);
return vo;
}
return flag;
return new AppScheduleVo();
}
@Override
public Boolean updateStatusByBo(AppScheduleBo bo) {
AppSchedule update = MapstructUtils.convert(bo, AppSchedule.class);
return baseMapper.updateById(update)>0;
}
/**
@@ -135,36 +159,47 @@ public class AppScheduleServiceImpl implements IAppScheduleService {
* @return 是否修改成功
*/
@Override
public List updateByBo(AppScheduleBo bo) {
@Transactional
public Map<String,Object> updateByBo(AppScheduleBo bo) {
AppSchedule update = MapstructUtils.convert(bo, AppSchedule.class);
validEntityBeforeSave(update);
//修改详情
for (AppScheduleBo.AppScheduleDetail item:bo.getDetails()){
AppScheduleDetail detail = new AppScheduleDetail();
detail.setWeekday(item.getWeekday());
detail.setStartTime(item.getStartTime());
detail.setDurationMin(item.getDurationMin());
detail.setZones(item.getZones());
detail.setTriggerType(item.getTriggerType());
scheduleDetailMapper.updateById(detail);
}
//绑定设备
for (Long deviceId:bo.getDeviceIds()){
//查询设备日程冲突
List list = checkConflict(deviceId, bo);
if (list.size()!=0){
//有冲突
return list;
Map<String,Object> repMap = new HashMap();
Boolean flag = baseMapper.updateById(update)>0;
repMap.put("flag", flag);
repMap.put("list", new ArrayList<>());
repMap.put("appSchedule", "");
if (flag){
AppScheduleVo appScheduleVo = baseMapper.selectVoById(update.getId());
//修改详情
List detailList = new ArrayList<>();
for (AppScheduleBo.AppScheduleDetail item:bo.getDetails()){
AppScheduleDetail detail = new AppScheduleDetail();
detail.setWeekday(item.getWeekday());
detail.setId(item.getId());
detail.setTimeData(JsonUtils.toJsonString(item.getTimeData()));
detail.setZones(item.getZones());
detail.setTriggerType(item.getTriggerType());
detail.setStatus(item.getStatus());
scheduleDetailMapper.updateById(detail);
List timeSlots = new ArrayList();
for (AppScheduleBo.TimeSlot timeSlot:item.getTimeData()){
timeSlots.add(timeSlot);
}
Map map = new HashMap();
map.put("id",detail.getId() );
map.put("weekday",detail.getWeekday() );
map.put("timeData",timeSlots );
map.put("triggerType",detail.getTriggerType() );
map.put("status",detail.getStatus() );
map.put("createTime",detail.getCreateTime() );
detailList.add(map);
}
//没冲突设备绑定日程
AppSchedulingDevice appSchedulingDevice = new AppSchedulingDevice();
appSchedulingDevice.setDeviceId(deviceId);
appSchedulingDevice.setSchedulingId(bo.getId());
appSchedulingDevice.setCreateTime(new Date());
appScheduleVo.setDetails(detailList);
repMap.put("appSchedule", appScheduleVo);
return repMap;
}
return new ArrayList();
return repMap;
}
/**
@@ -182,44 +217,55 @@ public class AppScheduleServiceImpl implements IAppScheduleService {
* @return 是否删除成功
*/
@Override
@Transactional
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
boolean flag = false;
try {
flag = baseMapper.deleteByIds(ids) > 0;
if (flag){
for (Long id :ids){
schedulingDeviceMapper.delete(new QueryWrapper<AppSchedulingDevice>().eq("schedule_id",id ));
scheduleDetailMapper.delete(new QueryWrapper<AppScheduleDetail>().eq("schedule_id", id));
}
}
return flag;
} catch (Exception e) {
throw new RuntimeException(e);
}
return baseMapper.deleteByIds(ids) > 0;
}
/**
* 检查新日程与设备已绑定日程是否存在时间冲突
*/
public List checkConflict(Long deviceId, AppScheduleBo newSchedule) {
public List checkConflict(Long deviceId, AppScheduleVo newSchedule) {
// 1. 获取该设备所有已绑定的日程
List<AppSchedulingDevice> existingBindings = schedulingDeviceMapper.selectList(new QueryWrapper<AppSchedulingDevice>().eq("device_id", deviceId));
List conflicts = new ArrayList<>();
//新日程的详情列
List<AppScheduleDetail> scheduleDetails = scheduleDetailMapper.selectList(new QueryWrapper<AppScheduleDetail>().eq("schedule_id", newSchedule.getId()));
// 2. 对新日程的每一天,与已存在的每一天逐一比较
for (AppScheduleDetail newDay : newSchedule.getDetails()) {
//关闭的排程直接跳出
if ("0".equals(newSchedule.getStatus())) break;
for (AppScheduleDetail newDay : scheduleDetails) {
//此设备日程
for (AppSchedulingDevice existing : existingBindings){
AppScheduleVo appScheduleVo = baseMapper.selectVoById(existing.getSchedulingId());
AppScheduleVo appScheduleVo = baseMapper.selectVoById(existing.getScheduleId());
if (ObjectUtil.isNotNull(appScheduleVo) && !"0".equals(appScheduleVo.getStatus())){
List<AppScheduleDetail> details = scheduleDetailMapper.selectList(new QueryWrapper<AppScheduleDetail>().eq("scheduling_id", existing.getSchedulingId()));
List<AppScheduleDetail> details = scheduleDetailMapper.selectList(new QueryWrapper<AppScheduleDetail>().eq("schedule_id", existing.getScheduleId()));
for (AppScheduleDetail existingDay:details ){
// 3. 同一天才检查时间重叠
if (newDay.getWeekday() == existingDay.getWeekday()) {
if (timeOverlap(newDay, existingDay)) {
Map map = new HashMap();
map.put("scheduleName", appScheduleVo.getName());
map.put("newDay", newDay);
map.put("existingDay", existingDay);
conflicts.add(map);
}
// if (timeOverlap(newDay, existingDay)) {
//
// Map map = new HashMap();
// map.put("scheduleName", appScheduleVo.getName());
// map.put("newDay", newDay);
// map.put("existingDay", existingDay);
// conflicts.add(map);
// }
}
}
}
@@ -232,13 +278,13 @@ public class AppScheduleServiceImpl implements IAppScheduleService {
* 判断两段时间是否重叠
* 重叠条件start1 < end2 && start2 < end1
*/
public boolean timeOverlap(AppScheduleDetail a, AppScheduleDetail b) {
LocalTime bendTime = b.getStartTime().plusMinutes(b.getDurationMin());
LocalTime aendTime = a.getStartTime().plusMinutes(a.getDurationMin());
return a.getStartTime().isBefore(bendTime)
&& b.getStartTime().isBefore(aendTime);
}
// public boolean timeOverlap(AppScheduleDetail a, AppScheduleDetail b) {
// LocalTime bendTime = b.getStartTime().plusMinutes(b.getDurationMin());
// LocalTime aendTime = a.getStartTime().plusMinutes(a.getDurationMin());
//
// return a.getStartTime().isBefore(bendTime)
// && b.getStartTime().isBefore(aendTime);
// }
}

View File

@@ -1,7 +1,7 @@
package org.dromara.app.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -73,7 +73,7 @@ public class AppSchedulingDeviceServiceImpl implements IAppSchedulingDeviceServi
private LambdaQueryWrapper<AppSchedulingDevice> buildQueryWrapper(AppSchedulingDeviceBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<AppSchedulingDevice> lqw = Wrappers.lambdaQuery();
lqw.eq(bo.getSchedulingId() != null, AppSchedulingDevice::getSchedulingId, bo.getSchedulingId());
lqw.eq(bo.getScheduleId() != null, AppSchedulingDevice::getScheduleId, bo.getScheduleId());
lqw.eq(bo.getDeviceId() != null, AppSchedulingDevice::getDeviceId, bo.getDeviceId());
return lqw;
}
@@ -90,7 +90,7 @@ public class AppSchedulingDeviceServiceImpl implements IAppSchedulingDeviceServi
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setSchedulingId(add.getSchedulingId());
bo.setScheduleId(add.getScheduleId());
}
return flag;
}
@@ -129,4 +129,25 @@ public class AppSchedulingDeviceServiceImpl implements IAppSchedulingDeviceServi
}
return baseMapper.deleteByIds(ids) > 0;
}
@Override
public AppSchedulingDeviceVo queryById2DeviveId(Long scheduleId, Long id) {
return baseMapper.selectVoOne(new QueryWrapper<AppSchedulingDevice>().eq("schedule_id",scheduleId).eq("device_id",id));
}
@Override
public List<AppSchedulingDeviceVo> queryByDeviveId(Long id) {
return baseMapper.selectVoList(new QueryWrapper<AppSchedulingDevice>().eq("device_id",id));
}
@Override
public Boolean deleteWithValidByschedulingIds2Ids(Long schedulingId, Long deviceId) {
return baseMapper.delete(new QueryWrapper<AppSchedulingDevice>().eq("schedule_id",schedulingId).eq("device_id",deviceId)) > 0;
}
@Override
public List<AppSchedulingDeviceVo> findByDeviceId(Long deviceId) {
return baseMapper.selectVoList(new QueryWrapper<AppSchedulingDevice>().eq("device_id",deviceId));
}
}

View File

@@ -1,5 +1,6 @@
package org.dromara.app.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
@@ -9,6 +10,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.system.domain.SysConfig;
import org.springframework.stereotype.Service;
import org.dromara.app.domain.bo.AppWateringLogBo;
import org.dromara.app.domain.vo.AppWateringLogVo;
@@ -82,7 +84,10 @@ public class AppWateringLogServiceImpl implements IAppWateringLogService {
lqw.eq(StringUtils.isNotBlank(bo.getDurationMin()), AppWateringLog::getDurationMin, bo.getDurationMin());
lqw.eq(StringUtils.isNotBlank(bo.getZones()), AppWateringLog::getZones, bo.getZones());
lqw.eq(StringUtils.isNotBlank(bo.getTriggerType()), AppWateringLog::getTriggerType, bo.getTriggerType());
lqw.eq(bo.getCreatedTime() != null, AppWateringLog::getCreatedTime, bo.getCreatedTime());
// lqw.eq(bo.getCreateTime() != null, AppWateringLog::getCreateTime, bo.getCreateTime());
lqw.between(params.get("beginTime") != null && params.get("endTime") != null,
AppWateringLog::getCreateTime, params.get("beginTime"), params.get("endTime"));
return lqw;
}
@@ -137,4 +142,32 @@ public class AppWateringLogServiceImpl implements IAppWateringLogService {
}
return baseMapper.deleteByIds(ids) > 0;
}
@Override
public Long queryCount(Long userId) {
return baseMapper.selectCount(new QueryWrapper<AppWateringLog>().eq("user_id",userId));
}
@Override
public Long queryByMonCount(Long userId) {
return baseMapper.selectByMonCout(userId);
}
@Override
public Long queryByWeekCount(Long userId) {
return baseMapper.selectByWeekCount(userId);
}
@Override
public Long queryByTriggerTypeCount(Long userId, String triggerType) {
return baseMapper.selectByTriggerTypeCount(userId,triggerType);
}
@Override
public Long queryByTotalWateringTime(Long userId) {
return baseMapper.selectByTotalWateringTime(userId);
}
}