package com.qmth.sop.business.service.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.gson.reflect.TypeToken;
import com.qmth.sop.business.activiti.service.ActivitiService;
import com.qmth.sop.business.bean.dto.DataPermissionDto;
import com.qmth.sop.business.bean.dto.OrgUserNameDto;
import com.qmth.sop.business.bean.params.FlowApproveParam;
import com.qmth.sop.business.bean.result.*;
import com.qmth.sop.business.entity.*;
import com.qmth.sop.business.mapper.TBDingApplyMapper;
import com.qmth.sop.business.service.*;
import com.qmth.sop.common.contant.SystemConstant;
import com.qmth.sop.common.enums.*;
import com.qmth.sop.common.util.DateDisposeUtils;
import com.qmth.sop.common.util.GsonUtil;
import com.qmth.sop.common.util.ServletUtil;
import org.activiti.engine.TaskService;
import org.activiti.engine.task.IdentityLink;
import org.activiti.engine.task.Task;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 * 考勤补卡申请表 服务实现类
 * </p>
 *
 * @author wangliang
 * @since 2023-08-01
 */
@Service
public class TBDingApplyServiceImpl extends ServiceImpl<TBDingApplyMapper, TBDingApply> implements TBDingApplyService {

    @Resource
    TFCustomFlowEntityService tfCustomFlowEntityService;

    @Resource
    ActivitiService activitiService;

    @Resource
    TBDingService tbDingService;

    @Resource
    BasicAttachmentService basicAttachmentService;

    @Resource
    TaskService taskService;

    @Resource
    TBDingApplyService tbDingApplyService;

    @Resource
    TBCrmService tbCrmService;

    @Resource
    TBUserArchivesService tbUserArchivesService;

    @Resource
    SysUserService sysUserService;

    @Resource
    SysUserRoleService sysUserRoleService;

    @Resource
    TFFlowApproveService tfFlowApproveService;

    @Resource
    TFFlowLogService tfFlowLogService;

    @Resource
    TBUserArchivesAllocationService tbUserArchivesAllocationService;

    @Resource
    TBCrmDetailService tbCrmDetailService;

    @Resource
    TBDingStatisticService tbDingStatisticService;

    @Resource
    TBDingSubmitService tbDingSubmitService;

    @Resource
    SysDingDateService sysDingDateService;

    /**
     * 新增考勤异常补卡申请
     *
     * @param tbDingApply
     * @return
     * @throws InterruptedException
     */
    @Override
    @Transactional
    public Boolean saveDingApply(TBDingApply tbDingApply) throws Exception {
        SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
        TBDing tbDing = tbDingService.getById(tbDingApply.getDingId());
        String sopNo = Objects.nonNull(tbDing) ? tbDing.getSopNo() : tbDingApply.getSopNo();

        String crmNo = Objects.nonNull(tbDing) ? tbDing.getCrmNo() : tbDingApply.getCrmNo();
        if (!SystemConstant.strNotNull(crmNo)) {
            crmNo = "-1";
        }
        Long serviceId = Objects.nonNull(tbDing) ? tbDing.getServiceId() : tbDingApply.getServiceId();

        int count = tbDingService.findRemainCount(sysUser.getId(), serviceId, sopNo);
        if (count == 0) {
            throw ExceptionResultEnum.ERROR.exception("该用户剩余补卡次数为0");
        }
        List<String> approveUserIds = new ArrayList<>();
        if (SystemConstant.strNotNull(sopNo)) {
            List<String> sysUserRoleList = sysUserRoleService.listByServiceId(serviceId, sysUser.getId(), sopNo);
            approveUserIds.addAll(sysUserRoleList);
        } else {
            // 区协选定审核人
            List<String> sysUserRoleList = tbDingApply.getApproveUserIds();
            approveUserIds.addAll(sysUserRoleList);
        }
        FlowApproveParam flowApproveParam = new FlowApproveParam(tbDingApply.getFlowDeploymentId(),
                FlowApprovePassEnum.START, approveUserIds, crmNo);
        flowApproveParam.setApproveRemark(FlowApprovePassEnum.START.getTitle());
        Map<String, Object> map = activitiService.taskApprove(flowApproveParam);
        TFCustomFlowEntity tfCustomFlowEntity = (TFCustomFlowEntity) map.get(SystemConstant.FLOW_ENTITY);
        if (!CollectionUtils.isEmpty(tbDingApply.getAttachmentIdList())) {
            List<BasicAttachment> basicAttachmentList = basicAttachmentService.listByIds(
                    tbDingApply.getAttachmentIdList());
            List<String> paths = new ArrayList<>(basicAttachmentList.size());
            for (BasicAttachment b : basicAttachmentList) {
                paths.add(basicAttachmentService.filePreview(b));
            }
            tbDingApply.setAttachmentPaths(StringUtils.join(paths, ";"));
        }
        tbDingApply.setCode(tfCustomFlowEntity.getCode(), tbDingApply.getAttachmentIdList(), sysUser.getId());
        tfCustomFlowEntity.setObjId(tbDingApply.getId());
        tfCustomFlowEntityService.updateById(tfCustomFlowEntity);

        if (!tbDingSubmitService.canUpdateDingSetting(serviceId, sopNo, sysUser.getId())) {
            throw ExceptionResultEnum.ERROR.exception("考勤已提交，不能申请补卡");
        }
        return tbDingApplyService.save(tbDingApply);
    }

