package jnpf.cultivate.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.shaded.com.google.common.base.Splitter;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.base.Joiner;
import jnpf.base.vo.PageListVO;
import jnpf.cultivate.mapper.*;
import jnpf.cultivate.service.*;
import jnpf.cultivate.utils.CultivatePerUtils;
import jnpf.cultivate.utils.UserApiV2Util;
import jnpf.entity.cultivate.*;
import jnpf.enums.cultivate.ApplyResultEnum;
import jnpf.enums.cultivate.ApplySourceEnum;
import jnpf.enums.cultivate.ApplyStatusEnum;
import jnpf.enums.cultivate.ApplyTypeEnum;
import jnpf.message.SentMessageApi;
import jnpf.message.model.SentMessageIdentify;
import jnpf.message.model.SentMessageInfo;
import jnpf.model.cultivate.CultivatePage;
import jnpf.model.cultivate.dto.identify.*;
import jnpf.model.cultivate.dto.learn.BatchCommonCountDto;
import jnpf.model.cultivate.dto.statistics.FtbCultivateStatisticsDTO;
import jnpf.model.cultivate.event.JnpfApplicationEvent;
import jnpf.model.cultivate.event.dto.certificate.CertificateEventDTO;
import jnpf.model.cultivate.event.dto.file.FileEventDTO;
import jnpf.model.cultivate.po.FtbCultivateFile;
import jnpf.model.cultivate.po.learn.FtbCultivateLearnTaskExam;
import jnpf.model.cultivate.po.learn.FtbCultivateLearnTaskIdentification;
import jnpf.model.cultivate.po.position.FtbCultivatePosition;
import jnpf.model.cultivate.po.position.FtbCultivatePositionCourseIdentity;
import jnpf.model.cultivate.po.position.FtbCultivatePositionIdentifyResult;
import jnpf.model.cultivate.vo.common.InnerPowerUserVO;
import jnpf.model.cultivate.vo.identify.*;
import jnpf.model.cultivate.vo.offline.FtbCultivateOfflineFileVO;
import jnpf.permission.UserApi;
import jnpf.permission.entity.UserEntity;
import jnpf.permission.model.user.UserInfoVO;
import jnpf.permission.vo.v2.user.UserBoundVO;
import jnpf.permission.vo.v2.user.UserPageListVO;
import jnpf.util.*;
import jnpf.util.context.SpringContext;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 实操鉴定申请表
 *
 * @author shitou
 * @email shitou@niujiekeji.com
 * @date 2023-12-19 11:10:53
 */
@Slf4j
@Service("cultivateIdentifyApplyService")
public class CultivateIdentifyApplyServiceImpl extends ServiceImpl<CultivateIdentifyApplyMapper, CultivateIdentifyApply> implements CultivateIdentifyApplyService {

    @Resource
    FtbCultivatePositionIdentifyResultMapper ftbCultivatePositionIdentifyResultMapper;
    @Autowired
    FtbCultivatePromotionNewMapper promotionNewMapper;
    @Autowired
    FtbCultivateExamUserService ftbCultivateExamUserService;
    @Autowired
    FtbCultivateMyLearnTaskInfoService ftbCultivateMyLearnTaskInfoService;
    @Autowired
    FtbCultivateLearnTaskExamService ftbCultivateLearnTaskExamService;
    @Autowired
    FtbCultivateLearnTaskIdentificationService ftbCultivateLearnTaskIdentificationService;
    @Autowired
    private UserApi userApi;
    @Autowired
    private UserApiV2Util userApiV2Util;
    @Autowired
    private UserProvider userProvider;
    @Autowired
    private SentMessageApi sentMessageApi;
    @Autowired
    private CultivateIdentifyTableService identifyTableService;
    @Autowired
    private CultivateIdentifyItemsService identifyItemsService;
    @Autowired
    private CultivateIdentifyApplyDetailsMapper applyDetailsMapper;
    @Autowired
    private CultivateIdentifyApplyDetailsService applyDetailsService;
    @Autowired
    private PositionCultivateIdentifyService cultivateIdentifyService;
    @Autowired
    private CultivateIdentifyApplyTableBackupsService applyTableBackupsService;
    @Autowired
    private CultivateIdentifyApplyDetailsBackupsService applyDetailsBackupsService;
    @Autowired
    private CultivatePerUtils cultivatePerUtils;
    @Resource
    private FtbCultivateFileService ftbCultivateFileService;
    @Resource
    private FtbCultivatePositionCourseIdentityMapper ftbCultivatePositionCourseIdentityMapper;
    @Resource
    private FtbCultivatePositionMapper ftbCultivatePositionMapper;
    @Autowired
    private RedissonClient redissonClient;

    @NotNull
    private static List<String> getStrings(String[] beIdentifyUserIds, Map<String, UserBoundVO> userMap) {
        List<String> listName = new ArrayList<>();
        for (String userId : beIdentifyUserIds) {
            if (userMap.containsKey(userId)) {
                String realName = userMap.get(userId).getUserName();
                listName.add(realName);
            }
        }
        return listName;
    }

