/**
 * Copyright (c) 2018-2099, Chill Zhuang 庄骞 (bladejava@qq.com).
 * <p>
 * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.gnu.org/licenses/lgpl.html
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.xiaoniu.subsystem.business.controller;

import com.alibaba.nacos.common.utils.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.xiaoniu.common.core.result.R;
import com.xiaoniu.common.core.utils.BeanUtil;
import com.xiaoniu.common.core.utils.DateUtils;
import com.xiaoniu.common.core.utils.poi.ExcelUtil;
import com.xiaoniu.common.log.annotation.Log;
import com.xiaoniu.common.log.enums.BusinessType;
import com.xiaoniu.subsystem.business.domain.*;
import com.xiaoniu.subsystem.business.domain.dto.ProjectPersonnelInfoDTO;
import com.xiaoniu.subsystem.business.domain.dto.ProjectPersonnelPageDTO;
import com.xiaoniu.subsystem.business.domain.dto.ProjectUserExamineDTO;
import com.xiaoniu.subsystem.business.domain.vo.*;
import com.xiaoniu.subsystem.business.service.*;
import com.xiaoniu.subsystem.system.domain.SysDictData;
import com.xiaoniu.subsystem.system.domain.Unit;
import com.xiaoniu.subsystem.system.service.ISysDictDataService;
import com.xiaoniu.subsystem.system.service.IUnitService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

import static com.xiaoniu.common.security.utils.SecurityUtils.getUnitId;
import static com.xiaoniu.common.security.utils.SecurityUtils.getUserId;

/**
 * 计划人员信息表 控制器
 *
 * @author sst
 * @since 2024-11-26
 */
@RestController
@AllArgsConstructor
@RequestMapping("/projectpersonnelinfo")
@Tag(name = "计划人员信息表", description = "计划人员信息表接口")
public class ProjectPersonnelInfoController {

    private IProjectPersonnelInfoService projectPersonnelInfoService;
    private IProjectService projectService;
    private ISysDictDataService dictDataService;
    private IUnitService unitService;
    private IWaitDoneService waitDoneService;
    private IGraduationAssessmentService graduationAssessmentService;
    private IStudentInfoService studentInfoService;

    /**
     * 详情
     */
    @GetMapping("/detail")
    @ApiOperationSupport(order = 1)
    @Operation(summary = "详情", description = "传入projectPersonnelInfo")
    public R<PersonnelInfoVO> detail(@Parameter(description = "主键", required = true)
                                     @RequestParam Long projectPersonnelInfoId) {
        ProjectPersonnelInfo detail = projectPersonnelInfoService.getById(projectPersonnelInfoId);
        if (null != detail) {
            List<ProjectPersonnelInfo> list = projectPersonnelInfoService.list(
                    new LambdaQueryWrapper<ProjectPersonnelInfo>()
                            .eq(ProjectPersonnelInfo::getIdCard, detail.getIdCard()));
            return R.data(BeanUtil.copy(detail, PersonnelInfoVO.class)
                    .setInfoVOS(BeanUtil.copy(list, ProjectPersonnelInfoVO.class)));
        }
        return R.data(BeanUtil.copy(detail, PersonnelInfoVO.class));
    }

    /**
     * 分页 计划人员信息表
     */
    @GetMapping("/page")
    @ApiOperationSupport(order = 2)
    @Operation(summary = "分页", description = "传入projectPersonnelInfo")
    public R<IPage<ProjectPersonnelInfoVO>> page(@Validated ProjectPersonnelPageDTO dto) {
        IPage<ProjectPersonnelInfo> pages = projectPersonnelInfoService.page(
                new Page<>(dto.getPageNum(), dto.getPageSize()), set(dto));
        return R.data(BeanUtil.copy(pages, ProjectPersonnelInfoVO.class));
    }

    /**
     * 导出
     */
    @GetMapping("/export")
    @ApiOperationSupport(order = 3)
    @Log(title = "人员导出", businessType = BusinessType.EXPORT)
    @Operation(summary = "导出", description = "传入ids")
    public void export(HttpServletResponse response, @Validated ProjectPersonnelPageDTO dto) {
        List<ProjectPersonnelInfo> list;
        if (StringUtils.isNotBlank(dto.getIds())) {
            list = projectPersonnelInfoService.list(new LambdaQueryWrapper<ProjectPersonnelInfo>()
                    .orderByDesc(ProjectPersonnelInfo::getCreateTime)
                    .in(StringUtils.isNotBlank(dto.getIds()), ProjectPersonnelInfo::getUserId,
                            Arrays.stream(dto.getIds().split(",")).toList()));
        } else {
            list = projectPersonnelInfoService.list(set(dto));
        }
        List<ProjectPersonnelInfoExcelVO> list1 = new ArrayList<ProjectPersonnelInfoExcelVO>();
        if (CollectionUtils.isNotEmpty(list)) {
            List<SysDictData> data = dictDataService.list(
                    new LambdaQueryWrapper<SysDictData>().eq(SysDictData::getDictType, "1"));
            Map<String, String> map = data.stream()
                    .collect(Collectors.toMap(SysDictData::getDictLabel, SysDictData::getDictValue));
            List<SysDictData> data1 = dictDataService.list(
                    new LambdaQueryWrapper<SysDictData>().eq(SysDictData::getDictType, "2"));
            Map<String, String> map1 = data1.stream()
                    .collect(Collectors.toMap(SysDictData::getDictLabel, SysDictData::getDictValue));
            list1.addAll(list.stream().map(l ->
                    BeanUtil.copy(l, ProjectPersonnelInfoExcelVO.class)
                            .setTraineeTypeName(Arrays.stream(l.getTraineeType()
                                    .split(",")).map(map1::get).collect(Collectors.joining(",")))
                            .setMajorTypeName(map.get(l.getMajorType()))).collect(Collectors.toList()));
        }
        ExcelUtil<ProjectPersonnelInfoExcelVO> excelUtil = new ExcelUtil<>(ProjectPersonnelInfoExcelVO.class);
        excelUtil.exportExcel(response, list1, "人员数据");
    }

