package com.usky.pm.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.datascope.annotation.DataScope;
import com.ruoyi.common.datascope.context.DataScopeContextHolder;
import com.usky.common.core.bean.CommonPage;
import com.usky.common.core.exception.BusinessException;
import com.usky.common.security.utils.SecurityUtils;
import com.usky.pm.domain.PmProject;
import com.usky.pm.domain.PmWorkContent;
import com.usky.pm.domain.PmWorkReport;
import com.usky.pm.mapper.PmProjectMapper;
import com.usky.pm.mapper.PmWorkContentMapper;
import com.usky.pm.mapper.PmWorkReportMapper;
import com.usky.pm.mapper.SysUserMapper;
import com.usky.pm.service.PmProjectService;
import com.usky.common.mybatis.core.AbstractCrudService;
import com.usky.pm.service.PmWorkContentService;
import com.usky.pm.service.vo.PmProjectWorkTimeTwoVo;
import com.usky.pm.service.vo.PmUsersProjectWorkTimeVO;
import com.usky.system.domain.SysUser;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * <p>
 * 项目表 服务实现类
 * </p>
 *
 * @author fu
 * @since 2024-05-20
 */
@Slf4j
@Service
public class PmProjectServiceImpl extends AbstractCrudService<PmProjectMapper, PmProject> implements PmProjectService {

    @Autowired
    private PmWorkContentMapper pmWorkContentMapper;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private PmProjectMapper pmProjectMapper;

    @Autowired
    private PmWorkReportMapper pmWorkReportMapper;

    @Autowired
    private PmWorkContentService pmWorkContentService;

    private static final String FIND_IN_SET_SQL = "FIND_IN_SET(?, project_member) > 0";

    @Override
    public void addProject(PmProject project) {
        Long deptId = SecurityUtils.getLoginUser().getSysUser().getDeptId();
        String userName = SecurityUtils.getUsername();
        Integer tenantId = SecurityUtils.getTenantId();
        LocalDateTime now = LocalDateTime.now();

        // 验证项目成员
        validateProjectMember(project.getProjectMember());

        // 检查项目名称是否为空或超过长度限制
        String projectName = project.getProjectName();
        if (StringUtils.isBlank(projectName)) {
            throw new BusinessException("项目名称不能为空！");
        } else if (projectName.length() > 50) {
            throw new BusinessException("项目名称长度不能超过50个字符!");
        }

        // 检查项目名称是否已存在
        if (Objects.isNull(project.getId())) {
            checkProjectNameExistence(project, tenantId);
        }

        // 检查项目类型是否为空或不在有效范围内
        Integer projectType = project.getProjectType();
        if (projectType == null) {
            throw new BusinessException("项目类型不能为空且");
        } else if (projectType < 1 || projectType > 6) {
            throw new BusinessException("项目类型传参有误!");
        }

        // 检查项目状态是否为空或不在有效范围内
        Integer projectStatus = project.getProjectStatus();
        if (projectStatus == null) {
            throw new BusinessException("项目状态不能为空且!");
        } else if (projectStatus < 1 || projectStatus > 5) {
            throw new BusinessException("项目状态传参有误!");
        }

        // 设置项目工作量和校验
        handleProjectWorkload(project);

        // 保存或更新项目
        saveOrUpdateProject(project, userName, now, deptId, tenantId);
    }

    // 验证项目成员
    private void validateProjectMember(String member) {
        if (StringUtils.isBlank(member)) {
            return;
        }
        if (!member.matches("\\d+(,\\d+)*")) {
            throw new BusinessException("项目成员格式错误！");
        }
    }

    // 检查项目名称是否已存在
    private void checkProjectNameExistence(PmProject project, Integer tenantId) {
        LambdaQueryWrapper<PmProject> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(PmProject::getProjectName, project.getProjectName())
                .eq(PmProject::getTenantId, tenantId)
                .eq(PmProject::getDelFlag, 0);
        PmProject existingProject = pmProjectMapper.selectOne(wrapper);
        if (Objects.nonNull(existingProject)) {
            throw new BusinessException("已存在同名项目！请检查后重试");
        }
    }

