package jnpf.attendance.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import com.alibaba.excel.util.DateUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import jnpf.attendance.antifreeze.UserAntifreeze;
import jnpf.attendance.mapper.AttendanceConfirmMapper;
import jnpf.attendance.service.*;
import jnpf.base.service.SuperServiceImpl;
import jnpf.emnus.MiniAppEnum;
import jnpf.emnus.WorkStatusEnum;
import jnpf.emnus.WorkTypeEnum;
import jnpf.entity.AttendanceGroupUser;
import jnpf.entity.attendance.AttendanceConfirm;
import jnpf.enums.attendance.StatisticsEnumUtil;
import jnpf.model.attendance.dto.ConfirmPageListDto;
import jnpf.model.attendance.dto.ConfirmStatisticsDto;
import jnpf.model.attendance.dto.GroupFilterDto;
import jnpf.model.attendance.dto.StatisticsDataQueryDto;
import jnpf.model.attendance.vo.attendance.*;
import jnpf.model.common.DateRangeDto;
import jnpf.model.thousandsfaces.TodayWorkVo;
import jnpf.permission.eum.v2.UserWorkStatusEnums;
import jnpf.permission.model.user.PartUserInfoVo;
import jnpf.permission.vo.v2.user.UserBoundVO;
import jnpf.util.RandomUtil;
import jnpf.util.ServiceException;
import jnpf.util.StringUtil;
import jnpf.util.UserProvider;
import jnpf.util.attendance.DayStatisticsUtils;
import jnpf.util.context.ThreadContext;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

import javax.annotation.Resource;
import java.time.YearMonth;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;

/**
 * 考勤确认
 *
 * @author shitou
 * @email shitou@niujiekeji.com
 * @date 2024-11-07 09:33:43
 */
@Slf4j
@Service
public class AttendanceConfirmServiceImpl extends SuperServiceImpl<AttendanceConfirmMapper, AttendanceConfirm> implements AttendanceConfirmService {
    @Resource
    private UserAntifreeze userAntifreeze;
    @Resource
    private AttendanceUserService userService;
    @Resource(name = "ioIntensiveThreadPool")
    private ThreadPoolExecutor threadPoolExecutor;
    @Resource
    private TransactionTemplate transactionTemplate;
    @Resource
    private AttendanceConfirmService confirmService;
    @Resource
    private AttendanceUserService attendanceUserService;
    @Resource
    private AttendanceDayStatisticsService dayStatisticsService;
    @Resource
    private AttendanceCustomizeTableService customizeTableService;
    @Resource
    private AttendanceConfirmSettingService confirmSettingService;

    @Override
    public String getConfirmMonth() {
        AttendanceConfirm confirm = this.lambdaQuery().orderByDesc(AttendanceConfirm::getYear)
                .orderByDesc(AttendanceConfirm::getMonth)
                .last("limit 1")
                .one();
        if (Objects.isNull(confirm)) {
            return DateUtil.format(new Date(), DatePattern.NORM_MONTH_PATTERN);
        }
        YearMonth yearMonth = YearMonth.of(confirm.getYear(), confirm.getMonth());
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM");
        return yearMonth.format(formatter);
    }

    /**
     * 获取有权限的用户列表
     *
     * @param filterList 筛选条件
     * @param workStatus 用户状态
     * @return 用户列表
     */
    private List<UserBoundVO> getUserIdArr(List<GroupFilterDto> filterList, String workStatus) {
        List<String> groupIds = filterList.stream()
                .map(GroupFilterDto::getGroupId)
                .distinct()
                .collect(Collectors.toList());
        StatisticsEnumUtil.WorkStatusEnum workStatusEnum = StatisticsEnumUtil.WorkStatusEnum.getWorkStatusEnum(workStatus);
        Assert.notNull(workStatusEnum, "工作状态不正确");
        List<UserWorkStatusEnums> workStatusEnums = DayStatisticsUtils.getWorkStatusEnumList(Objects.requireNonNull(workStatusEnum));
        List<UserBoundVO> userBoundVoList = attendanceUserService.batchGetUserBoundVO(groupIds, workStatusEnums);
        return CollUtil.isNotEmpty(userBoundVoList) ? userBoundVoList : CollUtil.newArrayList();
    }