    /**
     * 新增 计划人员信息表
     */
    @PostMapping("/save")
    @ApiOperationSupport(order = 4)
    @Operation(summary = "新增", description = "传入projectPersonnelInfo")
    public R save(@Valid @RequestBody ProjectPersonnelInfoDTO dto) {
        long count = projectPersonnelInfoService.count(new LambdaQueryWrapper<ProjectPersonnelInfo>()
                .eq(ProjectPersonnelInfo::getFlightId, dto.getFlightId())
                .eq(ProjectPersonnelInfo::getFlightName, dto.getFlightName())
                .eq(ProjectPersonnelInfo::getTrainingTime, dto.getTrainingTime())
                .eq(ProjectPersonnelInfo::getYear, StringUtils.isBlank(dto.getYear()) ?
                        DateUtils.parseDateToStr("yyyy", dto.getTrainingTime()) : dto.getYear())
                // .eq(ProjectPersonnelInfo::getProjectId, dto.getProjectId())
                .eq(ProjectPersonnelInfo::getIdCard, dto.getIdCard()));
        if (count > 0) {
            return R.fail("年度：" + (StringUtils.isBlank(dto.getYear()) ?
                    DateUtils.parseDateToStr("yyyy", dto.getTrainingTime()) : dto.getYear()) +
                    ",开训时间：" + DateUtils.dateTime(dto.getTrainingTime()) +
                    ",专业（班次）名称：" + dto.getFlightName() +
                    ",的计划下已存在身份证号：" + dto.getIdCard() + "的人员，添加单位:" + dto.getSendingUnitName());
        }
        return R.status(projectPersonnelInfoService.save(
                dto.setYear(StringUtils.isBlank(dto.getYear()) ?
                                DateUtils.parseDateToStr("yyyy", dto.getTrainingTime()) : dto.getYear())
                        .setIsReport("1")
                        .setStatus(1)
                        .setCreateDept(getUnitId())
                        .setCreateUser(getUserId())
                        .setCreateTime(new Date())));
    }

    /**
     * 修改 计划人员信息表
     */
    @PostMapping("/update")
    @ApiOperationSupport(order = 5)
    @Operation(summary = "修改", description = "传入projectPersonnelInfo")
    public R update(@Valid @RequestBody ProjectPersonnelInfoDTO dto) {
        long count = projectPersonnelInfoService.count(new LambdaQueryWrapper<ProjectPersonnelInfo>()
                // .eq(ProjectPersonnelInfo::getProjectId, dto.getProjectId())
                .eq(ProjectPersonnelInfo::getFlightId, dto.getFlightId())
                .eq(ProjectPersonnelInfo::getFlightName, dto.getFlightName())
                .eq(ProjectPersonnelInfo::getTrainingTime, dto.getTrainingTime())
                .eq(ProjectPersonnelInfo::getYear, StringUtils.isBlank(dto.getYear()) ?
                        DateUtils.parseDateToStr("yyyy", dto.getTrainingTime()) : dto.getYear())
                .eq(ProjectPersonnelInfo::getIdCard, dto.getIdCard())
                .ne(ProjectPersonnelInfo::getUserId, dto.getUserId()));
        if (count > 0) {
            return R.fail("年度：" + (StringUtils.isBlank(dto.getYear()) ?
                    DateUtils.parseDateToStr("yyyy", dto.getTrainingTime()) : dto.getYear()) +
                    ",开训时间：" + DateUtils.dateTime(dto.getTrainingTime()) +
                    ",专业（班次）名称：" + dto.getFlightName() +
                    ",的计划下已存在身份证号：" + dto.getIdCard() + "的人员，添加单位:" + dto.getSendingUnitName());
        }
        return R.status(projectPersonnelInfoService.updateById(
                dto.setStatus(1)
                        .setYear(StringUtils.isBlank(dto.getYear()) ?
                                DateUtils.parseDateToStr("yyyy", dto.getTrainingTime()) : dto.getYear())
                        .setUpdateUser(getUserId()).setUpdateTime(new Date())));
    }