    // 处理项目工作量
    private void handleProjectWorkload(PmProject project) {
        if (Objects.isNull(project.getProjectWorkload())) {
            return;
        }

        if (project.getProjectWorkload().scale() > 1) {
            throw new BusinessException("计划人/天小数位超出长度，请重新输入！");
        } else if (project.getProjectWorkload().precision() - project.getProjectWorkload().scale() > 5) {
            throw new BusinessException("计划人/天整数位超出长度，请重新输入！");
        }
    }

    // 保存或更新项目
    private void saveOrUpdateProject(PmProject project, String userName, LocalDateTime now, Long deptId, Integer tenantId) {
        if (Objects.isNull(project.getId())) {
            project.setCreateBy(userName);
            project.setCreateTime(now);
            project.setDeptId(deptId);
            project.setTenantId(tenantId);
            this.save(project);
        } else {
            project.setUpdateBy(userName);
            project.setUpdateTime(now);
            this.updateById(project);
        }
    }

    /**
     * 删除项目
     *
     * @param projectId 项目id
     */
    @Override
    public void delProject(Integer projectId) {
        LambdaQueryWrapper<PmWorkContent> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(PmWorkContent::getProjectId, projectId);
        List<PmWorkContent> pmWorkContent = pmWorkContentMapper.selectList(queryWrapper);
        if (pmWorkContent.size() != 0) {
            throw new BusinessException("该项目下存在日报，无法删除！若有疑问请联系管理员");
        } else {
            LambdaQueryWrapper<PmProject> query = Wrappers.lambdaQuery();
            query.eq(PmProject::getId, projectId);
            PmProject project = baseMapper.selectOne(query);
            project.setDelFlag(1);
            project.setUpdateBy(SecurityUtils.getUsername());
            project.setUpdateTime(LocalDateTime.now());
            baseMapper.updateById(project);
        }
    }

    /**
     * 添加工作报告项目下拉框
     * 查询当前租户所有项目
     *
     * @return 只返回项目id和名称
     */
    @Override
    public List<PmProject> queryProject() {
        Integer tenantId = SecurityUtils.getTenantId();
        Long userId = SecurityUtils.getUserId();
        LambdaQueryWrapper<PmProject> wrapper = Wrappers.lambdaQuery();
        wrapper.select(PmProject::getId, PmProject::getProjectName)
                .eq(PmProject::getTenantId, tenantId)
                .eq(PmProject::getDelFlag, 0)
                .and(qw -> qw
                        .eq(PmProject::getProjectHead, userId)
                        .or().apply("FIND_IN_SET('" + SecurityUtils.getUserId() + "', project_member) > 0")
                )
                .in(PmProject::getProjectStatus, 1, 2, 3);
        List<PmProject> list = this.list(wrapper);
        if (list.isEmpty()) {
            return list;
        }

        List<Integer> projectIds = list.stream().map(PmProject::getId).collect(Collectors.toList());
        LambdaQueryWrapper<PmWorkContent> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.select(PmWorkContent::getProjectId)
                .eq(PmWorkContent::getSubmitterId, userId)
                .in(PmWorkContent::getProjectId, projectIds)
                .between(PmWorkContent::getCreateTime, LocalDateTime.now().minusDays(29), LocalDateTime.now());
        List<PmWorkContent> pmWorkContents = pmWorkContentMapper.selectList(queryWrapper);
        if (pmWorkContents.isEmpty()) {
            for (PmProject project : list) {
                project.setSubmissions(0L);
            }
            return list;
        }

        Map<Integer, Long> projectIdCountMap = pmWorkContents.stream()
                .collect(Collectors.groupingBy(PmWorkContent::getProjectId, Collectors.counting()));

        for (PmProject project : list) {
            Integer id = project.getId();
            Long aLong = projectIdCountMap.getOrDefault(id, 0L);
            project.setSubmissions(aLong);
        }
        // 降序排序
        Collections.sort(list, new Comparator<PmProject>() {
            @Override
            public int compare(PmProject p1, PmProject p2) {
                return Long.compare(p2.getSubmissions(), p1.getSubmissions());
            }
        });

        return list;
    }