    @Override
    public ConfirmStatisticsVo getStatistics(ConfirmStatisticsDto dto) {
        DateRangeDto dateRangeDto = new DateRangeDto(dto.getMonth(), Boolean.TRUE);
        StatisticsDataQueryDto queryDto = new StatisticsDataQueryDto();
        BeanUtils.copyProperties(dto, queryDto);
        queryDto.setStartDate(dateRangeDto.getStartDate());
        queryDto.setEndDate(dateRangeDto.getEndDate());
        Date newDate = new Date();
        List<String> groupIds = dto.getFilterList().stream()
                .map(GroupFilterDto::getGroupId)
                .distinct()
                .collect(Collectors.toList());
        //获取有权限的用户列表
        List<UserBoundVO> userBoundVoList = getUserIdArr(dto.getFilterList(), dto.getWorkStatus());
        if (StringUtil.isNotEmpty(dto.getKeyword())) {
            userBoundVoList = userBoundVoList.stream().filter(item ->
                            (StringUtil.isNotEmpty(item.getPhone()) && item.getPhone().contains(dto.getKeyword())) ||
                                    (StringUtil.isNotEmpty(item.getName()) && item.getName().contains(dto.getKeyword())) ||
                                    (StringUtil.isNotEmpty(item.getOrganizeName()) && item.getOrganizeName().contains(dto.getKeyword())) ||
                                    (StringUtil.isNotEmpty(item.getPositionName()) && item.getPositionName().contains(dto.getKeyword())) ||
                                    (StringUtil.isNotEmpty(item.getGradeName()) && item.getGradeName().contains(dto.getKeyword())))
                    .collect(Collectors.toList());
        }
        if (CollUtil.isEmpty(userBoundVoList)) {
            return new ConfirmStatisticsVo();
        }
        List<AttendanceGroupUser> groupUserList = userService.getAttendanceGroupUsersOfSecondment(newDate, newDate,
                userBoundVoList.stream().map(UserBoundVO::getId).distinct().collect(Collectors.toList()), groupIds);
        List<String> userIdList = CollUtil.isNotEmpty(groupUserList) ? groupUserList.stream()
                .map(AttendanceGroupUser::getUserId).distinct().collect(Collectors.toList()) : CollUtil.newArrayList();
        if (CollUtil.isEmpty(userIdList)) {
            return new ConfirmStatisticsVo();
        }
        DateTimeFormatter monthFormatter = DateTimeFormatter.ofPattern("yyyy-MM", Locale.ENGLISH);
        YearMonth yearMonth = YearMonth.parse(dto.getMonth(), monthFormatter);
        return this.baseMapper.getStatistics(userIdList, yearMonth.getYear(), yearMonth.getMonthValue(), null);
    }