    /**
     * 人员统计列表-单位统计
     */
    @GetMapping("/unit/total")
    @ApiOperationSupport(order = 6)
    @Operation(summary = "人员统计列表-单位统计")
    public R<List<UnitTotalVO>> unitTotal(@Parameter(description = "班次名称") @RequestParam(required = false) String flightName,
                                          @Parameter(description = "年度") @RequestParam(required = false) String year) {

        List<UnitTotalVO> unitTotalVOS = new ArrayList<>();
        List<StudentInfo> studentInfos = studentInfoService.list(new LambdaQueryWrapper<StudentInfo>()
                .like(StringUtils.isNotBlank(flightName), StudentInfo::getFlightName, flightName)
                .eq(StringUtils.isNotBlank(year), StudentInfo::getYear, year)
                .eq(StudentInfo::getCreateDept, getUnitId())
        );
        if (CollectionUtils.isEmpty(studentInfos)) {
            return R.data(unitTotalVOS);
        }
        Map<String, List<StudentInfo>> map = studentInfos.stream().collect(Collectors.groupingBy(StudentInfo::getMainUnitName));
        map.keySet().forEach(k -> {
            List<StudentInfoVO> infoVOs = new ArrayList<>();
            // 匹配考评等级和培训结束时间
            for (StudentInfo studentInfo : map.get(k)) {
                StudentInfoVO studentInfoVO = BeanUtil.copy(studentInfo, StudentInfoVO.class);
                // 匹配结束时间
                Date trainingTime = studentInfo.getTrainingTime();
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(trainingTime);
                calendar.add(Calendar.DATE, Integer.valueOf(studentInfo.getEducationalSystem()));
                studentInfoVO.setEndTime(calendar.getTime());
                // 屁屁额
                String idCard = studentInfo.getIdCard();
                Long flightId = studentInfo.getFlightId();
                GraduationAssessment graduationAssessment = graduationAssessmentService.getGraduationAssessmentByFlightIdAndIdCard(flightId, idCard);
                if (graduationAssessment != null) {
                    studentInfoVO.setEvaluationOrder(graduationAssessment.getEvaluationOrder());
                }
                infoVOs.add(studentInfoVO);
            }
            unitTotalVOS.add(new UnitTotalVO()
                    .setUnitName(k)
                    // 实际人数
                    .setActualNum(CollectionUtils.isNotEmpty(infoVOs) ? infoVOs.size() : 0)
                    // 待培训人数
                    .setAwaitNum(CollectionUtils.isNotEmpty(infoVOs) ?
                            (int) infoVOs.stream().filter(l -> new Date().compareTo(l.getTrainingTime()) < 0).count() : 0)
                    // 在培训人数
                    .setProceedNum(CollectionUtils.isNotEmpty(infoVOs) ?
                            (int) infoVOs.stream().filter(
                                    l -> l.getTrainingTime().compareTo(new Date()) < 0 && l.getEndTime().compareTo(new Date()) > 0).count() : 0)
                    // 已培训人数
                    .setCompleteNum(CollectionUtils.isNotEmpty(infoVOs) ?
                            (int) infoVOs.stream().filter(
                                    l -> l.getEndTime().compareTo(new Date()) < 0).count() : 0)
                    // 优秀毕业人数
                    .setOptimalNum(CollectionUtils.isNotEmpty(infoVOs) ?
                            (int) infoVOs.stream().filter(
                                    l -> l.getEndTime().compareTo(new Date()) < 0 && StringUtils.equals("0", l.getEvaluationOrder())).count() : 0));

        });
        return R.data(unitTotalVOS);

/*        List<UnitTotalVO> unitTotalVOS = new ArrayList<UnitTotalVO>();
        List<Project> list = projectService.list(new LambdaQueryWrapper<Project>()
                .like(StringUtils.isNotBlank(flightName), Project::getFlightName, flightName)
                .eq(StringUtils.isNotBlank(year), Project::getYear, year)
                .eq(Project::getCreateDept, getUnitId()));
        if (CollectionUtils.isEmpty(list)) {
            return R.data(unitTotalVOS);
        }
        //通过计划人员获取单位ids
        List<Long> ids = list.stream().map(Project::getProjectId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(ids)){
            return R.data(unitTotalVOS);
        }
        List<ProjectPersonnelInfo> infos = projectPersonnelInfoService.list(new LambdaQueryWrapper<ProjectPersonnelInfo>()
                .in(ProjectPersonnelInfo::getProjectId,ids));
        Map<String, List<ProjectPersonnelInfo>> map = infos.stream().collect(Collectors.groupingBy(ProjectPersonnelInfo::getSendingUnitName));
        map.keySet().forEach(k -> {
            //匹配考评等级
            for (ProjectPersonnelInfo projectPersonnelInfo : map.get(k)) {
                String idCard = projectPersonnelInfo.getIdCard();
                Long flightId = projectPersonnelInfo.getFlightId();
                GraduationAssessment graduationAssessment = graduationAssessmentService.getGraduationAssessmentByFlightIdAndIdCard(flightId, idCard);
                if (graduationAssessment != null){
                    projectPersonnelInfo.setEvaluationOrder(graduationAssessment.getEvaluationOrder());
                }
            }
            unitTotalVOS.add(new UnitTotalVO()
                    .setUnitName(k)
*//*                    .setProjectNnum(list.stream().map(s ->
                                    BigDecimal.valueOf(Double.parseDouble(StringUtils.isEmpty(s.getShouldAttendance()) ?
                                            "0" : s.getShouldAttendance())))
                            .reduce(BigDecimal.ZERO, BigDecimal::add).intValue())*//*
                    //实际人数
                    .setActualNum(CollectionUtils.isNotEmpty(map.get(k)) ? map.get(k).size() : 0)
                    //待培训人数
                    .setAwaitNum(CollectionUtils.isNotEmpty(map.get(k)) ?
                            (int) map.get(k).stream().filter(l -> new Date().compareTo(l.getTrainingTime()) < 0).count() : 0)
                    //在培训人数
                    .setProceedNum(CollectionUtils.isNotEmpty(map.get(k)) ?
                            (int) map.get(k).stream().filter(l -> l.getTrainingTime().compareTo(new Date()) < 0
                                    && StringUtils.equals("0", l.getIsFinishSchool())).count() : 0)
                    //已培训人数
                    .setCompleteNum(CollectionUtils.isNotEmpty(map.get(k)) ?
                            (int) map.get(k).stream().filter(l -> StringUtils.equals("1", l.getIsFinishSchool())).count() : 0)
                    .setOptimalNum(CollectionUtils.isNotEmpty(map.get(k)) ?
                            (int) map.get(k).stream().filter(l -> StringUtils.equals("1", l.getIsFinishSchool())
                                    && StringUtils.equals("0", l.getEvaluationOrder())).count() : 0));

        });
        return R.data(unitTotalVOS);*/
    }


