无关风月
2025-06-26 e6fac7e481db2795e46685446968b7b6a36eece8
Merge remote-tracking branch 'origin/master'

# Conflicts:
# ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java
# ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java
# ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java
# ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml
6个文件已添加
9个文件已修改
883 ■■■■■ 已修改文件
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/DataStatisticsController.java 584 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TLocationController.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TTaskController.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/TaskUtil.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TTaskDetailController.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/model/TProjectDept.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/query/DataStatisticsQuery.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/query/DataStatisticsRankQuery.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/vo/system/AnalysisUnqualifiedCleaningDetailVO.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/vo/system/AnalysisUnqualifiedCleaningVO.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/vo/system/DataStatisticsRankVO.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/DataStatisticsController.java
New file
@@ -0,0 +1,584 @@
package com.ruoyi.web.controller.api;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.system.model.*;
import com.ruoyi.system.query.DataStatisticsQuery;
import com.ruoyi.system.query.DataStatisticsRankQuery;
import com.ruoyi.system.query.InsepectorListQuery;
import com.ruoyi.system.service.*;
import com.ruoyi.system.vo.system.AnalysisUnqualifiedCleaningDetailVO;
import com.ruoyi.system.vo.system.AnalysisUnqualifiedCleaningVO;
import com.ruoyi.system.vo.system.DataStatisticsRankVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;
/**
 * <p>
 * 数据大屏 前端控制器
 * </p>
 *
 * @author xiaochen
 * @since 2025-05-28
 */