    @Override
    public PageInfo<ConfirmPageListVo> getPageList(ConfirmPageListDto dto) {
        PageInfo<ConfirmPageListVo> pageInfo = new PageInfo<>();
        pageInfo.setPageSize((int) dto.getPageSize());
        pageInfo.setPageNum((int) dto.getCurrentPage());
        Date newDate = new Date();
        List<String> groupIds = dto.getFilterList().stream()
                .map(GroupFilterDto::getGroupId)
                .distinct()
                .collect(Collectors.toList());
        //获取有权限的用户列表
        List<UserBoundVO> userBoundVoList = getUserIdArr(dto.getFilterList(), dto.getWorkStatus());
        if (CollUtil.isEmpty(userBoundVoList)) {
            return pageInfo;
        }
        Map<String, UserBoundVO> userBoundVoMap = userBoundVoList.stream().collect(Collectors.toMap(UserBoundVO::getId, a -> a, (k1, k2) -> k1));
        if (StringUtil.isNotEmpty(dto.getKeyword())) {
            userBoundVoList = userBoundVoList.stream().filter(item ->
                            (StringUtil.isNotEmpty(item.getPhone()) && item.getPhone().contains(dto.getKeyword())) ||
                                    (StringUtil.isNotEmpty(item.getName()) && item.getName().contains(dto.getKeyword())) ||
                                    (StringUtil.isNotEmpty(item.getOrganizeName()) && item.getOrganizeName().contains(dto.getKeyword())) ||
                                    (StringUtil.isNotEmpty(item.getPositionName()) && item.getPositionName().contains(dto.getKeyword())) ||
                                    (StringUtil.isNotEmpty(item.getGradeName()) && item.getGradeName().contains(dto.getKeyword())))
                    .collect(Collectors.toList());
        }
        List<AttendanceGroupUser> groupUserList = userService.getAttendanceGroupUsersOfSecondment(newDate, newDate,
                userBoundVoList.stream().map(UserBoundVO::getId).distinct().collect(Collectors.toList()), groupIds);
        List<String> userIdList = CollUtil.isNotEmpty(groupUserList) ? groupUserList.stream()
                .map(AttendanceGroupUser::getUserId).distinct().collect(Collectors.toList()) : CollUtil.newArrayList();
        if (CollUtil.isEmpty(userIdList)) {
            log.error("未查询到考勤组用户数据");
            return pageInfo;
        }
        DateTimeFormatter monthFormatter = DateTimeFormatter.ofPattern("yyyy-MM", Locale.ENGLISH);
        YearMonth yearMonth = YearMonth.parse(dto.getMonth(), monthFormatter);
        PageHelper.startPage(Math.toIntExact(dto.getCurrentPage()), Math.toIntExact(dto.getPageSize()));
        List<ConfirmListQueryVo> pageListVoList = this.baseMapper.getPageList(userIdList, yearMonth.getYear(), yearMonth.getMonthValue(), dto.getType());
        PageInfo<ConfirmPageListVo> pageInfo1 = new PageInfo<>(statisticsAssemble(pageListVoList, userBoundVoMap));
        pageInfo1.setTotal(new PageInfo<>(pageListVoList).getTotal());
        pageInfo1.setPageSize((int) dto.getPageSize());
        return pageInfo1;
    }

    /**
     * 封装考勤确认统计数据
     *
     * @param statisticsQueryVoList 考勤确认数据
     * @param staffRosterMap        员工花名册数据
     * @return 考勤确认统计数据
     */
    private List<ConfirmPageListVo> statisticsAssemble(List<ConfirmListQueryVo> statisticsQueryVoList, Map<String, UserBoundVO> staffRosterMap) {
        return statisticsQueryVoList.stream().map(item -> {
            ConfirmPageListVo statistics = ConfirmPageListVo.builder().build();
            BeanUtils.copyProperties(item, statistics);
            if (staffRosterMap.containsKey(item.getUserId())) {
                UserBoundVO staffRosterDto = staffRosterMap.get(item.getUserId());
                statistics.setDeptName(StringUtil.isNotEmpty(staffRosterDto.getOrganizeName()) ? staffRosterDto.getOrganizeName() : "");
                statistics.setPostName(StringUtil.isNotEmpty(staffRosterDto.getPositionName()) ? staffRosterDto.getPositionName() : "");
                statistics.setUserName(staffRosterDto.getName());
                statistics.setPhone(staffRosterDto.getPhone());
                statistics.setWorkStatus(staffRosterDto.getWorkStatusEnums().getCode());
            }
            return statistics;
        }).collect(Collectors.toList());
    }

    @Override
    public ConfirmDetailsVo getConfirmDetails(String id) {
        AttendanceConfirm attendanceConfirm = this.getById(id);
        ServiceException.notNull(attendanceConfirm, "未查询到考勤确认数据");
        ConfirmDetailsVo confirmDetailsVo = ConfirmDetailsVo.builder()
                .id(attendanceConfirm.getId())
                .status(attendanceConfirm.getStatus())
                .slippageResult(attendanceConfirm.getSlippageResult())
                .tipsStatus(attendanceConfirm.getTipsStatus())
                .confirmStatus(new Date().compareTo(attendanceConfirm.getStartTime()) >= 0)
                .deadline(DateUtils.format(attendanceConfirm.getEndTime(), "MM月dd日"))
                .build();
        //获取考勤确认数据
        getConfirmData(attendanceConfirm, confirmDetailsVo);
        return confirmDetailsVo;
    }