    /**
     * 人员单位统计导出
     */
    @GetMapping("/unitTotal/export")
    @ApiOperationSupport(order = 3)
    @Log(title = "人员单位统计导出", businessType = BusinessType.EXPORT)
    @Operation(summary = "人员统计列表-单位统计导出", description = "传入ids")
    public void unitTotalExport(HttpServletResponse response, @Validated ProjectPersonnelPageDTO dto) {
        List<UnitTotalVO> unitTotalVOS = new ArrayList<UnitTotalVO>();
        List<StudentInfo> studentInfos = studentInfoService.list(new LambdaQueryWrapper<StudentInfo>()
                .like(StringUtils.isNotBlank(dto.getFlightName()), StudentInfo::getFlightName, dto.getFlightName())
                .eq(StringUtils.isNotBlank(dto.getYear()), StudentInfo::getYear, dto.getYear())
                .eq(StudentInfo::getCreateDept, getUnitId())
        );
        if (CollectionUtils.isEmpty(studentInfos)) {
            ExcelUtil<UnitTotalVO> excelUtil = new ExcelUtil<>(UnitTotalVO.class);
            excelUtil.exportExcel(response, unitTotalVOS, "人员数据");
        }
        Map<String, List<StudentInfo>> map = studentInfos.stream().collect(Collectors.groupingBy(StudentInfo::getMainUnitName));
        map.keySet().forEach(k -> {
            List<StudentInfoVO> infoVOs = new ArrayList<>();
            // 匹配考评等级和培训结束时间
            for (StudentInfo studentInfo : map.get(k)) {
                StudentInfoVO studentInfoVO = BeanUtil.copy(studentInfo, StudentInfoVO.class);
                // 匹配时间
                Date trainingTime = studentInfo.getTrainingTime();
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(trainingTime);
                calendar.add(Calendar.DATE, Integer.valueOf(studentInfo.getEducationalSystem()));
                studentInfoVO.setEndTime(calendar.getTime());
                // 匹配等级
                String idCard = studentInfo.getIdCard();
                Long flightId = studentInfo.getFlightId();
                GraduationAssessment graduationAssessment = graduationAssessmentService.getGraduationAssessmentByFlightIdAndIdCard(flightId, idCard);
                if (graduationAssessment != null) {
                    studentInfoVO.setEvaluationOrder(graduationAssessment.getEvaluationOrder());
                }
                infoVOs.add(studentInfoVO);
            }
            unitTotalVOS.add(new UnitTotalVO()
                    .setUnitName(k)
                    // 实际人数
                    .setActualNum(CollectionUtils.isNotEmpty(infoVOs) ? infoVOs.size() : 0)
                    // 待培训人数
                    .setAwaitNum(CollectionUtils.isNotEmpty(infoVOs) ?
                            (int) infoVOs.stream().filter(l -> new Date().compareTo(l.getTrainingTime()) < 0).count() : 0)
                    // 在培训人数
                    .setProceedNum(CollectionUtils.isNotEmpty(infoVOs) ?
                            (int) infoVOs.stream().filter(
                                    l -> l.getTrainingTime().compareTo(new Date()) < 0 && l.getEndTime().compareTo(new Date()) > 0).count() : 0)
                    // 已培训人数
                    .setCompleteNum(CollectionUtils.isNotEmpty(infoVOs) ?
                            (int) infoVOs.stream().filter(
                                    l -> l.getEndTime().compareTo(new Date()) < 0).count() : 0)
                    // 优秀毕业人数
                    .setOptimalNum(CollectionUtils.isNotEmpty(infoVOs) ?
                            (int) infoVOs.stream().filter(
                                    l -> l.getEndTime().compareTo(new Date()) < 0 && StringUtils.equals("0", l.getEvaluationOrder())).count() : 0));

        });
        ExcelUtil<UnitTotalVO> excelUtil = new ExcelUtil<>(UnitTotalVO.class);
        excelUtil.exportExcel(response, unitTotalVOS, "人员单位统计数据");


        /*List<UnitTotalVO> unitTotalVOS = new ArrayList<UnitTotalVO>();
        List<Project> list = projectService.list(new LambdaQueryWrapper<Project>()
                .like(StringUtils.isNotBlank(dto.getFlightName()), Project::getFlightName, dto.getFlightName())
                .eq(StringUtils.isNotBlank(dto.getYear()), Project::getYear, dto.getYear())
                .eq(Project::getCreateDept, getUnitId()));
        if (CollectionUtils.isEmpty(list)) {
            ExcelUtil<UnitTotalVO> excelUtil = new ExcelUtil<>(UnitTotalVO.class);
            excelUtil.exportExcel(response, unitTotalVOS, "人员班次统计数据");
        }
        //通过计划人员获取单位ids
        List<Long> ids = list.stream().map(Project::getProjectId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(ids)){
            ExcelUtil<UnitTotalVO> excelUtil = new ExcelUtil<>(UnitTotalVO.class);
            excelUtil.exportExcel(response, unitTotalVOS, "人员班次统计数据");
        }
        List<ProjectPersonnelInfo> infos = projectPersonnelInfoService.list(new LambdaQueryWrapper<ProjectPersonnelInfo>()
                .in(ProjectPersonnelInfo::getProjectId,ids));
        Map<String, List<ProjectPersonnelInfo>> map = infos.stream().collect(Collectors.groupingBy(ProjectPersonnelInfo::getSendingUnitName));
        map.keySet().forEach(k -> {
            //匹配考评等级
            for (ProjectPersonnelInfo projectPersonnelInfo : map.get(k)) {
                String idCard = projectPersonnelInfo.getIdCard();
                Long flightId = projectPersonnelInfo.getFlightId();
                GraduationAssessment graduationAssessment = graduationAssessmentService.getGraduationAssessmentByFlightIdAndIdCard(flightId, idCard);
                if (graduationAssessment != null){
                    projectPersonnelInfo.setEvaluationOrder(graduationAssessment.getEvaluationOrder());
                }
            }
            unitTotalVOS.add(new UnitTotalVO()
                    .setUnitName(k)
                    .setActualNum(CollectionUtils.isNotEmpty(map.get(k)) ? map.get(k).size() : 0)
                    //待培训人数
                    .setAwaitNum(CollectionUtils.isNotEmpty(map.get(k)) ?
                            (int) map.get(k).stream().filter(l -> new Date().compareTo(l.getTrainingTime()) < 0).count() : 0)
                    //在培训人数
                    .setProceedNum(CollectionUtils.isNotEmpty(map.get(k)) ?
                            (int) map.get(k).stream().filter(l -> l.getTrainingTime().compareTo(new Date()) < 0
                                    && StringUtils.equals("0", l.getIsFinishSchool())).count() : 0)
                    //已培训人数
                    .setCompleteNum(CollectionUtils.isNotEmpty(map.get(k)) ?
                            (int) map.get(k).stream().filter(l -> StringUtils.equals("1", l.getIsFinishSchool())).count() : 0)
                    .setOptimalNum(CollectionUtils.isNotEmpty(map.get(k)) ?
                            (int) map.get(k).stream().filter(l -> StringUtils.equals("1", l.getIsFinishSchool())
                                    && StringUtils.equals("优", l.getEvaluationOrder())).count() : 0));

        });
        ExcelUtil<UnitTotalVO> excelUtil = new ExcelUtil<>(UnitTotalVO.class);
        excelUtil.exportExcel(response, unitTotalVOS, "人员数据");*/
    }

    /**
     * 删除 计划人员信息表
     */
    @PostMapping("/remove")
    @ApiOperationSupport(order = 7)
    @Operation(summary = "删除", description = "传入ids")
    public R remove(@Parameter(description = "主键集合", required = true) @RequestParam String projectPersonnelInfoIds) {
        return R.status(projectPersonnelInfoService.removeByIds(Arrays.stream(projectPersonnelInfoIds.split(",")).toList()));
    }

    @PostMapping("/import")
    @ApiOperationSupport(order = 8)
    @Log(title = "人员导入", businessType = BusinessType.IMPORT)
    @Operation(summary = "导入")
    public R importData(MultipartFile file,
                        @Parameter(description = "是否支持更新", required = true)
                        @RequestParam boolean updateSupport,
                        @Parameter(description = "导入位置（0计划详情 1参训人员管理）", required = true)
                        @RequestParam Integer type) throws Exception {
        ExcelUtil<ProjectPersonnelInfoExcelDTO> util = new ExcelUtil<>(ProjectPersonnelInfoExcelDTO.class);
        List<ProjectPersonnelInfoExcelDTO> list = util.importExcel(file.getInputStream());
        if (CollectionUtils.isEmpty(list)) {
            return R.fail("导入计划培训人员信息数据不能为空！");
        }
        List<SysDictData> data = dictDataService.list(
                new LambdaQueryWrapper<SysDictData>().eq(SysDictData::getDictType, "1"));
        Map<String, String> map = data.stream()
                .collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        List<SysDictData> data1 = dictDataService.list(
                new LambdaQueryWrapper<SysDictData>().eq(SysDictData::getDictType, "2"));
        Map<String, String> map1 = data1.stream()
                .collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        List<ProjectPersonnelInfo> list1 = new ArrayList<>();
        for (ProjectPersonnelInfoExcelDTO p : list) {
            if (StringUtils.isBlank(p.getMajorTypeName())) {
                return R.fail("专业类型不能为空");
            }
            if (StringUtils.isBlank(map.get(p.getMajorTypeName()))) {
                return R.fail("专业类型：" + p.getMajorTypeName() + ",不存在,请核对");
            }
            list1.add(BeanUtil.copy(p, ProjectPersonnelInfo.class)
                    .setTraineeType(p.getTraineeTypeName())
/*                    .setTraineeType(Arrays.stream(p.getTraineeTypeName()
                            .split(",")).map(map1::get).collect(Collectors.joining(",")))*/
                    .setMajorType(map.get(p.getMajorTypeName())));
        }
        return R.success(projectPersonnelInfoService.importData(list1, updateSupport, getUserId(), type));
    }