    /**
     * 分页
     *
     * @param projectName       项目名
     * @param projectType       类型(1：人力外包，2：项目研发，3：采购项目，4：过标项目，5：集成项目，6：其他)
     * @param projectStatus     状态(1：未开始；2；进行中；3：已完成；4：已暂停；5：已作废)
     * @param projectAscription 项目归属类型(0:全部；1：我负责；2：我参与)
     * @param pageNum           页码
     * @param pageSize          页大小
     * @param projectId         项目id
     * @return
     */
    @Override
    public CommonPage<PmProject> projectList(String projectName, Integer projectType, Integer projectStatus, Integer projectAscription, Integer pageNum, Integer pageSize, Integer projectId, Byte visibleRange) {
        IPage<PmProject> page = new Page<>(pageNum, pageSize);
        Long userId = SecurityUtils.getUserId();
        String username = SecurityUtils.getUsername();
        String nickName = SecurityUtils.getLoginUser().getSysUser().getNickName();
        Integer tenantId = SecurityUtils.getTenantId();

        LambdaQueryWrapper<PmProject> lambdaQuery = Wrappers.lambdaQuery();
        lambdaQuery.eq(PmProject::getTenantId, tenantId)
                .eq(PmProject::getDelFlag, 0);

        if (projectId != null && projectId != 0) {
            lambdaQuery.eq(PmProject::getId, projectId);
        }

        switch (projectAscription) {
            case 0:
                if (visibleRange == null) {
                    lambdaQuery.and(wrapper -> wrapper
                            .and(qw -> qw
                                    .eq(PmProject::getProjectHead, userId)
                                    .or()
                                    .apply("FIND_IN_SET('" + userId + "', project_member) > 0")
                                    .or()
                                    .eq(PmProject::getCreateBy, username)
                            )
                            .or()
                            .eq(PmProject::getVisibleRange, 1)
                    );
                } else if (visibleRange == 2) {
                    lambdaQuery.and(wrapper -> wrapper
                            .eq(PmProject::getProjectHead, userId)
                            .or()
                            .apply("FIND_IN_SET('" + userId + "', project_member) > 0")
                            .or()
                            .eq(PmProject::getCreateBy, username)
                    );
                }
                lambdaQuery.like(StringUtils.isNotBlank(projectName), PmProject::getProjectName, projectName)
                        .eq(projectType != null, PmProject::getProjectType, projectType)
                        .eq(projectStatus != null, PmProject::getProjectStatus, projectStatus);
                break;
            case 1:
                lambdaQuery.eq(PmProject::getProjectHead, userId)
                        .like(StringUtils.isNotBlank(projectName), PmProject::getProjectName, projectName)
                        .eq(projectType != null, PmProject::getProjectType, projectType)
                        .eq(projectStatus != null, PmProject::getProjectStatus, projectStatus);
                break;
            case 2:
                lambdaQuery.apply("FIND_IN_SET('" + userId + "', project_member) > 0")
                        .like(StringUtils.isNotBlank(projectName), PmProject::getProjectName, projectName)
                        .eq(projectType != null, PmProject::getProjectType, projectType)
                        .eq(projectStatus != null, PmProject::getProjectStatus, projectStatus);
                break;
            default:
                throw new BusinessException("查询项目列表参数错误");
        }

        lambdaQuery.eq(visibleRange != null, PmProject::getVisibleRange, visibleRange)
                .orderByDesc(PmProject::getCreateTime);
        List<PmProject> pmProjects = pmProjectMapper.selectList(lambdaQuery);
        if (pmProjects.isEmpty()) {
            return new CommonPage<>(pmProjects, 0, pageSize, pageNum);
        }

        // 替换创建人和更新人名字（username→nickname）
        LambdaQueryWrapper<SysUser> query = Wrappers.lambdaQuery();
        query.select(SysUser::getUserName, SysUser::getNickName)
                .eq(SysUser::getTenantId, tenantId)
                .eq(SysUser::getDelFlag, 0)
                .eq(SysUser::getStatus, "0");
        List<SysUser> sysUsers = sysUserMapper.selectList(query);

        Map<String, String> userNameToNickName = new HashMap<>();
        for (SysUser sysUser : sysUsers) {
            if (sysUser != null && sysUser.getUserName() != null) {
                userNameToNickName.put(sysUser.getUserName(), nickName);
            }
        }

        page.getRecords().forEach(project -> {
            if (project != null) {
                String createBy = project.getCreateBy();
                String updateBy = project.getUpdateBy();
                if (createBy != null) {
                    project.setCreateBy(userNameToNickName.getOrDefault(createBy, createBy));
                }
                if (updateBy != null) {
                    project.setUpdateBy(userNameToNickName.getOrDefault(updateBy, updateBy));
                }
            }
        });

        page = this.page(page, lambdaQuery);
        if (page.getRecords() == null || page.getRecords().isEmpty()) {
            return new CommonPage<>(Collections.emptyList(), 0, pageSize, pageNum);
        }
        return new CommonPage<>(page.getRecords(), page.getTotal(), pageSize, pageNum);
    }