    @Override
    public ConfirmDetailsVo getAppConfirmDetails(String id) {
        LambdaQueryChainWrapper<AttendanceConfirm> lambdaQueryChainWrapper = this.lambdaQuery()
                .orderByDesc(AttendanceConfirm::getCreateTime)
                .eq(AttendanceConfirm::getUserId, UserProvider.getUser().getUserId());
        if (StringUtil.isNotEmpty(id)) {
            lambdaQueryChainWrapper.eq(AttendanceConfirm::getId, id);
        }
        lambdaQueryChainWrapper.last("limit 1");
        AttendanceConfirm attendanceConfirm = lambdaQueryChainWrapper.one();
        ServiceException.notNull(attendanceConfirm, "未查询到考勤确认数据");
        ConfirmDetailsVo confirmDetailsVo = ConfirmDetailsVo.builder()
                .id(attendanceConfirm.getId())
                .status(attendanceConfirm.getStatus())
                .slippageResult(attendanceConfirm.getSlippageResult())
                .tipsStatus(attendanceConfirm.getTipsStatus())
                .confirmStatus(new Date().compareTo(attendanceConfirm.getStartTime()) >= 0)
                .deadline(DateUtils.format(attendanceConfirm.getEndTime(), "MM月dd日"))
                .build();
        //获取考勤确认数据
        getConfirmData(attendanceConfirm, confirmDetailsVo);
        return confirmDetailsVo;
    }

    @Override
    @Transactional
    public boolean autoCreateConfirm() {
        ConfirmSettingInfoVo confirmSetting = confirmSettingService.getConfirmSetting(Boolean.TRUE);
        Integer allowConfirm = confirmSetting.getAllowConfirm();
        Date date = DateUtil.beginOfDay(new Date());
        int day = DateUtil.dayOfMonth(date);
        if (!Objects.equals(allowConfirm, day)) {
            return false;
        }
        int month = DateUtil.month(date) + 1;
        int year = DateUtil.year(date);
        Date expectedTime = DateUtil.offsetDay(date, confirmSetting.getConfirmDuration());
        date = DateUtil.offsetMonth(date, -1);
        if (Objects.equals(confirmSetting.getConfirmMonth(), 2)) {
            month = DateUtil.month(date) + 1;
            year = DateUtil.year(date);
        }
        //异步生成考勤确认数据
        int finalYear = year;
        int finalMonth = month;
        CompletableFuture.runAsync(ThreadContext.wrap(() -> {
                    transactionTemplate.execute(new TransactionCallbackWithoutResult() {
                        @Override
                        protected void doInTransactionWithoutResult(@NotNull TransactionStatus status) {
                            try {
                                confirmService.createConfirm(finalYear, finalMonth, expectedTime, DateUtil.beginOfDay(new Date()), confirmSetting.getSlippageResult());
                            } catch (Exception e) {
                                log.error("异步生成考勤确认数据失败，事务回滚", e);
                                status.setRollbackOnly();
                                throw e;
                            }
                        }
                    });
                }), threadPoolExecutor)
                .exceptionally(ex -> {
                    log.error("生成考勤确认数据异常", ex);
                    return null;
                });
        return Boolean.TRUE;
    }

    @Override
    @Transactional
    public void createConfirm(int year, int month, Date expectedTime, Date startTime, Integer slippageResult) {
        lambdaUpdate().eq(AttendanceConfirm::getMonth, month)
                .eq(AttendanceConfirm::getYear, year)
                .remove();
        Date now = new Date();
        YearMonth yearMonth = YearMonth.of(year, month);
        Date startDate = Date.from(yearMonth.atDay(1).atStartOfDay(ZoneId.systemDefault()).toInstant());
        Date endDate = Date.from(yearMonth.atEndOfMonth().atStartOfDay(ZoneId.systemDefault()).toInstant());
        List<AttendanceGroupUser> attendanceGroupUsers = userService.getAttendanceGroupUsersOfSecondment(startDate,endDate,null,null); Map<String, AttendanceGroupUser> userGroupMap = attendanceGroupUsers.stream().collect(Collectors.toMap(AttendanceGroupUser::getUserId, a -> a, (k1, k2) -> k1));
        List<AttendanceConfirm> collect = new ArrayList<>();
        userGroupMap.forEach((key, value) -> {
            AttendanceConfirm confirm = AttendanceConfirm.builder()
                    .id(RandomUtil.uuId())
                    .userId(value.getUserId())
                    .year(year)
                    .month(month)
                    .status(0)
                    .slippageResult(0)
                    .startTime(startTime)
                    .endTime(expectedTime)
                    .createTime(now)
                    .build();
            //判断是否逾期
            if (now.compareTo(expectedTime) >= 0) {
                confirm.setSlippageResult(slippageResult);
                if (slippageResult.equals(1)) {
                    confirm.setStatus(2);
                    confirm.setUpdateTime(new Date());
                }
            }
            collect.add(confirm);
        });
        if (CollUtil.isNotEmpty(collect)) {
            List<String> userIds = collect.stream().map(AttendanceConfirm::getUserId).collect(Collectors.toList());
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM");
            // 获取自定义表单数据
            List<AttendanceCustomizeTableVo> customizeTableVos = getAttendanceCustomizeTableVos();
            processJsonData(yearMonth.format(formatter), userIds, customizeTableVos, collect);
            saveBatch(collect);
        }
    }