    @GetMapping("/importTemplate")
    @ApiOperationSupport(order = 9)
    @Operation(summary = "导入模版下载")
    public void importTemplate(HttpServletResponse response) {
        ExcelUtil<ProjectPersonnelInfo> util = new ExcelUtil<>(ProjectPersonnelInfo.class);
        util.importTemplateExcel(response, "人员导入模版");
    }

    /**
     * 上报机关
     */
    @GetMapping("/reportingAuthority")
    @ApiOperationSupport(order = 10)
    @Operation(summary = "上报机关")
    public R reportingAuthority(@Parameter(description = "计划ID") @RequestParam Long projectId) {
        return R.status(projectPersonnelInfoService.reportingAuthority(projectId));
    }

    /**
     * 审核
     */
    @PostMapping("/examine")
    @ApiOperationSupport(order = 11)
    @Operation(summary = "审核")
    public R examine(@RequestBody @Validated ProjectUserExamineDTO dto) {
        return R.status(projectPersonnelInfoService.examine(dto));
    }

    /**
     * 分页 计划详情分页
     */
    @GetMapping("/examine/page")
    @ApiOperationSupport(order = 12)
    @Operation(summary = "计划详情分页", description = "传入projectPersonnelInfo")
    public R<IPage<ProjectPersonnelInfoVO>> examinePage(@Validated ProjectPersonnelPageDTO dto) {
        List<Unit> units = unitService.list(new LambdaQueryWrapper<Unit>()
                .eq(Unit::getParentId, getUnitId()));
        List<Long> longs = new ArrayList<Long>();
        longs.add(dto.getProjectId());
        List<Project> projects = projectService.list(new LambdaQueryWrapper<Project>()
                .eq(Project::getParentId, dto.getProjectId()));
        getLongList(projects, longs);
        IPage<ProjectPersonnelInfo> pages = projectPersonnelInfoService.page(
                new Page<>(dto.getPageNum(), dto.getPageSize()), set(dto)
                        .eq(CollectionUtils.isNotEmpty(units), ProjectPersonnelInfo::getIsReport, "1")
                        .in(CollectionUtils.isNotEmpty(longs), ProjectPersonnelInfo::getProjectId, longs));
        return R.data(BeanUtil.copy(pages, ProjectPersonnelInfoVO.class));
    }

    /**
     * 人员审核导出
     */
    @GetMapping("/examine/export")
    @ApiOperationSupport(order = 13)
    @Log(title = "人员审核导出", businessType = BusinessType.EXPORT)
    @Operation(summary = "人员审核导出", description = "传入ids")
    public void examineExport(HttpServletResponse response, @Validated ProjectPersonnelPageDTO dto) {
        List<ProjectPersonnelInfo> list = new ArrayList<>();
        if (StringUtils.isNotBlank(dto.getIds())) {
            list.addAll(projectPersonnelInfoService.list(new LambdaQueryWrapper<ProjectPersonnelInfo>()
                    .orderByDesc(ProjectPersonnelInfo::getCreateTime)
                    .in(StringUtils.isNotBlank(dto.getIds()), ProjectPersonnelInfo::getUserId,
                            Arrays.stream(dto.getIds().split(",")).toList())));
        } else {
            List<Long> longs = new ArrayList<Long>();
            longs.add(dto.getProjectId());
            List<Project> projects = projectService.list(new LambdaQueryWrapper<Project>()
                    .eq(Project::getParentId, dto.getProjectId()));
            getLongList(projects, longs);
            List<Unit> units = unitService.list(new LambdaQueryWrapper<Unit>()
                    .eq(Unit::getParentId, getUnitId()));
            list.addAll(projectPersonnelInfoService.list(set(dto)
                    .eq(CollectionUtils.isNotEmpty(units), ProjectPersonnelInfo::getIsReport, "1")
                    .in(CollectionUtils.isNotEmpty(longs), ProjectPersonnelInfo::getProjectId, longs)));
        }
        List<ProjectPersonnelInfoExcelVO> list1 = new ArrayList<ProjectPersonnelInfoExcelVO>();
        if (CollectionUtils.isNotEmpty(list)) {
            List<SysDictData> data = dictDataService.list(
                    new LambdaQueryWrapper<SysDictData>().eq(SysDictData::getDictType, "1"));
            Map<String, String> map = data.stream()
                    .collect(Collectors.toMap(SysDictData::getDictLabel, SysDictData::getDictValue));
            List<SysDictData> data1 = dictDataService.list(
                    new LambdaQueryWrapper<SysDictData>().eq(SysDictData::getDictType, "2"));
            Map<String, String> map1 = data1.stream()
                    .collect(Collectors.toMap(SysDictData::getDictLabel, SysDictData::getDictValue));
            list1.addAll(list.stream().map(l ->
                    BeanUtil.copy(l, ProjectPersonnelInfoExcelVO.class)
                            .setTraineeTypeName(Arrays.stream(l.getTraineeType()
                                    .split(",")).map(map1::get).collect(Collectors.joining(",")))
                            .setMajorTypeName(map.get(l.getMajorType()))).collect(Collectors.toList()));
        }
        ExcelUtil<ProjectPersonnelInfoExcelVO> excelUtil = new ExcelUtil<>(ProjectPersonnelInfoExcelVO.class);
        excelUtil.exportExcel(response, list1, "人员数据");
    }

