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;
}
}