    /**
     * 处理自定义表单数据
     *
     * @param month 月份
     * @param userIds 用户Id
     * @param customizeTableVos 自定义表单
     * @param collect 考勤确认数据
     */
    private void processJsonData(String month, List<String> userIds, List<AttendanceCustomizeTableVo> customizeTableVos, List<AttendanceConfirm> collect) {
        // 实时查询自定义请假类型
        List<MonthConfirmStatisticsListVo> infoByMonth = this.dayStatisticsService.getConfirmDetailsInfoByMonth(userIds, month);
        Map<String, ConfirmDetailsInfoNew> confirmDetailsInfoMap = infoByMonth.stream()
                .collect(Collectors.toMap(MonthConfirmStatisticsListVo::getUserId,
                        item -> BeanUtil.toBean(item, ConfirmDetailsInfoNew.class), (k1, k2) -> k1));
        collect.forEach(confirm -> {
            ConfirmDetailsInfoNew confirmDetailsInfo = confirmDetailsInfoMap.getOrDefault(confirm.getUserId(), new ConfirmDetailsInfoNew());
            confirmDetailsInfo.setMonth(confirm.getYear() + "年" + confirm.getMonth() + "月");
            Map<String, Object> confirmDetailsMap = DayStatisticsUtils.convertToMap(confirmDetailsInfo);
            List<ConfirmDetails> detailsList = new ArrayList<>();
            customizeTableVos.forEach(item -> {
                ConfirmDetails details = ConfirmDetails.builder()
                        .fieldName(item.getFieldName())
                        .customLeave(item.getCustomLeave())
                        .value(confirmDetailsMap.getOrDefault(item.getField() + "&" + item.getFieldName(), null))
                        .sort(item.getSort())
                        .build();
                detailsList.add(details);
            });
            confirm.setDetailDataJson(JSON.toJSONString(detailsList));
        });
    }

    @Override
    @Transactional
    public boolean confirmAutoSlippage() {
        Date date = DateUtil.beginOfDay(new Date());
        List<AttendanceConfirm> list = lambdaQuery()
                .eq(AttendanceConfirm::getSlippageResult, 0)
                .eq(AttendanceConfirm::getEndTime, date)
                .list();
        // 实时查询自定义请假类型
        List<AttendanceCustomizeTableVo> customizeTableVos = getAttendanceCustomizeTableVos();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM");
        Map<String, List<AttendanceConfirm>> batcheMap = list.stream().collect(Collectors.groupingBy(a -> YearMonth.of(a.getYear(), a.getMonth()).format(formatter)));
        batcheMap.forEach((month, dataList) -> {
            List<String> userIds = dataList.stream().map(AttendanceConfirm::getUserId).collect(Collectors.toList());
            // 处理json数据
            processJsonData(month, userIds, customizeTableVos, dataList);
            dataList.forEach(confirm -> {
                confirm.setStatus(2);
                confirm.setSlippageResult(1);
                confirm.setUpdateTime(new Date());
            });
            this.updateBatchById(dataList);
        });
        return Boolean.TRUE;
    }

    @Override
    public Boolean tipsClos(String id) {
        AttendanceConfirm attendanceConfirm = this.getById(id);
        ServiceException.notNull(attendanceConfirm, "未查询到考勤确认数据");
        attendanceConfirm.setTipsStatus(1);
        return this.updateById(attendanceConfirm);

    }