    /**
     * 查询项目名
     *
     * @param projectIds
     * @return
     */
    @Override
    public List<PmProject> projectName(List<Integer> projectIds) {
        LambdaQueryWrapper<PmProject> wrapper = Wrappers.lambdaQuery();
        wrapper.select(PmProject::getId, PmProject::getProjectName)
                .in(PmProject::getId, projectIds);
        return this.list(wrapper);
    }

    /**
     * 统计
     *
     * @return
     */
    @Override
    public Map<String, Integer> sum() {
        Integer tenantId = SecurityUtils.getTenantId();
        Long userId = SecurityUtils.getUserId();

        LambdaQueryWrapper<PmProject> lambdaQuery = Wrappers.lambdaQuery();
        lambdaQuery.eq(PmProject::getTenantId, tenantId)
                .eq(PmProject::getDelFlag, 0)
                .eq(PmProject::getVisibleRange, 2)
                .and(q -> q.or().eq(PmProject::getProjectHead, userId)
                        .or().apply("FIND_IN_SET('" + userId + "', project_member) > 0")
                        .or().eq(PmProject::getCreateBy, SecurityUtils.getUsername()));
        Integer allA = this.count(lambdaQuery);

        LambdaQueryWrapper<PmProject> lambdaQuery3 = Wrappers.lambdaQuery();
        lambdaQuery3.eq(PmProject::getTenantId, tenantId)
                .eq(PmProject::getVisibleRange, 1)
                .eq(PmProject::getDelFlag, 0);
        Integer allB = this.count(lambdaQuery3);
        int all = allA + allB;

        LambdaQueryWrapper<PmProject> lambdaQuery1 = Wrappers.lambdaQuery();
        lambdaQuery1.eq(PmProject::getTenantId, tenantId)
                .eq(PmProject::getDelFlag, 0)
                .eq(PmProject::getProjectHead, userId);
        Integer head = this.count(lambdaQuery1);

        LambdaQueryWrapper<PmProject> lambdaQuery2 = Wrappers.lambdaQuery();
        lambdaQuery2.eq(PmProject::getTenantId, tenantId)
                .eq(PmProject::getDelFlag, 0)
                .apply("FIND_IN_SET('" + userId + "', project_member) > 0");
        Integer join = this.count(lambdaQuery2);

        Map<String, Integer> sumMap = new HashMap<>();
        sumMap.put("allProject", all);
        sumMap.put("headProject", head);
        sumMap.put("joinProject", join);
        return sumMap;
    }