    @Override
    public PageInfo<IdentifyApplyListVo> getPageApplyList(IdentifyApplyListDto req) {
        com.github.pagehelper.Page<Object> objects = PageHelper.startPage(Math.toIntExact(req.getCurrentPage()), Math.toIntExact(req.getPageSize()));
        InnerPowerUserVO innerPowerUserVO = userApiV2Util.getLoginManagerUserIdsForEncode();
        if (innerPowerUserVO.getCode() == 1) {
            req.setInnerPowerUserIds(innerPowerUserVO.getUserIds());
        } else if (innerPowerUserVO.getCode() == 0) {
            req.setInnerPowerUserIds(new ArrayList<>());
        } else {
            PageInfo<IdentifyApplyListVo> page = new PageInfo<>();
            page.setPageSize((int) req.getPageSize());
            page.setPageNum((int) req.getCurrentPage());
            page.setTotal(0);
            page.setSize(0);
            page.setList(new ArrayList<>());
            return page;
        }
//        req.setLeaverUserIds(userApiV2Util.queryLeaveUserId());

        PageInfo<IdentifyApplyListDbVo> pageEntity = new PageInfo<>(this.baseMapper.getPageList(req));
        List<IdentifyApplyListVo> applyListVoList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(pageEntity.getList())) {
            //查询到人员名称-服务调用
            List<String> userIdList = new ArrayList<>();
            pageEntity.getList().forEach(item -> {
                userIdList.add(item.getBeIdentifyUserId());
                if (StringUtil.isNotEmpty(item.getIdentifyUserId())) {
                    String[] split = item.getIdentifyUserId().split(",");
                    userIdList.addAll(Arrays.asList(split));
                }
            });
            Map<String, UserBoundVO> userMap = userApiV2Util.getUserPrimaryBoundBatch(userIdList, null);
            pageEntity.getList().forEach(item -> {
                IdentifyApplyListVo applyListVo = new IdentifyApplyListVo();
                BeanUtils.copyProperties(item, applyListVo);
                applyListVo.setUserTime(item.getUseTime());
                //被鉴定用户信息
                IdentifyUserOrgInfoVo beIdentifyUserInfo = new IdentifyUserOrgInfoVo();
                UserBoundVO beUserInfoVo = userMap.get(item.getBeIdentifyUserId());
                // 获取用户头像
                if (Objects.nonNull(beUserInfoVo) && !StringUtil.isEmpty(beUserInfoVo.getHeadIcon())) {
                    beIdentifyUserInfo.setUserHeadIcon(UploaderUtil.uploaderImg(beUserInfoVo.getHeadIcon()));
                }
                beIdentifyUserInfo.setUserId(item.getBeIdentifyUserId());
                beIdentifyUserInfo.setUserName(Objects.isNull(userMap.get(item.getBeIdentifyUserId())) ?
                        "未查询到用户" : userMap.get(item.getBeIdentifyUserId()).getUserName());
                //被鉴定人职等的组织信息

                if (beUserInfoVo != null) {
                    UserOrgInfoVo orgInfoVo = new UserOrgInfoVo();
                    orgInfoVo.setUserOrgName(beUserInfoVo.getOrganizeName());
                    orgInfoVo.setUserPostName(beUserInfoVo.getPositionName());
                    orgInfoVo.setUserOfficialRankName(beUserInfoVo.getGradeName());
                    beIdentifyUserInfo.setUserOrgInfoPushVoList(List.of(orgInfoVo));
                }


                List<IdentifyUserOrgInfoVo> identifyUserInfos = new ArrayList<>();
                if (StringUtil.isNotEmpty(item.getIdentifyUserId())) {
                    for (String tempId : item.getIdentifyUserId().split(",")) {
                        //鉴定用户信息
                        IdentifyUserOrgInfoVo identifyUserInfo = new IdentifyUserOrgInfoVo();
                        UserBoundVO userInfoVo = userMap.get(tempId);
                        // 获取用户头像
                        if (Objects.nonNull(userInfoVo) && !StringUtil.isEmpty(userInfoVo.getHeadIcon())) {
                            identifyUserInfo.setUserHeadIcon(UploaderUtil.uploaderImg(userInfoVo.getHeadIcon()));
                        }
                        identifyUserInfo.setUserId(item.getIdentifyUserId());
                        identifyUserInfo.setUserName(Objects.isNull(userMap.get(item.getIdentifyUserId())) ?
                                "未查询到用户" : userMap.get(item.getIdentifyUserId()).getUserName());
                        //鉴定人职等的组织信息
                        List<UserOrgInfoAll1Vo> orgInfoAll1VoList = JSON.parseArray(item.getOfficialRankInfoJson(), UserOrgInfoAll1Vo.class);
                        if (CollectionUtil.isNotEmpty(orgInfoAll1VoList)) {
                            identifyUserInfo.setUserOrgInfoPushVoList(orgInfoAll1VoList.stream().map(orgInfoAll1Vo -> {
                                UserOrgInfoVo orgInfoVo = new UserOrgInfoVo();
                                BeanUtils.copyProperties(orgInfoAll1Vo, orgInfoVo);
                                return orgInfoVo;
                            }).collect(Collectors.toList()));
                        }
                        identifyUserInfos.add(identifyUserInfo);
                    }
                }
                applyListVo.setBeIdentifyUserInfo(beIdentifyUserInfo);
                applyListVo.setIdentifyUserInfo(identifyUserInfos);
                applyListVoList.add(applyListVo);
            });
        }
        PageInfo<IdentifyApplyListVo> page = new PageInfo<>();
        BeanUtils.copyProperties(pageEntity, page);
        page.setList(applyListVoList);
        page.setTotal(objects.getTotal());
        page.setPageNum(objects.getPageNum());
        page.setPageSize(objects.getPageSize());
        return page;
    }

    @Override
    public IdentifyApplyBasicInfoVo getApplyBasicInfo(IdentifyTableInfoDto req) {
        CultivateIdentifyApply apply = this.baseMapper.selectById(req.getId());
        ServiceException.notNull(apply, "未查询到实操鉴定记录");
        CultivateIdentifyApplyTableBackups table = this.applyTableBackupsService.getById(apply.getTableId());
        ServiceException.notNull(table, "未查询到实操鉴定表记录");
        IdentifyApplyBasicInfoVo applyBasicInfoVo = new IdentifyApplyBasicInfoVo();
        BeanUtils.copyProperties(apply, applyBasicInfoVo);

        applyBasicInfoVo.setId(apply.getId());
        applyBasicInfoVo.setTableId(table.getTableId());
        applyBasicInfoVo.setTableName(table.getName());
        applyBasicInfoVo.setRuleId(table.getRuleId());
        String beIdentifyUserId = apply.getBeIdentifyUserId();
        String identifyUserId = apply.getIdentifyUserId();
        String[] userIds = new String[]{};
        if (StringUtil.isNotEmpty(identifyUserId)) {
            userIds = identifyUserId.split(",");
            applyBasicInfoVo.setIdentifyUserId(List.of(userIds));
        } else {
            applyBasicInfoVo.setIdentifyUserId(new ArrayList<>());
        }
        String[] beIdentifyUserIds = beIdentifyUserId.split(",");
        Map<String, UserBoundVO> userMap = getUserMaps(identifyUserId, beIdentifyUserId);
        //被鉴定用户信息
        IdentifyUserOrgInfoVo beIdentifyUserInfo = new IdentifyUserOrgInfoVo();
        beIdentifyUserInfo.setUserId(beIdentifyUserId);
        if (StringUtils.isNotEmpty(beIdentifyUserId)) {
            List<String> listName = getStrings(beIdentifyUserIds, userMap);
            beIdentifyUserInfo.setUserName(CollUtil.isEmpty(listName) ?
                    "未查询到用户" : String.join(",", listName));
        }
        //被鉴定人职等的组织信息
        List<UserOrgInfoAll1Vo> beOrgInfoAll1VoList = JSON.parseArray(apply.getBeOfficialRankInfoJson(), UserOrgInfoAll1Vo.class);
        if (CollectionUtil.isNotEmpty(beOrgInfoAll1VoList)) {
            beIdentifyUserInfo.setUserOrgInfoPushVoList(beOrgInfoAll1VoList.stream().map(item -> {
                UserOrgInfoVo orgInfoVo = new UserOrgInfoVo();
                BeanUtils.copyProperties(item, orgInfoVo);
                return orgInfoVo;
            }).collect(Collectors.toList()));
        }

        //鉴定用户信息
        IdentifyUserOrgInfoVo identifyUserInfo = new IdentifyUserOrgInfoVo();
        identifyUserInfo.setUserId(apply.getIdentifyUserId());
        if (StringUtils.isNotEmpty(beIdentifyUserId)) {
            List<String> listName = getStrings(userIds, userMap);
            identifyUserInfo.setUserName(CollUtil.isEmpty(listName) ?
                    "未查询到用户" : String.join(",", listName));
        }
        //鉴定人职等的组织信息
        List<UserOrgInfoAll1Vo> orgInfoAll1VoList = JSON.parseArray(apply.getOfficialRankInfoJson(), UserOrgInfoAll1Vo.class);
        if (CollectionUtil.isNotEmpty(orgInfoAll1VoList)) {
            identifyUserInfo.setUserOrgInfoPushVoList(orgInfoAll1VoList.stream().map(item -> {
                UserOrgInfoVo orgInfoVo = new UserOrgInfoVo();
                BeanUtils.copyProperties(item, orgInfoVo);
                return orgInfoVo;
            }).collect(Collectors.toList()));
        }
        applyBasicInfoVo.setBeIdentifyUserInfo(beIdentifyUserInfo);
        applyBasicInfoVo.setIdentifyUserInfo(identifyUserInfo);
        return applyBasicInfoVo;
    }

    @Override
    public IdentifyApplyInfoVo getApplyInfo(IdentifyTableInfoDto req) {
        CultivateIdentifyApply apply = this.baseMapper.selectById(req.getId());
        ServiceException.notNull(apply, "未查询到实操鉴定记录");
        CultivateIdentifyApplyTableBackups table = this.applyTableBackupsService.getById(apply.getTableId());
        ServiceException.notNull(table, "未查询到实操鉴定表记录");
        IdentifyApplyInfoVo applyInfoVo = new IdentifyApplyInfoVo();
        BeanUtils.copyProperties(apply, applyInfoVo);
        applyInfoVo.setUserTime(apply.getUseTime());
        applyInfoVo.setTableName(table.getName());
        applyInfoVo.setRuleDesc(table.getRuleDesc());
        String identifyUserId = apply.getIdentifyUserId();
        String[] userIds = new String[]{};
        if (StringUtil.isNotEmpty(identifyUserId)) {
            userIds = identifyUserId.split(",");
        }
        String beIdentifyUserId = apply.getBeIdentifyUserId();

        String[] beIdentifyUserIds = beIdentifyUserId.split(",");
        Map<String, UserBoundVO> userMap = getUserMaps(identifyUserId, beIdentifyUserId);
        //被鉴定用户信息
        IdentifyUserOrgInfoVo beIdentifyUserInfo = new IdentifyUserOrgInfoVo();
        beIdentifyUserInfo.setUserId(beIdentifyUserId);
        if (StringUtils.isNotEmpty(beIdentifyUserId)) {
            List<String> listName = getStrings(beIdentifyUserIds, userMap);
            beIdentifyUserInfo.setUserName(CollUtil.isEmpty(listName) ?
                    "未查询到用户" : String.join(",", listName));
        }
        //被鉴定人职等的组织信息
        List<UserOrgInfoAll1Vo> beOrgInfoAll1VoList = JSON.parseArray(apply.getBeOfficialRankInfoJson(), UserOrgInfoAll1Vo.class);
        if (CollectionUtil.isNotEmpty(beOrgInfoAll1VoList)) {
            beIdentifyUserInfo.setUserOrgInfoPushVoList(beOrgInfoAll1VoList.stream().map(item -> {
                UserOrgInfoVo orgInfoVo = new UserOrgInfoVo();
                BeanUtils.copyProperties(item, orgInfoVo);
                return orgInfoVo;
            }).collect(Collectors.toList()));
        }
        IdentifyUserOrgInfoVo identifyUserInfo = new IdentifyUserOrgInfoVo();
        identifyUserInfo.setUserId(identifyUserId);
        if (StringUtils.isNotEmpty(identifyUserId)) {
            List<String> listName = getStrings(userIds, userMap);
            identifyUserInfo.setUserName(CollUtil.isEmpty(listName) ?
                    "未查询到用户" : String.join(",", listName));
        }
        //被鉴定人职等的组织信息
        List<UserOrgInfoAll1Vo> orgInfoAll1VoList = JSON.parseArray(apply.getOfficialRankInfoJson(), UserOrgInfoAll1Vo.class);
        if (CollectionUtil.isNotEmpty(orgInfoAll1VoList)) {
            identifyUserInfo.setUserOrgInfoPushVoList(orgInfoAll1VoList.stream().map(item -> {
                UserOrgInfoVo orgInfoVo = new UserOrgInfoVo();
                BeanUtils.copyProperties(item, orgInfoVo);
                return orgInfoVo;
            }).collect(Collectors.toList()));
        }
        applyInfoVo.setBeIdentifyUserInfo(beIdentifyUserInfo);
        applyInfoVo.setIdentifyUserInfo(identifyUserInfo);
        //设置鉴定项得分集合
        List<IdentifyApplyDetailsInfoVo> detailsInfoVos = this.applyDetailsMapper.getIdentifyItemList(apply.getId());
        applyInfoVo.setIdentifyItemList(CollectionUtil.isNotEmpty(detailsInfoVos) ? detailsInfoVos : CollectionUtil.newArrayList());
        BigDecimal totalScore = BigDecimal.ZERO;
        if (CollectionUtil.isNotEmpty(detailsInfoVos) && apply.getStatus().equals(ApplyStatusEnum.YJD.getCode())) {
            for (IdentifyApplyDetailsInfoVo detailsInfoVo : detailsInfoVos) {
                totalScore = totalScore.add(detailsInfoVo.getScore());
            }
            applyInfoVo.setTotalScore(totalScore);
        } else {
            applyInfoVo.setTotalScore(null);
            applyInfoVo.setUserTime(null);
            applyInfoVo.setResult(null);
        }
        // 查询当前申请时上传的文件信息

        LambdaQueryWrapper<FtbCultivateFile> wrapperFile = Wrappers.lambdaQuery();
        wrapperFile.eq(FtbCultivateFile::getBusinessId, apply.getId());
        List<FtbCultivateFile> fileLists = ftbCultivateFileService.list(wrapperFile);
        LambdaQueryWrapper<FtbCultivateFile> wrapperFile2 = Wrappers.lambdaQuery();
        wrapperFile2.eq(FtbCultivateFile::getBusinessId, apply.getId() + apply.getBeIdentifyUserId());
        List<FtbCultivateFile> fileLists2 = ftbCultivateFileService.list(wrapperFile2);
        List<FtbCultivateOfflineFileVO> fileVOS = fileLists.stream()
                .map(FtbCultivateOfflineFileVO::convertFtbCultivateOfflineFileVO).collect(Collectors.toList());
        List<FtbCultivateOfflineFileVO> fileVOS2 = fileLists2.stream()
                .map(FtbCultivateOfflineFileVO::convertFtbCultivateOfflineFileVO).collect(Collectors.toList());
        List<FtbCultivateOfflineFileVO> file = new ArrayList<>();
        file.addAll(fileVOS2);
        file.addAll(fileVOS);
        applyInfoVo.setFiles(file);
        return applyInfoVo;
    }

    public Map<String, UserBoundVO> getUserMaps(String identifyUserId, String beIdentifyUserId) {
        List<String> list = new ArrayList<>();
        List<String> identifyUserIdList = new ArrayList<>();
        if (StringUtil.isNotEmpty(identifyUserId)) {
            identifyUserIdList = List.of(identifyUserId.split(","));
        }
        if (CollectionUtil.isNotEmpty(identifyUserIdList)) {
            list.addAll(identifyUserIdList);
        }
        List<String> beIdentifyUserIds = List.of(beIdentifyUserId.split(","));
        if (CollectionUtil.isNotEmpty(beIdentifyUserIds)) {
            list.addAll(beIdentifyUserIds);
        }
        if (CollUtil.isEmpty(list)) {
            return new HashMap<>();
        }
        return userApiV2Util.getUserPrimaryBoundBatch(list, null);
    }

    @Override
    @Transactional
    public void applyDataSave(IdentifyApplySaveDto req) throws RuntimeException {
        //判断鉴定人与被鉴定人是否同一个人
        ServiceException.isTrue(!req.getBeIdentifyUserId().equals(req.getIdentifyUserId()), "鉴定人与被鉴定人不能是同一个");
        CultivateIdentifyTable table = this.identifyTableService.getById(req.getTableId());
        ServiceException.notNull(table, "未查询到实操鉴定表记录");

        List<CultivateIdentifyItems> identifyItemsList = this.identifyItemsService.lambdaQuery()
                .eq(CultivateIdentifyItems::getTableId, req.getTableId())
                .eq(CultivateIdentifyItems::getDeleteMark, ConstantUtil.NUM_FALSE)
                .list();
        //生成鉴定项数据
        ServiceException.notNull(identifyItemsList, "未查询到鉴定项数据");

        CultivateIdentifyApply apply = new CultivateIdentifyApply();
        apply.setId(RandomUtil.uuId());
        BeanUtils.copyProperties(req, apply);
        apply.setStatus(ApplyStatusEnum.DJD.getCode());
        apply.setIsReIdentify(ConstantUtil.NUM_FALSE);
        //用户userId集合
        List<String> userIdList = new ArrayList<>();
        userIdList.add(req.getBeIdentifyUserId());
        //查询用户直系领导组织信息
        Map<String, List<UserBoundVO>> userOrgMap = userApiV2Util.getUserPrimaryBoundBatchCompatible(userIdList, null);
        apply.setIsChoose(ConstantUtil.NUM_FALSE);

        //设置被鉴定人信息
        List<UserOrgInfoAll1Vo> beIdentifyUserInfoJsonList = CollectionUtil.newArrayList();
        List<UserBoundVO> beIdentifyUserInfoList = userOrgMap.get(req.getBeIdentifyUserId());
        ServiceException.notNull(beIdentifyUserInfoList, "未查询到鉴定用户直系领导组织信息");

        beIdentifyUserInfoJsonList.addAll(beIdentifyUserInfoList.stream().map(item -> {
            UserOrgInfoAll1Vo all1Vo = new UserOrgInfoAll1Vo();
            all1Vo.setUserOrgName(item.getOrganizeName());
            all1Vo.setUserOrgCode(item.getOrganizeEnCode());
            all1Vo.setUserPostName(item.getPositionName());
            all1Vo.setUserPostCode(item.getPositionEnCode());
            all1Vo.setUserOfficialRankName(item.getGradeName());
            return all1Vo;
        }).collect(Collectors.toList()));
        apply.setBeIdentifyOrgList(Joiner.on(",").join(beIdentifyUserInfoList.stream().map(
                UserBoundVO::getOrganizeId).distinct().collect(Collectors.toList())));
        apply.setBeIdentifyUserId(req.getBeIdentifyUserId());
        apply.setBeOfficialRankInfoJson(JSON.toJSONString(beIdentifyUserInfoJsonList));
        //生成鉴定项数据
        apply.setSource(req.getSource());
        //生成鉴定表、鉴定项备份数据
        CultivateIdentifyApplyTableBackups applyTableBackups = new CultivateIdentifyApplyTableBackups();
        BeanUtils.copyProperties(table, applyTableBackups);
        applyTableBackups.setId(RandomUtil.uuId());
        applyTableBackups.setTableId(table.getId());
        apply.setTableId(applyTableBackups.getId());
        apply.setSource(req.getSource());
        //生成鉴定项数据

        List<CultivateIdentifyApplyDetailsBackups> applyDetailsBackupsList = CollectionUtil.newArrayList();
        if (CollectionUtil.isNotEmpty(identifyItemsList)) {
            applyDetailsBackupsList.addAll(identifyItemsList.stream().map(item -> {
                CultivateIdentifyApplyDetailsBackups applyDetailsBackups = new CultivateIdentifyApplyDetailsBackups();
                BeanUtils.copyProperties(item, applyDetailsBackups);
                applyDetailsBackups.setId(RandomUtil.uuId());
                applyDetailsBackups.setTableId(applyTableBackups.getId());
                applyDetailsBackups.setItemsId(item.getId());
                return applyDetailsBackups;
            }).collect(Collectors.toList()));
        }
        //生成鉴定项数据
        List<CultivateIdentifyApplyDetails> applyDetailsList = CollectionUtil.newArrayList();
        if (CollectionUtil.isNotEmpty(applyDetailsBackupsList)) {
            applyDetailsList.addAll(applyDetailsBackupsList.stream().map(item -> {
                CultivateIdentifyApplyDetails applyDetails = new CultivateIdentifyApplyDetails();
                applyDetails.setApplyId(apply.getId());
                applyDetails.setItemsId(item.getId());
                return applyDetails;
            }).collect(Collectors.toList()));
        } else {
            ServiceException.notNull(apply, "未查询到鉴定项数据");
        }
        //保存备份数据
        this.applyTableBackupsService.save(applyTableBackups);
        if (CollectionUtil.isNotEmpty(applyDetailsBackupsList)) {
            this.applyDetailsBackupsService.saveBatch(applyDetailsBackupsList);
        }
        //保存鉴定数据
        this.save(apply);
        if (CollectionUtil.isNotEmpty(applyDetailsList)) {
            this.applyDetailsService.saveBatch(applyDetailsList);
        }
        //通过文件事件监听信息
        SpringContext.getApplicationContext().publishEvent(new JnpfApplicationEvent<>(FileEventDTO.builder()
                .files(req.getFiles())
                .businessTypeID(apply.getId() + apply.getBeIdentifyUserId())
                .type(FileEventDTO.FileType.PRACTICAL_APPRAISAL)
                .build()));
    }


    private IdentifyApplySaveDto convertToIdentifyApplySaveDto(@Valid BatchIdentifyApplySaveDto req) {
        IdentifyApplySaveDto identifyApplySaveDto = new IdentifyApplySaveDto();
        identifyApplySaveDto.setTableId(req.getTableId());
        identifyApplySaveDto.setAppraisalResults(req.getAppraisalResults());
        identifyApplySaveDto.setSource(req.getSource());
        identifyApplySaveDto.setFiles(req.getFiles());
        return identifyApplySaveDto;
    }

    private void checkBatchParam(@Valid BatchIdentifyApplySaveDto req) {
        List<IdentifyUserInfoDto> beIdentifyUserInfoDtoList = req.getBeIdentifyUserInfoDtoList();
        if (CollUtil.isEmpty(beIdentifyUserInfoDtoList)) {
            throw new RuntimeException("被鉴定人信息不能为空");
        }
    }

    @Override
    @Transactional
    public void applyDataSaveBatch(BatchIdentifyApplySaveDto req) throws RuntimeException {
        checkBatchParam(req);
        CultivateIdentifyTable table = this.identifyTableService.getById(req.getTableId());
        ServiceException.notNull(table, "未查询到实操鉴定表记录");
        IdentifyApplySaveDto identifyApplySaveDto = convertToIdentifyApplySaveDto(req);
        List<CultivateIdentifyApply> applyList = CollectionUtil.newArrayList();

        List<CultivateIdentifyItems> identifyItemsList = this.identifyItemsService.lambdaQuery()
                .eq(CultivateIdentifyItems::getTableId, req.getTableId())
                .eq(CultivateIdentifyItems::getDeleteMark, ConstantUtil.NUM_FALSE)
                .list();
        ServiceException.notNull(identifyItemsList, "未查询到鉴定项数据");

        List<String> identifyUserIds = req.getBeIdentifyUserInfoDtoList().stream().map(IdentifyUserInfoDto::getBeIdentifyUserId).collect(Collectors.toList());
        Map<String, List<UserBoundVO>> userPrimaryBoundBatchCompatibleMap = userApiV2Util.getUserPrimaryBoundBatchCompatible(identifyUserIds, null);

        for (IdentifyUserInfoDto identifyUserInfoDto : req.getBeIdentifyUserInfoDtoList()) {
            List<UserBoundVO> userBoundVOS = userPrimaryBoundBatchCompatibleMap.get(identifyUserInfoDto.getBeIdentifyUserId());
            if (CollUtil.isEmpty(userBoundVOS)) {
                throw new RuntimeException("用户:" + identifyUserInfoDto.getBeIdentifyUserName() + ",未查询到该被鉴定人组织、岗位信息");
            }
        }

        for (IdentifyUserInfoDto identifyUserInfoDto : req.getBeIdentifyUserInfoDtoList()) {
            identifyApplySaveDto.setBeIdentifyUserId(identifyUserInfoDto.getBeIdentifyUserId());
            identifyApplySaveDto.setBeIdentifyOrgId(identifyUserInfoDto.getBeIdentifyOrgId());
            identifyApplySaveDto.setBeIdentifyPostId(identifyUserInfoDto.getBeIdentifyPostId());
            identifyApplySaveDto.setBeIdentifyPostRankId(identifyUserInfoDto.getBeIdentifyPostRankId());
            applyList.add(this.applyDataSaveNew(identifyApplySaveDto, table, identifyItemsList, userPrimaryBoundBatchCompatibleMap));
        }

        for (CultivateIdentifyApply apply : applyList) {
            //通过文件事件监听信息
            SpringContext.getApplicationContext().publishEvent(new JnpfApplicationEvent<>(FileEventDTO.builder()
                    .files(req.getFiles())
                    .businessTypeID(apply.getId() + apply.getBeIdentifyUserId())
                    .type(FileEventDTO.FileType.PRACTICAL_APPRAISAL)
                    .build()));
        }
    }

    public CultivateIdentifyApply applyDataSaveNew(IdentifyApplySaveDto req, CultivateIdentifyTable table, List<CultivateIdentifyItems> identifyItemsList, Map<String, List<UserBoundVO>> userOrgMap) throws RuntimeException {
        CultivateIdentifyApply apply = new CultivateIdentifyApply();
        apply.setId(RandomUtil.uuId());
        apply.setName(table.getName());
        BeanUtils.copyProperties(req, apply);
        apply.setStatus(ApplyStatusEnum.DJD.getCode());
        apply.setIsReIdentify(ConstantUtil.NUM_FALSE);
        //设置被鉴定人信息
        List<UserOrgInfoAll1Vo> beIdentifyUserInfoJsonList = CollectionUtil.newArrayList();
        List<UserBoundVO> beIdentifyUserInfoList = userOrgMap.get(req.getBeIdentifyUserId());
        beIdentifyUserInfoJsonList.addAll(beIdentifyUserInfoList.stream().map(item -> {
            UserOrgInfoAll1Vo all1Vo = new UserOrgInfoAll1Vo();
            all1Vo.setUserOrgCode(item.getOrganizeEnCode());
            all1Vo.setUserOrgName(item.getOrganizeName());
            all1Vo.setUserPostCode(item.getPositionEnCode());
            all1Vo.setUserPostName(item.getPositionName());
            all1Vo.setUserOfficialRankCode(item.getGradeId());
            all1Vo.setUserOfficialRankName(item.getGradeName());
            return all1Vo;
        }).collect(Collectors.toList()));
        apply.setBeIdentifyOrgList(Joiner.on(",").join(beIdentifyUserInfoList.stream().map(
                UserBoundVO::getOrganizeId).distinct().collect(Collectors.toList())));
        apply.setBeIdentifyUserId(req.getBeIdentifyUserId());
        apply.setBeOfficialRankInfoJson(JSON.toJSONString(beIdentifyUserInfoJsonList));
        //生成鉴定表、鉴定项备份数据
        CultivateIdentifyApplyTableBackups applyTableBackups = new CultivateIdentifyApplyTableBackups();
        BeanUtils.copyProperties(table, applyTableBackups);
        applyTableBackups.setId(RandomUtil.uuId());
        applyTableBackups.setTableId(table.getId());
        apply.setTableId(applyTableBackups.getId());
        apply.setSource(req.getSource());

        //生成鉴定项数据
        List<CultivateIdentifyApplyDetailsBackups> applyDetailsBackupsList = CollectionUtil.newArrayList();
        if (CollectionUtil.isNotEmpty(identifyItemsList)) {
            applyDetailsBackupsList.addAll(identifyItemsList.stream().map(item -> {
                CultivateIdentifyApplyDetailsBackups applyDetailsBackups = new CultivateIdentifyApplyDetailsBackups();
                BeanUtils.copyProperties(item, applyDetailsBackups);
                applyDetailsBackups.setId(RandomUtil.uuId());
                applyDetailsBackups.setTableId(applyTableBackups.getId());
                applyDetailsBackups.setItemsId(item.getId());
                return applyDetailsBackups;
            }).collect(Collectors.toList()));
        }
        //生成鉴定项数据
        List<CultivateIdentifyApplyDetails> applyDetailsList = CollectionUtil.newArrayList();
        if (CollectionUtil.isNotEmpty(applyDetailsBackupsList)) {
            applyDetailsList.addAll(applyDetailsBackupsList.stream().map(item -> {
                CultivateIdentifyApplyDetails applyDetails = new CultivateIdentifyApplyDetails();
                applyDetails.setApplyId(apply.getId());
                applyDetails.setItemsId(item.getId());
                return applyDetails;
            }).collect(Collectors.toList()));
        } else {
            ServiceException.notNull(apply, "未查询到鉴定项数据");
        }
        //保存备份数据
        this.applyTableBackupsService.save(applyTableBackups);
        if (CollectionUtil.isNotEmpty(applyDetailsBackupsList)) {
            this.applyDetailsBackupsService.saveBatch(applyDetailsBackupsList);
        }
        //保存鉴定数据
        this.save(apply);
        if (CollectionUtil.isNotEmpty(applyDetailsList)) {
            this.applyDetailsService.saveBatch(applyDetailsList);
        }
        return apply;
    }

    @Override
    @Transactional
    public String applyDataPush(IdentifyApplyDataPushDto req) throws RuntimeException {
        // 构建带分隔符的锁键，防止键冲突
        String lockKey = String.format("lock:applyDataPush:%s:%s:%s:%s:%s",
                req.getDataId(),
                req.getSource(),
                req.getTableId(),
                req.getIdentifyUserId(),
                req.getPostId());
        RLock lock = redissonClient.getLock(lockKey);
        try {
            // 尝试获取锁，等待0秒，锁自动释放时间30秒
            if (lock.tryLock(0, 30, TimeUnit.SECONDS)) {
                return applyDataPushReal(req);
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt(); // 恢复中断状态
            throw new RuntimeException("Lock acquisition interrupted", e);
        } finally {
            if (lock.isHeldByCurrentThread() && lock.isLocked()) {
                lock.unlock();
            }
        }
        return "";
    }


    public String applyDataPushReal(IdentifyApplyDataPushDto req) throws RuntimeException {
        CultivateIdentifyTable table = this.identifyTableService.getById(req.getTableId());
        ServiceException.notNull(table, "未查询到实操鉴定表记录");
        LambdaQueryWrapper<CultivateIdentifyApply> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(CultivateIdentifyApply::getSourceId, req.getDataId());
        wrapper.eq(CultivateIdentifyApply::getSource, req.getSource());
        wrapper.eq(CultivateIdentifyApply::getBeIdentifyUserId, req.getIdentifyUserId());
        wrapper.eq(CultivateIdentifyApply::getDeleteMark, ConstantUtil.NUM_FALSE);
        // 任务鉴定不需要去校验table申请
        wrapper.eq(req.getSource() != 4, CultivateIdentifyApply::getTableId, req.getTableId());
        wrapper.last("limit 1");
        CultivateIdentifyApply oldApply = baseMapper.selectOne(wrapper);
        CultivateIdentifyApply apply = null;
        if (oldApply != null) {
            if (oldApply.getStatus().equals(1) || oldApply.getStatus().equals(0)) {
                return null;
            }
            oldApply.setDeleteMark(1);
            deleteApplyDetails(oldApply.getId());
            baseMapper.updateById(oldApply);
            apply = oldApply;
        } else {
            apply = new CultivateIdentifyApply();
        }


        apply.setId(RandomUtil.uuId());
        BeanUtils.copyProperties(req, apply);
        apply.setIdentifyUserId("");
        apply.setIdentifyOrgList("");
        apply.setSourceId(req.getDataId());
        apply.setAppraisalResults(ConstantUtil.NUM_FALSE);

        List<CultivateIdentifyItems> identifyItemsList = this.identifyItemsService.lambdaQuery()
                .eq(CultivateIdentifyItems::getTableId, req.getTableId())
                .eq(CultivateIdentifyItems::getDeleteMark, ConstantUtil.NUM_FALSE)
                .list();
        ServiceException.notNull(identifyItemsList, "未查询到鉴定项数据");

        // 默认申请的打开可见性, 默认为0
        if (req.getSource() == 2 && (req.getIsTurnOnVisibility() != null && req.getIsTurnOnVisibility() == 1)) {
            apply.setIsVisible(1);
        }
        if (req.getSource() == 4 && (req.getIsTurnOnVisibility() != null && req.getIsTurnOnVisibility() == 1)) {
            apply.setIsVisible(1);
        }
        //设置被鉴定人信息
        apply.setBeIdentifyUserId(req.getIdentifyUserId());
        apply.setIsChoose(ConstantUtil.NUM_FALSE);
        apply.setStatus(ApplyStatusEnum.DJD.getCode());
        apply.setStudyFinishTime(req.getStudyFinishTime());
        apply.setIsReIdentify(ConstantUtil.NUM_FALSE);
        apply.setDeleteMark(0);
        // 岗位学习和课程实操鉴定，不进行直属主管判定，因为直属主管需要组织、岗位、职等进行确定
        UserBoundVO beIdentifyUserInfoList = userApiV2Util.getUserPrimaryBoundOne(req.getIdentifyUserId(), null);
        ServiceException.notNull(beIdentifyUserInfoList, "被鉴定人信息为null");

        //被鉴定人组织信息
        List<UserOrgInfoAll1Vo> beIdentifyUserInfoJsonList = CollectionUtil.newArrayList();
        ServiceException.notNull(beIdentifyUserInfoList, "未查询到被鉴定人组织信息");
        UserOrgInfoAll1Vo all1Vo = new UserOrgInfoAll1Vo();
        all1Vo.setUserOrgCode(beIdentifyUserInfoList.getOrganizeEnCode());
        all1Vo.setUserOrgName(beIdentifyUserInfoList.getOrganizeName());
        all1Vo.setUserPostCode(beIdentifyUserInfoList.getPositionEnCode());
        all1Vo.setUserPostName(beIdentifyUserInfoList.getPositionName());
        all1Vo.setUserOfficialRankCode(beIdentifyUserInfoList.getGradeId());
        all1Vo.setUserOfficialRankName(beIdentifyUserInfoList.getGradeName());
        beIdentifyUserInfoJsonList.add(all1Vo);

        apply.setBeIdentifyOrgList(beIdentifyUserInfoList.getOrganizeId());
        apply.setBeIdentifyUserId(req.getIdentifyUserId());
        apply.setBeOfficialRankInfoJson(JSON.toJSONString(beIdentifyUserInfoJsonList));

        //生成鉴定表、鉴定项备份数据
        CultivateIdentifyApplyTableBackups applyTableBackups = new CultivateIdentifyApplyTableBackups();
        BeanUtils.copyProperties(table, applyTableBackups);
        applyTableBackups.setId(RandomUtil.uuId());
        applyTableBackups.setTableId(table.getId());
        apply.setTableId(applyTableBackups.getId());

        List<CultivateIdentifyApplyDetailsBackups> applyDetailsBackupsList = CollectionUtil.newArrayList();
        if (CollectionUtil.isNotEmpty(identifyItemsList)) {
            applyDetailsBackupsList.addAll(identifyItemsList.stream().map(item -> {
                CultivateIdentifyApplyDetailsBackups applyDetailsBackups = new CultivateIdentifyApplyDetailsBackups();
                BeanUtils.copyProperties(item, applyDetailsBackups);
                applyDetailsBackups.setId(RandomUtil.uuId());
                applyDetailsBackups.setItemsId(item.getId());
                applyDetailsBackups.setTableId(applyTableBackups.getId());
                return applyDetailsBackups;
            }).collect(Collectors.toList()));
        }
        //生成鉴定项数据
        List<CultivateIdentifyApplyDetails> applyDetailsList = CollectionUtil.newArrayList();
        CultivateIdentifyApply finalApply = apply;
        applyDetailsList.addAll(applyDetailsBackupsList.stream().map(item -> {
            CultivateIdentifyApplyDetails applyDetails = new CultivateIdentifyApplyDetails();
            applyDetails.setApplyId(finalApply.getId());
            applyDetails.setItemsId(item.getId());
            return applyDetails;
        }).collect(Collectors.toList()));
        //保存备份数据
        this.applyTableBackupsService.save(applyTableBackups);
        if (CollectionUtil.isNotEmpty(applyDetailsBackupsList)) {
            this.applyDetailsBackupsService.saveBatch(applyDetailsBackupsList);
        }
        //保存鉴定数据
        apply.setPostId(req.getPostId());
        this.save(apply);
        if (CollectionUtil.isNotEmpty(applyDetailsList)) {
            this.applyDetailsService.saveBatch(applyDetailsList);
        }
        return apply.getId();
    }

    private void deleteApplyDetails(String appId) {
        this.applyDetailsService.update(new LambdaUpdateWrapper<CultivateIdentifyApplyDetails>()
                .set(CultivateIdentifyApplyDetails::getDeleteMark, 1)
                .eq(CultivateIdentifyApplyDetails::getApplyId, appId)
                .eq(CultivateIdentifyApplyDetails::getDeleteMark, 0))
        ;
    }

    @Override
    public void turnOnVisibility(String id, String userId) {
        // 根据岗位id查询岗位学习绑定的实操鉴定主键
        log.info("turnOnVisibility={},{}", id, userId);
        String appply = baseMapper.querAppplyUserIds(id, userId);
        if (StringUtils.isEmpty(appply)) {
            return;
        }
        log.info("applyId=--->{}", appply);
        // 考试合格后设置为可见
        CultivateIdentifyApply identifyApply = new CultivateIdentifyApply();
        identifyApply.setId(appply);
        identifyApply.setIsVisible(0);
        identifyApply.setDeleteMark(0);
        baseMapper.updateById(identifyApply);
    }

    /**
     * 任务鉴定考试合格后打开可见性
     *
     * @param taskId 任务id
     * @param userId 用户id
     * @param status 合格- 3   不合格-4    5-优秀
     */
    @Override
    public void turnOnVisibilityWithTaskId(String taskId, String userId, Integer status) {

        LambdaQueryWrapper<CultivateIdentifyApply> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(CultivateIdentifyApply::getSourceId, taskId);
        queryWrapper.eq(CultivateIdentifyApply::getBeIdentifyUserId, userId);
        queryWrapper.eq(CultivateIdentifyApply::getDeleteMark, 0);
        CultivateIdentifyApply apply = baseMapper.selectOne(queryWrapper);
        LambdaQueryWrapper<FtbCultivateLearnTaskExam> learnTaskExamWrapper = Wrappers.lambdaQuery();
        learnTaskExamWrapper.eq(FtbCultivateLearnTaskExam::getTaskId, taskId);
        learnTaskExamWrapper.eq(FtbCultivateLearnTaskExam::getEnableMark, 0);

        List<FtbCultivateLearnTaskExam> learnTaskExams = ftbCultivateLearnTaskExamService.list(learnTaskExamWrapper);
        if (CollUtil.isEmpty(learnTaskExams)) {
            throw new RuntimeException("任务关联考试信息不存在");
        }
        FtbCultivateLearnTaskExam ftbCultivateLearnTaskExam = learnTaskExams.get(0);
        if (apply != null) {
            // 考试合格后设置为可见
            if (apply.getIsVisible() == 1) {
                CultivateIdentifyApply updateApply = new CultivateIdentifyApply();
                updateApply.setId(apply.getId());
                updateApply.setIsVisible(0);
                updateApply.setDeleteMark(0);
                baseMapper.updateById(updateApply);
            }
            LambdaQueryWrapper<FtbCultivateLearnTaskIdentification> learnTaskIdentificateionWrapper = Wrappers.lambdaQuery();
            learnTaskIdentificateionWrapper.eq(FtbCultivateLearnTaskIdentification::getTaskId, taskId);
            learnTaskIdentificateionWrapper.eq(FtbCultivateLearnTaskIdentification::getEnableMark, 0);

            List<FtbCultivateLearnTaskIdentification> learnTaskIdentification = ftbCultivateLearnTaskIdentificationService.list(learnTaskIdentificateionWrapper);
            if (CollUtil.isEmpty(learnTaskIdentification)) {
                throw new RuntimeException("任务关联鉴定信息不存在");
            }
            //这里考试必定合格
            FtbCultivateLearnTaskIdentification ftbCultivateLearnTaskIdentification = learnTaskIdentification.get(0);
            if (ftbCultivateLearnTaskIdentification.getIsPassComplete() == 1 && (Objects.equals(apply.getResult(), ApplyResultEnum.HG.getCode())
                    || Objects.equals(apply.getResult(), ApplyResultEnum.YX.getCode()))) {
                SpringContext.getApplicationContext()
                        .publishEvent(new JnpfApplicationEvent<>(
                                CertificateEventDTO.builder()
                                        .source(2)
                                        .taskId(apply.getSourceId())
                                        .issuanceType(2)
                                        .userId(apply.getBeIdentifyUserId()).build()));
                // 如果是任务鉴定进行完成时间更新
                ftbCultivateMyLearnTaskInfoService.updateUserFinishTime(apply.getSourceId(), apply.getBeIdentifyUserId(), 2);
            } else if (ftbCultivateLearnTaskIdentification.getIsPassComplete() == 0 && (Objects.equals(apply.getResult(), ApplyResultEnum.HG.getCode())
                    || Objects.equals(apply.getResult(), ApplyResultEnum.YX.getCode()) || Objects.equals(apply.getResult(), ApplyResultEnum.BHG.getCode()))) {
                SpringContext.getApplicationContext()
                        .publishEvent(new JnpfApplicationEvent<>(
                                CertificateEventDTO.builder()
                                        .source(2)
                                        .taskId(apply.getSourceId())
                                        .issuanceType(2)
                                        .userId(apply.getBeIdentifyUserId()).build()));
                // 如果是任务鉴定进行完成时间更新
                ftbCultivateMyLearnTaskInfoService.updateUserFinishTime(apply.getSourceId(), apply.getBeIdentifyUserId(), 2);
            }

        } else {
            //考试合格才能完成
            if (ftbCultivateLearnTaskExam.getIsPassComplete() == 1 && (status == 3 || status == 5)) {
                //如果没有配置鉴定，就置为已完成 并颁发证书
                ftbCultivateMyLearnTaskInfoService.updateUserFinishTime(taskId, userId, 1);
                // 颁发证书
                SpringContext.getApplicationContext()
                        .publishEvent(new JnpfApplicationEvent<>(
                                CertificateEventDTO.builder()
                                        .source(1)
                                        .taskId(taskId)
                                        .issuanceType(2)
                                        .userId(userId)
                                        .build()));
            } else if (ftbCultivateLearnTaskExam.getIsPassComplete() == 0 && (status == 3 || status == 4 || status == 5)) {
                //如果没有配置鉴定，就置为已完成 并颁发证书
                ftbCultivateMyLearnTaskInfoService.updateUserFinishTime(taskId, userId, 1);
                // 颁发证书
                SpringContext.getApplicationContext()
                        .publishEvent(new JnpfApplicationEvent<>(
                                CertificateEventDTO.builder()
                                        .source(1)
                                        .taskId(taskId)
                                        .issuanceType(2)
                                        .userId(userId)
                                        .build()));
            }
        }

    }

    @Override
    @DSTransactional
    public void applyDataReIdentify(IdentifyApplyReIdentifyDto req) {
        CultivateIdentifyApply apply = this.lambdaQuery()
                .eq(CultivateIdentifyApply::getId, req.getId())
                .eq(CultivateIdentifyApply::getDeleteMark, ConstantUtil.NUM_FALSE)
                .eq(CultivateIdentifyApply::getIsVisible, 0)
                .last("limit 1")
                .one();
        ServiceException.notNull(apply, "未查询到实操鉴定数据");
        if (!apply.getResult().equals(ApplyResultEnum.BHG.getCode())) {
            throw new ServiceException("鉴定不合格的数据才能重新鉴定");
        }
        CultivateIdentifyApplyTableBackups applyTableBackupsOld = this.applyTableBackupsService.getById(apply.getTableId());
        ServiceException.notNull(applyTableBackupsOld, "未查询到实操鉴定备份表记录");
        //重新鉴定需拉取最新的鉴定表数据
        CultivateIdentifyTable table = this.identifyTableService.getById(applyTableBackupsOld.getTableId());
        ServiceException.notNull(table, "未查询到实操鉴定表记录");
        //生成鉴定申请
        CultivateIdentifyApply reIdentifyApply = JsonUtil.getJsonToBean(apply, CultivateIdentifyApply.class);
        reIdentifyApply.setId(RandomUtil.uuId());
        reIdentifyApply.setPlanIdentifyTime(null);
        reIdentifyApply.setIdentifyTime(null);
        reIdentifyApply.setUseTime(null);
        reIdentifyApply.setStatus(ApplyStatusEnum.DJD.getCode());
        reIdentifyApply.setResult(null);
        reIdentifyApply.setIsReIdentify(ConstantUtil.NUM_TRUE);
        if (!apply.getSource().equals(ApplySourceEnum.SDFQ.getCode())) {
            apply.setSource(null);
        }
        apply.setIsInitiate(ConstantUtil.NUM_TRUE);
        StringBuilder reIdentifyId = new StringBuilder(StringUtil.isNotEmpty(apply.getReIdentifyId()) ? apply.getReIdentifyId() : "");
        reIdentifyApply.setReIdentifyId(StringUtil.isNotEmpty(apply.getReIdentifyId()) ?
                reIdentifyId.append(",").append(apply.getId()).toString() :
                reIdentifyId.append(apply.getId()).toString());

        //生成鉴定表、鉴定项备份数据
        CultivateIdentifyApplyTableBackups applyTableBackups = new CultivateIdentifyApplyTableBackups();
        BeanUtils.copyProperties(table, applyTableBackups);
        applyTableBackups.setId(RandomUtil.uuId());
        applyTableBackups.setTableId(table.getId());
        reIdentifyApply.setTableId(applyTableBackups.getId());
        List<CultivateIdentifyItems> identifyItemsList = this.identifyItemsService.lambdaQuery()
                .eq(CultivateIdentifyItems::getTableId, table.getId())
                .eq(CultivateIdentifyItems::getDeleteMark, ConstantUtil.NUM_FALSE)
                .list();
        ServiceException.notNull(identifyItemsList, "未查询到鉴定项数据");
        List<CultivateIdentifyApplyDetailsBackups> applyDetailsBackupsList = CollectionUtil.newArrayList();
        if (CollectionUtil.isNotEmpty(identifyItemsList)) {
            applyDetailsBackupsList.addAll(identifyItemsList.stream().map(item -> {
                CultivateIdentifyApplyDetailsBackups applyDetailsBackups = new CultivateIdentifyApplyDetailsBackups();
                BeanUtils.copyProperties(item, applyDetailsBackups);
                applyDetailsBackups.setId(RandomUtil.uuId());
                applyDetailsBackups.setItemsId(item.getId());
                applyDetailsBackups.setTableId(applyTableBackups.getId());
                return applyDetailsBackups;
            }).collect(Collectors.toList()));
        }
        //生成鉴定项数据
        List<CultivateIdentifyApplyDetails> reIdentifyApplyDetailsList = CollectionUtil.newArrayList();
        reIdentifyApplyDetailsList.addAll(applyDetailsBackupsList.stream().map(item -> {
            CultivateIdentifyApplyDetails applyDetails = new CultivateIdentifyApplyDetails();
            applyDetails.setApplyId(reIdentifyApply.getId());
            applyDetails.setItemsId(item.getId());
            return applyDetails;
        }).collect(Collectors.toList()));

        //保存备份数据
        this.applyTableBackupsService.save(applyTableBackups);
        if (CollectionUtil.isNotEmpty(applyDetailsBackupsList)) {
            this.applyDetailsBackupsService.saveBatch(applyDetailsBackupsList);
        }
        //保存鉴定数据
        this.updateById(apply);
        this.save(reIdentifyApply);
        if (CollectionUtil.isNotEmpty(reIdentifyApplyDetailsList)) {
            this.applyDetailsService.saveBatch(reIdentifyApplyDetailsList);
        }
    }

    @Override
    public List<IdentifyApplyListVo> applyDataDeleteCheck(IdentifyTableInfoDto req) {
        List<IdentifyApplyListVo> applyListVoList = CollectionUtil.newArrayList();
        CultivateIdentifyApply apply = this.baseMapper.selectById(req.getId());
        ServiceException.notNull(apply, "未查询到实操鉴定记录");
        //判断是否重新鉴定
        if (apply.getIsReIdentify().equals(ConstantUtil.NUM_TRUE)) {
            //查询重新鉴定的源数据
            List<String> ids = Splitter.on(",").splitToList(apply.getReIdentifyId());
            List<IdentifyApplyListDbVo> listDbVoList = this.baseMapper.getList(ids);
            if (CollectionUtil.isNotEmpty(listDbVoList)) {
                //查询到人员名称-服务调用
                List<String> userIdList = new ArrayList<>();
                for (IdentifyApplyListDbVo identifyApplyListDbVo : listDbVoList) {
                    userIdList.add(identifyApplyListDbVo.getBeIdentifyUserId());
                    if (StringUtil.isNotEmpty(identifyApplyListDbVo.getIdentifyUserId())) {
                        String[] split = identifyApplyListDbVo.getIdentifyUserId().split(",");
                        userIdList.addAll(Arrays.asList(split));
                    }
                }
                Map<String, UserBoundVO> userMap = userApiV2Util.getUserPrimaryBoundBatch(userIdList, null);
                listDbVoList.forEach(item -> {
                    IdentifyApplyListVo applyListVo = new IdentifyApplyListVo();
                    BeanUtils.copyProperties(item, applyListVo);
                    applyListVo.setUserTime(item.getUseTime());
                    //被鉴定用户信息
                    IdentifyUserOrgInfoVo beIdentifyUserInfo = new IdentifyUserOrgInfoVo();
                    UserBoundVO beUserInfoVo = userMap.get(item.getBeIdentifyUserId());
                    // 获取用户头像
                    if (Objects.nonNull(beUserInfoVo) && !StringUtil.isEmpty(beUserInfoVo.getHeadIcon())) {
                        beIdentifyUserInfo.setUserHeadIcon(UploaderUtil.uploaderImg(beUserInfoVo.getHeadIcon()));
                    }
                    beIdentifyUserInfo.setUserId(item.getBeIdentifyUserId());
                    beIdentifyUserInfo.setUserName(Objects.isNull(userMap.get(item.getBeIdentifyUserId())) ?
                            "未查询到用户" : userMap.get(item.getBeIdentifyUserId()).getUserName());
                    //被鉴定人职等的组织信息
                    List<UserOrgInfoAll1Vo> beOrgInfoAll1VoList = JSON.parseArray(item.getBeOfficialRankInfoJson(), UserOrgInfoAll1Vo.class);
                    if (CollectionUtil.isNotEmpty(beOrgInfoAll1VoList)) {
                        beIdentifyUserInfo.setUserOrgInfoPushVoList(beOrgInfoAll1VoList.stream().map(orgInfoAll1Vo -> {
                            UserOrgInfoVo orgInfoVo = new UserOrgInfoVo();
                            BeanUtils.copyProperties(orgInfoAll1Vo, orgInfoVo);
                            return orgInfoVo;
                        }).collect(Collectors.toList()));
                    }

                    //鉴定用户信息
                    List<IdentifyUserOrgInfoVo> identifyUserInfos = new ArrayList<>();
                    if (StringUtil.isNotEmpty(item.getIdentifyUserId())) {
                        for (String templateId : item.getIdentifyUserId().split(",")) {
                            IdentifyUserOrgInfoVo identifyUserInfo = new IdentifyUserOrgInfoVo();
                            UserBoundVO userInfoVo = userMap.get(templateId);
                            // 获取用户头像
                            if (Objects.nonNull(userInfoVo) && !StringUtil.isEmpty(userInfoVo.getHeadIcon())) {
                                identifyUserInfo.setUserHeadIcon(UploaderUtil.uploaderImg(userInfoVo.getHeadIcon()));
                            }
                            identifyUserInfo.setUserId(item.getIdentifyUserId());
                            identifyUserInfo.setUserName(Objects.isNull(userMap.get(item.getIdentifyUserId())) ?
                                    "未查询到用户" : userMap.get(item.getIdentifyUserId()).getUserName());
                            //鉴定人职等的组织信息
                            List<UserOrgInfoAll1Vo> orgInfoAll1VoList = JSON.parseArray(item.getOfficialRankInfoJson(), UserOrgInfoAll1Vo.class);
                            if (CollectionUtil.isNotEmpty(orgInfoAll1VoList)) {
                                identifyUserInfo.setUserOrgInfoPushVoList(orgInfoAll1VoList.stream().map(orgInfoAll1Vo -> {
                                    UserOrgInfoVo orgInfoVo = new UserOrgInfoVo();
                                    BeanUtils.copyProperties(orgInfoAll1Vo, orgInfoVo);
                                    return orgInfoVo;
                                }).collect(Collectors.toList()));
                            }
                            identifyUserInfos.add(identifyUserInfo);
                        }
                    }
                    applyListVo.setBeIdentifyUserInfo(beIdentifyUserInfo);
                    applyListVo.setIdentifyUserInfo(identifyUserInfos);
                    applyListVoList.add(applyListVo);
                });
            }
        }
        return applyListVoList;
    }

    @Override
    @Transactional
    public void applyDataDelete(IdentifyTableInfoDto req) {
        Set<String> deleteIds = new LinkedHashSet<>();
        List<CultivateIdentifyApply> deleteApplyList = CollectionUtil.newArrayList();
        CultivateIdentifyApply apply = this.baseMapper.selectById(req.getId());
        ServiceException.notNull(apply, "未查询到实操鉴定记录");
        deleteIds.add(apply.getId());
        apply.setDeleteMark(ConstantUtil.NUM_TRUE);
        deleteApplyList.add(apply);
        //判断是否重新鉴定
        if (apply.getIsReIdentify().equals(ConstantUtil.NUM_TRUE)) {
            //查询重新鉴定的源数据
            List<String> ids = Splitter.on(",").splitToList(apply.getReIdentifyId());
            deleteIds.addAll(ids);
            LambdaQueryWrapper<CultivateIdentifyApply> applyLambdaQueryWrapper = new LambdaQueryWrapper<CultivateIdentifyApply>()
                    .in(CultivateIdentifyApply::getId, ids)
                    .eq(CultivateIdentifyApply::getIsVisible, 0)
                    .eq(CultivateIdentifyApply::getDeleteMark, ConstantUtil.NUM_FALSE);
            List<CultivateIdentifyApply> applyList = this.list(applyLambdaQueryWrapper);
            if (CollectionUtil.isNotEmpty(applyList)) {
                applyList.forEach(item -> {
                    item.setDeleteMark(ConstantUtil.NUM_TRUE);
                });
                deleteApplyList.addAll(applyList);
            }
        }
        //删除实操鉴定申请详情记录
        LambdaQueryWrapper<CultivateIdentifyApplyDetails> applyDetailsLambdaQueryWrapper = new LambdaQueryWrapper<CultivateIdentifyApplyDetails>()
                .in(CultivateIdentifyApplyDetails::getApplyId, deleteIds)
                .eq(CultivateIdentifyApplyDetails::getDeleteMark, ConstantUtil.NUM_FALSE);
        List<CultivateIdentifyApplyDetails> applyDetailsList = this.applyDetailsService.list(applyDetailsLambdaQueryWrapper);
        if (CollectionUtil.isNotEmpty(applyDetailsList)) {
            applyDetailsList.forEach(item -> {
                item.setDeleteMark(ConstantUtil.NUM_TRUE);
            });
        }
        //删除岗位学习鉴定申请记录id集合(调用岗位学习的方法)
        Set<String> sourceIds = new LinkedHashSet<>();
        //删除实操鉴定数据
        if (CollectionUtil.isNotEmpty(deleteApplyList)) {
            sourceIds.addAll(deleteApplyList.stream().map(CultivateIdentifyApply::getSourceId).collect(Collectors.toList()));
            this.updateBatchById(deleteApplyList);
        }
        //删除实操鉴定详情
        if (CollectionUtil.isNotEmpty(applyDetailsList)) {
            this.applyDetailsService.updateBatchById(applyDetailsList);
        }
        if (CollectionUtil.isNotEmpty(sourceIds)) {
            //删除岗位学习鉴定申请记录
            this.cultivateIdentifyService.batchDeleteCorrelationRecord(new ArrayList<>(sourceIds));
        }
    }

    @Override
    public Integer getPageAppListCount(IdentifyApplyListAppDto req) {

        String userId = userProvider.get().getUserId();
        return this.baseMapper.getPageAppListCount(req, userId);

    }

    @Override
    public PageInfo<IdentifyApplyListAppVo> getPageAppList(IdentifyApplyListAppDto req) {
        com.github.pagehelper.Page<Object> objects = PageHelper.startPage(Math.toIntExact(req.getCurrentPage()), Math.toIntExact(req.getPageSize()));
        String userId = userProvider.get().getUserId();
        List<String> powerUserIds = new ArrayList<>();
        if (req.getStatus() != null && req.getStatus() >= 0) {
            InnerPowerUserVO innerPowerUserVO = userApiV2Util.getLoginManagerUserIdsForEncode();
            if (innerPowerUserVO.getCode().equals(1)) {
                powerUserIds = innerPowerUserVO.getUserIds();
            } else if (innerPowerUserVO.getCode().equals(2)) {
                powerUserIds.add("-1");
            }
        }
        List<IdentifyApplyListAppDbVo> applyListAppDbVoList = this.baseMapper.getPageAppList(req, userId, powerUserIds);
        if (CollUtil.isEmpty(applyListAppDbVoList)) {
            return new PageInfo<>();
        }
        List<IdentifyApplyListAppVo> applyListVoList = CollectionUtil.newArrayList();

        List<String> refPostId = applyListAppDbVoList.stream().map(IdentifyApplyListAppDbVo::getSourceId).collect(Collectors.toList());
        if (CollectionUtil.isEmpty(refPostId)) {
            refPostId.add("-1");
        }

        QueryWrapper<FtbCultivatePosition> positionQueryWrapper = new QueryWrapper<>();
        positionQueryWrapper.lambda()
                .in(FtbCultivatePosition::getId, refPostId);
        List<FtbCultivatePosition> positionList = ftbCultivatePositionMapper.selectList(positionQueryWrapper);
        Map<String, FtbCultivatePosition> refPostMap = positionList.stream().collect(Collectors.toMap(FtbCultivatePosition::getId, post -> post));

        if (CollectionUtil.isNotEmpty(applyListAppDbVoList)) {
            List<UserPageListVO> subordinateUserInfoVOS = userApiV2Util.listUnderlingTargetUser(userId, null);
            List<String> userSubordin = new ArrayList<>();
            if (CollectionUtil.isNotEmpty(subordinateUserInfoVOS)) {
                userSubordin = subordinateUserInfoVOS.stream().map(UserPageListVO::getId).collect(Collectors.toList());
            }
            //查询到人员名称-服务调用
            List<String> userIdList = new ArrayList<>();
            for (IdentifyApplyListAppDbVo identifyApplyListAppDbVo : applyListAppDbVoList) {
                userIdList.add(identifyApplyListAppDbVo.getBeIdentifyUserId());
                if (StringUtil.isNotEmpty(identifyApplyListAppDbVo.getIdentifyUserId())) {
                    String[] split = identifyApplyListAppDbVo.getIdentifyUserId().split(",");
                    userIdList.addAll(Arrays.asList(split));
                }
            }
            Map<String, UserBoundVO> userMap = userApiV2Util.getUserPrimaryBoundBatch(userIdList, null);
            List<String> finalUserSubordin = userSubordin;
            applyListVoList.addAll(applyListAppDbVoList.stream().map(item -> {
                IdentifyApplyListAppVo applyListAppVo = new IdentifyApplyListAppVo();
                BeanUtils.copyProperties(item, applyListAppVo);

                //被鉴定用户信息
                IdentifyUserOrgInfoVo beIdentifyUserInfo = new IdentifyUserOrgInfoVo();

                String beIdentifyUserId = item.getBeIdentifyUserId();
                UserBoundVO beUserInfoVo = userMap.get(beIdentifyUserId);
                if (finalUserSubordin.contains(beIdentifyUserId)) {
                    beIdentifyUserInfo.setSubordinateMark("1");
                } else {
                    beIdentifyUserInfo.setSubordinateMark("0");
                }
                // 获取用户头像
                if (Objects.nonNull(beUserInfoVo) && !StringUtil.isEmpty(beUserInfoVo.getHeadIcon())) {
                    beIdentifyUserInfo.setUserHeadIcon(UploaderUtil.uploaderImg(beUserInfoVo.getHeadIcon()));
                }
                beIdentifyUserInfo.setUserId(item.getBeIdentifyUserId());
                beIdentifyUserInfo.setUserName(Objects.isNull(userMap.get(item.getBeIdentifyUserId())) ?
                        "未查询到用户" : userMap.get(item.getBeIdentifyUserId()).getUserName());
                //被鉴定人职等的组织信息
                List<UserOrgInfoAll1Vo> beOrgInfoAll1VoList = JSON.parseArray(item.getBeOfficialRankInfoJson(), UserOrgInfoAll1Vo.class);
                if (CollectionUtil.isNotEmpty(beOrgInfoAll1VoList)) {
                    beIdentifyUserInfo.setUserOrgInfoPushVoList(beOrgInfoAll1VoList.stream().map(orgInfoAll1Vo -> {
                        UserOrgInfoVo orgInfoVo = new UserOrgInfoVo();
                        BeanUtils.copyProperties(orgInfoAll1Vo, orgInfoVo);
                        return orgInfoVo;
                    }).collect(Collectors.toList()));
                    FtbCultivatePosition ftbCultivatePosition = refPostMap.get(item.getSourceId());
                    if (ObjectUtil.isNotNull(ftbCultivatePosition)) {
                        String postId = ftbCultivatePosition.getPostId();
                        List<UserOrgInfoAll1Vo> postList = beOrgInfoAll1VoList.stream().filter(userOrg -> {
                            return userOrg.getUserPostCode().equals(postId);
                        }).collect(Collectors.toList());
                        beIdentifyUserInfo.setTriggerPostName(CollectionUtil.isNotEmpty(postList) ? postList.get(0).getUserPostName() : null);
                    }

                }
                //鉴定用户信息
                IdentifyUserOrgInfoVo identifyUserInfo = new IdentifyUserOrgInfoVo();
                UserBoundVO userInfoVo = userMap.get(item.getIdentifyUserId());
                // 获取用户头像
                if (Objects.nonNull(userInfoVo) && !StringUtil.isEmpty(userInfoVo.getHeadIcon())) {
                    identifyUserInfo.setUserHeadIcon(UploaderUtil.uploaderImg(userInfoVo.getHeadIcon()));
                }
                identifyUserInfo.setUserId(item.getIdentifyUserId());
                identifyUserInfo.setUserName(Objects.isNull(userMap.get(item.getIdentifyUserId())) ?
                        "未查询到用户" : userMap.get(item.getIdentifyUserId()).getUserName());
                //鉴定人职等的组织信息
                List<UserOrgInfoAll1Vo> orgInfoAll1VoList = JSON.parseArray(item.getOfficialRankInfoJson(), UserOrgInfoAll1Vo.class);
                if (CollectionUtil.isNotEmpty(orgInfoAll1VoList)) {
                    identifyUserInfo.setUserOrgInfoPushVoList(orgInfoAll1VoList.stream().map(orgInfoAll1Vo -> {
                        UserOrgInfoVo orgInfoVo = new UserOrgInfoVo();
                        BeanUtils.copyProperties(orgInfoAll1Vo, orgInfoVo);
                        return orgInfoVo;
                    }).collect(Collectors.toList()));
                }
                applyListAppVo.setBeIdentifyUserInfo(beIdentifyUserInfo);
                applyListAppVo.setIdentifyUserInfo(identifyUserInfo);
                return applyListAppVo;
            }).collect(Collectors.toList()));
        }
        //怎么获取总条数

        PageInfo<IdentifyApplyListAppVo> identifyApplyListAppVoPageInfo = new PageInfo<>(applyListVoList);
        identifyApplyListAppVoPageInfo.setTotal(objects.getTotal());
        identifyApplyListAppVoPageInfo.setPageNum(objects.getPageNum());
        identifyApplyListAppVoPageInfo.setPageSize(objects.getPageSize());
        return identifyApplyListAppVoPageInfo;
    }

    @Override
    @Transactional
    public void deleteIds(IdentifyApplyDeleteAppDto req) {
        List<CultivateIdentifyApply> deleteApplyList = CollectionUtil.newArrayList();
        LambdaQueryWrapper<CultivateIdentifyApply> applyLambdaQueryWrapper = new LambdaQueryWrapper<CultivateIdentifyApply>()
                .in(CultivateIdentifyApply::getId, req.getIds())
                .eq(CultivateIdentifyApply::getIsVisible, 0)
                .eq(CultivateIdentifyApply::getDeleteMark, ConstantUtil.NUM_FALSE);
        List<CultivateIdentifyApply> applyList = this.list(applyLambdaQueryWrapper);
        ServiceException.notNull(applyList, "未查询到实操鉴定记录");
        Set<String> reDeleteIds = new LinkedHashSet<>();
        if (CollectionUtil.isNotEmpty(applyList)) {
            applyList.forEach(item -> {
                if (item.getIsReIdentify().equals(ConstantUtil.NUM_TRUE)) {
                    //查询重新鉴定的源数据
                    List<String> ids = Splitter.on(",").splitToList(item.getReIdentifyId());
                    reDeleteIds.addAll(ids);
                }
                item.setDeleteMark(ConstantUtil.NUM_TRUE);
            });
            deleteApplyList.addAll(applyList);
        }
        if (CollectionUtil.isNotEmpty(reDeleteIds)) {
            LambdaQueryWrapper<CultivateIdentifyApply> reApplyLambdaQueryWrapper = new LambdaQueryWrapper<CultivateIdentifyApply>()
                    .in(CultivateIdentifyApply::getId, reDeleteIds)
                    .eq(CultivateIdentifyApply::getDeleteMark, ConstantUtil.NUM_FALSE)
                    .eq(CultivateIdentifyApply::getIsVisible, 0);
            List<CultivateIdentifyApply> reApplyList = this.list(reApplyLambdaQueryWrapper);
            if (CollectionUtil.isNotEmpty(reApplyList)) {
                reApplyList.forEach(item -> {
                    item.setDeleteMark(ConstantUtil.NUM_TRUE);
                });
                deleteApplyList.addAll(reApplyList);
            }
        }
        //删除实操鉴定申请详情记录
        Set<String> deleteIds = new LinkedHashSet<>(CollectionUtil.isNotEmpty(deleteApplyList) ? deleteApplyList.stream().map(CultivateIdentifyApply::getId).collect(Collectors.toList()) : CollectionUtil.newArrayList());
        LambdaQueryWrapper<CultivateIdentifyApplyDetails> applyDetailsLambdaQueryWrapper = new LambdaQueryWrapper<CultivateIdentifyApplyDetails>()
                .in(CultivateIdentifyApplyDetails::getApplyId, deleteIds)
                .eq(CultivateIdentifyApplyDetails::getDeleteMark, ConstantUtil.NUM_FALSE);
        List<CultivateIdentifyApplyDetails> applyDetailsList = this.applyDetailsService.list(applyDetailsLambdaQueryWrapper);
        if (CollectionUtil.isNotEmpty(applyDetailsList)) {
            applyDetailsList.forEach(item -> {
                item.setDeleteMark(ConstantUtil.NUM_TRUE);
            });
        }
        //删除岗位学习鉴定申请记录id集合(调用岗位学习的方法)
        Set<String> sourceIds = new LinkedHashSet<>();
        //删除实操鉴定数据
        if (CollectionUtil.isNotEmpty(deleteApplyList)) {
            sourceIds.addAll(deleteApplyList.stream().map(CultivateIdentifyApply::getSourceId).collect(Collectors.toList()));
            this.updateBatchById(deleteApplyList);
        }
        //删除实操鉴定详情
        if (CollectionUtil.isNotEmpty(applyDetailsList)) {
            this.applyDetailsService.updateBatchById(applyDetailsList);
        }
        if (CollectionUtil.isNotEmpty(sourceIds)) {
            //删除岗位学习鉴定申请记录
            this.cultivateIdentifyService.batchDeleteCorrelationRecord(new ArrayList<>(sourceIds));
        }
    }

    @Override
    public IdentifyInfoAppVo getIdentifyApplyInfoApp(IdentifyTableInfoDto req) {
        CultivateIdentifyApply apply = this.baseMapper.selectById(req.getId());
        ServiceException.notNull(apply, "未查询到实操鉴定记录");
        CultivateIdentifyApplyTableBackups table = this.applyTableBackupsService.getById(apply.getTableId());
        ServiceException.notNull(table, "未查询到实操鉴定表记录");
        LambdaQueryWrapper<CultivateIdentifyApplyDetailsBackups> itemsLambdaQueryWrapper = new LambdaQueryWrapper<CultivateIdentifyApplyDetailsBackups>()
                .eq(CultivateIdentifyApplyDetailsBackups::getTableId, table.getId());
        List<CultivateIdentifyApplyDetailsBackups> identifyItemsList = this.applyDetailsBackupsService.list(itemsLambdaQueryWrapper);
        ServiceException.notNull(identifyItemsList, "未查询到实操鉴定项记录");
        IdentifyInfoAppVo infoAppVo = new IdentifyInfoAppVo();
        infoAppVo.setId(apply.getId());
        infoAppVo.setTableName(table.getName());
        infoAppVo.setIdentifyItemSize(identifyItemsList.size());
        BigDecimal sum = BigDecimal.ZERO;
        for (CultivateIdentifyApplyDetailsBackups identifyItems : identifyItemsList) {
            sum = sum.add(identifyItems.getScore());
        }
        infoAppVo.setTotalScore(sum);
        //计算合格分数
        BigDecimal qualifiedScore;
        if (table.getPassType().equals(ApplyTypeEnum.GDF.getCode())) {
            qualifiedScore = table.getPassScore();
        } else {
            qualifiedScore = sum.multiply(table.getPassScore().divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP));
        }
        //计算优秀分数
        BigDecimal excellentScore;
        if (table.getExcellentType().equals(ApplyTypeEnum.GDF.getCode())) {
            excellentScore = table.getExcellentScore();
        } else {
            excellentScore = sum.multiply(table.getExcellentScore().divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP));
        }
        infoAppVo.setPassScore(qualifiedScore);
        infoAppVo.setExcellentScore(excellentScore);
        infoAppVo.setPlanIdentifyTime(Objects.isNull(apply.getPlanIdentifyTime()) ? null : apply.getPlanIdentifyTime());
        infoAppVo.setSource(apply.getSource());
        infoAppVo.setRuleDesc(table.getRuleDesc());
        infoAppVo.setStatus(apply.getStatus());
        Map<String, UserBoundVO> userMap = userApiV2Util.getUserPrimaryBoundBatch(Collections.singletonList(apply.getBeIdentifyUserId()), null);
        //被鉴定用户信息
        IdentifyUserOrgInfoVo beIdentifyUserInfo = new IdentifyUserOrgInfoVo();
        UserBoundVO beUserInfoVo = userMap.get(apply.getBeIdentifyUserId());
        // 获取用户头像
        if (Objects.nonNull(beUserInfoVo) && !StringUtil.isEmpty(beUserInfoVo.getHeadIcon())) {
            beIdentifyUserInfo.setUserHeadIcon(UploaderUtil.uploaderImg(beUserInfoVo.getHeadIcon()));
        }
        beIdentifyUserInfo.setUserId(apply.getBeIdentifyUserId());
        beIdentifyUserInfo.setUserName(Objects.isNull(userMap.get(apply.getBeIdentifyUserId())) ?
                "未查询到用户" : userMap.get(apply.getBeIdentifyUserId()).getUserName());
        //被鉴定人职等的组织信息
        List<UserOrgInfoAll1Vo> beOrgInfoAll1VoList = JSON.parseArray(apply.getBeOfficialRankInfoJson(), UserOrgInfoAll1Vo.class);
        if (CollectionUtil.isNotEmpty(beOrgInfoAll1VoList)) {
            beIdentifyUserInfo.setUserOrgInfoPushVoList(beOrgInfoAll1VoList.stream().map(orgInfoAll1Vo -> {
                UserOrgInfoVo orgInfoVo = new UserOrgInfoVo();
                BeanUtils.copyProperties(orgInfoAll1Vo, orgInfoVo);
                return orgInfoVo;
            }).collect(Collectors.toList()));
        }

        infoAppVo.setBeIdentifyUserInfo(beIdentifyUserInfo);
        // 查询当前申请时上传的文件信息
        LambdaQueryWrapper<FtbCultivateFile> wrapperFile = Wrappers.lambdaQuery();
        wrapperFile.eq(FtbCultivateFile::getBusinessId, apply.getId());
        List<FtbCultivateFile> fileLists = ftbCultivateFileService.list(wrapperFile);
        LambdaQueryWrapper<FtbCultivateFile> wrapperFile2 = Wrappers.lambdaQuery();
        wrapperFile2.eq(FtbCultivateFile::getBusinessId, apply.getId() + apply.getBeIdentifyUserId());
        List<FtbCultivateFile> fileLists2 = ftbCultivateFileService.list(wrapperFile2);
        List<FtbCultivateOfflineFileVO> fileVOS = fileLists.stream()
                .map(FtbCultivateOfflineFileVO::convertFtbCultivateOfflineFileVO).collect(Collectors.toList());
        List<FtbCultivateOfflineFileVO> fileVOS2 = fileLists2.stream()
                .map(FtbCultivateOfflineFileVO::convertFtbCultivateOfflineFileVO).collect(Collectors.toList());
        List<FtbCultivateOfflineFileVO> file = new ArrayList<>();
        file.addAll(fileVOS2);
        file.addAll(fileVOS);
        infoAppVo.setFiles(file);
        return infoAppVo;
    }

    @Override
    public IdentifyItemsInfoAppVo getApplyIdentifyItemsInfoApp(IdentifyTableInfoDto req) {
        CultivateIdentifyApply apply = this.baseMapper.selectById(req.getId());
        ServiceException.notNull(apply, "未查询到实操鉴定记录");
        IdentifyItemsInfoAppVo appVo = new IdentifyItemsInfoAppVo();
        appVo.setId(apply.getId());
        LambdaQueryWrapper<CultivateIdentifyApplyDetails> applyDetailsLambdaQueryWrapper = new LambdaQueryWrapper<CultivateIdentifyApplyDetails>()
                .eq(CultivateIdentifyApplyDetails::getApplyId, apply.getId())
                .eq(CultivateIdentifyApplyDetails::getDeleteMark, ConstantUtil.NUM_FALSE);
        List<CultivateIdentifyApplyDetails> applyDetailsList = this.applyDetailsService.list(applyDetailsLambdaQueryWrapper);
        if (CollectionUtil.isNotEmpty(applyDetailsList)) {
            List<String> itemsIds = applyDetailsList.stream().map(CultivateIdentifyApplyDetails::getItemsId).collect(Collectors.toList());
            LambdaQueryWrapper<CultivateIdentifyApplyDetailsBackups> identifyItemsLambdaQueryWrapper = new LambdaQueryWrapper<CultivateIdentifyApplyDetailsBackups>()
                    .in(CultivateIdentifyApplyDetailsBackups::getId, itemsIds);
            List<CultivateIdentifyApplyDetailsBackups> itemsList = this.applyDetailsBackupsService.list(identifyItemsLambdaQueryWrapper);
            Map<String, CultivateIdentifyApplyDetailsBackups> fileMap = itemsList.stream().collect(Collectors.toMap(CultivateIdentifyApplyDetailsBackups::getId, a -> a, (k1, k2) -> k1));
            appVo.setIdentifyItemList(applyDetailsList.stream().map(item -> {
                IdentifyItemsInfoVo infoVo = new IdentifyItemsInfoVo();
                CultivateIdentifyApplyDetailsBackups identifyItems = fileMap.get(item.getItemsId());
                infoVo.setId(item.getId());
                infoVo.setName(identifyItems.getName());
                infoVo.setScore(identifyItems.getScore());
                return infoVo;
            }).collect(Collectors.toList()));
        }
        return appVo;
    }

    @Override
    @Transactional
    public void applyDataSubmit(IdentifyApplySubmitDto req) {
        String identifyUserId = UserProvider.getLoginUserId();
        CultivateIdentifyApply apply = this.baseMapper.selectById(req.getId());
        ServiceException.notNull(apply, "未查询到实操鉴定记录");
        if (identifyUserId.equals(apply.getBeIdentifyUserId())) {
            throw new ServiceException("对不起,不能够自己给自己鉴定");
        }
        // 重新鉴定先清除之前上传的附件
        if (Objects.equals(apply.getStatus(), ApplyStatusEnum.YJD.getCode())) {
            LambdaUpdateWrapper<FtbCultivateFile> update = Wrappers.lambdaUpdate();
            update.eq(FtbCultivateFile::getBusinessId, apply.getId());
            update.eq(FtbCultivateFile::getType, FileEventDTO.FileType.PRACTICAL_APPRAISAL.getType());
            ftbCultivateFileService.remove(update);
        }
        CultivateIdentifyApplyTableBackups table = this.applyTableBackupsService.getById(apply.getTableId());
        ServiceException.notNull(table, "未查询到实操鉴定表记录");
        LambdaQueryWrapper<CultivateIdentifyApplyDetailsBackups> itemsLambdaQueryWrapper = new LambdaQueryWrapper<CultivateIdentifyApplyDetailsBackups>()
                .eq(CultivateIdentifyApplyDetailsBackups::getTableId, table.getId())
                .eq(CultivateIdentifyApplyDetailsBackups::getDeleteMark, ConstantUtil.NUM_FALSE);
        List<CultivateIdentifyApplyDetailsBackups> identifyItemsList = this.applyDetailsBackupsService.list(itemsLambdaQueryWrapper);
        ServiceException.notNull(identifyItemsList, "未查询到实操鉴定项记录");
        List<String> ids = req.getIdentifyItemList().stream().map(IdentifyApplyItemsSubmitDto::getId).collect(Collectors.toList());
        Map<String, IdentifyApplyItemsSubmitDto> fileMap = req.getIdentifyItemList().stream().collect(Collectors.toMap(IdentifyApplyItemsSubmitDto::getId, a -> a, (k1, k2) -> k1));
        LambdaQueryWrapper<CultivateIdentifyApplyDetails> applyDetailsLambdaQueryWrapper = new LambdaQueryWrapper<CultivateIdentifyApplyDetails>()
                .in(CultivateIdentifyApplyDetails::getId, ids)
                .eq(CultivateIdentifyApplyDetails::getDeleteMark, ConstantUtil.NUM_FALSE);
        List<CultivateIdentifyApplyDetails> applyDetailsList = this.applyDetailsService.list(applyDetailsLambdaQueryWrapper);
        if (CollectionUtil.isNotEmpty(applyDetailsList)) {
            applyDetailsList.forEach(item -> {
                item.setScore(fileMap.get(item.getId()).getIdentifyScore());
            });
            this.applyDetailsService.updateBatchById(applyDetailsList);
        }
        //变更为已鉴定
        apply.setStatus(ApplyStatusEnum.YJD.getCode());
        apply.setIdentifyTime(new Date());
        apply.setUseTime(req.getUseTime());
        // 变更鉴定人为当前登录用户
        List<UserOrgInfoAll1Vo> identifyUserInfoJsonList = CollectionUtil.newArrayList();
        Map<String, List<UserBoundVO>> userOrgMap = userApiV2Util.getUserPrimaryBoundBatchCompatible(List.of(identifyUserId), null);
        List<UserBoundVO> identifyUserInfoList = userOrgMap.get(identifyUserId);
        ServiceException.notNull(!identifyUserInfoList.isEmpty(), "获取鉴定人组织信息失败，鉴定人id:！" + identifyUserId);
        identifyUserInfoJsonList.addAll(identifyUserInfoList.stream().map(item -> {
            UserOrgInfoAll1Vo all1Vo = new UserOrgInfoAll1Vo();
            all1Vo.setUserOrgName(item.getOrganizeName());
            all1Vo.setUserOrgCode(item.getOrganizeEnCode());
            all1Vo.setUserPostCode(item.getPositionEnCode());
            all1Vo.setUserPostName(item.getPositionName());
            all1Vo.setUserOfficialRankCode(item.getGradeId());
            all1Vo.setUserOfficialRankName(item.getGradeName());
            return all1Vo;
        }).collect(Collectors.toList()));
        apply.setIdentifyUserId(identifyUserId);
        apply.setOfficialRankInfoJson(JSON.toJSONString(identifyUserInfoJsonList));
        apply.setIdentifyOrgList(Joiner.on(",").join(identifyUserInfoList.stream().map(
                UserBoundVO::getOrganizeId).distinct().collect(Collectors.toList())));
        /*设置鉴定结果*/
        //鉴定总得分
        BigDecimal identifyTotalScore = BigDecimal.ZERO;
        for (CultivateIdentifyApplyDetailsBackups identifyItems : identifyItemsList) {
            identifyTotalScore = identifyTotalScore.add(identifyItems.getScore());
        }
        BigDecimal totalScore = BigDecimal.ZERO;
        for (IdentifyApplyItemsSubmitDto identifyItems : req.getIdentifyItemList()) {
            totalScore = totalScore.add(identifyItems.getIdentifyScore());
        }
        //计算合格分数
        BigDecimal qualifiedScore;
        if (table.getPassType().equals(ApplyTypeEnum.GDF.getCode())) {
            qualifiedScore = table.getPassScore();
        } else {
            qualifiedScore = identifyTotalScore.multiply(table.getPassScore().divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP));
        }
        //计算优秀分数
        BigDecimal excellentScore;
        if (table.getExcellentType().equals(ApplyTypeEnum.GDF.getCode())) {
            excellentScore = table.getExcellentScore();
        } else {
            excellentScore = identifyTotalScore.multiply(table.getExcellentScore().divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP));
        }
        if (totalScore.compareTo(qualifiedScore) < 0) {
            apply.setResult(ApplyResultEnum.BHG.getCode());
        } else if (totalScore.compareTo(qualifiedScore) >= 0 && totalScore.compareTo(excellentScore) < 0) {
            apply.setResult(ApplyResultEnum.HG.getCode());
        } else if (totalScore.compareTo(excellentScore) >= 0) {
            apply.setResult(ApplyResultEnum.YX.getCode());
        }
        this.baseMapper.updateById(apply);
        //通过文件事件监听信息
        SpringContext.getApplicationContext().publishEvent(new JnpfApplicationEvent<>(FileEventDTO.builder()
                .files(req.getFiles())
                .businessTypeID(apply.getId())
                .type(FileEventDTO.FileType.PRACTICAL_APPRAISAL)
                .build()));
        // 自动颁发证书
        String string = table.getTableId();
        LambdaQueryWrapper<FtbCultivatePositionIdentifyResult> lambdaQuery = Wrappers.lambdaQuery();
        lambdaQuery.eq(FtbCultivatePositionIdentifyResult::getIdentifyId, string);
        lambdaQuery.eq(FtbCultivatePositionIdentifyResult::getIdentifyRecordId, apply.getId());
        lambdaQuery.eq(FtbCultivatePositionIdentifyResult::getUserId, apply.getBeIdentifyUserId());
        lambdaQuery.eq(FtbCultivatePositionIdentifyResult::getEnabledMark, 0);

        FtbCultivatePositionIdentifyResult result = ftbCultivatePositionIdentifyResultMapper.selectOne(lambdaQuery);


        // 实操鉴定触发自动颁发
        if (result == null && apply.getSource() != 4) {
            return;
        }
        String postRankId = null;
        if (apply.getSource() != 4) {
            //任务鉴定
            postRankId = result.getPostRankId();
        }

        if (apply.getSource() == 2 && (Objects.equals(apply.getResult(), ApplyResultEnum.HG.getCode())
                || Objects.equals(apply.getResult(), ApplyResultEnum.YX.getCode()))) {
            // 颁发证书
            // 鉴定表id
            SpringContext.getApplicationContext()
                    .publishEvent(new JnpfApplicationEvent<>(
                            CertificateEventDTO.builder()
                                    .source(2)
                                    .postId(postRankId)
                                    .issuanceType(1)
                                    .userId(apply.getBeIdentifyUserId()).build()));
        } else if (apply.getSource() == 4 && (Objects.equals(apply.getResult(), ApplyResultEnum.HG.getCode())
                || Objects.equals(apply.getResult(), ApplyResultEnum.YX.getCode()))) {
            SpringContext.getApplicationContext()
                    .publishEvent(new JnpfApplicationEvent<>(
                            CertificateEventDTO.builder()
                                    .source(2)
                                    .taskId(apply.getSourceId())
                                    .postId(postRankId)
                                    .issuanceType(2)
                                    .userId(apply.getBeIdentifyUserId()).build()));
        } else if (apply.getSource() == 1 && (Objects.equals(apply.getResult(), ApplyResultEnum.HG.getCode())
                || Objects.equals(apply.getResult(), ApplyResultEnum.YX.getCode()))) {
            //1课程学习鉴定 证书颁发

//            QueryWrapper<FtbCultivatePositionCourseIdentity> courseIdentityQueryWrapper = new QueryWrapper<>();
//            courseIdentityQueryWrapper.lambda()
//                            .eq(FtbCultivatePositionCourseIdentity::getPostRankId, postRankId)
//                                    .eq(FtbCultivatePositionCourseIdentity::getPostLearnId, apply.getSourceId());
//            FtbCultivatePositionCourseIdentity courseIdentity = ftbCultivatePositionCourseIdentityMapper.selectOne(courseIdentityQueryWrapper);
//
            QueryWrapper<FtbCultivatePositionIdentifyResult> identifyResultQueryWrapper = new QueryWrapper<>();
            identifyResultQueryWrapper.lambda()
                    .eq(FtbCultivatePositionIdentifyResult::getIdentifyRecordId, apply.getId());
            FtbCultivatePositionIdentifyResult identifyResult = ftbCultivatePositionIdentifyResultMapper.selectOne(identifyResultQueryWrapper);

            QueryWrapper<FtbCultivatePositionCourseIdentity> positionCourseIdentityQueryWrapper = new QueryWrapper<>();
            positionCourseIdentityQueryWrapper.lambda()
                    .eq(FtbCultivatePositionCourseIdentity::getIdentityId, identifyResult.getIdentifyId())
                    .eq(FtbCultivatePositionCourseIdentity::getPostRankId, postRankId)
                    .eq(FtbCultivatePositionCourseIdentity::getPostLearnId, identifyResult.getPostLearnId());

            List<FtbCultivatePositionCourseIdentity> ftbCultivatePositionCourseIdentityList = ftbCultivatePositionCourseIdentityMapper.selectList(positionCourseIdentityQueryWrapper);

            SpringContext.getApplicationContext().publishEvent(new JnpfApplicationEvent<>(
                    CertificateEventDTO.builder()
                            .source(1)
                            .courseId(ftbCultivatePositionCourseIdentityList.get(0).getCourseId())
                            .issuanceType(0)
                            .postId(postRankId)
                            .userId(apply.getBeIdentifyUserId()).build()

            ));
        }
        // 提醒考试是否需要鉴定
        ftbCultivateExamUserService.completeIdentifyCallBack(apply.getBeIdentifyUserId(), postRankId);
        // 如果是任务鉴定进行完成时间更新
        if (apply.getSource() == 4) {
            ftbCultivateMyLearnTaskInfoService.updateUserFinishTime(apply.getSourceId(), apply.getBeIdentifyUserId(), 2);
        }
    }

    @Override
    @DSTransactional
    public void setApplyDataTime(IdentifyApplySetTimeAppDto req) {
        CultivateIdentifyApply apply = this.baseMapper.selectById(req.getId());
        ServiceException.notNull(apply, "未查询到实操鉴定记录");
        apply.setPlanIdentifyTime(DateUtil.stringToDate(req.getTime()));
        this.baseMapper.updateById(apply);
    }

    @Override
    public IdentifyApplyBasicInfoAppVo getApplyBasicInfoApp(IdentifyTableInfoDto req) {
        CultivateIdentifyApply apply = this.baseMapper.selectById(req.getId());
        ServiceException.notNull(apply, "未查询到实操鉴定记录");
        if (apply.getStatus().equals(ApplyStatusEnum.DJD.getCode())) {
            ServiceException.isTrue(Boolean.FALSE, "暂无鉴定结果");
        }
        CultivateIdentifyApplyTableBackups table = this.applyTableBackupsService.getById(apply.getTableId());
        ServiceException.notNull(table, "未查询到实操鉴定表记录");
        LambdaQueryWrapper<CultivateIdentifyApplyDetails> applyDetailsLambdaQueryWrapper = new LambdaQueryWrapper<CultivateIdentifyApplyDetails>()
                .eq(CultivateIdentifyApplyDetails::getApplyId, apply.getId())
                .eq(CultivateIdentifyApplyDetails::getDeleteMark, ConstantUtil.NUM_FALSE);
        List<CultivateIdentifyApplyDetails> applyDetailsList = this.applyDetailsService.list(applyDetailsLambdaQueryWrapper);
        List<CultivateIdentifyApplyDetailsBackups> identifyItemsList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(applyDetailsList)) {
            List<String> itemsIds = applyDetailsList.stream().map(CultivateIdentifyApplyDetails::getItemsId).collect(Collectors.toList());
            LambdaQueryWrapper<CultivateIdentifyApplyDetailsBackups> itemsLambdaQueryWrapper = new LambdaQueryWrapper<CultivateIdentifyApplyDetailsBackups>()
                    .eq(CultivateIdentifyApplyDetailsBackups::getTableId, table.getId())
                    .in(CultivateIdentifyApplyDetailsBackups::getId, itemsIds);
            identifyItemsList = this.applyDetailsBackupsService.list(itemsLambdaQueryWrapper);
        }
        IdentifyApplyBasicInfoAppVo appVo = new IdentifyApplyBasicInfoAppVo();
        appVo.setId(apply.getId());
        appVo.setTableName(table.getName());
        appVo.setIdentifyTime(apply.getIdentifyTime());
        appVo.setIdentifyItemSize(identifyItemsList.size());
        BigDecimal identifyTotalScore = BigDecimal.ZERO;
        for (CultivateIdentifyApplyDetailsBackups identifyItems : identifyItemsList) {
            identifyTotalScore = identifyTotalScore.add(identifyItems.getScore());
        }
        appVo.setTotalScore(identifyTotalScore);
        BigDecimal totalScore = BigDecimal.ZERO;
        for (CultivateIdentifyApplyDetails identifyItems : applyDetailsList) {
            totalScore = totalScore.add(identifyItems.getScore());
        }
        appVo.setIdentifyScore(totalScore);
        appVo.setUserTime(apply.getUseTime());
        appVo.setStatus(apply.getStatus());
        appVo.setResult(apply.getResult());
        appVo.setSource(apply.getSource());
        appVo.setRuleDesc(table.getRuleDesc());
        //查询鉴定表有多少人使用
        appVo.setUseNumber(this.baseMapper.getTableUseNumber(table.getId()));
        List<String> userList = new ArrayList<>();
        userList.add(apply.getBeIdentifyUserId());
        if (StringUtil.isNotEmpty(apply.getIdentifyUserId())) {
            String[] split = apply.getIdentifyUserId().split(",");
            userList.addAll(Arrays.asList(split));
        }
        Map<String, UserBoundVO> userMap = userApiV2Util.getUserPrimaryBoundBatch(userList, null);
        //被鉴定用户信息
        IdentifyUserOrgInfoVo beIdentifyUserInfo = new IdentifyUserOrgInfoVo();
        UserBoundVO beUserInfoVo = userMap.get(apply.getBeIdentifyUserId());
        // 获取用户头像
        if (Objects.nonNull(beUserInfoVo) && !StringUtil.isEmpty(beUserInfoVo.getHeadIcon())) {
            beIdentifyUserInfo.setUserHeadIcon(UploaderUtil.uploaderImg(beUserInfoVo.getHeadIcon()));
        }
        beIdentifyUserInfo.setUserId(apply.getBeIdentifyUserId());
        beIdentifyUserInfo.setUserName(Objects.isNull(userMap.get(apply.getBeIdentifyUserId())) ?
                "未查询到用户" : userMap.get(apply.getBeIdentifyUserId()).getUserName());
        //被鉴定人职等的组织信息
        List<UserOrgInfoAll1Vo> beOrgInfoAll1VoList = JSON.parseArray(apply.getBeOfficialRankInfoJson(), UserOrgInfoAll1Vo.class);
        if (CollectionUtil.isNotEmpty(beOrgInfoAll1VoList)) {
            beIdentifyUserInfo.setUserOrgInfoPushVoList(beOrgInfoAll1VoList.stream().map(orgInfoAll1Vo -> {
                UserOrgInfoVo orgInfoVo = new UserOrgInfoVo();
                BeanUtils.copyProperties(orgInfoAll1Vo, orgInfoVo);
                return orgInfoVo;
            }).collect(Collectors.toList()));
        }
        //鉴定用户信息
        IdentifyUserOrgInfoVo identifyUserInfo = new IdentifyUserOrgInfoVo();
        UserBoundVO userInfoVo = null;
        if (StringUtil.isNotEmpty(apply.getIdentifyUserId())) {
            String[] split = apply.getIdentifyUserId().split(",");
            userInfoVo = userMap.get(split[0]);
        }

        // 获取用户头像
        if (Objects.nonNull(userInfoVo) && !StringUtil.isEmpty(userInfoVo.getHeadIcon())) {
            identifyUserInfo.setUserHeadIcon(UploaderUtil.uploaderImg(userInfoVo.getHeadIcon()));
        }
        identifyUserInfo.setUserId(apply.getIdentifyUserId());
        identifyUserInfo.setUserName(Objects.isNull(userMap.get(apply.getIdentifyUserId())) ?
                "未查询到用户" : userMap.get(apply.getIdentifyUserId()).getUserName());
        //鉴定人职等的组织信息
        List<UserOrgInfoAll1Vo> orgInfoAll1VoList = JSON.parseArray(apply.getOfficialRankInfoJson(), UserOrgInfoAll1Vo.class);
        if (CollectionUtil.isNotEmpty(orgInfoAll1VoList)) {
            identifyUserInfo.setUserOrgInfoPushVoList(orgInfoAll1VoList.stream().map(orgInfoAll1Vo -> {
                UserOrgInfoVo orgInfoVo = new UserOrgInfoVo();
                BeanUtils.copyProperties(orgInfoAll1Vo, orgInfoVo);
                return orgInfoVo;
            }).collect(Collectors.toList()));
        }
        appVo.setBeIdentifyUserInfo(beIdentifyUserInfo);
        appVo.setIdentifyUserInfo(identifyUserInfo);
        return appVo;
    }

    @Override
    public IdentifyApplyInfoAppVo getApplyInfoApp(IdentifyTableInfoDto req) {
        CultivateIdentifyApply apply = this.baseMapper.selectById(req.getId());
        ServiceException.notNull(apply, "未查询到实操鉴定记录");
        if (apply.getStatus().equals(ApplyStatusEnum.DJD.getCode())) {
            ServiceException.isTrue(Boolean.FALSE, "暂无鉴定结果");
        }
        CultivateIdentifyApplyTableBackups table = this.applyTableBackupsService.getById(apply.getTableId());
        ServiceException.notNull(table, "未查询到实操鉴定表记录");
        LambdaQueryWrapper<CultivateIdentifyApplyDetails> applyDetailsLambdaQueryWrapper = new LambdaQueryWrapper<CultivateIdentifyApplyDetails>()
                .eq(CultivateIdentifyApplyDetails::getApplyId, apply.getId())
                .eq(CultivateIdentifyApplyDetails::getDeleteMark, ConstantUtil.NUM_FALSE);
        List<CultivateIdentifyApplyDetails> applyDetailsList = this.applyDetailsService.list(applyDetailsLambdaQueryWrapper);
        List<CultivateIdentifyApplyDetailsBackups> identifyItemsList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(applyDetailsList)) {
            List<String> itemsIds = applyDetailsList.stream().map(CultivateIdentifyApplyDetails::getItemsId).collect(Collectors.toList());
            LambdaQueryWrapper<CultivateIdentifyApplyDetailsBackups> itemsLambdaQueryWrapper = new LambdaQueryWrapper<CultivateIdentifyApplyDetailsBackups>()
                    .eq(CultivateIdentifyApplyDetailsBackups::getTableId, table.getId())
                    .in(CultivateIdentifyApplyDetailsBackups::getId, itemsIds);
            identifyItemsList = this.applyDetailsBackupsService.list(itemsLambdaQueryWrapper);
        }
        IdentifyApplyInfoAppVo appVo = new IdentifyApplyInfoAppVo();
        BigDecimal identifyTotalScore = BigDecimal.ZERO;
        for (CultivateIdentifyApplyDetailsBackups identifyItems : identifyItemsList) {
            identifyTotalScore = identifyTotalScore.add(identifyItems.getScore());
        }
        appVo.setTotalScore(identifyTotalScore);
        BigDecimal totalScore = BigDecimal.ZERO;
        for (CultivateIdentifyApplyDetails identifyItems : applyDetailsList) {
            totalScore = totalScore.add(identifyItems.getScore());
        }
        appVo.setScore(totalScore);
        if (CollectionUtil.isNotEmpty(applyDetailsList)) {
            Map<String, CultivateIdentifyApplyDetailsBackups> fileMap = identifyItemsList.stream().collect(
                    Collectors.toMap(CultivateIdentifyApplyDetailsBackups::getId, a -> a, (k1, k2) -> k1));
            appVo.setDetailsList(applyDetailsList.stream().map(item -> {
                CultivateIdentifyApplyDetailsBackups items = fileMap.get(item.getItemsId());
                IdentifyApplyDetailsAppVo applyDetailsAppVo = new IdentifyApplyDetailsAppVo();
                applyDetailsAppVo.setId(item.getId());
                applyDetailsAppVo.setName(items.getName());
                applyDetailsAppVo.setTotalScore(items.getScore());
                applyDetailsAppVo.setScore(item.getScore());
                return applyDetailsAppVo;
            }).collect(Collectors.toList()));
        }
        // 查询当前申请时上传的文件信息
        LambdaQueryWrapper<FtbCultivateFile> wrapperFile = Wrappers.lambdaQuery();
        wrapperFile.eq(FtbCultivateFile::getBusinessId, apply.getId());
        List<FtbCultivateFile> fileLists = ftbCultivateFileService.list(wrapperFile);
        LambdaQueryWrapper<FtbCultivateFile> wrapperFile2 = Wrappers.lambdaQuery();
        wrapperFile2.eq(FtbCultivateFile::getBusinessId, apply.getId() + apply.getBeIdentifyUserId());
        List<FtbCultivateFile> fileLists2 = ftbCultivateFileService.list(wrapperFile2);
        List<FtbCultivateOfflineFileVO> fileVOS = fileLists.stream()
                .map(FtbCultivateOfflineFileVO::convertFtbCultivateOfflineFileVO).collect(Collectors.toList());
        List<FtbCultivateOfflineFileVO> fileVOS2 = fileLists2.stream()
                .map(FtbCultivateOfflineFileVO::convertFtbCultivateOfflineFileVO).collect(Collectors.toList());
        List<FtbCultivateOfflineFileVO> file = new ArrayList<>();
        file.addAll(fileVOS2);
        file.addAll(fileVOS);
        appVo.setFiles(file);
        return appVo;
    }

    @Override
    public List<IdentifyApplyInfoApiVo> getUserIdentifyInfoApi(List<String> ids) {
        log.error("查询鉴定IDs：{}", JSONObject.toJSON(ids));
        LambdaQueryWrapper<CultivateIdentifyApply> applyLambdaQueryWrapper = new LambdaQueryWrapper<CultivateIdentifyApply>()
                .in(CultivateIdentifyApply::getId, ids)
                .eq(CultivateIdentifyApply::getDeleteMark, ConstantUtil.NUM_FALSE)
                .eq(CultivateIdentifyApply::getIsVisible, 0);
        List<CultivateIdentifyApply> applyList = this.list(applyLambdaQueryWrapper);
        if (CollectionUtil.isEmpty(applyList)) {
            return CollectionUtil.newArrayList();
        }
        List<String> userList = new ArrayList<>();
        for (CultivateIdentifyApply cultivateIdentifyApply : applyList) {
            userList.add(cultivateIdentifyApply.getBeIdentifyUserId());
            if (StringUtil.isNotEmpty(cultivateIdentifyApply.getIdentifyUserId())) {
                String[] split = cultivateIdentifyApply.getIdentifyUserId().split(",");
                userList.addAll(Arrays.asList(split));
            }
        }
        Map<String, UserBoundVO> userMap = userApiV2Util.getUserPrimaryBoundBatch(userList, null);
        LambdaQueryWrapper<CultivateIdentifyApplyTableBackups> tableLambdaQueryWrapper = new LambdaQueryWrapper<CultivateIdentifyApplyTableBackups>()
                .in(CultivateIdentifyApplyTableBackups::getId, applyList.stream().map(
                        CultivateIdentifyApply::getTableId).collect(Collectors.toList()));
        Map<String, CultivateIdentifyApplyTableBackups> tableMap = this.applyTableBackupsService.list(tableLambdaQueryWrapper)
                .stream().collect(Collectors.toMap(CultivateIdentifyApplyTableBackups::getId, a -> a, (k1, k2) -> k1));
        return applyList.stream().map(item -> {
            IdentifyApplyInfoApiVo infoApiVo = new IdentifyApplyInfoApiVo();
            BeanUtils.copyProperties(item, infoApiVo);
            infoApiVo.setIdIdentification(item.getId());
            infoApiVo.setTableName(Objects.isNull(tableMap.get(item.getTableId())) ?
                    "未查询到鉴定表" : tableMap.get(item.getTableId()).getName());
            if (StringUtil.isNotEmpty(item.getIdentifyUserId())) {
                String[] split = item.getIdentifyUserId().split(",");
                infoApiVo.setUserName(userMap.get(split[0]).getUserName());
            } else {
                infoApiVo.setUserName("未查询到用户");
            }

            infoApiVo.setBeUserName(Objects.isNull(userMap.get(item.getBeIdentifyUserId())) ?
                    "未查询到用户" : userMap.get(item.getBeIdentifyUserId()).getUserName());
            return infoApiVo;
        }).collect(Collectors.toList());
    }

    @Override
    public List<IdentifyApplyInfoApiVo> getUserIdentifyInfoWithUserId(String userId) {
        LambdaQueryWrapper<CultivateIdentifyApply> applyLambdaQueryWrapper = new LambdaQueryWrapper<CultivateIdentifyApply>()
                .in(CultivateIdentifyApply::getBeIdentifyUserId, userId)
                .eq(CultivateIdentifyApply::getDeleteMark, ConstantUtil.NUM_FALSE)
                .eq(CultivateIdentifyApply::getIsVisible, 0);
        List<CultivateIdentifyApply> applyList = this.list(applyLambdaQueryWrapper);
        if (CollectionUtil.isEmpty(applyList)) {
            return CollectionUtil.newArrayList();
        }
        List<String> allUserIds = new ArrayList<>();
        for (CultivateIdentifyApply cultivateIdentifyApply : applyList) {
            if (StringUtil.isNotEmpty(cultivateIdentifyApply.getIdentifyUserId())) {
                allUserIds.addAll(Arrays.asList(cultivateIdentifyApply.getIdentifyUserId().split(",")));
            }
            if (StringUtil.isNotEmpty(cultivateIdentifyApply.getBeIdentifyUserId())) {
                allUserIds.add(cultivateIdentifyApply.getBeIdentifyUserId());
            }
        }
        Map<String, UserBoundVO> infoMapByIds = userApiV2Util.getUserPrimaryBoundBatch(allUserIds, null);
        Map<String, String> userIdMap = cultivatePerUtils.coverPersonalIds(allUserIds);

        LambdaQueryWrapper<CultivateIdentifyApplyTableBackups> tableLambdaQueryWrapper = new LambdaQueryWrapper<CultivateIdentifyApplyTableBackups>()
                .in(CultivateIdentifyApplyTableBackups::getId, applyList.stream().map(
                        CultivateIdentifyApply::getTableId).collect(Collectors.toList()));
        Map<String, CultivateIdentifyApplyTableBackups> tableMap = this.applyTableBackupsService.list(tableLambdaQueryWrapper)
                .stream().collect(Collectors.toMap(CultivateIdentifyApplyTableBackups::getId, a -> a, (k1, k2) -> k1));
        return applyList.stream().map(item -> {
            IdentifyApplyInfoApiVo infoApiVo = new IdentifyApplyInfoApiVo();
            BeanUtils.copyProperties(item, infoApiVo);
            infoApiVo.setIdIdentification(item.getId());
            infoApiVo.setTableName(Objects.isNull(tableMap.get(item.getTableId())) ?
                    "未查询到鉴定表" : tableMap.get(item.getTableId()).getName());

            if (StringUtil.isNotEmpty(item.getIdentifyUserId())) {
                String[] split = item.getIdentifyUserId().split(",");
                List<String> tmpNameList = new ArrayList<>();
                List<String> workerIds = new ArrayList<>();
                for (String s : split) {
                    UserBoundVO userBoundVO = infoMapByIds.get(s);
                    if (userBoundVO != null) {
                        tmpNameList.add(userBoundVO.getUserName());
                    }
                    String workerId = userIdMap.get(s);
                    if (StringUtil.isNotEmpty(workerId)) {
                        workerIds.add(workerId);
                    }
                }
                if (CollUtil.isNotEmpty(tmpNameList)) {
                    infoApiVo.setUserName(String.join(",", tmpNameList));
                    infoApiVo.setSysUserId(String.join(",", workerIds));
                } else {
                    infoApiVo.setUserName("未查询到用户");
                }
            } else {
                infoApiVo.setUserName("未查询到用户");
            }
            if (StringUtil.isNotEmpty(item.getBeIdentifyUserId())) {
                UserBoundVO userBoundVO = infoMapByIds.get(item.getBeIdentifyUserId());
                if (userBoundVO != null) {
                    infoApiVo.setBeUserName(userBoundVO.getUserName());
                } else {
                    infoApiVo.setBeUserName("未查询到用户");
                }
            }
            return infoApiVo;
        }).collect(Collectors.toList());
    }

    @Override
    public IdentifyStatisticsForNewVo getHandsOnStatistics(FtbCultivateStatisticsDTO dto) {
        IdentifyStatisticsForNewVo statisticsVo = new IdentifyStatisticsForNewVo();
        LambdaQueryWrapper<CultivateIdentifyApply> query = Wrappers.lambdaQuery();
        query.in(CultivateIdentifyApply::getBeIdentifyUserId, dto.getUserIds());
        if (dto.getStartTime() != null && dto.getEndTime() != null) {
            query.between(CultivateIdentifyApply::getIdentifyTime, dto.getStartTime(), dto.getEndTime());
        }
        query.eq(CultivateIdentifyApply::getStatus, ApplyStatusEnum.YJD.getCode());
        query.eq(CultivateIdentifyApply::getDeleteMark, ConstantUtil.NUM_FALSE);
        query.eq(CultivateIdentifyApply::getIsVisible, 0);
        List<CultivateIdentifyApply> applyList = this.list(query);
        if (CollUtil.isEmpty(applyList)) {
            return statisticsVo;
        }
        // 总人数
        long rowNumber = applyList.stream().map(CultivateIdentifyApply::getBeIdentifyUserId).count();
        statisticsVo.setTotalPeople(rowNumber);
        // 合格人数
        long passNumber = applyList.stream().filter(item -> item.getResult() != null && item.getResult() != 2).count();
        statisticsVo.setPassNumber(passNumber);
        // 合格率 = 合格人数 / 总人数
        BigDecimal passRate = BigDecimal.valueOf(passNumber).divide(BigDecimal.valueOf(rowNumber), 2, RoundingMode.HALF_UP)
                .multiply(BigDecimal.valueOf(100)).setScale(2, RoundingMode.HALF_UP);
        statisticsVo.setPassRate(passRate);
        return statisticsVo;
    }

    @Override
    public Boolean whetherTheUserPositionHasBeenIdentified(String userId, String positionId) {
        // 是否存在岗位学习鉴定
        List<String> strings = promotionNewMapper.checkWhetherThereIsAPracticalAppraisalWithNew(positionId, userId);
        if (CollUtil.isEmpty(strings)) {
            return null;
        }
        LambdaQueryWrapper<CultivateIdentifyApply> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(CultivateIdentifyApply::getStatus, 1);
        wrapper.eq(CultivateIdentifyApply::getSource, 2);
        wrapper.in(CultivateIdentifyApply::getTableId, strings);
        wrapper.eq(CultivateIdentifyApply::getBeIdentifyUserId, userId);
        Long aLong = baseMapper.selectCount(wrapper);
        return aLong > 0;
    }

    @Override
    public void deleteLearnTaskApplyIdentified(String taskId) {
        LambdaQueryWrapper<CultivateIdentifyApply> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.select(CultivateIdentifyApply::getId);
        queryWrapper.eq(CultivateIdentifyApply::getSourceId, taskId);
//        queryWrapper.last("limit 1");
        // 查询主键
        List<CultivateIdentifyApply> list = baseMapper.selectList(queryWrapper);
        if (CollUtil.isEmpty(list)) {
            return;
        }
        for (CultivateIdentifyApply cultivateIdentifyApply : list) {
            LambdaQueryWrapper<CultivateIdentifyApplyDetails> listWrapper = Wrappers.lambdaQuery();
            String id = cultivateIdentifyApply.getId();
            listWrapper.eq(CultivateIdentifyApplyDetails::getApplyId, id);
            // 删除详情
            applyDetailsMapper.delete(listWrapper);
            // 删除主键
            baseMapper.deleteById(id);
        }

    }

    @Override
    public Map<String, IdentifyApplyStatisticsApiVo> getUserIdentifyStatistics(List<String> userIds) {
        List<IdentifyApplyStatisticsApiVo> statisticsApiVoList = this.baseMapper.getUserIdentifyStatistics(userIds);
        if (CollectionUtil.isNotEmpty(statisticsApiVoList)) {
            return statisticsApiVoList.stream().collect(Collectors.toMap(IdentifyApplyStatisticsApiVo::getUserId, a -> a, (k1, k2) -> k1));
        } else {
            return new HashMap<>();
        }
    }

    @Override
    public PageListVO<UserIdentifyPageVo> getUserIdentifyPage(String userId, CultivatePage page) {
        Page<UserIdentifyPageVo> objectPage = page.coverCultivatePage();
        Page<UserIdentifyPageVo> list = this.baseMapper.getUserIdentifyPage(objectPage, userId);
        List<UserIdentifyPageVo> records = list.getRecords();
        if (CollectionUtil.isNotEmpty(records)) {
            //查询到人员名称-服务调用
            List<String> userIdList = records.stream().map(UserIdentifyPageVo::getUserId).collect(Collectors.toList());
//            Map<String, PartUserInfoVo> userMap = userApi.getInfoMapByIds(userIdList);
            Map<String, UserBoundVO> userMap = userApiV2Util.getUserPrimaryBoundBatch(userIdList, null);
            records.forEach(item -> {
                UserBoundVO tempUser = userMap.get(item.getUserId());
                if (tempUser != null) {
                    item.setUserName(tempUser.getName());
                } else {
                    item.setUserName("未查询到用户");
                }
                String identifyUserId = item.getIdentifyUserId();
                if (StringUtil.isNotEmpty(identifyUserId)) {
                    String[] split = identifyUserId.split(",");
                    if (split.length > 0) {
//                    List<PartUserInfoVo> infoByIdsMany = userApi.getInfoByIdsMany(List.of(split));
                        List<UserBoundVO> infoByIdsMany = userApiV2Util.getUserPrimaryBoundBatchReturnList(List.of(split), null);
                        if (CollUtil.isNotEmpty(infoByIdsMany)) {
                            item.setIdentifyUserName(infoByIdsMany.stream().map(UserBoundVO::getUserName).collect(Collectors.joining(",")));
                        }
                    }
                }
            });
        }
        return CultivatePage.coverPageList(list);
    }

    @Override
    public IdentifyStatisticsVo getIdentifyStatistics(FtbCultivateStatisticsDTO req) {
        IdentifyStatisticsVo statisticsVo = new IdentifyStatisticsVo();
        LambdaQueryWrapper<CultivateIdentifyApply> applyLambdaQueryWrapper = new LambdaQueryWrapper<CultivateIdentifyApply>()
                .in(CultivateIdentifyApply::getBeIdentifyUserId, req.getUserIds())
                .between(CultivateIdentifyApply::getIdentifyTime, req.getStartTime(), req.getEndTime())
                .eq(CultivateIdentifyApply::getStatus, ApplyStatusEnum.YJD.getCode())
                .eq(CultivateIdentifyApply::getDeleteMark, ConstantUtil.NUM_FALSE)
                .eq(CultivateIdentifyApply::getIsVisible, 0);
        List<CultivateIdentifyApply> applyList = this.list(applyLambdaQueryWrapper);
        if (CollectionUtil.isNotEmpty(applyList)) {
            Map<String, List<CultivateIdentifyApply>> stringListMap = applyList.stream().collect(Collectors.groupingBy(CultivateIdentifyApply::getBeIdentifyUserId));
            //鉴定总人数
            statisticsVo.setTotalPeople(stringListMap.size());
            //鉴定总次数
            statisticsVo.setTotalNumber(applyList.size());
            //合格次数
            List<CultivateIdentifyApply> hgApplyList = applyList.stream().filter(m -> !m.getResult().equals(ApplyResultEnum.BHG.getCode())).collect(Collectors.toList());
            statisticsVo.setPassNumber(CollectionUtil.isNotEmpty(hgApplyList) ? hgApplyList.size() : 0);
            //合格率
            statisticsVo.setPassRate(CollectionUtil.isNotEmpty(hgApplyList) ?
                    new BigDecimal(statisticsVo.getPassNumber()).divide(
                                    new BigDecimal(statisticsVo.getTotalNumber()), 2, RoundingMode.HALF_UP)
                            .multiply(new BigDecimal(100)) :
                    BigDecimal.ZERO);
            //不合格次数
            List<CultivateIdentifyApply> bhgApplyList = applyList.stream().filter(m -> m.getResult().equals(ApplyResultEnum.BHG.getCode())).collect(Collectors.toList());
            statisticsVo.setNoPassNumber(CollectionUtil.isNotEmpty(bhgApplyList) ? bhgApplyList.size() : 0);
            //不合格率
            statisticsVo.setNoPassRate(CollectionUtil.isNotEmpty(bhgApplyList) ?
                    new BigDecimal(statisticsVo.getNoPassNumber()).divide(
                                    new BigDecimal(statisticsVo.getTotalNumber()), 2, RoundingMode.HALF_UP)
                            .multiply(new BigDecimal(100)) : BigDecimal.ZERO);
        }
        //查询年度合格率
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, Calendar.JANUARY);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        long startTime = calendar.getTimeInMillis();
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, Calendar.DECEMBER);
        calendar.set(Calendar.DAY_OF_MONTH, 31);
        long endTime = calendar.getTimeInMillis();
        LambdaQueryWrapper<CultivateIdentifyApply> annualApplyLambdaQueryWrapper = new LambdaQueryWrapper<CultivateIdentifyApply>()
                .in(CultivateIdentifyApply::getBeIdentifyUserId, req.getUserIds())
                .between(CultivateIdentifyApply::getIdentifyTime, new Date(startTime), new Date(endTime))
                .eq(CultivateIdentifyApply::getStatus, ApplyStatusEnum.YJD.getCode())
                .eq(CultivateIdentifyApply::getDeleteMark, ConstantUtil.NUM_FALSE)
                .eq(CultivateIdentifyApply::getIsVisible, 0);
        List<CultivateIdentifyApply> annualApplyList = this.list(annualApplyLambdaQueryWrapper);
        if (CollectionUtil.isNotEmpty(annualApplyList)) {
            //鉴定总次数
            int yearTotal = annualApplyList.size();
            //合格次数
            List<CultivateIdentifyApply> hgApplyList = annualApplyList.stream().filter(m -> !m.getResult().equals(ApplyResultEnum.BHG.getCode())).collect(Collectors.toList());
            int yearPass = CollectionUtil.isNotEmpty(hgApplyList) ? hgApplyList.size() : 0;
            //合格率
            statisticsVo.setAnnualPassRate(CollectionUtil.isNotEmpty(hgApplyList) ?
                    new BigDecimal(yearPass).divide(
                                    new BigDecimal(yearTotal), 2, RoundingMode.HALF_UP)
                            .multiply(new BigDecimal(100)) :
                    BigDecimal.ZERO);
        }
        return statisticsVo;
    }

    @Override
    public List<IdentifyTopVo> getIdentifyTop(FtbCultivateStatisticsDTO req) {
        List<IdentifyTopVo> topVoList = new ArrayList<>();
        LambdaQueryWrapper<CultivateIdentifyApply> applyLambdaQueryWrapper = new LambdaQueryWrapper<CultivateIdentifyApply>()
                .in(CultivateIdentifyApply::getBeIdentifyUserId, req.getUserIds())
                .isNotNull(CultivateIdentifyApply::getIdentifyTime)
                .between(CultivateIdentifyApply::getIdentifyTime, req.getStartTime(), req.getEndTime())
                .eq(CultivateIdentifyApply::getStatus, ApplyStatusEnum.YJD.getCode())
                .eq(CultivateIdentifyApply::getDeleteMark, ConstantUtil.NUM_FALSE)
                .eq(CultivateIdentifyApply::getIsVisible, 0);
        List<CultivateIdentifyApply> applyList = this.list(applyLambdaQueryWrapper);
        if (CollUtil.isEmpty(applyList)) {
            return topVoList;
        }

        Map<String, UserEntity> userMap = userApiV2Util.getUserNameAndCopyForUserIds(applyList.stream().map(CultivateIdentifyApply::getBeIdentifyUserId).distinct().collect(Collectors.toList()));
        Map<String, List<CultivateIdentifyApply>> stringListMap = applyList.stream().collect(Collectors.groupingBy(CultivateIdentifyApply::getBeIdentifyUserId));
        for (Map.Entry<String, List<CultivateIdentifyApply>> entry : stringListMap.entrySet()) {
            IdentifyTopVo topVo = new IdentifyTopVo();
            topVo.setUserId(entry.getKey());
            topVo.setUserName(Objects.isNull(userMap.get(entry.getKey())) ?
                    "未查询到用户" : userMap.get(entry.getKey()).getRealName());
            List<CultivateIdentifyApply> identifyApplyList = entry.getValue();
            //合格率
            List<CultivateIdentifyApply> htApplyList = identifyApplyList.stream().filter(m -> !m.getResult().equals(ApplyResultEnum.BHG.getCode())).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(htApplyList)) {
                topVo.setPassRate(new BigDecimal(htApplyList.size()).divide(new BigDecimal(identifyApplyList.size()), 2, RoundingMode.HALF_UP));
            }
            topVoList.add(topVo);
        }
        //按照合格率降序排列
        topVoList = topVoList.stream().sorted(Comparator.comparing(IdentifyTopVo::getPassRate).reversed()).collect(Collectors.toList());

        return topVoList;
    }

    @Override
    @Transactional
    public boolean setIdentifyBeOverdue() {
        //查询设置了计划鉴定时间并且到期未鉴定
        LambdaQueryWrapper<CultivateIdentifyApply> applyLambdaQueryWrapper = new LambdaQueryWrapper<CultivateIdentifyApply>()
                .isNotNull(CultivateIdentifyApply::getPlanIdentifyTime)
                .lt(CultivateIdentifyApply::getPlanIdentifyTime, DateUtil.getNowDate())
                .eq(CultivateIdentifyApply::getStatus, ApplyStatusEnum.DJD.getCode())
                .eq(CultivateIdentifyApply::getDeleteMark, ConstantUtil.NUM_FALSE)
                .eq(CultivateIdentifyApply::getIsVisible, 0);
        List<CultivateIdentifyApply> applyList = this.list(applyLambdaQueryWrapper);
        if (CollectionUtil.isNotEmpty(applyList)) {
            applyList.forEach(item -> {
                item.setStatus(ApplyStatusEnum.YQWJD.getCode());
                item.setLastModifyTime(new Date());
            });
            this.updateBatchById(applyList);
        }
        return true;
    }

    @Override
    @Transactional
    public boolean setIdentifyRemind(String tenantId) {
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime futureTime = now.plusHours(2);
        Date date = Date.from(futureTime.atZone(ZoneId.systemDefault()).toInstant());
        LambdaQueryWrapper<CultivateIdentifyApply> applyLambdaQueryWrapper = new LambdaQueryWrapper<CultivateIdentifyApply>()
                .isNotNull(CultivateIdentifyApply::getPlanIdentifyTime)
                .le(CultivateIdentifyApply::getPlanIdentifyTime, date)
                .eq(CultivateIdentifyApply::getIsRemind, ConstantUtil.NUM_FALSE)
                .eq(CultivateIdentifyApply::getStatus, ApplyStatusEnum.DJD.getCode())
                .eq(CultivateIdentifyApply::getDeleteMark, ConstantUtil.NUM_FALSE)
                .eq(CultivateIdentifyApply::getIsVisible, 0);
        List<CultivateIdentifyApply> applyList = this.list(applyLambdaQueryWrapper);
        if (CollectionUtil.isNotEmpty(applyList)) {
            log.error("ID分别为:{}", JSONObject.toJSON(applyList.stream().map(CultivateIdentifyApply::getId).collect(Collectors.toList())));
            SentMessageIdentify req = new SentMessageIdentify();
            List<SentMessageInfo> infoList = new ArrayList<>();
            applyList.forEach(item -> {
                item.setIsRemind(ConstantUtil.NUM_TRUE);
                SentMessageInfo messageInfo = new SentMessageInfo();
                String identifyUserId = item.getIdentifyUserId();
                messageInfo.setToUserId(identifyUserId);
                UserInfoVO bossByUserId = userApi.getBossByUserId(identifyUserId);
                if (ObjectUtil.isNotEmpty(bossByUserId)) {
                    messageInfo.setTitle(String.format("请去鉴定%s的鉴定申请", bossByUserId.getRealName()));
                }
                infoList.add(messageInfo);
            });
            req.setInfoList(infoList);
            req.setBodyText("鉴定提醒");
            req.setSource(2);
            req.setType(1);
            req.setUserId(applyList.get(0).getIdentifyUserId());
            req.setTenantId(tenantId);
            log.error("鉴定提醒消息发送请求参数：{}", JSONObject.toJSON(req));
            sentMessageApi.sentMessageIdentify(req);
            return this.updateBatchById(applyList);
        } else {
            return true;
        }
    }

    @Override
    public Map<String, Integer> groupIdentifyCountNum(List<String> taskIds, Integer type) {
        Map<String, Integer> ret = new HashMap<>();
        if (CollUtil.isEmpty(taskIds)) {
            return ret;
        }
        List<BatchCommonCountDto> list = baseMapper.groupIdentifyCountNum(taskIds, type);
        if (CollectionUtil.isEmpty(list)) {
            return ret;
        }
        for (BatchCommonCountDto batchCommonCountDto : list) {
            ret.put(batchCommonCountDto.getSelectKey(), batchCommonCountDto.getNum());
        }
        return ret;
    }

    @Override
    public List<CultivateIdentifyApply> queryIdentifyApply(String userId, List<String> identifyIds, Integer source, String sourceId) {
        return baseMapper.queryIdentifyApply(userId, identifyIds, source, sourceId);
    }
}