    @Override
    @Transactional
    public Boolean confirmDetailsSubmit(String id) {
        AttendanceConfirm attendanceConfirm = this.getById(id);
        ServiceException.notNull(attendanceConfirm, "未查询到考勤确认数据");
        //判断是否已逾期
        ServiceException.isTrue(attendanceConfirm.getSlippageResult().equals(0), "该考勤确认已逾期");
        attendanceConfirm.setStatus(2);
        attendanceConfirm.setUpdateTime(new Date());
        // 实时查询自定义请假类型
        List<AttendanceCustomizeTableVo> customizeTableVos = getAttendanceCustomizeTableVos();
        YearMonth yearMonth = YearMonth.of(attendanceConfirm.getYear(), attendanceConfirm.getMonth());
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM");
        List<AttendanceConfirm> attendanceConfirmList = List.of(attendanceConfirm);
        // 处理json数据
        processJsonData(yearMonth.format(formatter), List.of(attendanceConfirm.getUserId()), customizeTableVos, attendanceConfirmList);
        return this.updateBatchById(attendanceConfirmList);
    }

    /**
     * 获取自定义表单
     *
     * @return 自定义表单
     */
    private List<AttendanceCustomizeTableVo> getAttendanceCustomizeTableVos() {
        List<AttendanceCustomizeTableVo> customizeTableVos = customizeTableService.findList(null, 1, 2);
        List<String> removeIds = List.of("userName", "groupName", "deptName", "postName", "workStatus", "cycleList");
        customizeTableVos.removeIf(item -> removeIds.contains(item.getField()));
        customizeTableVos.sort(Comparator.comparingInt(AttendanceCustomizeTableVo::getSort));
        return customizeTableVos;
    }

    @Override
    public Boolean look(String id) {
        AttendanceConfirm attendanceConfirm = this.getById(id);
        ServiceException.notNull(attendanceConfirm, "未查询到考勤确认数据");
        attendanceConfirm.setStatus(1);
        this.updateById(attendanceConfirm);
        return Boolean.TRUE;
    }

    @Override
    public List<TodayWorkVo> getTodayWorkConfirmList() {
        List<TodayWorkVo> result = new ArrayList<>();
        LambdaQueryWrapper<AttendanceConfirm> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(AttendanceConfirm::getUserId, UserProvider.getUser().getUserId());
        lambdaQueryWrapper.isNotNull(AttendanceConfirm::getMonth);
        lambdaQueryWrapper.and(i -> i
                .le(AttendanceConfirm::getCreateTime, DateUtil.endOfDay(new Date()))
                .or()
                .le(AttendanceConfirm::getUpdateTime, DateUtil.endOfDay(new Date()))
        );
        List<AttendanceConfirm> attendanceConfirmList = this.list(lambdaQueryWrapper);
        //获取代办数据
        List<AttendanceConfirm> todoList = CollUtil.isNotEmpty(attendanceConfirmList) ? attendanceConfirmList.stream().filter(item ->
                item.getStatus() != 2 && item.getSlippageResult().equals(0)).collect(Collectors.toList()) : new ArrayList<>();
        //获取已逾期数据（只获取今天范围内的）
        List<AttendanceConfirm> overdueList = CollUtil.isNotEmpty(attendanceConfirmList) ? attendanceConfirmList.stream().filter(item -> null != item.getUpdateTime() &&
                item.getSlippageResult().equals(2) && DateUtil.isIn(item.getUpdateTime(), DateUtil.beginOfDay(new Date()), DateUtil.endOfDay(new Date()))).collect(Collectors.toList()) : new ArrayList<>();
        //获取已确认数据（只获取今天范围内的）
        List<AttendanceConfirm> completeList = CollUtil.isNotEmpty(attendanceConfirmList) ? attendanceConfirmList.stream().filter(item -> null != item.getUpdateTime() && item.getStatus().equals(2) &&
                DateUtil.isIn(item.getUpdateTime(), DateUtil.beginOfDay(new Date()), DateUtil.endOfDay(new Date()))).collect(Collectors.toList()) : new ArrayList<>();
        processDailyPlans(todoList, WorkStatusEnum.TO_DO, result);
        processDailyPlans(overdueList, WorkStatusEnum.OVERDUE, result);
        processDailyPlans(completeList, WorkStatusEnum.FINISHED, result);
        return result;
    }