    /**
     * 人员统计列表-年度统计
     */
    @GetMapping("/year/total")
    @ApiOperationSupport(order = 14)
    @Operation(summary = "人员统计列表-年度统计")
    public R<List<YearTotalVO>> yearTotal(@Parameter(description = "班次名称") @RequestParam(required = false) String flightName,
                                          @Parameter(description = "年度") @RequestParam(required = false) String year) {

        List<YearTotalVO> yearTotalVOS = new ArrayList<YearTotalVO>();
        List<StudentInfo> studentInfos = studentInfoService.list(new LambdaQueryWrapper<StudentInfo>()
                .like(StringUtils.isNotBlank(flightName), StudentInfo::getFlightName, flightName)
                .eq(StringUtils.isNotBlank(year), StudentInfo::getYear, year)
                .eq(StudentInfo::getCreateDept, getUnitId())
        );
        if (CollectionUtils.isEmpty(studentInfos)) {
            return R.data(yearTotalVOS);
        }
        Map<String, List<StudentInfo>> map = studentInfos.stream().collect(Collectors.groupingBy(StudentInfo::getYear));
        map.keySet().forEach(k -> {
            List<StudentInfoVO> infoVOs = new ArrayList<>();
            // 匹配考评等级和培训结束时间
            for (StudentInfo studentInfo : map.get(k)) {
                StudentInfoVO studentInfoVO = BeanUtil.copy(studentInfo, StudentInfoVO.class);
                // 匹配时间
                Date trainingTime = studentInfo.getTrainingTime();
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(trainingTime);
                calendar.add(Calendar.DATE, Integer.valueOf(studentInfo.getEducationalSystem()));
                studentInfoVO.setEndTime(calendar.getTime());
                // 匹配等级
                String idCard = studentInfo.getIdCard();
                Long flightId = studentInfo.getFlightId();
                GraduationAssessment graduationAssessment = graduationAssessmentService.getGraduationAssessmentByFlightIdAndIdCard(flightId, idCard);
                if (graduationAssessment != null) {
                    studentInfoVO.setEvaluationOrder(graduationAssessment.getEvaluationOrder());
                }
                infoVOs.add(studentInfoVO);
            }
            yearTotalVOS.add(new YearTotalVO()
                    .setYear(k)
                    // 实际人数
                    .setActualNum(CollectionUtils.isNotEmpty(infoVOs) ? infoVOs.size() : 0)
                    // 待培训人数
                    .setAwaitNum(CollectionUtils.isNotEmpty(infoVOs) ?
                            (int) infoVOs.stream().filter(l -> new Date().compareTo(l.getTrainingTime()) < 0).count() : 0)
                    // 在培训人数
                    .setProceedNum(CollectionUtils.isNotEmpty(infoVOs) ?
                            (int) infoVOs.stream().filter(
                                    l -> l.getTrainingTime().compareTo(new Date()) < 0 && l.getEndTime().compareTo(new Date()) > 0).count() : 0)
                    // 已培训人数
                    .setCompleteNum(CollectionUtils.isNotEmpty(infoVOs) ?
                            (int) infoVOs.stream().filter(
                                    l -> l.getEndTime().compareTo(new Date()) < 0).count() : 0)
                    // 优秀毕业人数
                    .setOptimalNum(CollectionUtils.isNotEmpty(infoVOs) ?
                            (int) infoVOs.stream().filter(
                                    l -> l.getEndTime().compareTo(new Date()) < 0 && StringUtils.equals("0", l.getEvaluationOrder())).count() : 0));

        });
        return R.data(yearTotalVOS);


       /* List<YearTotalVO> yearTotalVOS = new ArrayList<YearTotalVO>();
        List<Project> list = projectService.list(new LambdaQueryWrapper<Project>()
                .orderByDesc(Project::getYear)
                .like(StringUtils.isNotBlank(flightName), Project::getFlightName, flightName)
                .eq(StringUtils.isNotBlank(year), Project::getYear, year)
                .eq(Project::getCreateDept, getUnitId()));
        if (CollectionUtils.isEmpty(list)) {
            return R.data(yearTotalVOS);
        }
        List<ProjectPersonnelInfo> infos = projectPersonnelInfoService.list(
                new LambdaQueryWrapper<ProjectPersonnelInfo>()
                        .eq(ProjectPersonnelInfo::getStatus, 1)
                        .in(CollectionUtils.isNotEmpty(list), ProjectPersonnelInfo::getProjectId,
                                list.stream().map(Project::getProjectId).toList()));
        Map<String, List<Project>> listMap = list.stream().collect(Collectors.groupingBy(Project::getYear));
        listMap.keySet().forEach(k -> {
            List<ProjectPersonnelInfo> yearInfos = infos.stream().filter(i -> i.getYear().equals(k)).toList();
            //匹配考评等级
            for (ProjectPersonnelInfo projectPersonnelInfo : yearInfos) {
                String idCard = projectPersonnelInfo.getIdCard();
                Long flightId = projectPersonnelInfo.getFlightId();
                GraduationAssessment graduationAssessment = graduationAssessmentService.getGraduationAssessmentByFlightIdAndIdCard(flightId, idCard);
                if (graduationAssessment != null){
                    projectPersonnelInfo.setEvaluationOrder(graduationAssessment.getEvaluationOrder());
                }
            }
            yearTotalVOS.add(new YearTotalVO()
                    .setYear(k)
*//*                    .setProjectNnum(listMap.get(k).stream().map(s ->
                                    BigDecimal.valueOf(Double.parseDouble(StringUtils.isEmpty(s.getShouldAttendance()) ?
                                            "0" : s.getShouldAttendance())))
                            .reduce(BigDecimal.ZERO, BigDecimal::add).intValue())*//*
                    //实际人数
                    .setActualNum(CollectionUtils.isNotEmpty(yearInfos) ? yearInfos.size() : 0)
                    //待培训人数
                    .setAwaitNum(CollectionUtils.isNotEmpty(yearInfos) ?
                            (int) yearInfos.stream().filter(l -> new Date().compareTo(l.getTrainingTime()) < 0).count() : 0)
                    //正在培训人数
                    .setProceedNum(CollectionUtils.isNotEmpty(yearInfos) ?
                            (int) yearInfos.stream().filter(l -> l.getTrainingTime().compareTo(new Date()) < 0
                                    && StringUtils.equals("0", l.getIsFinishSchool())).count() : 0)
                    //已培训人数
                    .setCompleteNum(CollectionUtils.isNotEmpty(yearInfos) ?
                            (int) yearInfos.stream().filter(l -> StringUtils.equals("1", l.getIsFinishSchool())).count() : 0)
                    .setOptimalNum(CollectionUtils.isNotEmpty(yearInfos) ?
                            (int) yearInfos.stream().filter(l -> StringUtils.equals("1", l.getIsFinishSchool())
                                    && StringUtils.equals("0", l.getEvaluationOrder())).count() : 0));
        });
        return R.data(yearTotalVOS);*/
    }

