diff --git a/zsw-farm/zsw-farm-api/src/main/java/cn/iocoder/yudao/module/farm/enums/ErrorCodeConstants.java b/zsw-farm/zsw-farm-api/src/main/java/cn/iocoder/yudao/module/farm/enums/ErrorCodeConstants.java index dad78503..e8d8257c 100644 --- a/zsw-farm/zsw-farm-api/src/main/java/cn/iocoder/yudao/module/farm/enums/ErrorCodeConstants.java +++ b/zsw-farm/zsw-farm-api/src/main/java/cn/iocoder/yudao/module/farm/enums/ErrorCodeConstants.java @@ -61,6 +61,8 @@ public interface ErrorCodeConstants{ ErrorCode TASK_COMPLETE_CHANGE_FAIL = new ErrorCode(100000727, "任务更改失败, 已完成的任务不能修改任何信息"); ErrorCode TASK_STARTED_FAIL = new ErrorCode(100000728, "任务更改失败, 所选资源已被占用"); + + ErrorCode EXECUTE_TIME_IS_BEFORE_TODAY = new ErrorCode(100000729, "执行时间不能在今天之前,操作失败"); } diff --git a/zsw-farm/zsw-farm-api/src/main/java/cn/iocoder/yudao/module/farm/enums/FarmTimeEnum.java b/zsw-farm/zsw-farm-api/src/main/java/cn/iocoder/yudao/module/farm/enums/FarmTimeEnum.java index 77345801..e856231d 100644 --- a/zsw-farm/zsw-farm-api/src/main/java/cn/iocoder/yudao/module/farm/enums/FarmTimeEnum.java +++ b/zsw-farm/zsw-farm-api/src/main/java/cn/iocoder/yudao/module/farm/enums/FarmTimeEnum.java @@ -15,7 +15,13 @@ public enum FarmTimeEnum { TWO_WEEK(5,"两周内,往前推14天"), ONE_MONTH(6,"一个月,往前30天"), - THREE_MONTH(7,"三个月,往前90天"); + THREE_MONTH(7,"三个月,往前90天"), + + + + IS_TODAY(8, "是今天"), + BEFORE_TODAY(9, "今天之前"), + AFTER_TODAY(10, "今天之后"); private final Integer code; diff --git a/zsw-farm/zsw-farm-api/src/main/java/cn/iocoder/yudao/module/farm/util/FarmTimeUtil.java b/zsw-farm/zsw-farm-api/src/main/java/cn/iocoder/yudao/module/farm/util/FarmTimeUtil.java index 29cbd325..f91abc54 100644 --- a/zsw-farm/zsw-farm-api/src/main/java/cn/iocoder/yudao/module/farm/util/FarmTimeUtil.java +++ b/zsw-farm/zsw-farm-api/src/main/java/cn/iocoder/yudao/module/farm/util/FarmTimeUtil.java @@ -8,8 +8,9 @@ import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.module.farm.enums.FarmTimeEnum; import lombok.experimental.UtilityClass; +import java.time.LocalDate; import java.time.LocalDateTime; -import java.time.temporal.ChronoUnit; +import java.time.format.DateTimeFormatter; import java.util.Date; /** @@ -54,8 +55,28 @@ public class FarmTimeUtil { return null; } return TimeLimitDTO.builder().startTime(startTime).endTime(currentTime).build(); + } + /** + * 根据传来的时间 与 今天比较 + * @Return 是今天、今天之前、今天之后 + */ + public FarmTimeEnum checkingDate(Date date){ + String dateTime = DateUtil.format(date, "yyyy-MM-dd"); + LocalDate date1 = LocalDateTimeUtil.parseDate(dateTime, DateTimeFormatter.ofPattern("yyyy-MM-dd")); + if (date1.isBefore(LocalDate.now())){ + //1、执行时间在今天之前,返回失败 + return FarmTimeEnum.BEFORE_TODAY; + }else if (date1.equals(LocalDate.now())){ + //2、执行时间在今天,变成进行中 + return FarmTimeEnum.IS_TODAY; + }else { + //3、执行时间在今天之后, 变成准备中 + return FarmTimeEnum.AFTER_TODAY; + } } + + } diff --git a/zsw-farm/zsw-farm-impl/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/statistical/StatisticalController.java b/zsw-farm/zsw-farm-impl/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/statistical/StatisticalController.java index b83c17a0..ea064c0f 100644 --- a/zsw-farm/zsw-farm-impl/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/statistical/StatisticalController.java +++ b/zsw-farm/zsw-farm-impl/src/main/java/cn/iocoder/yudao/module/farm/controller/admin/statistical/StatisticalController.java @@ -57,14 +57,26 @@ public class StatisticalController { @PostMapping("/statisticalInformation") @ApiOperation("农场数据统计接口") public CommonResult statisticalInformation(@RequestBody RequestDTO searchDTO){ - TimeLimitDTO time = FarmTimeUtil.getStartTimeAndEndTime(searchDTO.getTimeEnum()); StatisticalVo vo = new StatisticalVo(); - //获取时间内的所有工时记录 - List workList = workHourMapper.selectList(Wrappers.lambdaQuery().ge(WorkHourDO::getCreateTime, time.getStartTime()).le(WorkHourDO::getCreateTime, time.getEndTime())); + //工时统计 + this.workHourMsg(searchDTO, vo); + //任务数据 + List taskList = this.projectMsg(vo); + //种植数量 饼状图 + this.cakeMsg(vo, taskList); + return CommonResult.success(vo); + } + /** + * 工时统计 + */ + public void workHourMsg(RequestDTO searchDTO, StatisticalVo vo){ + TimeLimitDTO time = FarmTimeUtil.getStartTimeAndEndTime(searchDTO.getTimeEnum()); vo.setStartTime(DateUtil.format(time.getStartTime(), "yyyy/MM/dd" )); vo.setEndTime(DateUtil.format(time.getEndTime(), "yyyy/MM/dd" )); + //获取时间内的所有工时记录 + List workList = workHourMapper.selectList(Wrappers.lambdaQuery().ge(WorkHourDO::getCreateTime, time.getStartTime()).le(WorkHourDO::getCreateTime, time.getEndTime())); //工时统计 条形图 List workMsgList = new ArrayList<>(); if (ObjectUtil.isEmpty(workList)){ @@ -74,11 +86,8 @@ public class StatisticalController { List workUserIdList = workList.stream().map(WorkHourDO::getUserId).collect(Collectors.toList()); //获取工时所有人信息 List userList = cpUserMapper.selectList(Wrappers.lambdaQuery().in(CpUserDO::getId, workUserIdList)); - Map> workMap = workList.stream().collect(Collectors.groupingBy(WorkHourDO::getUserId)); Iterator>> iterator = workMap.entrySet().iterator(); - - while (iterator.hasNext()){ Entry> entry = iterator.next(); Long userId = entry.getKey(); @@ -93,10 +102,12 @@ public class StatisticalController { workMsgList = workMsgList.stream().sorted(Comparator.comparing(WorkMsg::getHour).reversed()).collect(Collectors.toList()); vo.setWorkMsgList(workMsgList); } + } - - - //任务数据 + /** + * 项目数据 + */ + public List projectMsg(StatisticalVo vo){ List taskList = taskMapper.selectList(Wrappers.lambdaQuery().eq(TaskDO::getPretendDelete, false).eq(TaskDO::getDraft, false)); vo.setTaskTotalCount(taskList.size()); Long planeCount = taskList.stream().filter(plane -> plane.getStatus().equals(TaskStatus.PLAN) || plane.getStatus().equals(TaskStatus.READY)).count(); @@ -106,57 +117,52 @@ public class StatisticalController { vo.setTaskStartingCount(startCount.intValue()); Long completeCount = taskList.stream().filter(plane -> plane.getStatus().equals(TaskStatus.COMPLETE) || plane.getStatus().equals(TaskStatus.END)).count(); vo.setTaskCompleteCount(completeCount.intValue()); + return taskList; + } - + /** + * 饼状图数据 + */ + public void cakeMsg(StatisticalVo vo, List taskList){ //种植数量 饼状图 - //根据工时获取所有的活动 List finishTaskList = taskList.stream().filter(item -> item.getStatus().equals(TaskStatus.COMPLETE)).collect(Collectors.toList()); - List cropIdList = finishTaskList.stream().map(TaskDO::getCropId).collect(Collectors.toList()); + List cropIdList = finishTaskList.stream().map(TaskDO::getCropId).distinct().collect(Collectors.toList()); if (ObjectUtils.isEmpty(cropIdList)){ vo.setCakeSeries(new ArrayList<>()); }else { List cropList = cropMapper.selectList(Wrappers.lambdaQuery().in(CropDO::getId, cropIdList)); - List areaList = areaMapper.selectList(Wrappers.lambdaQuery().eq(AreaDO::getPretendDelete, false).ne(AreaDO::getParentId, 0)); Map cropMap = new HashMap<>(); - for (TaskDO taskDO : finishTaskList) { - for (CropDO cropDO : cropList) { - if (taskDO.getCropId().equals(cropDO.getId())){ - //这里是算 这个任务所选区域的总面积 - Double areaSum = new Double(0); - for (Long areaId : taskDO.getAreas()) { - List areaDOS = areaList.stream().filter(area -> area.getId().equals(areaId)).collect(Collectors.toList()); - if (ObjectUtil.isNotEmpty(areaDOS)){ - areaSum += areaDOS.stream().mapToDouble(AreaDO::getArea).sum(); - } - } - //饼状图 作物名 - if (cropMap.containsKey(cropDO.getId())){ - CakeSeries cakeSeries = cropMap.get(cropDO.getId()); - cakeSeries.setValue(cakeSeries.getValue() + areaSum); - cakeSeries.setLabelText(cakeSeries.getValue().toString()); - }else{ - CakeSeries cakeSeries = CakeSeries.builder() - .name(cropDO.getName()) - .value(areaSum) - .labelText(areaSum.toString()) - .build(); - cropMap.put(cropDO.getId(), cakeSeries); - } - } + cropList.forEach(item ->{ + //初始化cropMap, key = 作物id, value是饼状图属性 + cropMap.put(item.getId(), new CakeSeries().setName(item.getName()).setValue(0d).setLabelText("0")); + }); + + List areaIdList = new ArrayList<>(); + finishTaskList.stream().forEach(item ->{ + areaIdList.addAll(item.getAreas()); + }); + List distinctIdList = areaIdList.stream().distinct().collect(Collectors.toList()); + + List areaDOList = areaMapper.selectList(Wrappers.lambdaQuery().in(AreaDO::getId, distinctIdList)); + finishTaskList.forEach(taskDO -> { + //先算出每个完成的任务所选区域的面积和 + Double areaSum = 0d; + for (Long areaId : taskDO.getAreas()) { + Optional areaDO = areaDOList.stream().filter(item -> item.getId().equals(areaId)).collect(Collectors.toList()).stream().findFirst(); + areaSum += areaDO.isPresent() ? areaDO.get().getArea() : 0; } - } - List cakeList = new ArrayList<>(); - Iterator> cropItertor = cropMap.entrySet().iterator(); - while (cropItertor.hasNext()){ - cakeList.add(cropItertor.next().getValue()); - } + //再与cropMap 进行 累加面积 + if (cropMap.containsKey(taskDO.getCropId())){ + CakeSeries ck = cropMap.get(taskDO.getCropId()); + ck.setValue(ck.getValue() + areaSum); + ck.setLabelText(ck.getValue().toString()); + } + }); + List cakeList = cropMap.values().stream().collect(Collectors.toList()); vo.setCakeSeries(cakeList); } - vo.setCakeTitle("总数量"); vo.setCakeSubtitle(vo.getCakeSeries().stream().mapToDouble(CakeSeries::getValue).sum()+"平方"); - - return CommonResult.success(vo); } } diff --git a/zsw-farm/zsw-farm-impl/src/main/java/cn/iocoder/yudao/module/farm/service/task/TaskServiceImpl.java b/zsw-farm/zsw-farm-impl/src/main/java/cn/iocoder/yudao/module/farm/service/task/TaskServiceImpl.java index f63033ab..0b41964d 100644 --- a/zsw-farm/zsw-farm-impl/src/main/java/cn/iocoder/yudao/module/farm/service/task/TaskServiceImpl.java +++ b/zsw-farm/zsw-farm-impl/src/main/java/cn/iocoder/yudao/module/farm/service/task/TaskServiceImpl.java @@ -33,10 +33,12 @@ import cn.iocoder.yudao.module.farm.dal.mysql.resource.ResourceMapper; import cn.iocoder.yudao.module.farm.dal.mysql.resourceType.ResourceTypeMapper; import cn.iocoder.yudao.module.farm.dal.mysql.task.TaskMapper; import cn.iocoder.yudao.module.farm.dal.mysql.taskCate.TaskCateMapper; +import cn.iocoder.yudao.module.farm.enums.FarmTimeEnum; import cn.iocoder.yudao.module.farm.enums.ProjectStateEnum; import cn.iocoder.yudao.module.farm.enums.TaskMemberEnum; import cn.iocoder.yudao.module.farm.enums.TaskStatus; import cn.iocoder.yudao.module.farm.service.taskCate.TaskCateService; +import cn.iocoder.yudao.module.farm.util.FarmTimeUtil; import cn.iocoder.yudao.module.system.dal.dataobject.CpUser.CpUserDO; import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; import cn.iocoder.yudao.module.system.dal.mysql.CpUser.CpUserMapper; @@ -100,8 +102,10 @@ public class TaskServiceImpl implements TaskService { @Override public Long createTask(TaskCreateReqVO createReqVO) { TaskDO task = BeanUtil.copyProperties(createReqVO, TaskDO.class); - //检查任务能否新增 + //检查任务能否新增/修改 this.canTheTaskStart(task); + //根据执行时间 赋予任务状态 + this.checkStateByExecutionTime(task); //检查任务资源数量 // this.checkTaskResourceNumber(task); task.setDeptId(Objects.requireNonNull(SecurityFrameworkUtils.getLoginUser()).getDeptId()); @@ -114,12 +118,14 @@ public class TaskServiceImpl implements TaskService { @Override public void updateTask(TaskUpdateReqVO updateReqVO) { TaskDO task = BeanUtil.copyProperties(updateReqVO, TaskDO.class); - //项目能否更改状态 - this.checkTaskStatus(updateReqVO); - //检查项目能否开始 + //检查任务能否新增/修改 this.canTheTaskStart(task); + //根据执行时间 赋予任务状态 + this.checkStateByExecutionTime(task); // 校验存在 this.validateTaskExists(updateReqVO.getId()); + //项目能否更改状态 + this.checkTaskStatus(updateReqVO); //检查任务资源数量 // this.checkTaskResourceNumber(task); // 更新 @@ -540,32 +546,53 @@ public class TaskServiceImpl implements TaskService { if (task.getStatus().equals(TaskStatus.COMPLETE)){ throw exception(TASK_COMPLETE_CHANGE_FAIL); } - }else{ - //任务更改失败, 计划中或准备中的任务只能更改为开始 - if (task.getStatus().equals(TaskStatus.PLAN) || task.getStatus().equals(TaskStatus.READY)){ - if (!updateVO.getStatus().equals(TaskStatus.STARTED)){ - throw exception(TASK_STATE_CHANGE_FAIL); - } - } - //任务更改失败, 已开始的任务不能更改为计划中或准备中 - if (task.getStatus().equals(TaskStatus.STARTED)){ - if (updateVO.getStatus().equals(TaskStatus.PLAN) || updateVO.getStatus().equals(TaskStatus.READY)){ - throw exception(TASK_WAS_STARTED); - } - } - //任务更改失败, 已完成的任务只能更改为任务关闭 - if (task.getStatus().equals(TaskStatus.COMPLETE)){ - if (!updateVO.getStatus().equals(TaskStatus.END)){ - throw exception(TASK_WAS_END); - } + } +// else{ +// //任务更改失败, 计划中或准备中的任务只能更改为开始 +// if (task.getStatus().equals(TaskStatus.PLAN) || task.getStatus().equals(TaskStatus.READY)){ +// if (!updateVO.getStatus().equals(TaskStatus.STARTED)){ +// throw exception(TASK_STATE_CHANGE_FAIL); +// } +// } +// //任务更改失败, 已开始的任务不能更改为计划中或准备中 +// if (task.getStatus().equals(TaskStatus.STARTED)){ +// if (updateVO.getStatus().equals(TaskStatus.PLAN) || updateVO.getStatus().equals(TaskStatus.READY)){ +// throw exception(TASK_WAS_STARTED); +// } +// } +// //任务更改失败, 已完成的任务只能更改为任务关闭 +// if (task.getStatus().equals(TaskStatus.COMPLETE)){ +// if (!updateVO.getStatus().equals(TaskStatus.END)){ +// throw exception(TASK_WAS_END); +// } +// } +// } + } + + /** + * 新增和修改 根据执行时间 赋值任务状态 + * @param task 任务实体 + */ + public void checkStateByExecutionTime(TaskDO task){ + if (task.getPlanStartTime() != null){ + FarmTimeEnum timeEnum = FarmTimeUtil.checkingDate(task.getPlanStartTime()); + if (timeEnum.equals(FarmTimeEnum.BEFORE_TODAY)){ + throw exception(EXECUTE_TIME_IS_BEFORE_TODAY); + }else if (timeEnum.equals(FarmTimeEnum.IS_TODAY)){ + task.setStatus(TaskStatus.STARTED); + }else{ + task.setStatus(TaskStatus.READY); } } } + + /** * 定时任务:检查任务状态 计划中、准备中的到了执行时间变成已开始 + * 每天凌晨3点执行一次 */ - @Scheduled(cron = "* 0/10 * * * ?") + @Scheduled(cron = "0 0 3 * * ?") public void timingCheckTaskStatus(){ Boolean oldIgnore = TenantContextHolder.isIgnore(); try {