    /**
     * 查询所有项目负责人、成员和userid（此处逻辑为查询所有项目中的负责人、团队成员然后进行去重）
     *
     * @return
     */
    @Override
    public List<Map<String, Object>> projectUsers(Long userId) {
        List<Map<String, Object>> returnList = new ArrayList<>();
        List<SysUser> userList = new ArrayList<>();
        LambdaQueryWrapper<SysUser> queryNameId = Wrappers.lambdaQuery();
        if (userId != null) {
            queryNameId.select(SysUser::getUserId, SysUser::getNickName, SysUser::getUserName)
                    .eq(SysUser::getUserId, userId);
        } else {
            queryNameId.select(SysUser::getUserId, SysUser::getNickName, SysUser::getUserName)
                    .eq(SysUser::getDelFlag, 0)
                    .eq(SysUser::getStatus, "0")
                    .apply(Objects.nonNull(DataScopeContextHolder.getDataScopeSql()), DataScopeContextHolder.getDataScopeSql());
        }
        userList = sysUserMapper.selectList(queryNameId);
        for (SysUser user : userList) {
            Map<String, Object> map = new HashMap<>();
            map.put("id", user.getUserId());
            map.put("name", user.getNickName());
            returnList.add(map);
        }
        return returnList;
    }

    /**
     * 查询所有项目和id
     *
     * @return
     */
    @DataScope
    @Override
    public List<Map<String, Object>> projectIdName(Integer projectId) {
        Long userId = SecurityUtils.getUserId();
        List<Map<String, Object>> returnList = new ArrayList<>();
        LambdaQueryWrapper<PmProject> wrapper = Wrappers.lambdaQuery();
        wrapper.select(PmProject::getId, PmProject::getProjectName);
        if (projectId != null) {
            wrapper.eq(PmProject::getId, projectId);
        } else {
            wrapper.eq(PmProject::getDelFlag, 0)
                    .and(qw -> qw
                            .apply(Objects.nonNull(DataScopeContextHolder.getDataScopeSql()), DataScopeContextHolder.getDataScopeSql())
                            .or().eq(PmProject::getProjectHead, userId)
                            .or().eq(PmProject::getCreateBy, SecurityUtils.getUsername())
                            .or().apply("FIND_IN_SET('" + SecurityUtils.getUserId() + "', project_member) > 0")
                    );
        }

        List<PmProject> projects = pmProjectMapper.selectList(wrapper);
        for (PmProject project : projects) {
            Map<String, Object> returnMap = new HashMap<>();
            returnMap.put("id", project.getId());
            returnMap.put("name", project.getProjectName());
            returnList.add(returnMap);
        }
        return returnList;
    }

    /**
     * @param identifying 标识：1，返回人员userId和nickName；2：返回ProjectId和ProjectName
     * @return
     */
    @Override
    public List<Map<String, Object>> userOrProject(Integer identifying) {
        Integer projectId = null;
        Long userId = null;
        List<Map<String, Object>> returnList = new ArrayList<>();
        if (identifying == 1) {
            returnList = projectUsers(userId);
        } else if (identifying == 2) {
            returnList = projectIdName(projectId);
        }
        return returnList;
    }

    /**
     * 退出项目
     *
     * @param projectId
     */
    @Override
    public void exitProject(Integer projectId) {
        Long userId = SecurityUtils.getUserId();
        PmProject project = pmProjectMapper.selectById(projectId);
        String projectMember = project.getProjectMember();
        String[] parts = projectMember.split(",");
        String result = String.join(",", java.util.stream.Stream.of(parts)
                .filter(part -> !part.equals(String.valueOf(userId)))
                .collect(Collectors.toList()));
        project.setProjectMember(result);
        pmProjectMapper.updateById(project);
    }