    private void processDailyPlans(List<AttendanceConfirm> planList, WorkStatusEnum workStatus, List<TodayWorkVo> result) {
        if (CollUtil.isEmpty(planList)) {
            return;
        }
        List<TodayWorkVo> todayWorkVos = planList.stream().map(confirm -> {
            TodayWorkVo vo = new TodayWorkVo();
            vo.setWorkId(confirm.getId());
            vo.setWorkStatus(workStatus);
            vo.setTitle(confirm.getMonth() + "月考勤确认");
            vo.setFinishDate(confirm.getEndTime());
            vo.setCreatorTime(confirm.getCreateTime());
            vo.setWorkType(WorkTypeEnum.ATTENDANCE);
            vo.setMiniApp(MiniAppEnum.ATTENDANCE_CONFIRM);
            vo.setExtraJson(JSONObject.toJSONString(confirm));
            return vo;
        }).collect(Collectors.toList());
        result.addAll(todayWorkVos);
    }

    /**
     * 获取考勤确认数据
     *
     * @param attendanceConfirm 用户考勤确认数据
     * @param confirmDetailsVo  考勤确认数据
     */
    private void getConfirmData(AttendanceConfirm attendanceConfirm, ConfirmDetailsVo confirmDetailsVo) {
        Date newDate = new Date();
        List<AttendanceGroupUser> groupUserList = userService.getAttendanceGroupUsersOfSecondment(newDate, newDate, Collections.singletonList(attendanceConfirm.getUserId()), null);
        if (CollUtil.isEmpty(groupUserList)) {
            log.error("未查询到用户所属考勤组数据");
        }
        // 查询用户信息
        List<PartUserInfoVo> staffRosterDtoList = userAntifreeze.getInfoByIdsManyAndCopyPost(Collections.singletonList(attendanceConfirm.getUserId()), UserProvider.getUser().getTenantId());
        if (CollUtil.isEmpty(staffRosterDtoList)) {
            log.error("未查询到用户花名册数据:{}", attendanceConfirm.getUserId());
        }
        Map<String, PartUserInfoVo> staffRosterMap = staffRosterDtoList.stream().collect(Collectors.toMap(PartUserInfoVo::getUserId, a -> a, (k1, k2) -> k1));
        if (staffRosterMap.containsKey(attendanceConfirm.getUserId())) {
            BaseConfirmInfo baseInfo = BaseConfirmInfo.builder().build();
            PartUserInfoVo staffRosterDto = staffRosterMap.get(attendanceConfirm.getUserId());
            baseInfo.setDeptName(staffRosterDto.getOrganizeName());
            baseInfo.setPostName(staffRosterDto.getPositionName());
            baseInfo.setUserName(staffRosterDto.getRealName());
            baseInfo.setWorkStatus(staffRosterDto.getWorkerStatus());
            confirmDetailsVo.setBaseInfo(baseInfo);
        }
        // 获取考勤确认详情数据
        if (!attendanceConfirm.getStatus().equals(StatisticsEnumUtil.AttendanceConfirmStatusEnum.YQR.getCode())) {
            // 实时查询自定义请假类型
            List<AttendanceCustomizeTableVo> customizeTableVos = getAttendanceCustomizeTableVos();
            YearMonth yearMonth = YearMonth.of(attendanceConfirm.getYear(), attendanceConfirm.getMonth());
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM");
            List<AttendanceConfirm> attendanceConfirmList = List.of(attendanceConfirm);
            // 处理json数据
            processJsonData(yearMonth.format(formatter), List.of(attendanceConfirm.getUserId()), customizeTableVos, attendanceConfirmList);
        }
        List<ConfirmDetails> detailsList = JSON.parseArray(attendanceConfirm.getDetailDataJson(), ConfirmDetails.class);
        if (CollUtil.isNotEmpty(detailsList)) {
            detailsList.sort(Comparator.comparingInt(ConfirmDetails::getSort));
            confirmDetailsVo.setConfirmDetailsList(detailsList);
        }
    }
}