    /**
     * 导出
     */
    @GetMapping("/yearTotal/export")
    @ApiOperationSupport(order = 3)
    @Log(title = "人员年度统计导出", businessType = BusinessType.EXPORT)
    @Operation(summary = "人员统计列表-年度统计导出", description = "传入ids")
    public void yearTotalExport(HttpServletResponse response, @Validated ProjectPersonnelPageDTO dto) {
        List<YearTotalVO> yearTotalVOS = new ArrayList<YearTotalVO>();
        List<StudentInfo> studentInfos = studentInfoService.list(new LambdaQueryWrapper<StudentInfo>()
                .like(StringUtils.isNotBlank(dto.getFlightName()), StudentInfo::getFlightName, dto.getFlightName())
                .eq(StringUtils.isNotBlank(dto.getYear()), StudentInfo::getYear, dto.getYear())
                .eq(StudentInfo::getCreateDept, getUnitId())
        );
        if (CollectionUtils.isEmpty(studentInfos)) {
            ExcelUtil<YearTotalVO> excelUtil = new ExcelUtil<>(YearTotalVO.class);
            excelUtil.exportExcel(response, yearTotalVOS, "人员年度统计数据");
        }
        Map<String, List<StudentInfo>> map = studentInfos.stream().collect(Collectors.groupingBy(StudentInfo::getYear));
        map.keySet().forEach(k -> {
            List<StudentInfoVO> infoVOs = new ArrayList<>();
            // 匹配考评等级和培训结束时间
            for (StudentInfo studentInfo : map.get(k)) {
                StudentInfoVO studentInfoVO = BeanUtil.copy(studentInfo, StudentInfoVO.class);
                // 匹配时间
                Date trainingTime = studentInfo.getTrainingTime();
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(trainingTime);
                calendar.add(Calendar.DATE, Integer.valueOf(studentInfo.getEducationalSystem()));
                studentInfoVO.setEndTime(calendar.getTime());
                // 匹配等级
                String idCard = studentInfo.getIdCard();
                Long flightId = studentInfo.getFlightId();
                GraduationAssessment graduationAssessment = graduationAssessmentService.getGraduationAssessmentByFlightIdAndIdCard(flightId, idCard);
                if (graduationAssessment != null) {
                    studentInfoVO.setEvaluationOrder(graduationAssessment.getEvaluationOrder());
                }
                infoVOs.add(studentInfoVO);
            }
            yearTotalVOS.add(new YearTotalVO()
                    .setYear(k)
                    // 实际人数
                    .setActualNum(CollectionUtils.isNotEmpty(infoVOs) ? infoVOs.size() : 0)
                    // 待培训人数
                    .setAwaitNum(CollectionUtils.isNotEmpty(infoVOs) ?
                            (int) infoVOs.stream().filter(l -> new Date().compareTo(l.getTrainingTime()) < 0).count() : 0)
                    // 在培训人数
                    .setProceedNum(CollectionUtils.isNotEmpty(infoVOs) ?
                            (int) infoVOs.stream().filter(
                                    l -> l.getTrainingTime().compareTo(new Date()) < 0 && l.getEndTime().compareTo(new Date()) > 0).count() : 0)
                    // 已培训人数
                    .setCompleteNum(CollectionUtils.isNotEmpty(infoVOs) ?
                            (int) infoVOs.stream().filter(
                                    l -> l.getEndTime().compareTo(new Date()) < 0).count() : 0)
                    // 优秀毕业人数
                    .setOptimalNum(CollectionUtils.isNotEmpty(infoVOs) ?
                            (int) infoVOs.stream().filter(
                                    l -> l.getEndTime().compareTo(new Date()) < 0 && StringUtils.equals("0", l.getEvaluationOrder())).count() : 0));

        });
        ExcelUtil<YearTotalVO> excelUtil = new ExcelUtil<>(YearTotalVO.class);
        excelUtil.exportExcel(response, yearTotalVOS, "人员年度统计数据");



        /*List<YearTotalVO> yearTotalVOS = new ArrayList<YearTotalVO>();
        List<Project> list = projectService.list(new LambdaQueryWrapper<Project>()
                .orderByDesc(Project::getYear)
                .like(StringUtils.isNotBlank(dto.getFlightName()), Project::getFlightName, dto.getFlightName())
                .eq(StringUtils.isNotBlank(dto.getYear()), Project::getYear, dto.getYear())
                .eq(Project::getCreateDept, getUnitId()));
        if (CollectionUtils.isEmpty(list)) {
            ExcelUtil<YearTotalVO> excelUtil = new ExcelUtil<>(YearTotalVO.class);
            excelUtil.exportExcel(response, yearTotalVOS, "人员年度统计数据");
        }
        List<ProjectPersonnelInfo> infos = projectPersonnelInfoService.list(
                new LambdaQueryWrapper<ProjectPersonnelInfo>()
                        .eq(ProjectPersonnelInfo::getStatus, 1)
                        .in(CollectionUtils.isNotEmpty(list), ProjectPersonnelInfo::getProjectId,
                                list.stream().map(Project::getProjectId).toList()));
        Map<String, List<Project>> listMap = list.stream().collect(Collectors.groupingBy(Project::getYear));
        listMap.keySet().forEach(k -> {
            List<ProjectPersonnelInfo> yearInfos = infos.stream().filter(i -> i.getYear().equals(k)).toList();
            //匹配考评等级
            for (ProjectPersonnelInfo projectPersonnelInfo : yearInfos) {
                String idCard = projectPersonnelInfo.getIdCard();
                Long flightId = projectPersonnelInfo.getFlightId();
                GraduationAssessment graduationAssessment = graduationAssessmentService.getGraduationAssessmentByFlightIdAndIdCard(flightId, idCard);
                if (graduationAssessment != null){
                    projectPersonnelInfo.setEvaluationOrder(graduationAssessment.getEvaluationOrder());
                }
            }
            yearTotalVOS.add(new YearTotalVO()
                    .setYear(k)
                    //实际人数
                    .setActualNum(CollectionUtils.isNotEmpty(yearInfos) ? yearInfos.size() : 0)
                    //待培训人数
                    .setAwaitNum(CollectionUtils.isNotEmpty(yearInfos) ?
                            (int) yearInfos.stream().filter(l -> new Date().compareTo(l.getTrainingTime()) < 0).count() : 0)
                    //正在培训人数
                    .setProceedNum(CollectionUtils.isNotEmpty(yearInfos) ?
                            (int) yearInfos.stream().filter(l -> l.getTrainingTime().compareTo(new Date()) < 0
                                    && StringUtils.equals("0", l.getIsFinishSchool())).count() : 0)
                    //已培训人数
                    .setCompleteNum(CollectionUtils.isNotEmpty(yearInfos) ?
                            (int) yearInfos.stream().filter(l -> StringUtils.equals("1", l.getIsFinishSchool())).count() : 0)
                    .setOptimalNum(CollectionUtils.isNotEmpty(yearInfos) ?
                            (int) yearInfos.stream().filter(l -> StringUtils.equals("1", l.getIsFinishSchool())
                                    && StringUtils.equals("0", l.getEvaluationOrder())).count() : 0));
        });
        ExcelUtil<YearTotalVO> excelUtil = new ExcelUtil<>(YearTotalVO.class);
        excelUtil.exportExcel(response, yearTotalVOS, "人员年度统计数据");*/
    }

    /**
     * 计划上报人数查询
     */
    @GetMapping("/project/number")
    @ApiOperationSupport(order = 15)
    @Operation(summary = "计划上报人数查询")
    public R projectNumber(@Parameter(description = "计划ID") @RequestParam Long projectId) {
        return R.data(projectPersonnelInfoService.count(new LambdaQueryWrapper<ProjectPersonnelInfo>()
                .eq(ProjectPersonnelInfo::getProjectId, projectId)));
    }