    /**
     * 查询项目工时统计-时间
     *
     * @param projectId
     * @param startDate
     * @param endDate
     * @return
     */
    @Override
    public PmProjectWorkTimeTwoVo projectWorkTime(Integer projectId, String startDate, String endDate) {

        if (projectId == null || projectId <= 0) {
            throw new BusinessException("查询项目工时项目id有误！");
        }

        PmProjectWorkTimeTwoVo workTimeCount = new PmProjectWorkTimeTwoVo();
        List<LocalDate> dateList = new ArrayList<>();
        List<BigDecimal> workTimeList = new ArrayList<>();

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate startTime = null;
        LocalDate endTime = null;
        if (StringUtils.isNotBlank(startDate) && StringUtils.isNotBlank(endDate)) {
            try {
                startTime = LocalDate.parse(startDate, formatter);
                endTime = LocalDate.parse(endDate, formatter);
            } catch (Exception e) {
                log.error("查询项目工时时间统计时间格式有误！" + e);
                throw new BusinessException("传入时间参数有误！");
            }
        } else {
            endTime = LocalDate.now();
            startTime = LocalDate.now().minusDays(29);
        }

        LambdaQueryWrapper<PmWorkReport> wrapper2 = Wrappers.lambdaQuery();
        wrapper2.select(PmWorkReport::getId, PmWorkReport::getReportDate)
                .eq(PmWorkReport::getTenantId, SecurityUtils.getTenantId())
                .between(PmWorkReport::getReportDate, startTime, endTime)
                .orderByAsc(PmWorkReport::getReportDate);
        List<PmWorkReport> pmWorkReports = pmWorkReportMapper.selectList(wrapper2);

        List<Integer> reportIds = pmWorkReports.stream().map(PmWorkReport::getId).collect(Collectors.toList());
        if (reportIds.isEmpty()) {
            return workTimeCount;
        }

        LambdaQueryWrapper<PmWorkContent> wrapper = Wrappers.lambdaQuery();
        wrapper.select(PmWorkContent::getReportId, PmWorkContent::getSubmitterId, PmWorkContent::getWorkTime)
                .eq(PmWorkContent::getProjectId, projectId)
                .in(PmWorkContent::getReportId, reportIds);
        List<PmWorkContent> pmWorkContents = pmWorkContentMapper.selectList(wrapper);
        for (PmWorkReport report : pmWorkReports) {
            Integer id = report.getId();
            LocalDate reportDate = report.getReportDate();
            if (pmWorkContents.stream().anyMatch(content -> content.getReportId().equals(id))) {
                BigDecimal totalWorkTime = pmWorkContents.stream()
                        .filter(content -> content.getReportId().equals(id))
                        .map(PmWorkContent::getWorkTime)
                        .reduce(BigDecimal.ZERO, BigDecimal::add);
                dateList.add(reportDate);
                workTimeList.add(totalWorkTime);
            }
        }

        Map<LocalDate, BigDecimal> accumulatedWorkTimeMap = new LinkedHashMap<>();
        for (int i = 0; i < dateList.size(); i++) {
            LocalDate date = dateList.get(i);
            BigDecimal workTime = workTimeList.get(i);
            accumulatedWorkTimeMap.merge(date, workTime, BigDecimal::add);
        }
        List<LocalDate> newDateList = new ArrayList<>(accumulatedWorkTimeMap.keySet());
        List<BigDecimal> newWorkTimeList = new ArrayList<>(accumulatedWorkTimeMap.values());

        workTimeCount.setDateList(newDateList);
        workTimeCount.setWorkTimeList(newWorkTimeList);

        return workTimeCount;
    }

