package com.ruoyi.web.controller.api; import cn.hutool.core.util.RandomUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; 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.ruoyi.common.annotation.Log; import com.ruoyi.common.basic.PageInfo; import com.ruoyi.common.core.domain.BaseModel; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.domain.entity.SysRole; import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.utils.CodeGenerateUtils; import com.ruoyi.common.utils.bean.BeanUtils; import com.ruoyi.framework.web.service.TokenService; import com.ruoyi.system.applet.dto.*; import com.ruoyi.system.applet.query.*; import com.ruoyi.system.applet.vo.*; import com.ruoyi.system.model.*; import com.ruoyi.system.service.*; import com.ruoyi.system.vo.system.*; import com.ruoyi.web.controller.tool.AmapApiClient; import com.sun.org.apache.bcel.internal.generic.IF_ACMPEQ; import com.sun.org.apache.bcel.internal.generic.NEW; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.apache.poi.ss.formula.functions.T; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import java.io.IOException; import java.math.BigDecimal; import java.math.RoundingMode; import java.text.SimpleDateFormat; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.format.DateTimeFormatter; import java.util.*; import java.util.stream.Collectors; /** *

* 任务记录 前端控制器 *

* * @author xiaochen * @since 2025-05-28 */ @Api(tags = "首页") @RestController @RequestMapping("/t-index") public class TIndexController { @Resource private TTaskCleanService taskCleanerService; @Resource private TTaskDetailService taskDetailService; @Resource private TLocationTypeService locationTypeService; @Resource private TLocationService locationService; @Resource private TProjectDeptService projectDeptService; @Resource private TTaskDetailService tTaskDetailService; @Resource private TDeptService deptService; @Resource private ISysUserService sysUserService; @Resource private ISysRoleService roleService; @Resource private TDictDataService dictDataService; @Resource private TLeaveService leaveService; @Resource private TLeaveAuditService leaveAuditService; @Resource private TokenService tokenService; @Resource private TAppealService appealService; @Resource private TInspectorService inspectorService; @Resource private TFeedbackService feedbackService; @Resource private TProblemEscalationService problemEscalationService; @Autowired private AmapApiClient amapApiClient; @Resource private TSystemBulletinService systemBulletinService; @ApiOperation(value = "首页-系统公告") @PostMapping(value = "/systemBulletin") public R systemBulletin() { TSystemBulletin systemBulletin = systemBulletinService.lambdaQuery().eq(TSystemBulletin::getStatus, 1).last("limit 1").one(); return R.ok(systemBulletin); } @ApiOperation(value = "首页-数据概览-更多") @PostMapping(value = "/dataReport") public R dataReport(@RequestBody DataReportDTO dto) { DataReportQuery dataReportQuery = new DataReportQuery(); dataReportQuery.setStartTime(dto.getStartTime()+" 00:00:00"); dataReportQuery.setEndTime(dto.getEndTime()+" 23:59:59"); dataReportQuery.setPageNum(dto.getPageNum()); dataReportQuery.setPageSize(dto.getPageSize()); DataReportVO res = new DataReportVO(); List dataList = dictDataService.list(); List projectDepts = projectDeptService.list(); List taskDetails = taskDetailService.lambdaQuery() .isNotNull(TTaskDetail::getClearStatus) .eq(TTaskDetail::getHandleType,1) .eq(TTaskDetail::getAuditStatus,1) .orderByDesc(BaseModel::getCreateTime) .list(); taskDetails = new ArrayList<>(taskDetails.stream() .collect(Collectors.groupingBy( TTaskDetail::getTaskId, Collectors.collectingAndThen( Collectors.toList(), listAll -> listAll.get(0) ) )) .values()); List userDeptIds = new ArrayList<>(); LambdaQueryWrapper tTaskLambdaQueryWrapper = new LambdaQueryWrapper<>(); if (StringUtils.hasLength(dto.getProjectId())) { TProjectDept projectDept = projectDeptService.getById(dto.getProjectId()); if (!projectDept.getParentId().equals("0")) { tTaskLambdaQueryWrapper.eq(TTask::getProjectId, projectDept.getId()); userDeptIds.add(projectDept.getId()); } else { List list = projectDeptService.lambdaQuery().eq(TProjectDept::getParentId, projectDept.getId()).list(); List deptIds = list.stream().map(TProjectDept::getId).collect(Collectors.toList()); if (!deptIds.isEmpty()) { userDeptIds.addAll(deptIds); tTaskLambdaQueryWrapper.in(TTask::getProjectId, deptIds); } else { tTaskLambdaQueryWrapper.eq(TTask::getProjectId, "-1"); userDeptIds.add("-1"); } } } else { // 根据当前登录人查询部门 Long userId = tokenService.getLoginUserApplet().getUserId(); SysUser sysUser = sysUserService.selectUserById(userId); if (sysUser.getDeptType() == 1) { TProjectDept projectDept = projectDeptService.getById(sysUser.getDeptId()); if (projectDept != null) { if (!"0".equals(projectDept.getParentId())) { tTaskLambdaQueryWrapper.eq(TTask::getProjectId, projectDept.getId()); userDeptIds.add(projectDept.getId()); } else { userDeptIds.add(projectDept.getId()); List list = projectDeptService.lambdaQuery().eq(TProjectDept::getParentId, projectDept.getId()).list(); List deptIds = list.stream().map(TProjectDept::getId).collect(Collectors.toList()); if (!deptIds.isEmpty()) { tTaskLambdaQueryWrapper.in(TTask::getProjectId, deptIds); userDeptIds.addAll(deptIds); } else { tTaskLambdaQueryWrapper.eq(TTask::getProjectId, "-1"); userDeptIds.add("-1"); } } } } } dataReportQuery.setProjectIds(userDeptIds); if (StringUtils.hasLength(dto.getStartTime())) { tTaskLambdaQueryWrapper.ge(TTask::getImplementTime, dto.getStartTime()+" 00:00:00"); tTaskLambdaQueryWrapper.le(TTask::getImplementTime, dto.getEndTime()+" 23:59:59"); } else { // 获取今天凌晨00:00:00 和今天23:59:59 类型为LocalDateTime LocalDateTime startOfToday = LocalDateTime.of(LocalDate.now(), LocalTime.MIN); LocalDateTime endOfToday = LocalDateTime.of(LocalDate.now(), LocalTime.MAX); String startOfTodayStr = startOfToday.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); String endOfTodayStr = endOfToday.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); tTaskLambdaQueryWrapper.ge(TTask::getImplementTime, startOfTodayStr); tTaskLambdaQueryWrapper.le(TTask::getImplementTime, endOfTodayStr); } // tTaskLambdaQueryWrapper.ne(TTask::getStatus, 1); List tasks = taskCleanerService.list(tTaskLambdaQueryWrapper); HashMap taskMap = new HashMap<>(); HashMap statusMap = new HashMap<>(); statusMap.put("未执行", 0); statusMap.put("超时", 0); statusMap.put("待确认", 0); statusMap.put("已驳回", 0); statusMap.put("已完成", 0); HashMap clearMap = new HashMap<>(); clearMap.put("合格", 0); clearMap.put("不合格", 0); HashMap unqualifiedMap = new HashMap<>(); List dictData = dataList.stream().filter(e -> e.getDataType() == 2).collect(Collectors.toList()); for (TDictData dictDatum : dictData) { unqualifiedMap.put(dictDatum.getDataContent(), 0); } for (TTask task : tasks) { TProjectDept tProjectDept = projectDepts.stream().filter(e -> e.getId().equals(task.getProjectId())).findFirst().orElse(null); if (tProjectDept == null) continue; taskMap.put(tProjectDept.getProjectName(), taskMap.getOrDefault(tProjectDept.getProjectName(), 0) + 1); StringBuilder temp = new StringBuilder(); switch (task.getStatus()) { case 1: temp.append("未执行"); break; case 2: temp.append("超时"); break; case 3: temp.append("待确认"); break; case 4: temp.append("已驳回"); break; case 5: temp.append("已完成"); break; case 6: temp.append("已完成"); break; } statusMap.put(temp.toString(), statusMap.getOrDefault(temp.toString(), 0) + 1); TTaskDetail tTaskDetail = taskDetails.stream().filter(e -> e.getTaskId().equals(task.getId())).findFirst().orElse(null); StringBuilder temp1 = new StringBuilder(); if (tTaskDetail!=null){ switch (tTaskDetail.getClearStatus()) { case 1: temp1.append("合格"); break; case 2: temp1.append("不合格"); TDictData tDictData = dataList.stream().filter(e -> e.getId().equals(tTaskDetail.getUnqualified())).findFirst().orElse(null); if (tDictData != null){ unqualifiedMap.put(tDictData.getDataContent(), unqualifiedMap.getOrDefault(tDictData.getDataContent(), 0) + 1); } break; } clearMap.put(temp1.toString(), clearMap.getOrDefault(temp1.toString(), 0) + 1); } } PageInfo taskFinishListVOPageInfo = sysUserService.pageListReport(dataReportQuery); for (TaskFinishListVO record : taskFinishListVOPageInfo.getRecords()) { int pass=0; int unPass=0; List userTaskList = tasks.stream().filter(e -> e.getPatrolInspector().equals(record.getUserId() + "")).collect(Collectors.toList()); List userTaskListPass = tasks.stream().filter(e -> (e.getStatus()==5||e.getStatus()==6) && e.getPatrolInspector().equals(record.getUserId() + "")).collect(Collectors.toList()); for (TTask tTask : userTaskList) { TTaskDetail tTaskDetail = taskDetails.stream().filter(e -> e.getTaskId().equals(tTask.getId())).findFirst().orElse(null); if (tTaskDetail!=null){ switch (tTaskDetail.getClearStatus()){ case 1: pass++; break; case 2: unPass++; break; } } } record.setTotal(userTaskList.size()); record.setRate(pass+unPass!=0?new BigDecimal(pass).divide(new BigDecimal(pass+unPass),2,RoundingMode.HALF_DOWN).multiply(new BigDecimal(100)):BigDecimal.ZERO); record.setFinish(!userTaskList.isEmpty()?new BigDecimal(userTaskListPass.size()).divide(new BigDecimal(userTaskList.size()),2,RoundingMode.HALF_DOWN).multiply(new BigDecimal(100)):BigDecimal.ZERO); } // PageInfo taskFinishListVOPageInfo = new PageInfo<>(); // Page page = new Page<>(dto.getPageNum(), dto.getPageSize()); // Page tasksPage = taskCleanerService.page(page, tTaskLambdaQueryWrapper); res.setTaskMap(taskMap); res.setStatusMap(statusMap); res.setClearMap(clearMap); res.setUnqualifiedMap(unqualifiedMap); res.setTaskFinishList(taskFinishListVOPageInfo); return R.ok(res); } @ApiOperation(value = "根据当前登陆人查询项目部/片区不分页列表") @PostMapping(value = "/list") public R> list() { List list = projectDeptService.list(new LambdaQueryWrapper() .eq(TProjectDept::getParentId, "0") .eq(TProjectDept::getStatus, 1)); List projectDeptListNoLimitVOS = new ArrayList<>(); for (TProjectDept tProjectDept : list) { ProjectDeptListNoLimitVO projectDeptListNoLimitVO = new ProjectDeptListNoLimitVO(); BeanUtils.copyProperties(tProjectDept, projectDeptListNoLimitVO); List list1 = projectDeptService.list(new LambdaQueryWrapper() .eq(TProjectDept::getParentId, tProjectDept.getId()) .eq(TProjectDept::getStatus, 1)); List projectDeptListNoLimitVOS1 = new ArrayList<>(); for (TProjectDept projectDept : list1) { ProjectDeptListNoLimitVO projectDeptListNoLimitVO1 = new ProjectDeptListNoLimitVO(); BeanUtils.copyProperties(projectDept, projectDeptListNoLimitVO1); projectDeptListNoLimitVOS1.add(projectDeptListNoLimitVO1); } projectDeptListNoLimitVO.setChildrenList(projectDeptListNoLimitVOS1); projectDeptListNoLimitVOS.add(projectDeptListNoLimitVO); } return R.ok(projectDeptListNoLimitVOS); } @Resource private TNoticeService noticeService; @ApiOperation(value = "首页") @PostMapping(value = "/index") public R index(@RequestBody IndexDTO dto) throws IOException { IndexVO res = new IndexVO(); res.setIsNotice(0); Long userId = tokenService.getLoginUserApplet().getUserId(); Long count = noticeService.lambdaQuery().eq(TNotice::getUserId, userId).eq(TNotice::getStatus, 1).count(); if (count>0){ res.setIsNotice(1); } List projectListAll = projectDeptService.list(); List locationList = locationService.list(); List locationTypeList = locationTypeService.list(); dto.setUserId(userId); List taskAll = taskCleanerService.indexTask(dto); // List taskAll = taskCleanerService.lambdaQuery().eq(TTask::getPatrolInspector, userId).list(); // 获取今天凌晨00:00:00 和今天23:59:59 类型为LocalDateTime LocalDateTime startOfToday = LocalDateTime.of(LocalDate.now(), LocalTime.MIN); LocalDateTime endOfToday = LocalDateTime.of(LocalDate.now(), LocalTime.MAX); String startOfTodayStr = startOfToday.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); String endOfTodayStr = endOfToday.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); List taskToday = taskCleanerService.lambdaQuery() .between(TTask::getImplementTime, startOfTodayStr, endOfTodayStr) .eq(TTask::getPatrolInspector, userId).list(); List sysUsers = sysUserService.selectAllList(); SysUser sysUser = sysUserService.selectUserById(userId); Long userRole = sysUserService.getUserRole(userId); SysRole sysRole = roleService.selectRoleById(userRole); List users = new ArrayList<>(); if (!sysRole.getRoleName().equals("现场管理员")) { if (sysUser.getDeptType() == 1) { TProjectDept projectDept = projectDeptService.getById(sysUser.getDeptId()); if (projectDept != null) { if ("0".equals(projectDept.getParentId())) { List collect = projectListAll.stream().filter(e -> e.getParentId().equals(projectDept.getId())).map(TProjectDept::getId).collect(Collectors.toList()); collect.add(projectDept.getId()); // 查询片区下的所有人员 users = sysUsers.stream().filter(e ->collect.contains(e.getDeptId()) && e.getStatus().equals("0") && e.getDeptType() == 1).collect(Collectors.toList()); } else { TProjectDept parent = projectDeptService.getById(projectDept.getParentId()); users = sysUsers.stream().filter(e -> e.getDeptId() .equals(parent.getId()) && e.getStatus().equals("0") && e.getDeptType() == 1).collect(Collectors.toList()); List list = projectDeptService.lambdaQuery().eq(TProjectDept::getParentId, parent.getId()).list(); List deptIds = list.stream().map(TProjectDept::getId).collect(Collectors.toList()); if (!deptIds.isEmpty()) { List collect = sysUsers.stream().filter(e -> deptIds .contains(e.getDeptId()) && e.getStatus().equals("0") && e.getDeptType() == 1).collect(Collectors.toList()); users.addAll(collect); } } } } else { TDept dept = deptService.getById(sysUser.getDeptId()); if (dept != null) { if (!dept.getDeptName().contains("公司")) { users = sysUsers.stream().filter(e -> e.getDeptType() == 1).collect(Collectors.toList()); } } } } List pendingTask = new ArrayList<>(); res.setTotalUserCount(users.size()); if (!users.isEmpty()) { List userIds = users.stream().map(SysUser::getUserId).collect(Collectors.toList()); List tasks = taskCleanerService.lambdaQuery().in(TTask::getPatrolInspector, userIds).list(); List taskIds = tasks.stream().map(TTask::getId).collect(Collectors.toList()); if (!tasks.isEmpty()) { List status1 = tasks.stream().filter(e -> e.getStatus() == 5 || e.getStatus() == 6).collect(Collectors.toList()); List status2 = tasks.stream().filter(e -> e.getStatus() != 5 && e.getStatus() != 6).collect(Collectors.toList()); res.setMiddle(!status1.isEmpty() ? new BigDecimal(status1.size()) .divide(new BigDecimal(status1.size() + status2.size()), 2, RoundingMode.HALF_DOWN) .multiply(new BigDecimal(100)) : new BigDecimal(0)); List taskDetails = taskDetailService.lambdaQuery() .eq(TTaskDetail::getAuditStatus, 1) .in(TTaskDetail::getTaskId, taskIds) .isNotNull(TTaskDetail::getClearStatus) .eq(TTaskDetail::getHandleType,1) .orderByDesc(TTaskDetail::getCreateTime).list(); taskDetails = new ArrayList<>(taskDetails.stream() .collect(Collectors.groupingBy( TTaskDetail::getTaskId, Collectors.collectingAndThen( Collectors.toList(), listAll -> listAll.get(0) ) )) .values()); List status3 = taskDetails.stream().filter(e -> e.getClearStatus() == 1).collect(Collectors.toList()); List status4 = taskDetails.stream().filter(e -> e.getClearStatus() == 2).collect(Collectors.toList()); if (!status3.isEmpty()) { BigDecimal divide = new BigDecimal(status3.size() ) .divide(new BigDecimal(status3.size()+ status4.size()), 2, BigDecimal.ROUND_DOWN).multiply(new BigDecimal(100)); res.setRate(divide); } else { res.setRate(new BigDecimal(0)); } } else { res.setMiddle(new BigDecimal(0)); res.setRate(new BigDecimal(0)); } } else { res.setRate(new BigDecimal(0)); res.setMiddle(new BigDecimal(0)); res.setPendingTask(new ArrayList<>()); } List leaveList = new ArrayList<>(); List list = leaveService.lambdaQuery().eq(TLeave::getAuditId, userId).eq(TLeave::getAuditStatus, 1).list(); for (TLeave tLeave : list) { LeaveUserListVO leaveUserListVO = new LeaveUserListVO(); BeanUtils.copyProperties(tLeave, leaveUserListVO); SysUser user = sysUsers.stream() .filter(e -> e.getUserId().equals(Long.valueOf(tLeave.getLeavePerson()))).findFirst() .orElse(null); if (user == null) continue; leaveUserListVO.setLeavePersonName(user.getNickName()); leaveUserListVO.setCreateTime1(tLeave.getCreateTime()); leaveUserListVO.setStartTime1(tLeave.getStartTime()); leaveUserListVO.setEndTime1(tLeave.getEndTime()); leaveList.add(leaveUserListVO); } List taskList = taskAll.stream().filter(e -> e.getPatrolInspector().equals(userId + "") && e.getStatus() == 4).collect(Collectors.toList()); for (TTask tTask : taskList) { TTaskDetail taskDetailsStatus1 = taskDetailService.lambdaQuery() .eq(TTaskDetail::getTaskId, tTask.getId()) .in(TTaskDetail::getHandleType, Arrays.asList(3,6)) .orderByDesc(TTaskDetail::getCreateTime).last("limit 1").one(); TaskPendingVO taskTodayVO = new TaskPendingVO(); BeanUtils.copyProperties(tTask, taskTodayVO); TLocation tLocation = locationList.stream().filter(e -> e.getId().equals(tTask.getLocationId())).findFirst().orElse(null); if (tLocation != null) { taskTodayVO.setLocationAddress(tLocation.getLocationAddress()); taskTodayVO.setLocationLon(tLocation.getLocationLon()); taskTodayVO.setLocationLat(tLocation.getLocationLat()); taskTodayVO.setLocationName(tLocation.getLocationName()); if(StringUtils.hasLength(dto.getLon())){ taskTodayVO.setDistance(tTask.getDistance().divide(new BigDecimal(1000),2, RoundingMode.HALF_DOWN)); }else { taskTodayVO.setDistance(new BigDecimal("0")); } TLocationType tLocationType = locationTypeList.stream().filter(e -> e.getId().equals(tLocation.getLocationType())).findFirst().orElse(null); if (tLocationType != null) { taskTodayVO.setLocationTypeName(tLocationType.getLocationName()); taskTodayVO.setLocationTypeIcon(tLocationType.getLocationIcon()); } } if (taskDetailsStatus1!=null){ taskTodayVO.setRemark(taskDetailsStatus1.getAuditRemark()); } // 任务记录ids List collect = taskAll.stream().map(TTask::getId).collect(Collectors.toList()); if (!collect.isEmpty()){ List list1 = inspectorService.lambdaQuery() .in(TInspector::getTaskId, collect).eq(TInspector::getStatus, 2).list(); for (TInspector tInspector : list1) { TaskPendingVO taskTodayVOOne = new TaskPendingVO(); BeanUtils.copyProperties(tTask, taskTodayVOOne); taskTodayVOOne.setId(tInspector.getId()); TLocation tLocationOne = locationList.stream().filter(e -> e.getId().equals(tTask.getLocationId())).findFirst().orElse(null); if (tLocationOne != null) { taskTodayVOOne.setLocationAddress(tLocationOne.getLocationAddress()); taskTodayVOOne.setLocationLon(tLocationOne.getLocationLon()); taskTodayVOOne.setLocationLat(tLocationOne.getLocationLat()); taskTodayVOOne.setLocationName(tLocationOne.getLocationName()); if(StringUtils.hasLength(dto.getLon())){ taskTodayVO.setDistance(tTask.getDistance().divide(new BigDecimal(1000),2, RoundingMode.HALF_DOWN)); }else { taskTodayVO.setDistance(new BigDecimal("0")); } TLocationType tLocationType = locationTypeList.stream().filter(e -> e.getId().equals(tLocationOne.getLocationType())).findFirst().orElse(null); if (tLocationType != null) { taskTodayVOOne.setLocationTypeName(tLocationType.getLocationName()); taskTodayVOOne.setLocationTypeIcon(tLocationType.getLocationIcon()); } } taskTodayVOOne.setStatus(4); taskTodayVOOne.setRemark(tInspector.getAuditRemark()); pendingTask.add(taskTodayVOOne); } } pendingTask.add(taskTodayVO); } // 将pendingTask按照距离 从小到大排序 pendingTask.sort(Comparator.comparing(TaskPendingVO::getDistance)); res.setPendingTask(pendingTask); res.setLeaveList(leaveList); List todayTask = new ArrayList<>(); List collect = taskAll.stream().map(TTask::getId).collect(Collectors.toList()); for (TTask tTask : taskToday) { TaskTodayVO taskTodayVO = new TaskTodayVO(); if(CollectionUtils.isEmpty(collect)){ break; } TTaskDetail taskDetailsStatus1 = taskDetailService.lambdaQuery() .eq(TTaskDetail::getTaskId, tTask.getId()) .in(TTaskDetail::getHandleType, Arrays.asList(3,6)) .orderByDesc(TTaskDetail::getCreateTime).last("limit 1").one(); BeanUtils.copyProperties(tTask, taskTodayVO); TLocation tLocation = locationList.stream().filter(e -> e.getId().equals(tTask.getLocationId())).findFirst().orElse(null); if (tLocation != null) { taskTodayVO.setLocationAddress(tLocation.getLocationAddress()); taskTodayVO.setLocationLon(tLocation.getLocationLon()); taskTodayVO.setLocationLat(tLocation.getLocationLat()); taskTodayVO.setLocationName(tLocation.getLocationName()); if(StringUtils.hasLength(dto.getLon())){ Map distance = amapApiClient.getDistance(dto.getLon() + "," + dto.getLat(), tLocation.getLocationLon() + "," + tLocation.getLocationLat(), 1); if (distance != null) { taskTodayVO.setDistance(new BigDecimal(distance.get("distance")).divide(new BigDecimal(1000)).setScale(2, BigDecimal.ROUND_HALF_EVEN)); } else { taskTodayVO.setDistance(new BigDecimal("0")); } }else { taskTodayVO.setDistance(new BigDecimal("0")); } TLocationType tLocationType = locationTypeList.stream().filter(e -> e.getId().equals(tLocation.getLocationType())).findFirst().orElse(null); if (tLocationType != null) { taskTodayVO.setLocationTypeName(tLocationType.getLocationName()); taskTodayVO.setLocationTypeIcon(tLocationType.getLocationIcon()); } } if (taskDetailsStatus1!=null){ taskTodayVO.setRemark(taskDetailsStatus1.getAuditRemark()); } todayTask.add(taskTodayVO); } // 将todayTask进行排序 优先根据status状态排序,优先展示未执行、超时、待整改、待确认、整改完成、已完成,然后状态一样再根据距离排序 sortTodayTasks(todayTask); res.setTodayTask(todayTask); List tomorrowTask = new ArrayList<>(); for (TaskTodayVO taskTodayVO : todayTask) { TaskTomorrowVO taskTomorrowVO = new TaskTomorrowVO(); BeanUtils.copyProperties(taskTodayVO, taskTomorrowVO); tomorrowTask.add(taskTomorrowVO); } Collections.shuffle(tomorrowTask); List templates = templateService.list(); TTemplate tTemplate = templates.stream().filter(e -> e.getId().equals(sysUser.getTemplateId())).findFirst() .orElse(null); if (tTemplate!=null){ List inspection = createInspection(tTemplate, userId); List collect1 = inspection.stream().map(TTask::getId).collect(Collectors.toList()); if (collect1.isEmpty()){ collect1.add("0"); } List temp =new ArrayList<>(); if (!StringUtils.hasLength(dto.getLon())){ temp = inspection; }else{ temp = taskCleanerService.getTaskByIds(collect1,dto.getLon(),dto.getLat()); } List taskTomorrowVOS = new ArrayList<>(); for (TTask tTask : temp) { TaskTomorrowVO taskTomorrowVO = new TaskTomorrowVO(); BeanUtils.copyProperties(tTask, taskTomorrowVO); TLocation tLocation = locationList.stream().filter(e -> e.getId().equals(tTask.getLocationId())).findFirst().orElse(null); if (tLocation!=null){ TLocationType tLocationType = locationTypeList.stream().filter(e -> e.getId().equals(tLocation.getLocationType())).findFirst().orElse(null); if (tLocationType!=null){ taskTomorrowVO.setLocationId(tLocation.getId()); taskTomorrowVO.setLocationName(tLocation.getLocationName()); taskTomorrowVO.setLocationTypeName(tLocationType.getLocationName()); taskTomorrowVO.setLocationTypeIcon(tLocationType.getLocationIcon()); taskTomorrowVO.setLocationAddress(tLocation.getLocationAddress()); taskTomorrowVO.setLocationLon(tLocation.getLocationLon()); taskTomorrowVO.setLocationLat(tLocation.getLocationLat()); if (StringUtils.hasLength(dto.getLon())){ taskTomorrowVO.setDistance(tTask.getDistance().divide(new BigDecimal("1000"),2, RoundingMode.HALF_DOWN)); }else { taskTomorrowVO.setDistance(new BigDecimal("0")); } } } taskTomorrowVOS.add(taskTomorrowVO); } res.setTomorrowTask(taskTomorrowVOS); }else{ res.setTomorrowTask(new ArrayList<>()); } res.setIsLeave(0); // 查询请假状态 List list2 = leaveService.lambdaQuery().eq(TLeave::getLeavePerson, userId) .eq(TLeave::getAuditStatus, 2) .list(); for (TLeave tLeave : list2) { LocalDate now = LocalDate.now(); LocalDate startDate = tLeave.getStartTime().toLocalDate(); LocalDate endDate = tLeave.getStartTime().toLocalDate(); if (now.isAfter(startDate) && now.isBefore(endDate)) { res.setIsLeave(1); } else if (now.isEqual(startDate) || now.isEqual(endDate)) { res.setIsLeave(1); } } return R.ok(res); } @Resource private TTemplateService templateService; // 项目部权重标识 private static final String PROJECT_DEPT_WEIGHT = ":PROJECT_DEPT_WEIGHT"; // 保洁员权重标识 private static final String CLEANER_WEIGHT = ":CLEANER_WEIGHT"; // 重复点位标识 private static final String REPEAT_LOCATION = ":REPEAT_LOCATION"; @Autowired private RedisCache redisCache; @Autowired private TTemplateDetailService templateDetailService; public List createInspection(TTemplate template,Long userId) { // 查询所有的模板详情 List list = templateDetailService.list(Wrappers.lambdaQuery(TTemplateDetail.class) .eq(TTemplateDetail::getTemplateId, template.getId())); if (CollectionUtils.isEmpty(list)) { return new ArrayList<>(); } List taskAll = new ArrayList<>(); // 通过模板id查询员工巡检员 List sysUsers = sysUserService.selectUserByTempLateId(template.getId()); sysUsers = sysUsers.stream().filter(e->e.getUserId().equals(userId)).collect(Collectors.toList()); // 创建任务 for (TTemplateDetail detail : list) { // 计算周期 int cycle = detail.getCycle(); switch (detail.getCycleType()){ case 2: cycle = cycle * 7; break; case 3: cycle = cycle * 30; break; case 4: cycle = cycle * 90; break; case 5: cycle = cycle * 365; break; } // 拿到保洁抽查次数 int num1 = detail.getNum1(); // 拿到项目部数 int num2 = detail.getNum2(); // 拿到每日重复点位 int num3 = detail.getNum3(); // 获取点位类型的占比 String num4 = detail.getNum4(); // 未绑定员工 if(CollectionUtils.isEmpty(sysUsers)){ continue; } int taskCount = 0; for (SysUser sysUser : sysUsers) { if("1".equals(sysUser.getStatus())){ continue; } List projectDeptLists = new ArrayList<>(); if(sysUser.getDeptType() == 1){ TProjectDept projectDept = projectDeptService.getById(sysUser.getDeptId()); if(projectDept.getStatus() == 1){ if("0".equals(projectDept.getParentId())){ projectDeptLists = projectDeptService.list(Wrappers.lambdaQuery(TProjectDept.class) .eq(TProjectDept::getParentId, projectDept.getId()) .eq(TProjectDept::getStatus, 1)); }else { projectDeptLists.add(projectDept); } } }else { projectDeptLists = projectDeptService.list(Wrappers.lambdaQuery(TProjectDept.class) .ne(TProjectDept::getParentId,0) .eq(TProjectDept::getStatus, 1)); } if(CollectionUtils.isEmpty(projectDeptLists)){ continue; } List proDeptIds = projectDeptLists.stream().map(TProjectDept::getId).collect(Collectors.toList()); // 获取项目部在该模板详情中的权重 List projectDeptIds = redisCache.getCacheList(detail.getId() + PROJECT_DEPT_WEIGHT); // 获取项目部列表 List projectDeptList; if(CollectionUtils.isEmpty(projectDeptIds)){ projectDeptList = projectDeptLists; }else { projectDeptList = projectDeptService.list(Wrappers.lambdaQuery(TProjectDept.class) .ne(TProjectDept::getParentId,0) .in(TProjectDept::getId, proDeptIds) .notIn(TProjectDept::getId, projectDeptIds)); // 所过所有的项目部都被抽取了,则重新抽取,并且清空项目部权重 if(CollectionUtils.isEmpty(projectDeptList)){ projectDeptList = projectDeptLists; } } // 如果可抽取的项目部数不足,先抽取余下项目部后,再清空权重,重新抽取 List projectDepts = randomSelection(projectDeptList, num2); if(projectDepts.size() < num2){ List proIds = projectDepts.stream().map(TProjectDept::getId).collect(Collectors.toList()); List projectDeptList1 = projectDeptService.list(Wrappers.lambdaQuery(TProjectDept.class) .notIn(TProjectDept::getId, proIds) .ne(TProjectDept::getParentId,0)); List projectDepts1 = randomSelection(projectDeptList1, num2 - projectDepts.size()); List proIds1 = projectDepts1.stream().map(TProjectDept::getId).collect(Collectors.toList()); // 将已抽取的项目部id保存到redis中 projectDepts.addAll(projectDepts1); }else { List proIds = projectDepts.stream().map(TProjectDept::getId).collect(Collectors.toList()); // 将已抽取的项目部id保存到redis中 } List proIds = projectDepts.stream().map(TProjectDept::getId).collect(Collectors.toList()); // 拿到抽取的项目部下的所有保洁员 // List tProjectDeptList = projectDeptService.list(Wrappers.lambdaQuery(TProjectDept.class) // .in(TProjectDept::getId, proIds)); // 获取片区id List areaIds = projectDepts.stream().map(TProjectDept::getId).collect(Collectors.toList()); if(CollectionUtils.isEmpty(areaIds)){ return new ArrayList<>(); } // 计算每天需要抽取多少个保洁员 long count = cleanerService.count(Wrappers.lambdaQuery(TCleaner.class) .in(TCleaner::getProjectId, areaIds)); int cleanerSums = num1 * Integer.parseInt(count + ""); // 获取每天需要抽取的保洁员数,向上取整 if (cleanerSums < cycle){ cleanerSums = cycle; } int dayCleanerCount = cleanerSums / cycle; if((cycle == detail.getCurrentValue()) && cleanerSums % cycle != 0){ dayCleanerCount++; } // 获取保洁员权重 List cleanerIds = redisCache.getCacheList(detail.getId() + CLEANER_WEIGHT); // 获取保洁员列表 List cleaners; if(CollectionUtils.isEmpty(cleanerIds)){ cleaners = cleanerService.list(Wrappers.lambdaQuery(TCleaner.class) .in(TCleaner::getProjectId, areaIds)); }else { cleaners = cleanerService.list(Wrappers.lambdaQuery(TCleaner.class) .in(TCleaner::getProjectId, areaIds) .notIn(TCleaner::getId, cleanerIds)); if(CollectionUtils.isEmpty(cleaners)){ cleaners = cleanerService.list(Wrappers.lambdaQuery(TCleaner.class) .in(TCleaner::getProjectId, areaIds)); } } // 抽取保洁员 List tCleaners = randomSelection(cleaners, dayCleanerCount); if(CollectionUtils.isEmpty(tCleaners)){ continue; } if(tCleaners.size() < dayCleanerCount){ List cleanIds = tCleaners.stream().map(TCleaner::getId).collect(Collectors.toList()); List cleaners1 = cleanerService.list(Wrappers.lambdaQuery(TCleaner.class) .in(TCleaner::getProjectId, areaIds) .notIn(TCleaner::getId, cleanIds)); List tCleaners1 = randomSelection(cleaners1, dayCleanerCount - tCleaners.size()); List cleanIds1 = tCleaners1.stream().map(TCleaner::getId).collect(Collectors.toList()); // 将已抽取的保洁员id保存到redis中 cleanIds1.addAll(cleanIds); tCleaners.addAll(tCleaners1); }else { List cleanIds = tCleaners.stream().map(TCleaner::getId).collect(Collectors.toList()); } // 通过保洁员id查询点位 List cleanersIds = tCleaners.stream().map(TCleaner::getId).collect(Collectors.toList()); List locationList = locationService.list(Wrappers.lambdaQuery(TLocation.class) .in(TLocation::getLocationCleaner, cleanersIds)); // 查询点位类型 JSONArray jsonArray = JSONObject.parseArray(num4); List tLocationList = new ArrayList<>(); for (Object o : jsonArray) { JSONObject jsonObject = JSONObject.parseObject(o.toString()); String id = jsonObject.getString("id"); BigDecimal value = jsonObject.getBigDecimal("value"); List locations = locationList.stream().filter(tLocation -> tLocation.getLocationType().equals(id)).collect(Collectors.toList()); if(!CollectionUtils.isEmpty(locations)){ BigDecimal bigDecimal = new BigDecimal(locations.size()).multiply(value.divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN)).setScale(0, BigDecimal.ROUND_UP); int locationCount = bigDecimal.intValue(); if(locationCount > 0){ List tLocations = randomSelection(locations, locationCount); tLocationList.addAll(tLocations); } } } tLocationList = tLocationList.stream().distinct().collect(Collectors.toList()); // 抽取重复点位 Integer currentValue = detail.getCurrentValue(); if(currentValue != cycle){ // 周期天数加一 detail.setCurrentValue(currentValue + 1); // 获取重复点位 Set repeatLocation = redisCache.getCacheSet(detail.getId() + ":" + sysUser.getUserId() + REPEAT_LOCATION); if(!CollectionUtils.isEmpty(repeatLocation)){ List locations = randomSelection(new ArrayList<>(tLocationList), num3); tLocationList.addAll(locations); } Set locationSet = new HashSet<>(tLocationList); }else { // 设置当前周期为0 detail.setCurrentValue(0); } // 查询请假记录 TLeave leave = leaveService.getOne(Wrappers.lambdaQuery(TLeave.class) .eq(TLeave::getLeavePerson, sysUser.getUserId()) .eq(TLeave::getAuditStatus, 2) .orderByDesc(TLeave::getCreateTime) .last("LIMIT 1")); // 创建任务 List tasks = new ArrayList<>(); for (TLocation tLocation : tLocationList) { TTask task = new TTask(); // 获取保洁员 tCleaners.stream().filter(tCleaner -> tCleaner.getId().equals(tLocation.getLocationCleaner())).findFirst().ifPresent(tCleaner -> { task.setProjectId(tCleaner.getProjectId()); task.setCleanerId(tCleaner.getId()); }); // 获取巡检员 task.setPatrolInspector(sysUser.getUserId().toString()); task.setPatrolInspectorDept(sysUser.getDeptId()); task.setUserId(sysUser.getUserId()); task.setStatus(1); task.setLocationId(tLocation.getId()); // 判断今天是否在请假时间内 if(Objects.nonNull(leave) && ((leave.getStartTime().toLocalDate().isBefore(LocalDate.now().plusDays(1)) && leave.getEndTime().toLocalDate().isAfter(LocalDate.now().plusDays(1))) || (leave.getStartTime().toLocalDate().isEqual(LocalDate.now().plusDays(1)) || leave.getEndTime().toLocalDate().isEqual(LocalDate.now().plusDays(1))))){ task.setImplementTime(leave.getEndTime().plusDays(1)); }else { task.setImplementTime(LocalDateTime.now().plusDays(1)); } task.setTaskType(1); task.setTemplateId(detail.getTemplateId()); String nameAndCode = CodeGenerateUtils.generateVolumeSn(); task.setTaskName(nameAndCode); task.setTaskCode(nameAndCode); task.setDisabled(true); tasks.add(task); } // 添加应生成任务数量 TTemplateCount templateCount = new TTemplateCount(); templateCount.setTemplateId(detail.getTemplateId()); // 查询所有的保洁员下面的点位 List cleanIds = cleaners.stream().map(TCleaner::getId).collect(Collectors.toList()); List tLocations = locationService.list(Wrappers.lambdaQuery(TLocation.class) .in(TLocation::getLocationCleaner, cleanIds)); templateCount.setTaskCount(tLocations.size()); templateCount.setUserId(sysUser.getUserId()); // templateCountService.save(templateCount); taskAll.addAll(tasks); taskCleanerService.saveBatch(tasks); taskCount = taskCount + tasks.size(); } template.setTaskCount(taskCount); // templateService.updateById(template); // templateDetailService.updateById(detail); } return taskAll; } @Autowired private TTemplateCountService templateCountService; @Autowired private TCleanerService cleanerService; public static void sortTodayTasks(List taskList) { Map statusOrder = new HashMap<>(); statusOrder.put(1, 0); statusOrder.put(2, 1); statusOrder.put(4, 2); statusOrder.put(3, 3); statusOrder.put(5, 4); statusOrder.put(6, 5); taskList.sort(Comparator.comparingInt((TaskTodayVO o) -> statusOrder.getOrDefault(o.getStatus(), Integer.MAX_VALUE)).thenComparing(TaskTodayVO::getDistance)); } private static List randomSelection(List list, int size) { List selected = new ArrayList<>(); int length = list.size(); for (int i = 0; i < size; i++) { Collections.shuffle(list); // 如果需求的大小超过了集合的长度,则只能取到集合的全部元素 int subListSize = Math.min(size - selected.size(), length); selected.addAll(list.subList(0, subListSize)); } return selected; } }