    @GetMapping("/project/flight/info")
    @ApiOperationSupport(order = 16)
    @Operation(summary = "计划班次信息列表")
    public R<List<FlightVO>> projectFlightInfo() {
        List<Project> list = projectService.list(new LambdaQueryWrapper<Project>()
                .orderByDesc(Project::getFlightId)
                .eq(Project::getCreateDept, getUnitId())
//                .in(Project::getIsDistribution, 0, 1, 2)
                .eq(Project::getParentId, 0));
        if (CollectionUtils.isEmpty(list)) {
            return R.data(Collections.emptyList());
        }
        return R.data(BeanUtil.copy(list.stream().map(l ->
                new FlightVO()
                        .setFlightId(l.getFlightId())
                        .setFlightName(l.getFlightName())
                        .setFlightCode(l.getFlightCode())
                        .setTissueUnitId(l.getTrainingUnitId())
                        .setTissueUnitName(l.getTrainingUnitName())
                        .setYear(l.getYear())
                        .setTrainingTime(l.getTrainingTime())
                        .setProjectId(l.getProjectId())
        ).collect(Collectors.toList()), FlightVO.class));
    }

    private LambdaQueryWrapper<ProjectPersonnelInfo> set(ProjectPersonnelPageDTO dto) {
        return new LambdaQueryWrapper<ProjectPersonnelInfo>()
                .orderByDesc(ProjectPersonnelInfo::getYear, ProjectPersonnelInfo::getFlightId, ProjectPersonnelInfo::getTrainingTime)
                .eq(null != dto.getStatus(), ProjectPersonnelInfo::getStatus, dto.getStatus())
                .like(StringUtils.isNotBlank(dto.getUserName()), ProjectPersonnelInfo::getUserName, dto.getUserName())
                .eq(StringUtils.isNotBlank(dto.getTraineeType()), ProjectPersonnelInfo::getTraineeType,
                        dto.getTraineeType())
                .eq(StringUtils.isNotBlank(dto.getSex()), ProjectPersonnelInfo::getSex, dto.getSex())
                .eq(null != dto.getFlightId(), ProjectPersonnelInfo::getFlightId, dto.getFlightId())
                .like(StringUtils.isNotBlank(dto.getFlightName()), ProjectPersonnelInfo::getFlightName,
                        dto.getFlightName())
                .eq(null != dto.getTrainingUnitId(), ProjectPersonnelInfo::getTrainingUnitId, dto.getTrainingUnitId())
                .eq(null == dto.getTrainingUnitId(), ProjectPersonnelInfo::getTrainingUnitId, getUnitId())
                .like(StringUtils.isNotBlank(dto.getTrainingUnitName()),
                        ProjectPersonnelInfo::getTrainingUnitName, dto.getTrainingUnitName())
                .eq(null != dto.getPresentPostId(), ProjectPersonnelInfo::getPresentPostId, dto.getPresentPostId())
                .like(StringUtils.isNotBlank(dto.getPresentPostName()),
                        ProjectPersonnelInfo::getPresentPostName, dto.getPresentPostName())
                .like(StringUtils.isNotBlank(dto.getJob()), ProjectPersonnelInfo::getJob, dto.getJob())
                .eq(StringUtils.isNotBlank(dto.getYear()), ProjectPersonnelInfo::getYear, dto.getYear())
                .like(StringUtils.isNotBlank(dto.getIdCard()), ProjectPersonnelInfo::getIdCard, dto.getIdCard())
                .eq(StringUtils.isNotBlank(dto.getIsFinishSchool()), ProjectPersonnelInfo::getIsFinishSchool,
                        dto.getIsFinishSchool())
                .eq(StringUtils.isNotBlank(dto.getEvaluationOrder()),
                        ProjectPersonnelInfo::getEvaluationOrder, dto.getEvaluationOrder())
                .eq(null != dto.getSendingUnitId(), ProjectPersonnelInfo::getSendingUnitId, dto.getSendingUnitId())
                .like(StringUtils.isNotBlank(dto.getSendingUnitName()),
                        ProjectPersonnelInfo::getSendingUnitName, dto.getSendingUnitName())
                .ge(StringUtils.isNotBlank(dto.getOverallPracticalScoreMin()),
                        ProjectPersonnelInfo::getOverallPracticalScore, dto.getOverallPracticalScoreMin())
                .le(StringUtils.isNotBlank(dto.getOverallPracticalScoreMax()),
                        ProjectPersonnelInfo::getOverallPracticalScore, dto.getOverallPracticalScoreMax())
                .ge(StringUtils.isNotBlank(dto.getTheoreticalAchievementMin()),
                        ProjectPersonnelInfo::getTheoreticalAchievement, dto.getTheoreticalAchievementMin())
                .le(StringUtils.isNotBlank(dto.getTheoreticalAchievementMax()),
                        ProjectPersonnelInfo::getTheoreticalAchievement, dto.getTheoreticalAchievementMax())
                .ge(StringUtils.isNotBlank(dto.getTotalScoreMin()),
                        ProjectPersonnelInfo::getTotalScore, dto.getTotalScoreMin())
                .le(StringUtils.isNotBlank(dto.getTotalScoreMax()),
                        ProjectPersonnelInfo::getTotalScore, dto.getTotalScoreMax())
                .like(StringUtils.isNotBlank(dto.getPhonenumber()), ProjectPersonnelInfo::getPhonenumber, dto.getPhonenumber())
                .like(StringUtils.isNotBlank(dto.getMilitaryRank()), ProjectPersonnelInfo::getMilitaryRank, dto.getMilitaryRank());
    }

    private void getLongList(List<Project> list, List<Long> longs) {
        if (CollectionUtils.isNotEmpty(list)) {
            List<Long> longList = list.stream().map(Project::getProjectId).toList();
            longs.addAll(longList);
            List<Project> projectList = projectService.list(new LambdaQueryWrapper<Project>()
                    .in(Project::getParentId, longList));
            getLongList(projectList, longs);
        }
    }

    private void getUnitProjectVO(Unit unit, String flightName, String year, List<Project> projects) {
        List<Project> list = projectService.list(new LambdaQueryWrapper<Project>()
                .like(StringUtils.isNotBlank(flightName), Project::getFlightName, flightName)
                .eq(StringUtils.isNotBlank(year), Project::getYear, year)
                .eq(Project::getCreateDept, unit.getUnitId()));
        projects.addAll(list);
        List<Unit> units = unitService.list(new LambdaQueryWrapper<Unit>()
                .eq(Unit::getParentId, unit.getUnitId()));
        if (CollectionUtils.isNotEmpty(units)) {
            for (Unit u : units) {
                getUnitProjectVO(u, flightName, year, projects);
            }
        }
    }

}