    /**
     * @description: 查询人员项目工时统计
     * @author: fu
     * @date: 2024/8/12 15:44
     * @param: [projectId]
     * @return: java.util.List<java.util.Map < java.lang.String, java.math.BigDecimal>>
     **/
    @Override
    public PmUsersProjectWorkTimeVO usersProjectWorkTime(Integer projectId, String startDate, String endDate) {

        if (projectId == null || projectId <= 0) {
            throw new BusinessException("查询项目工时项目id有误！");
        }

        PmUsersProjectWorkTimeVO workTimeCount = new PmUsersProjectWorkTimeVO();

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate startTime = null;
        LocalDate endTime = null;
        if (StringUtils.isNotBlank(startDate) && StringUtils.isNotBlank(endDate)) {
            try {
                startTime = LocalDate.parse(startDate, formatter);
                endTime = LocalDate.parse(endDate, formatter);
            } catch (Exception e) {
                log.error("查询人员项目工时统计时间格式有误！" + e);
                throw new BusinessException("传入时间参数有误！");
            }
        } else {
            startTime = LocalDate.now();
            endTime = LocalDate.now().minusDays(29);
        }

        LambdaQueryWrapper<PmWorkReport> wrapper2 = Wrappers.lambdaQuery();
        wrapper2.select(PmWorkReport::getId);
        wrapper2.between(PmWorkReport::getReportDate, startTime, endTime);
        List<Integer> reportIds = pmWorkReportMapper.selectList(wrapper2).stream().map(PmWorkReport::getId).collect(Collectors.toList());

        // 项目成员与实际填写报告的人员可能会有差异
        LambdaQueryWrapper<PmWorkContent> wrapper = Wrappers.lambdaQuery();
        wrapper.select(PmWorkContent::getSubmitterId, PmWorkContent::getWorkTime)
                .eq(PmWorkContent::getProjectId, projectId)
                .eq(PmWorkContent::getTenantId, SecurityUtils.getTenantId());
        if (!reportIds.isEmpty()) {
            wrapper.in(PmWorkContent::getReportId, reportIds);
        }
        List<PmWorkContent> pmWorkContents = pmWorkContentMapper.selectList(wrapper);
        Set<Long> userIds = pmWorkContents.stream().map(PmWorkContent::getSubmitterId).collect(Collectors.toSet());

        LambdaQueryWrapper<PmProject> wrapper1 = Wrappers.lambdaQuery();
        wrapper1.select(PmProject::getProjectMember)
                .eq(PmProject::getId, projectId);
        if (StringUtils.isNotBlank(pmProjectMapper.selectOne(wrapper1).getProjectMember())) {
            List<Long> userIds1 = Arrays.stream(pmProjectMapper.selectOne(wrapper1).getProjectMember().split(",")).map(Long::parseLong).collect(Collectors.toList());
            userIds.addAll(userIds1);
        }

        List<Long> userIds1 = new ArrayList<>(userIds);

        if (userIds1.isEmpty()) {
            return workTimeCount;
        }

        List<SysUser> sysUsers = pmWorkContentService.nickNames(userIds1);
        BigDecimal totalWorkTime = BigDecimal.ZERO;

        List<String> users2 = new ArrayList<>();
        List<BigDecimal> workTime1 = new ArrayList<>();

        for (SysUser sysUser : sysUsers) {
            users2.add(sysUser.getNickName());
            BigDecimal userWorkTime = pmWorkContents.stream()
                    .filter(pmWorkContent -> pmWorkContent.getSubmitterId().equals(sysUser.getUserId()))
                    .map(PmWorkContent::getWorkTime)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            workTime1.add(userWorkTime);
            totalWorkTime = totalWorkTime.add(userWorkTime);
        }
        workTimeCount.setUsers(users2);
        if (reportIds.isEmpty()) {
            List<BigDecimal> workTime = IntStream.range(0, users2.size())
                    .mapToObj(index -> BigDecimal.ZERO)
                    .collect(Collectors.toList());
            workTimeCount.setWorkTime(workTime);
            return workTimeCount;
        }
        workTimeCount.setWorkTime(workTime1);

        return workTimeCount;
    }

    /**
     * @description: 项目成员加入项目
     * @author: fu
     * @date: 2024/8/12 15:44
     * @param: [projectId]
     * @return: void
     **/
    @Override
    public void joinProject(Integer projectId) {
        Long userId = SecurityUtils.getUserId();
        PmProject pmProject = pmProjectMapper.selectById(projectId);
        if (pmProject == null) {
            throw new BusinessException("加入项目不存在！请刷新后重试");
        }
        pmProject.setProjectMember(pmProject.getProjectMember() + "," + userId);
        try {
            pmProjectMapper.updateById(pmProject);
        } catch (Exception e) {
            throw new BusinessException("加入项目失败！请联系管理员");
        }
    }

}