@Api(tags = "数据大屏")
@RestController
@RequestMapping("/statistics")
public class DataStatisticsController {
    @Resource
    private TTaskCleanService taskCleanService;
    @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 TokenService tokenService;
    @Resource
    private TAppealService appealService;
    @Resource
    private TDictDataService dictDataService;
    @ApiOperation(value = "查询片区")
    @GetMapping(value = "/queryProject")
    public R<List<TProjectDept>> queryProject() {
        Integer deptType = tokenService.getLoginUser().getUser().getDeptType();
        String deptId = tokenService.getLoginUser().getUser().getDeptId();
        List<TProjectDept> projectDeptList = new ArrayList<>();
        if (deptType == 1) {
            // 查询片区
            TProjectDept projectDept = projectDeptService.getById(deptId);
            // 查询项目部
            TProjectDept parent = projectDeptService.getById(projectDept.getParentId());
            List<TProjectDept> children = new ArrayList<>();
            children.add(projectDept);
            parent.setChildren(children);
            projectDeptList.add(parent);
        }else {
            projectDeptList = projectDeptService.list(Wrappers.lambdaQuery(TProjectDept.class)
                    .eq(TProjectDept::getStatus,1)
                    .eq(TProjectDept::getParentId,0));
            // 查询片区
            projectDeptList.forEach(projectDept -> {
                List<TProjectDept> children = projectDeptService.list(Wrappers.lambdaQuery(TProjectDept.class)
                        .eq(TProjectDept::getParentId, projectDept.getId()));
                projectDept.setChildren(children);
            });
        }
        return R.ok(projectDeptList);
    }
    @ApiOperation(value = "通过片区id查询点位类型")
    @GetMapping(value = "/queryLocationByProjectId")
    public R<List<TLocationType>> queryLocationByProjectId(@RequestParam(value = "projectId") String projectId) {
        List<TLocationType> locationTypes = new ArrayList<>();
        // 通过片区id查询点位
        List<TLocation> locationList = locationService.list(Wrappers.lambdaQuery(TLocation.class)
                .eq(TLocation::getProjectId, projectId));
        if(CollectionUtils.isEmpty(locationList)){
            return R.ok(locationTypes);
        }
        List<String> typeIds = locationList.stream().map(TLocation::getLocationType).collect(Collectors.toList());
        locationTypes = locationTypeService.list(Wrappers.lambdaQuery(TLocationType.class)
                .in(TLocationType::getId, typeIds));
        return R.ok(locationTypes);
    }
    @ApiOperation(value = "数据概览")
    @PostMapping(value = "/dataOverview")
    public R<Map<String, Object>> dataOverview(@RequestBody DataStatisticsQuery query) {
        Map<String, Object> map = new HashMap<>();
        Integer deptType = tokenService.getLoginUser().getUser().getDeptType();
        String deptId = tokenService.getLoginUser().getUser().getDeptId();
        Long userId = tokenService.getLoginUser().getUserId();
        String startTime = LocalDate.now() + " 00:00:00";
        String endTime = LocalDate.now() + " 23:59:59";
        LambdaQueryWrapper<TTask> wrapper = new LambdaQueryWrapper<>();
        wrapper.between(TTask::getImplementTime, startTime, endTime);
        // 查询点位类型
        if(StringUtils.isNotEmpty(query.getLocationTypeId())){
            // 查询点位
            List<TLocation> locationList = locationService.list(Wrappers.lambdaQuery(TLocation.class)
                    .in(TLocation::getLocationType, query.getLocationTypeId()));
            if(!CollectionUtils.isEmpty(locationList)){
                List<String> locationIds = locationList.stream().map(TLocation::getId).collect(Collectors.toList());
                wrapper.in(TTask::getLocationId, locationIds);
            }
        }
        List<TTask> taskList = new ArrayList<>();
        if (deptType == 1) {
            // 项目部人员
            List<String> projectIds = new ArrayList<>();
            projectIds.add(deptId);
            query.setProjectId(projectIds);
        }else {
            // 公司人员
            // 查询自己的任务列表
            taskList = taskCleanService.list(Wrappers.lambdaQuery(TTask.class)
                    .eq(TTask::getPatrolInspector, userId)
                    .between(TTask::getImplementTime, startTime, endTime));
            if(CollectionUtils.isEmpty(query.getProjectId())){
                // 查询所有项目部的任务列表
                List<TProjectDept> tProjectDeptList = projectDeptService.list(Wrappers.lambdaQuery(TProjectDept.class)
                        .eq(TProjectDept::getStatus, 1)
                        .ne(TProjectDept::getParentId, 0));
                if(!CollectionUtils.isEmpty(tProjectDeptList)){
                    List<String> projectIds = tProjectDeptList.stream().map(TProjectDept::getId).collect(Collectors.toList());
                    wrapper.in(TTask::getProjectId, projectIds);
                }
            }
        }
        // 查询片区
        if(!CollectionUtils.isEmpty(query.getProjectId())){
            wrapper.in(TTask::getProjectId, query.getProjectId());
        }
        List<TTask> list = taskCleanService.list(wrapper);
        if(CollectionUtils.isEmpty(list)){
            return R.ok(map);
        }
        if(!CollectionUtils.isEmpty(taskList)){
            list.addAll(taskList);
        }
        map.put("taskCount", list.size());
        map.put("taskUnExecutedCount", list.stream().filter(task -> task.getStatus() == 1).count());
        map.put("taskPendingCount", list.stream().filter(task -> task.getStatus() == 3).count());
        map.put("taskFinishCount", list.stream().filter(task -> task.getStatus() == 6).count());
        return R.ok(map);
    }
    @ApiOperation(value = "点位类型")
    @PostMapping(value = "/locationType")
    public R<Map<String, Object>> locationType(@RequestBody DataStatisticsQuery query) {
        Map<String, Object> map = new HashMap<>();
        Integer deptType = tokenService.getLoginUser().getUser().getDeptType();
        String deptId = tokenService.getLoginUser().getUser().getDeptId();
        // 查询点位类型
        if(StringUtils.isNotEmpty(query.getLocationTypeId())){
            // 查询点位
            List<TLocation> locationList = locationService.list(Wrappers.lambdaQuery(TLocation.class)
                    .in(TLocation::getLocationType, query.getLocationTypeId()));
            // 查询类型
            TLocationType locationType = locationTypeService.getById(query.getLocationTypeId());
            map.put(locationType.getLocationName(), locationList.size());
            return R.ok(map);
        }
        if (deptType == 1) {
            // 项目部人员
            List<String> projectIds = new ArrayList<>();
            projectIds.add(deptId);
            query.setProjectId(projectIds);
        }else {
            if(CollectionUtils.isEmpty(query.getProjectId())) {
                // 查询所有项目部的任务列表
                List<TProjectDept> tProjectDeptList = projectDeptService.list(Wrappers.lambdaQuery(TProjectDept.class)
                        .eq(TProjectDept::getStatus, 1)
                        .ne(TProjectDept::getParentId, 0));
                if (!CollectionUtils.isEmpty(tProjectDeptList)) {
                    List<String> projectIds = tProjectDeptList.stream().map(TProjectDept::getId).collect(Collectors.toList());
                    List<TLocation> locationList = locationService.list(Wrappers.lambdaQuery(TLocation.class)
                            .in(TLocation::getProjectId, projectIds));
                    List<String> locationTypeList = locationList.stream().map(TLocation::getLocationType).distinct().collect(Collectors.toList());
                    List<TLocationType> locationTypes = locationTypeService.list(Wrappers.lambdaQuery(TLocationType.class)
                            .in(TLocationType::getId, locationTypeList));
                    for (TLocationType locationType : locationTypes) {
                        List<TLocation> locationList1 = locationList.stream().filter(location -> location.getLocationType().equals(locationType.getId())).collect(Collectors.toList());
                        map.put(locationType.getLocationName(), locationList1.size());
                    }
                    return R.ok(map);
                }
            }
        }
        // 查询片区
        if(!CollectionUtils.isEmpty(query.getProjectId())){
            List<TLocation> locationList = locationService.list(Wrappers.lambdaQuery(TLocation.class)
                    .eq(TLocation::getProjectId, query.getProjectId()));
            List<String> locationTypeList = locationList.stream().map(TLocation::getLocationType).distinct().collect(Collectors.toList());
            List<TLocationType> locationTypes = locationTypeService.list(Wrappers.lambdaQuery(TLocationType.class)
                    .in(TLocationType::getId, locationTypeList));
            for (TLocationType locationType : locationTypes) {
                List<TLocation> locationList1 = locationList.stream().filter(location -> location.getLocationType().equals(locationType.getId())).collect(Collectors.toList());
                map.put(locationType.getLocationName(), locationList1.size());
            }
            return R.ok(map);
        }
        return R.ok(map);
    }
    @ApiOperation(value = "预警汇总")
    @PostMapping(value = "/warningSummary")
    public R<Map<String, Object>> warningSummary(@RequestBody DataStatisticsQuery query) {
        Map<String, Object> map = new HashMap<>();
        Integer deptType = tokenService.getLoginUser().getUser().getDeptType();
        String deptId = tokenService.getLoginUser().getUser().getDeptId();
        Long userId = tokenService.getLoginUser().getUserId();
        LambdaQueryWrapper<TTask> wrapper = new LambdaQueryWrapper<>();
        // 查询点位类型
        if(StringUtils.isNotEmpty(query.getLocationTypeId())){
            // 查询点位
            List<TLocation> locationList = locationService.list(Wrappers.lambdaQuery(TLocation.class)
                    .in(TLocation::getLocationType, query.getLocationTypeId()));
            if(!CollectionUtils.isEmpty(locationList)){
                List<String> locationIds = locationList.stream().map(TLocation::getId).collect(Collectors.toList());
                wrapper.in(TTask::getLocationId, locationIds);
            }
        }
        List<TTask> taskList = new ArrayList<>();
        if (deptType == 1) {
            // 项目部人员
            List<String> projectIds = new ArrayList<>();
            projectIds.add(deptId);
            query.setProjectId(projectIds);
        }else {
            // 公司人员
            // 查询自己的任务列表
            taskList = taskCleanService.list(Wrappers.lambdaQuery(TTask.class)
                    .eq(TTask::getPatrolInspector, userId));
            if(CollectionUtils.isEmpty(query.getProjectId())){
                // 查询所有项目部的任务列表
                List<TProjectDept> tProjectDeptList = projectDeptService.list(Wrappers.lambdaQuery(TProjectDept.class)
                        .eq(TProjectDept::getStatus, 1)
                        .ne(TProjectDept::getParentId, 0));
                if(!CollectionUtils.isEmpty(tProjectDeptList)){
                    List<String> projectIds = tProjectDeptList.stream().map(TProjectDept::getId).collect(Collectors.toList());
                    wrapper.in(TTask::getProjectId, projectIds);
                }
            }
        }
        // 查询片区
        if(!CollectionUtils.isEmpty(query.getProjectId())){
            wrapper.in(TTask::getProjectId, query.getProjectId());
        }
        List<TTask> list = taskCleanService.list(wrapper);
        if(CollectionUtils.isEmpty(list)){
            return R.ok(map);
        }
        if(!CollectionUtils.isEmpty(taskList)){
            list.addAll(taskList);
        }
        map.put("timeoutWarn", list.stream().filter(task -> task.getStatus() == 2).count());
        List<TTask> tasks = list.stream().filter(task -> task.getStatus() != 1 && task.getStatus() != 2).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(tasks)){
            map.put("unqualifiedWarn", 0);
            return R.ok(map);
        }
        List<String> taskIds = tasks.stream().map(TTask::getId).collect(Collectors.toList());
        List<TTaskDetail> taskDetails = tTaskDetailService.list(Wrappers.lambdaQuery(TTaskDetail.class)
                .in(TTaskDetail::getTaskId, taskIds)
                .orderByDesc(TTaskDetail::getCreateTime));
        int unqualifiedWarn = 0;
        for (TTask task : list) {
            TTaskDetail tTaskDetail = taskDetails.stream().filter(taskDetail -> taskDetail.getTaskId().equals(task.getId())).findFirst().orElse(null);
            if(Objects.nonNull(tTaskDetail)){
                if(tTaskDetail.getClearStatus() == 2){
                    unqualifiedWarn++;
                }
            }
        }
        map.put("unqualifiedWarn", unqualifiedWarn);
        return R.ok(map);
    }
    @ApiOperation(value = "清洁不合格分析")
    @PostMapping(value = "/analysisUnqualifiedCleaning")
    public R<AnalysisUnqualifiedCleaningVO> analysisUnqualifiedCleaning(@RequestBody DataStatisticsQuery query) {
        Integer deptType = tokenService.getLoginUser().getUser().getDeptType();
        String deptId = tokenService.getLoginUser().getUser().getDeptId();
        Long userId = tokenService.getLoginUser().getUserId();
        LambdaQueryWrapper<TTask> wrapper = new LambdaQueryWrapper<>();
        // 查询点位类型
        if(StringUtils.isNotEmpty(query.getLocationTypeId())){
            // 查询点位
            List<TLocation> locationList = locationService.list(Wrappers.lambdaQuery(TLocation.class)
                    .in(TLocation::getLocationType, query.getLocationTypeId()));
            if(!CollectionUtils.isEmpty(locationList)){
                List<String> locationIds = locationList.stream().map(TLocation::getId).collect(Collectors.toList());
                wrapper.in(TTask::getLocationId, locationIds);
            }
        }
        List<TTask> taskList = new ArrayList<>();
        if (deptType == 1) {
            // 项目部人员
            List<String> projectIds = new ArrayList<>();
            projectIds.add(deptId);
            query.setProjectId(projectIds);
        }else {
            // 公司人员
            // 查询自己的任务列表
            taskList = taskCleanService.list(Wrappers.lambdaQuery(TTask.class)
                    .eq(TTask::getPatrolInspector, userId));
            if(CollectionUtils.isEmpty(query.getProjectId())){
                // 查询所有项目部的任务列表
                List<TProjectDept> tProjectDeptList = projectDeptService.list(Wrappers.lambdaQuery(TProjectDept.class)
                        .eq(TProjectDept::getStatus, 1)
                        .ne(TProjectDept::getParentId, 0));
                if(!CollectionUtils.isEmpty(tProjectDeptList)){
                    List<String> projectIds = tProjectDeptList.stream().map(TProjectDept::getId).collect(Collectors.toList());
                    wrapper.in(TTask::getProjectId, projectIds);
                }
            }
        }
        // 查询片区
        if(!CollectionUtils.isEmpty(query.getProjectId())){
            wrapper.in(TTask::getProjectId, query.getProjectId());
        }
        List<TTask> list = taskCleanService.list(wrapper);
        if(CollectionUtils.isEmpty(list)){
            return R.ok();
        }
        if(!CollectionUtils.isEmpty(taskList)){
            list.addAll(taskList);
        }
        List<TTask> tasks = list.stream().filter(task -> task.getStatus() != 1 && task.getStatus() != 2).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(tasks)){
            return R.ok();
        }
        List<String> taskIds = tasks.stream().map(TTask::getId).collect(Collectors.toList());
        List<TTaskDetail> taskDetails = tTaskDetailService.list(Wrappers.lambdaQuery(TTaskDetail.class)
                .in(TTaskDetail::getTaskId, taskIds)
                .eq(TTaskDetail::getClearStatus, 2)
                .orderByDesc(TTaskDetail::getCreateTime));
        List<TTaskDetail> taskDetailList = new ArrayList<>();
        for (TTask task : list) {
            TTaskDetail tTaskDetail = taskDetails.stream().filter(taskDetail -> taskDetail.getTaskId().equals(task.getId())).findFirst().orElse(null);
            if(Objects.nonNull(tTaskDetail)){
                taskDetailList.add(tTaskDetail);
            }
        }
        AnalysisUnqualifiedCleaningVO analysisUnqualifiedCleaningVO = new AnalysisUnqualifiedCleaningVO();
        analysisUnqualifiedCleaningVO.setTotal(taskDetailList.size());
        // 查询所有的不合格原因
        List<TDictData> dictDataList = dictDataService.list(Wrappers.lambdaQuery(TDictData.class)
                .eq(TDictData::getDataType, 2));
        List<AnalysisUnqualifiedCleaningDetailVO> analysisUnqualifiedCleaningDetailVOS = new ArrayList<>();
        for (TDictData tDictData : dictDataList) {
            List<TTaskDetail> tTaskDetails = taskDetailList.stream().filter(taskDetail -> taskDetail.getUnqualified().equals(tDictData.getId())).collect(Collectors.toList());
            AnalysisUnqualifiedCleaningDetailVO analysisUnqualifiedCleaningDetailVO = new AnalysisUnqualifiedCleaningDetailVO();
            analysisUnqualifiedCleaningDetailVO.setUnqualifiedName(tDictData.getDataContent());
            analysisUnqualifiedCleaningDetailVO.setCount(tTaskDetails.size());
            analysisUnqualifiedCleaningDetailVOS.add(analysisUnqualifiedCleaningDetailVO);
        }
        analysisUnqualifiedCleaningVO.setAnalysisUnqualifiedCleaningDetailVOS(analysisUnqualifiedCleaningDetailVOS);
        return R.ok(analysisUnqualifiedCleaningVO);
    }
    @ApiOperation(value = "巡检排行榜")
    @PostMapping(value = "/inspectionRankingList")
    public R<List<DataStatisticsRankVO>> inspectionRankingList(@RequestBody DataStatisticsRankQuery query) {
        Integer deptType = tokenService.getLoginUser().getUser().getDeptType();
        String deptId = tokenService.getLoginUser().getUser().getDeptId();
        Long userId = tokenService.getLoginUser().getUserId();
        LambdaQueryWrapper<TTask> wrapper = new LambdaQueryWrapper<>();
        // 判断时间
        String startTime = "";
        String endTime = "";
        switch (query.getTimeType()){
            case 1:
                Map<String, Date> monthDate = DateUtils.getMonthDate(new Date());
                startTime = new SimpleDateFormat("yyyy-MM-dd").format((monthDate.get("first"))) + " 00:00:00";
                endTime = new SimpleDateFormat("yyyy-MM-dd").format((monthDate.get("last"))) + " 23:59:59";
                break;
            case 2:
                Map<String, Date> quarterDate = DateUtils.getQuarterDate(new Date());
                startTime = new SimpleDateFormat("yyyy-MM-dd").format((quarterDate.get("first"))) + " 00:00:00";
                endTime = new SimpleDateFormat("yyyy-MM-dd").format((quarterDate.get("last"))) + " 23:59:59";
                break;
            case 3:
                Map<String, Date> yearDate = DateUtils.getYearDate(new Date());
                startTime = new SimpleDateFormat("yyyy-MM-dd").format((yearDate.get("first"))) + " 00:00:00";
                endTime = new SimpleDateFormat("yyyy-MM-dd").format((yearDate.get("last"))) + " 23:59:59";
                break;
        }
        wrapper.between(TTask::getCreateTime, startTime, endTime);
        // 查询点位类型
        if(StringUtils.isNotEmpty(query.getLocationTypeId())){
            // 查询点位
            List<TLocation> locationList = locationService.list(Wrappers.lambdaQuery(TLocation.class)
                    .in(TLocation::getLocationType, query.getLocationTypeId()));
            if(!CollectionUtils.isEmpty(locationList)){
                List<String> locationIds = locationList.stream().map(TLocation::getId).collect(Collectors.toList());
                wrapper.in(TTask::getLocationId, locationIds);
            }
        }
        List<TTask> taskList = new ArrayList<>();
        List<SysUser> sysUsers = new ArrayList<>();
        if(query.getRankType() == 1){
            sysUsers = sysUserService.selectListByDeptId(deptId);
        }
        if (deptType == 1) {
            // 项目部人员
            List<String> projectIds = new ArrayList<>();
            projectIds.add(deptId);
            query.setProjectId(projectIds);
        }else {
            // 公司人员
            // 查询自己的任务列表
            taskList = taskCleanService.list(Wrappers.lambdaQuery(TTask.class)
                    .eq(TTask::getPatrolInspector, userId));
            if(CollectionUtils.isEmpty(query.getProjectId())){
                // 查询所有项目部的任务列表
                List<TProjectDept> tProjectDeptList = projectDeptService.list(Wrappers.lambdaQuery(TProjectDept.class)
                        .eq(TProjectDept::getStatus, 1)
                        .ne(TProjectDept::getParentId, 0));
                if(!CollectionUtils.isEmpty(tProjectDeptList)){
                    List<String> projectIds = tProjectDeptList.stream().map(TProjectDept::getId).collect(Collectors.toList());
                    wrapper.in(TTask::getProjectId, projectIds);
                }
                if(query.getRankType() == 1){
                    // 查询所有项目部的人员
                    List<SysUser> sysUserList = sysUserService.selectListByDeptType(1);
                    if(!CollectionUtils.isEmpty(sysUserList)){
                        sysUsers.addAll(sysUserList);
                    }
                }
            }else {
                if(query.getRankType() == 1){
                    // 查询所有片区
                    List<TProjectDept> tProjectDeptList = projectDeptService.list(Wrappers.lambdaQuery(TProjectDept.class)
                            .eq(TProjectDept::getStatus, 1)
                            .in(TProjectDept::getId, query.getProjectId()));
                    if(!CollectionUtils.isEmpty(tProjectDeptList)){
                        List<String> projectIds = tProjectDeptList.stream().map(TProjectDept::getId).distinct().collect(Collectors.toList());
                        List<SysUser> sysUserList = sysUserService.selectListByDeptIds(projectIds);
                        sysUsers.addAll(sysUserList);
                    }
                }
            }
        }
        // 查询片区
        if(!CollectionUtils.isEmpty(query.getProjectId())){
            wrapper.in(TTask::getProjectId, query.getProjectId());
        }
        List<TTask> list = taskCleanService.list(wrapper);
        if(CollectionUtils.isEmpty(list)){
            return R.ok();
        }
        if(!CollectionUtils.isEmpty(taskList)){
            list.addAll(taskList);
        }
        List<TTask> tasks = list.stream().filter(task -> task.getStatus() != 1 && task.getStatus() != 2).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(tasks)){
            return R.ok();
        }
        List<String> taskIds = tasks.stream().map(TTask::getId).collect(Collectors.toList());
        List<TTaskDetail> taskDetails = tTaskDetailService.list(Wrappers.lambdaQuery(TTaskDetail.class)
                .in(TTaskDetail::getTaskId, taskIds)
                .eq(TTaskDetail::getClearStatus, 1)
                .orderByDesc(TTaskDetail::getCreateTime));
        List<DataStatisticsRankVO> result = new ArrayList<>();
        if(query.getRankType() == 1){
            // 用户排名
            for (SysUser sysUser : sysUsers) {
                DataStatisticsRankVO dataStatisticsRankVO = new DataStatisticsRankVO();
                dataStatisticsRankVO.setName(sysUser.getNickName());
                List<String> taskIdList = tasks.stream().filter(task -> task.getPatrolInspector().equals(String.valueOf(sysUser.getUserId()))).map(TTask::getId).collect(Collectors.toList());
                dataStatisticsRankVO.setTaskCount(taskIdList.size());
                long count = taskDetails.stream().filter(taskDetail -> taskIdList.contains(taskDetail.getTaskId())).count();
                dataStatisticsRankVO.setQualifiedCount(count);
            }
        }else {
            // 查询项目部
            List<TProjectDept> projectDepts;
            if(deptType == 1){
                projectDepts = new ArrayList<>();
                // 当前项目部
                TProjectDept projectDept = projectDeptService.getById(deptId);
                projectDepts.add(projectDept);
            }else {
                if (CollectionUtils.isEmpty(query.getProjectId())){
                    projectDepts = projectDeptService.list(Wrappers.lambdaQuery(TProjectDept.class)
                            .eq(TProjectDept::getStatus, 1)
                            .eq(TProjectDept::getParentId, 0));
                }else {
                    List<TProjectDept> projectDeptList = projectDeptService.list(Wrappers.lambdaQuery(TProjectDept.class)
                            .eq(TProjectDept::getStatus, 1)
                            .in(TProjectDept::getId, query.getProjectId()));
                    List<String> parentIds = projectDeptList.stream().map(TProjectDept::getParentId).collect(Collectors.toList());
                    projectDepts = projectDeptService.list(Wrappers.lambdaQuery(TProjectDept.class)
                            .eq(TProjectDept::getStatus, 1)
                            .in(TProjectDept::getId, parentIds));
                }
            }
            if(CollectionUtils.isEmpty(projectDepts)){
                return R.ok();
            }
            // 查询所有片区
            List<TProjectDept> tProjectDeptList = projectDeptService.list(Wrappers.lambdaQuery(TProjectDept.class)
                    .eq(TProjectDept::getStatus, 1)
                    .ne(TProjectDept::getParentId, 0));
            for (TProjectDept projectDept : projectDepts) {
                DataStatisticsRankVO dataStatisticsRankVO = new DataStatisticsRankVO();
                dataStatisticsRankVO.setName(projectDept.getProjectName());
                List<String> taskIdList;
                if(!CollectionUtils.isEmpty(tProjectDeptList)){
                    List<String> projectIds = tProjectDeptList.stream().map(TProjectDept::getId).collect(Collectors.toList());
                    taskIdList = tasks.stream().filter(task -> projectIds.contains(task.getProjectId())).map(TTask::getId).collect(Collectors.toList());
                } else {
                    taskIdList = new ArrayList<>();
                }
                dataStatisticsRankVO.setTaskCount(taskIdList.size());
                if(CollectionUtils.isEmpty(taskIdList)){
                    dataStatisticsRankVO.setQualifiedCount(0L);
                    continue;
                }
                long count = taskDetails.stream().filter(taskDetail -> taskIdList.contains(taskDetail.getTaskId())).count();
                dataStatisticsRankVO.setQualifiedCount(count);
            }
        }
        return R.ok(result);
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TLocationController.java
@@ -298,12 +298,12 @@
    @ApiOperation(value = "点位导入")
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRES_NEW)
    @PostMapping("/importLocation")
    public R<List<CustomerImportFailedData>> importLocation(@RequestPart("file") MultipartFile file) {
    public R<String> importLocation(@RequestPart("file") MultipartFile file) {
        ImportParams params = new ImportParams();
        params.setTitleRows(2); // 标题行数
        params.setHeadRows(1); //表头行数
        InputStream inputStream = null;
        List<CustomerImportFailedData> failedData = new ArrayList<>();
//        List<CustomerImportFailedData> failedData = new ArrayList<>();
        List<TLocationImportExcel> locationExcelList;
        try {
            inputStream = file.getInputStream();
@@ -323,12 +323,50 @@
        if (CollectionUtils.isEmpty(locationExcelList)) {
            throw new ServiceException("点位数据为空!");
        }
//        List<TLocation> saveOrUpdateList = new ArrayList<>();
        // 查询所有类型点位
        List<TLocationType> locationTypes = locationTypeService.list();
        // 查询所有用户
        List<SysUser> users = sysUserService.selectAllList();
        // 查询所有部门
        List<TDept> deptList = deptService.list();
        // 查询所有保洁员
        List<TCleaner> cleaners = cleanerService.list();
        for (TLocationImportExcel locationExcel : locationExcelList) {
            System.err.println(locationExcel);
            TLocation location = new TLocation();
            location.setLocationCode(locationExcel.getLocationCode());
            location.setLocationName(locationExcel.getLocationName());
            TLocationType tLocationType = locationTypes.stream().filter(locationType -> locationType.getLocationName().equals(locationExcel.getLocationType())).findFirst().orElse(null);
            if (Objects.nonNull(tLocationType)){
                location.setLocationType(tLocationType.getId());
            }
            location.setLocationAddress(locationExcel.getLocationAddress());
            String[] addressLonLat = locationExcel.getLocationAddressLonLat().split("/");
            location.setLocationLon(addressLonLat[0]);
            location.setLocationLat(addressLonLat[1]);
            location.setLocationAddressEnd(locationExcel.getLocationAddressEnd());
            String[] addressEndLonLat = locationExcel.getLocationAddressEndLonLat().split("/");
            location.setLocationLonEnd(addressEndLonLat[0]);
            location.setLocationLatEnd(addressEndLonLat[1]);
            TDept tDept = deptList.stream().filter(dept -> dept.getCode().equals(locationExcel.getDeptCode())).findFirst().orElse(null);
            if(Objects.nonNull(tDept)){
                location.setProjectId(tDept.getId());
            }
            SysUser sysUser = users.stream().filter(user -> user.getNickName().equals(locationExcel.getNickName())).findFirst().orElse(null);
            if(Objects.nonNull(sysUser)){
                location.setLocationLeader(String.valueOf(sysUser.getUserId()));
            }
            cleaners.stream().filter(cleaner -> cleaner.getCleanerCode().equals(locationExcel.getCleanerCodeClear())
                    && cleaner.getDeptCode().equals(locationExcel.getDeptCodeClear())
                    && cleaner.getProjectCode().equals(locationExcel.getProjectCodeClear())).findFirst().orElse(null);
            location.setLocationCleaner(locationExcel.getProjectCodeClear());
            locationService.save(location);
        }
//        locationService.saveOrUpdateBatch(saveOrUpdateList);
        return R.ok(failedData);
        return R.ok();
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TTaskController.java
@@ -32,6 +32,7 @@
import io.swagger.annotations.ApiOperation;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@@ -196,7 +197,7 @@
    @Log(title = "批量审核任务", businessType = BusinessType.UPDATE)
    @ApiOperation(value = "批量审核任务")
    @PostMapping(value = "/auditBatch")
    public R<Boolean> auditBatch(@RequestBody @Valid TTaskAuditBatchDTO dto) {
    public R<Boolean> auditBatch(@RequestBody @Validated TTaskAuditBatchDTO dto) {
        List<TTaskDetail> tTaskDetails = new ArrayList<>();
        for (String s : dto.getTaskIds().split(",")) {
            TTask byId = taskCleanerService.getById(s);
ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/TaskUtil.java
@@ -150,6 +150,9 @@
                    .in(TProjectDept::getParentId, proIds));
            // 获取片区id
            List<String> areaIds = tProjectDeptList.stream().map(TProjectDept::getId).collect(Collectors.toList());
            if(CollectionUtils.isEmpty(areaIds)){
                return;
            }
            // 计算每天需要抽取多少个保洁员
            long count = cleanerService.count(Wrappers.lambdaQuery(TCleaner.class)
ruoyi-applet/src/main/java/com/ruoyi/web/controller/api/TTaskDetailController.java
@@ -1,9 +1,30 @@
package com.ruoyi.web.controller.api;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.system.dto.TTaskAuditBatchDTO;
import com.ruoyi.system.model.TAppeal;
import com.ruoyi.system.model.TTask;
import com.ruoyi.system.model.TTaskDetail;
import com.ruoyi.system.service.TAppealService;
import com.ruoyi.system.service.TTaskCleanService;
import com.ruoyi.system.service.TTaskDetailService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
/**
 * <p>
@@ -18,5 +39,33 @@
@RequestMapping("/t-task-detail")
public class TTaskDetailController {
    @Autowired
    private TTaskDetailService taskDetailService;
    @Autowired
    private TTaskCleanService taskService;
    @Autowired
    private TAppealService appealService;
    @ApiOperation(value = "上传任务")
    @PostMapping(value = "/uploadTask")
    public R<Boolean> uploadTask(@RequestBody TTaskDetail dto) {
        taskDetailService.save(dto);
        // 修改任务状态
        taskService.update(Wrappers.<TTask>lambdaUpdate().set(TTask::getStatus, 3).eq(TTask::getId, dto.getTaskId()));
        return R.ok();
    }
    @ApiOperation(value = "申诉")
    @PostMapping(value = "/appeal")
    public R<Boolean> appeal(@RequestBody TAppeal dto) {
        appealService.save(dto);
        // 添加任务详情
        TTaskDetail taskDetail = new TTaskDetail();
        taskDetail.setTaskId(dto.getTaskId());
        taskDetail.setHandleType(4);
        taskDetailService.save(taskDetail);
        return R.ok();
    }
}
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java
@@ -184,4 +184,26 @@
    List<SysUser> selectUserByDeptId(@Param("id")String id);
    List<TaskFinishListVO> pageListReport(@Param("query")DataReportQuery query, @Param("pageInfo")PageInfo<TaskFinishListVO> pageInfo);
    /**
     * 通过部门id查询用户
     * @param deptId
     * @return
     */
    List<SysUser> selectListByDeptId(@Param("deptId")String deptId);
    /**
     * 通过部门类型查询用户
     * @param deptType
     * @return
     */
    List<SysUser> selectListByDeptType(@Param("deptType")Integer deptType);
    /**
     *  通过部门id查询用户
     * @param projectIds
     * @return
     */
    List<SysUser> selectListByDeptIds(@Param("projectIds")List<String> projectIds);
}
ruoyi-system/src/main/java/com/ruoyi/system/model/TProjectDept.java
@@ -9,6 +9,7 @@
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List;
/**
 * <p>
@@ -44,5 +45,7 @@
    @TableField("status")
    private Integer status;
    @TableField(exist = false)
    private List<TProjectDept> children;
}
ruoyi-system/src/main/java/com/ruoyi/system/query/DataStatisticsQuery.java
New file
@@ -0,0 +1,20 @@
package com.ruoyi.system.query;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
@Data
@ApiModel(value = "数据统计查询参数Query")
public class DataStatisticsQuery implements Serializable {
    @ApiModelProperty(value = "片区id")
    private List<String> projectId;
    @ApiModelProperty(value = "点位类型id")
    private String locationTypeId;
}
ruoyi-system/src/main/java/com/ruoyi/system/query/DataStatisticsRankQuery.java
New file
@@ -0,0 +1,29 @@
package com.ruoyi.system.query;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
@Data
@ApiModel(value = "数据统计巡检排行榜查询参数Query")
public class DataStatisticsRankQuery implements Serializable {
    @ApiModelProperty(value = "片区id")
    private List<String> projectId;
    @ApiModelProperty(value = "点位类型id")
    private String locationTypeId;
    @ApiModelProperty(value = "排名类型 1=人员排名 2=项目部排名")
    private Integer rankType;
    @ApiModelProperty(value = "时间类型 1=月排行 2=季度排行 3=年度排行")
    private Integer timeType;
    @ApiModelProperty(value = "排序类型 1=升序 2=降序")
    private Integer sortType;
}
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java
@@ -266,6 +266,27 @@
    List<SysUser> selectUserByTempLateId(String templateId);
    /**
     * 查询自己项目部的人员
     * @param deptId
     * @return
     */
    List<SysUser> selectListByDeptId(String deptId);
    /**
     * 查询部门类型下的人员
     * @param deptType
     * @return
     */
    List<SysUser> selectListByDeptType(Integer deptType);
    /**
     * 批量查询人员
     * @param projectIds
     * @return
     */
    List<SysUser> selectListByDeptIds(List<String> projectIds);
    List<SysUser> selectUserByDeptId(String id);
    PageInfo<TaskFinishListVO> pageListReport(DataReportQuery dataReportQuery);
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java
@@ -731,6 +731,21 @@
    }
    @Override
    public List<SysUser> selectListByDeptId(String deptId) {
        return userMapper.selectListByDeptId(deptId);
    }
    @Override
    public List<SysUser> selectListByDeptType(Integer deptType) {
        return userMapper.selectListByDeptType(deptType);
    }
    @Override
    public List<SysUser> selectListByDeptIds(List<String> projectIds) {
        return userMapper.selectListByDeptIds(projectIds);
    }
    @Override
    public List<SysUser> selectUserByDeptId(String id) {
        return userMapper.selectUserByDeptId(id);
    }
ruoyi-system/src/main/java/com/ruoyi/system/vo/system/AnalysisUnqualifiedCleaningDetailVO.java
New file
@@ -0,0 +1,19 @@
package com.ruoyi.system.vo.system;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
@Data
@ApiModel(value = "清洁不合格分析详情VO")
public class AnalysisUnqualifiedCleaningDetailVO implements Serializable {
    @ApiModelProperty(value = "不合格原因名称")
    private String unqualifiedName;
    @ApiModelProperty(value = "数量")
    private Integer count;
}
ruoyi-system/src/main/java/com/ruoyi/system/vo/system/AnalysisUnqualifiedCleaningVO.java
New file
@@ -0,0 +1,20 @@
package com.ruoyi.system.vo.system;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
@Data
@ApiModel(value = "清洁不合格分析VO")
public class AnalysisUnqualifiedCleaningVO implements Serializable {
    @ApiModelProperty(value = "不合格任务总数")
    private Integer total;
    @ApiModelProperty(value = "不合格任务分类统计")
    private List<AnalysisUnqualifiedCleaningDetailVO> analysisUnqualifiedCleaningDetailVOS;
}
ruoyi-system/src/main/java/com/ruoyi/system/vo/system/DataStatisticsRankVO.java
New file
@@ -0,0 +1,23 @@
package com.ruoyi.system.vo.system;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
@Data
@ApiModel(value = "巡检排行榜VO")
public class DataStatisticsRankVO implements Serializable {
    @ApiModelProperty(value = "名称")
    private String name;
    @ApiModelProperty(value = "任务总数")
    private Integer taskCount;
    @ApiModelProperty(value = "合格数")
    private Long qualifiedCount;
}
ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml
@@ -290,8 +290,32 @@
        and t1.del_flag = '0'
        and t1.dept_type = 1
    </select>
    <select id="selectListByDeptId" resultType="com.ruoyi.common.core.domain.entity.SysUser">
        select u.user_id AS userId, u.dept_id AS deptId, u.user_name AS userName, u.nick_name AS nickName, u.email AS email, u.avatar AS avatar,
               u.phonenumber AS phonenumber, u.sex AS sex, u.status AS status, u.del_flag AS delFlag, u.login_ip AS loginIp,
               u.login_date AS loginDate, u.create_by AS createBy, u.create_time AS createTime, u.remark AS remark,u.templateId
        from sys_user u where u.deptId = #{deptId} and u.status = 0 and u.del_flag = 0
    </select>
    <select id="selectListByDeptType" resultType="com.ruoyi.common.core.domain.entity.SysUser">
        select u.user_id AS userId, u.dept_id AS deptId, u.user_name AS userName, u.nick_name AS nickName, u.email AS email, u.avatar AS avatar,
               u.phonenumber AS phonenumber, u.sex AS sex, u.status AS status, u.del_flag AS delFlag, u.login_ip AS loginIp,
               u.login_date AS loginDate, u.create_by AS createBy, u.create_time AS createTime, u.remark AS remark,u.templateId
        from sys_user u where u.deptType = #{deptType} and u.status = 0 and u.del_flag = 0
    </select>
    <select id="selectListByDeptIds" resultType="com.ruoyi.common.core.domain.entity.SysUser">
        select u.user_id AS userId, u.dept_id AS deptId, u.user_name AS userName, u.nick_name AS nickName, u.email AS email, u.avatar AS avatar,
               u.phonenumber AS phonenumber, u.sex AS sex, u.status AS status, u.del_flag AS delFlag, u.login_ip AS loginIp,
               u.login_date AS loginDate, u.create_by AS createBy, u.create_time AS createTime, u.remark AS remark,u.templateId
        from sys_user u where u.status = 0 and u.del_flag = 0
        <if test="projectIds != null and projectIds.size() > 0">
            and u.dept_id in
            <foreach item="item" collection="projectIds" open="(" separator="," close=")">
                #{item}
            </foreach>
        </if>
    </select>
    <insert id="insertUser" parameterType="SysUser" useGeneratedKeys="true" keyProperty="userId">
    <insert id="insertUser" parameterType="SysUser" useGeneratedKeys="true" keyProperty="userId">
         insert into sys_user(
             <if test="userId != null and userId != 0">user_id,</if>
             <if test="deptId != null and deptId != 0">dept_id,</if>