    /**
     * 异常待审核接口
     *
     * @param iPage
     * @param serviceId
     * @param name
     * @param supplierId
     * @param customName
     * @param startTime
     * @param endTime
     * @param applyStartTime
     * @param applyEndTime
     * @param roleType
     * @return
     */
    @Override
    public IPage<DingApplyUnDoneResult> flowTaskUnDoneList(IPage<Map> iPage, Long serviceId, String name,
            Long supplierId, String customName, Long startTime, Long endTime, Long applyStartTime, Long applyEndTime,
            RoleTypeEnum roleType) throws Exception {
        SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
        DataPermissionDto dpr = sysUserService.buildUserDataPermission(requestUser.getId());
        if (dpr.getHasThirdPmo()) {
            // 乙方PMO
            Long userSupplierId = requestUser.getSupplierId();
            if (userSupplierId == null || userSupplierId == 0) {
                throw ExceptionResultEnum.ERROR.exception(
                        String.format("请先在用户管理中绑定[%s]对应的供应商", RoleTypeEnum.THIRD_PMO.getDesc()));
            }
            supplierId = userSupplierId;
        }
        IPage<DingApplyUnDoneResult> dingApplyUnDoneResultIPage = this.baseMapper.flowTaskUnDoneList(iPage, serviceId,
                name, supplierId, customName, startTime, endTime, applyStartTime, applyEndTime, dpr,
                Objects.nonNull(roleType) ? roleType.name() : null);
        if (Objects.nonNull(dingApplyUnDoneResultIPage) && !CollectionUtils.isEmpty(
                dingApplyUnDoneResultIPage.getRecords())) {
            for (DingApplyUnDoneResult d : dingApplyUnDoneResultIPage.getRecords()) {
                TFFlowLog tfFlowLog = tfFlowLogService.findByLastFlowLog(d.getFlowId());
                if (Objects.nonNull(tfFlowLog) && Objects.nonNull(tfFlowLog.getPendApproveId())) {
                    List<String> userList = Arrays.asList(
                            tfFlowLog.getPendApproveId().split(SystemConstant.LIST_JOIN_SPLIT));
                    List<OrgUserNameDto> orgUserNameDtoList = sysUserService.findOrgUserName(
                            userList.stream().map(s -> Long.parseLong(s)).collect(Collectors.toList()));
                    List<String> userName = orgUserNameDtoList.stream().map(s -> s.getOrgUserName())
                            .collect(Collectors.toList());
                    d.setApproveUserName(StringUtils.join(userName, SystemConstant.LIST_JOIN_SPLIT));
                }
                List<Task> taskList = taskService.createTaskQuery().processInstanceId(String.valueOf(d.getFlowId()))
                        .list();
                if (!CollectionUtils.isEmpty(taskList)) {
                    for (Task task : taskList) {
                        if (Objects.nonNull(task.getAssignee()) && task.getAssignee()
                                .equals(requestUser.getId().toString())) {
                            d.setMyself(true);
                            d.setTaskId(Long.parseLong(task.getId()));
                            break;
                        } else {
                            List<IdentityLink> identityLinkList = taskService.getIdentityLinksForTask(task.getId());
                            if (!CollectionUtils.isEmpty(identityLinkList)) {
                                for (IdentityLink i : identityLinkList) {
                                    if (i.getUserId().equals(requestUser.getId().toString())) {
                                        d.setMyself(true);
                                        d.setTaskId(Long.parseLong(task.getId()));
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        return dingApplyUnDoneResultIPage;
    }

    /**
     * 异常已审核接口
     *
     * @param iPage
     * @param serviceId
     * @param name
     * @param supplierId
     * @param dingExceptionApprove
     * @param customName
     * @param startTime
     * @param endTime
     * @param applyStartTime
     * @param applyEndTime
     * @param roleType
     * @return
     */
    @Override
    public IPage<DingApplyDoneResult> flowTaskDoneList(IPage<Map> iPage, Long serviceId, String name, Long supplierId,
            DingExceptionApproveEnum dingExceptionApprove, String customName, Long startTime, Long endTime,
            Long applyStartTime, Long applyEndTime, RoleTypeEnum roleType) throws Exception {
        SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
        DataPermissionDto dpr = sysUserService.buildUserDataPermission(requestUser.getId());
        if (dpr.getHasThirdPmo()) {
            // 乙方PMO
            Long userSupplierId = requestUser.getSupplierId();
            if (userSupplierId == null || userSupplierId == 0) {
                throw ExceptionResultEnum.ERROR.exception(
                        String.format("请先在用户管理中绑定[%s]对应的供应商", RoleTypeEnum.THIRD_PMO.getDesc()));
            }
            supplierId = userSupplierId;
        }
        IPage<DingApplyDoneResult> dingApplyDoneResultIPage = this.baseMapper.flowTaskDoneList(iPage, serviceId, name,
                supplierId, Objects.nonNull(dingExceptionApprove) ? dingExceptionApprove.name() : null, customName,
                startTime, endTime, applyStartTime, applyEndTime, dpr,
                Objects.nonNull(roleType) ? roleType.name() : null);
        if (Objects.nonNull(dingApplyDoneResultIPage) && !CollectionUtils.isEmpty(
                dingApplyDoneResultIPage.getRecords())) {
            for (DingApplyDoneResult d : dingApplyDoneResultIPage.getRecords()) {
                String string = tfFlowLogService.findByLastFlowLogApproveUser(d.getFlowId());
                if (Objects.nonNull(string)) {
                    List<String> userList = Arrays.asList(string.split(SystemConstant.LIST_JOIN_SPLIT));
                    List<OrgUserNameDto> orgUserNameDtoList = sysUserService.findOrgUserName(
                            userList.stream().map(s -> Long.parseLong(s)).collect(Collectors.toList()));
                    List<String> userName = orgUserNameDtoList.stream().map(s -> s.getOrgUserName())
                            .collect(Collectors.toList());
                    d.setApproveUsersName(StringUtils.join(userName, SystemConstant.LIST_JOIN_SPLIT));
                }
                if (Objects.nonNull(d.getApproveInfo())) {
                    String[] strs = d.getApproveInfo().split(";");
                    d.setDingExceptionApprove(strs[0]);
                    d.setApproveTime(Long.parseLong(strs[1]));
                    d.setApproveInfo(null);
                }
            }
        }
        return dingApplyDoneResultIPage;
    }

    /**
     * 考勤异常审核接口
     *
     * @param taskId
     * @param dingExceptionApprove
     * @param userId
     * @return
     * @throws InterruptedException
     */
    @Override
    @Transactional
    public Boolean flowApprove(Long taskId, DingExceptionApproveEnum dingExceptionApprove, Long userId)
            throws InterruptedException {
        SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
        userId = Objects.nonNull(sysUser) ? sysUser.getId() : userId;
        return tbDingApplyService.taskApprove(taskId, userId, dingExceptionApprove);
    }

    /**
     * 更新考勤异常打卡时间
     *
     * @param tbDingApply
     * @param dingExceptionApprove
     * @return
     */
    @Override
    @Transactional
    public Boolean updateDingExceptionTime(TBDingApply tbDingApply, DingExceptionApproveEnum dingExceptionApprove) {
        if (dingExceptionApprove == DingExceptionApproveEnum.PASS) {
            String sopNo = tbDingApply.getSopNo();
            TBDing tbDing;
            if (Objects.isNull(tbDingApply.getDingId())) {
                String date = DateUtil.format(new Date(tbDingApply.getApplyTime()),
                        SystemConstant.DEFAULT_DATE_YMD_S_QUERY_PATTERN);
                String[] strs = date.split("-");
                QueryWrapper<TBDing> tbDingQueryWrapper = new QueryWrapper<>();
                tbDingQueryWrapper.lambda().eq(TBDing::getSignYear, strs[0]).eq(TBDing::getSignDate, strs[1])
                        .eq(TBDing::getUserId, tbDingApply.getCreateId());
                if (SystemConstant.strNotNull(sopNo)) {
                    tbDingQueryWrapper.lambda().eq(TBDing::getSopNo, sopNo);
                } else {
                    tbDingQueryWrapper.lambda().isNull(TBDing::getSopNo);
                }
                if (tbDingApply.getType() == InOutTypeEnum.IN) {
                    tbDingQueryWrapper.lambda().isNull(TBDing::getSignInTime);
                } else {
                    tbDingQueryWrapper.lambda().isNull(TBDing::getSignOutTime);
                }
                tbDing = tbDingService.getOne(tbDingQueryWrapper);
            } else {
                tbDing = tbDingService.getById(tbDingApply.getDingId());
            }
            if (Objects.nonNull(tbDing)) {
                tbDingApply.setDingId(tbDing.getId());
                if (tbDingApply.getType() == InOutTypeEnum.IN) {
                    tbDing.setSignInTime(tbDingApply.getApplyTime());
                    tbDing.setSignInAddress("(补卡)");
                } else if (tbDingApply.getType() == InOutTypeEnum.OUT) {
                    tbDing.setSignOutTime(tbDingApply.getApplyTime());
                    tbDing.setSignOutAddress("(补卡)");
                }
                if (Objects.isNull(tbDing.getDateType())) {
                    DingDateTypeEnum dateType = sysDingDateService.getDingDateType(
                            DateDisposeUtils.timestampToLocalDate(tbDingApply.getApplyTime()));
                    tbDing.setDateType(dateType);
                }
                tbDingService.updateById(tbDing);
            } else {
                SysUser sysUser = sysUserService.getById(tbDingApply.getCreateId());
                Optional.ofNullable(sysUser).orElseThrow(ExceptionResultEnum.USER_NO_EXISTS::exception);
                UserArchivesResult userArchivesResult = tbUserArchivesService.findUserArchivesByArchivesIdORUserId(null,
                        sysUser.getId());

                List<SysRole> sysRoleList = sysUserRoleService.listRoleByUserId(sysUser.getId());
                if (CollectionUtils.isEmpty(sysRoleList)) {
                    throw ExceptionResultEnum.ERROR.exception("用户角色不存在");
                }
                if (SystemConstant.strNotNull(sopNo)) {
                    TFCustomFlowEntity tfCustomFlowEntity = tfCustomFlowEntityService.findByCode(sopNo);

                    List<SopRoleTypeEnum> roleType = tbUserArchivesAllocationService.findSopRoleTypeByUserSopNo(
                            sysUser.getId(), sopNo);
                    if (org.apache.commons.collections4.CollectionUtils.isEmpty(roleType)) {
                        throw ExceptionResultEnum.ERROR.exception("未找到用户在当前sop的身份信息");
                    }
                    tbDing = new TBDing(sopNo, tbDingApply.getCrmNo(), tbDingApply.getServiceId(),
                            userArchivesResult.getUserArchivesId(), JSON.toJSONString(roleType), sysUser.getId(),
                            tfCustomFlowEntity.getFlowId());
                } else {
                    // 区协
                    tbDing = new TBDing(null, null, tbDingApply.getServiceId(), userArchivesResult.getUserArchivesId(),
                            JSON.toJSONString(Collections.singletonList(SopRoleTypeEnum.REGION_COORDINATOR)),
                            sysUser.getId(), null);
                }
                tbDing.setSignDate(
                        DateFormatUtils.format(tbDingApply.getApplyTime(), SystemConstant.DEFAULT_DATE_DAY_PATTERN));
                tbDing.setSignYear(
                        DateFormatUtils.format(tbDingApply.getApplyTime(), SystemConstant.DEFAULT_DATE_YEAR_PATTERN));
                if (tbDingApply.getType() == InOutTypeEnum.IN) {
                    tbDing.setSignInTime(tbDingApply.getApplyTime());
                    tbDing.setSignInAddress("(补卡)");
                } else if (tbDingApply.getType() == InOutTypeEnum.OUT) {
                    tbDing.setSignOutTime(tbDingApply.getApplyTime());
                    tbDing.setSignOutAddress("(补卡)");
                }
                DingDateTypeEnum dateType = sysDingDateService.getDingDateType(
                        DateDisposeUtils.timestampToLocalDate(tbDingApply.getApplyTime()));
                tbDing.setDateType(dateType);
                tbDingService.save(tbDing);
                tbDingApply.setDingId(tbDing.getId());
            }
        }
        tbDingApply.setApprove(dingExceptionApprove);
        return tbDingApplyService.updateById(tbDingApply);
    }

    /**
     * 考勤异常审核接口
     *
     * @param taskIds
     * @param dingExceptionApprove
     * @param userId
     * @return
     * @throws InterruptedException
     */
    @Override
    @Transactional
    public Boolean flowBatchApprove(List<Long> taskIds, DingExceptionApproveEnum dingExceptionApprove, Long userId)
            throws InterruptedException {
        SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
        userId = Objects.nonNull(sysUser) ? sysUser.getId() : userId;
        for (Long l : taskIds) {
            tbDingApplyService.taskApprove(l, userId, dingExceptionApprove);
        }
        return true;
    }

    /**
     * 审批公用方法
     *
     * @param taskId
     * @param userId
     * @param dingExceptionApprove
     * @return
     * @throws InterruptedException
     */
    @Override
    public Boolean taskApprove(Long taskId, Long userId, DingExceptionApproveEnum dingExceptionApprove)
            throws InterruptedException {
        Optional.ofNullable(taskId).orElseThrow(() -> ExceptionResultEnum.FLOW_TASK_ID_IS_NULL.exception());

        SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
        Task task = taskService.createTaskQuery().taskId(String.valueOf(taskId)).singleResult();
        Optional.ofNullable(task).orElseThrow(() -> ExceptionResultEnum.FLOW_TASK_NO_DATA.exception());

        List<String> taskApproveUserList = activitiService.getTaskApprove(task);
        if (!CollectionUtils.isEmpty(taskApproveUserList) && !taskApproveUserList.contains(
                sysUser.getId().toString())) {
            throw ExceptionResultEnum.FLOW_DATA_NOT_ME.exception();
        }

        TFCustomFlowEntity tfCustomFlowEntity = tfCustomFlowEntityService.findByFlowId(
                Long.parseLong(task.getProcessInstanceId()));
        TBDingApply tbDingApply = this.getOne(new QueryWrapper<TBDingApply>().lambda()
                .eq(TBDingApply::getDingExceptionNo, tfCustomFlowEntity.getCode()));
        Optional.ofNullable(tbDingApply).orElseThrow(() -> ExceptionResultEnum.DING_APPLY_NO_DATA.exception());

        List<String> approveUserIds = new ArrayList<>();
        if (!Objects.equals(tfCustomFlowEntity.getCrmNo(), "-1")) {
            TBCrmDetail tbCrmDetail = tbCrmDetailService.findBySopNo(tfCustomFlowEntity.getCode());
            CrmProjectResult crmProjectResult = tbCrmService.findCrmProjectInfo(
                    Objects.nonNull(tbCrmDetail) ? tbCrmDetail.getSopNo() : null,
                    Objects.nonNull(tbCrmDetail) ? tbCrmDetail.getId() : null, tfCustomFlowEntity.getCrmNo());
            Optional.ofNullable(crmProjectResult).orElseThrow(() -> ExceptionResultEnum.CRM_NO_NO_DATA.exception());

            //        List<UserArchivesDto> regionCoordinatorList = crmProjectResult.getRegionCoordinatorList();
            //        if (CollectionUtils.isEmpty(regionCoordinatorList)) {
            //            throw ExceptionResultEnum.ERROR.exception("crm区域协调人数据为空");
            //        }
            //        Optional.ofNullable(regionCoordinatorList.get(0).getUserId())
            //                .orElseThrow(() -> ExceptionResultEnum.ERROR.exception("crm区域协调人数据为空"));
            List<String> sysUserRoleList = sysUserRoleService.listByServiceId(crmProjectResult.getServiceUnitId(),
                    tbDingApply.getCreateId(), tbDingApply.getSopNo());

            approveUserIds.addAll(sysUserRoleList);
        } else {
            // 区协补卡的审核
            approveUserIds.addAll(Collections.singletonList(String.valueOf(sysUser.getId())));
        }
        activitiService.taskApprove(
                new FlowApproveParam(taskId, FlowApprovePassEnum.PASS, approveUserIds, tfCustomFlowEntity.getCrmNo(),
                        dingExceptionApprove.getTitle()));
        return tbDingApplyService.updateDingExceptionTime(tbDingApply, dingExceptionApprove);
    }

    /**
     * 考勤异常申请详情接口
     *
     * @param id
     * @return
     */
    @Override
    public TBDingApplyViewResult view(Long id) {
        TBDingApply tbDingApply = this.getById(id);
        Optional.ofNullable(tbDingApply).orElseThrow(() -> ExceptionResultEnum.DING_APPLY_NO_DATA.exception());

        CrmProjectResult crmProjectResult = null;
        if (Objects.nonNull(tbDingApply.getSopNo())) {
            TBCrmDetail tbCrmDetail = tbCrmDetailService.findBySopNo(tbDingApply.getSopNo());
            crmProjectResult = tbCrmService.findCrmProjectInfo(
                    Objects.nonNull(tbCrmDetail) ? tbCrmDetail.getSopNo() : null,
                    Objects.nonNull(tbCrmDetail) ? tbCrmDetail.getId() : null, tbDingApply.getCrmNo());
            Optional.ofNullable(crmProjectResult).orElseThrow(() -> ExceptionResultEnum.CRM_NO_NO_DATA.exception());
        }

        TFCustomFlowEntity tfCustomFlowEntity = tfCustomFlowEntityService.findByCode(tbDingApply.getDingExceptionNo());
        //获取当前流程节点
        TFFlowApprove tfFlowApprove = tfFlowApproveService.findByFlowId(tfCustomFlowEntity.getFlowId());
        FlowResult flowResult = JSONObject.parseObject(tfCustomFlowEntity.getFlowProcessVar(), FlowResult.class);
        LinkedHashMap<String, FlowTaskResult> setupMap = flowResult.getSetupMap();
        FlowTaskResult currFlowTaskResult = null;
        List<FlowTaskResult> flowTaskHistoryList = null;
        List<Long> taskIdList = null;

        //获取流程审批历史
        List<TFFlowViewLogResult> flowApproveHistoryList = null;
        Map<Integer, Integer> approveSetupMap = new HashMap<>();
        List<TFFlowLogResult> tfFlowLogResultList = tfFlowLogService.findByObjectId(tfCustomFlowEntity.getId());
        if (!CollectionUtils.isEmpty(tfFlowLogResultList)) {
            flowApproveHistoryList = GsonUtil.fromJson(GsonUtil.toJson(tfFlowLogResultList),
                    new TypeToken<List<TFFlowViewLogResult>>() {

                    }.getType());
            for (TFFlowViewLogResult t : flowApproveHistoryList) {
                t.setMessageType(FlowMsgTypeEnum.STANDARD);
                approveSetupMap.put(t.getApproveSetup(), t.getApproveSetup());
            }
        }
        for (Map.Entry<String, FlowTaskResult> entry : setupMap.entrySet()) {
            FlowTaskResult flowTaskResult = GsonUtil.fromJson(GsonUtil.toJson(entry.getValue()), FlowTaskResult.class);
            if (flowTaskResult.getSetup() > 0) {
                //正在审批的表单
                if (Objects.nonNull(tfFlowApprove.getSetup())
                        && flowTaskResult.getSetup().intValue() == tfFlowApprove.getSetup().intValue()) {
                    currFlowTaskResult = flowTaskResult;
                    List<Task> taskList = taskService.createTaskQuery()
                            .processInstanceId(String.valueOf(tfCustomFlowEntity.getFlowId())).list();
                    if (!CollectionUtils.isEmpty(taskList)) {
                        taskIdList = taskList.stream().map(s -> Long.parseLong(s.getId())).collect(Collectors.toList());
                    }
                } else if (approveSetupMap.containsKey(flowTaskResult.getSetup())) {//已经审批过的表单
                    flowTaskHistoryList = CollectionUtils.isEmpty(flowTaskHistoryList) ?
                            new ArrayList<>(approveSetupMap.size()) :
                            flowTaskHistoryList;
                    flowTaskHistoryList.add(flowTaskResult);
                }
            }
        }
        TFFlowLog tfFlowLog = tfFlowLogService.findByLastFlowLog(tfFlowApprove.getFlowId());
        if (Objects.nonNull(tfFlowLog) && Objects.nonNull(tfFlowLog.getPendApproveId())) {
            List<String> userList = Arrays.asList(tfFlowLog.getPendApproveId().split(SystemConstant.LIST_JOIN_SPLIT));
            List<OrgUserNameDto> orgUserNameDtoList = sysUserService.findOrgUserName(
                    userList.stream().map(s -> Long.parseLong(s)).collect(Collectors.toList()));
            List<String> userName = orgUserNameDtoList.stream().map(s -> s.getOrgUserName())
                    .collect(Collectors.toList());
            tbDingApply.setApproveUserName(StringUtils.join(userName, SystemConstant.LIST_JOIN_SPLIT));
        }
        TBDing tbDing = tbDingService.getById(tbDingApply.getDingId());
        if (Objects.nonNull(tbDing)) {
            tbDingApply.setExceptionTime(tbDing.getSignDate());
        }
        return new TBDingApplyViewResult(crmProjectResult, tbDingApply, taskIdList, flowTaskHistoryList,
                currFlowTaskResult, flowApproveHistoryList);
    }

    @Override
    public List<SearchResult> findRegionCoordinatorAuditor(Long serviceId, Long userId) {
        List<SearchResult> result = new ArrayList<>();
        List<TBUserArchivesAllocation> tbUserArchivesAllocationList = tbUserArchivesAllocationService.list(
                new QueryWrapper<TBUserArchivesAllocation>().lambda()
                        .eq(TBUserArchivesAllocation::getServiceId, serviceId)
                        .eq(TBUserArchivesAllocation::getUserId, userId)
                        .eq(TBUserArchivesAllocation::getSopRoleType, SopRoleTypeEnum.REGION_COORDINATOR));
        List<String> crmNoList = tbUserArchivesAllocationList.stream().map(TBUserArchivesAllocation::getCrmNo)
                .distinct().collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(crmNoList)) {
            List<TBCrm> tbCrmList = tbCrmService.list(
                    new QueryWrapper<TBCrm>().lambda().in(TBCrm::getCrmNo, crmNoList));
            List<Long> leaderIdList = tbCrmList.stream().map(TBCrm::getLeadId).distinct().collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(leaderIdList)) {
                result = sysUserService.listByIds(leaderIdList).stream().flatMap(e -> {
                    SearchResult searchResult = new SearchResult();
                    searchResult.setId(e.getId());
                    searchResult.setValue(e.getRealName());
                    return Stream.of(searchResult);
                }).collect(Collectors.toList());
            }
        }
        return result;
    }
}
