package jnpf.personnels.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
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.conditions.update.UpdateWrapper;
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.PageInfo;
import io.seata.spring.annotation.GlobalTransactional;
import jnpf.attendance.AttendanceGroupApi;
import jnpf.attendance.dto.GroupUpdateByUserDTO;
import jnpf.base.ActionResult;
import jnpf.base.UserInfo;
import jnpf.entity.AttendanceGroup;
import jnpf.entity.StoreEntity;
import jnpf.enums.personnel.FtbPersonnelsCheckStatusCodeEnum;
import jnpf.model.vo.UserSalaryHistoryVo;
import jnpf.model.cultivate.CultivatePage;
import jnpf.model.cultivate.req.paper.SavePaperReq;
import jnpf.model.enums.FtbPersonnelsAuditTaskEnum;
import jnpf.model.enums.FtbPersonnelsCofigEnum;
import jnpf.model.enums.GrowthLogEnum;
import jnpf.model.enums.SalaryChangeTypeEnum;
import jnpf.model.personnels.dto.audit.FtbPersonnelsAuditDto;
import jnpf.model.personnels.dto.salary.FtbPersonnelsSalaryInfo;
import jnpf.model.personnels.dto.staff.growth.AddGrowthLogDto;
import jnpf.model.personnels.dto.staff.registerform.ProbationPeriodDto;
import jnpf.model.personnels.dto.staff.roster.WorkerGroupDataDto;
import jnpf.model.personnels.dto.staff.salarylog.AddSalaryChangeLogDto;
import jnpf.model.personnels.dto.staff.transfer.FtbPersonnelsStaffTransferPositionHandoverDto;
import jnpf.model.personnels.dto.staff.transfer.TransferGrowthLogDto;
import jnpf.model.personnels.dto.staff.transfer.TransferPositionCountDto;
import jnpf.model.personnels.dto.staff.transfer.TransferPositionDto;
import jnpf.model.personnels.po.FtbPersonnelsStaffRegistrationFormData;
import jnpf.model.personnels.po.FtbPersonnelsStaffRoster;
import jnpf.model.personnels.po.FtbPersonnelsStaffTransferPosition;
import jnpf.model.personnels.po.FtbPersonnelsStaffTransferPositionHandover;
import jnpf.model.personnels.req.employment.EmploymentApplyCheckDto;
import jnpf.model.personnels.req.transfer.*;
import jnpf.model.personnels.vo.app.FtbPersonnelsBubbleCountVO;
import jnpf.model.personnels.vo.salary.UserInfoWithSalary;
import jnpf.model.personnels.vo.task.FtbPersonnelsAuditInfoVO;
import jnpf.permission.PositionApi;
import jnpf.permission.RoleApi;
import jnpf.permission.UserApi;
import jnpf.permission.UserPrimaryPositionApi;
import jnpf.permission.dto.SynUserBoundRoleDTO;
import jnpf.permission.dto.UpdateUserManagerBoundDTO;
import jnpf.permission.dto.position.CheckExistByPositionDTO;
import jnpf.permission.dto.relation.BaseUserPrimaryPositionDTO;
import jnpf.permission.dto.role.RemoveUserRolesDTO;
import jnpf.permission.entity.OrganizeEntity;
import jnpf.permission.entity.PositionEntity;
import jnpf.permission.entity.UserEntity;
import jnpf.permission.model.position.PositionGradesInfoVO;
import jnpf.permission.model.role.RoleListVO;
import jnpf.permission.model.role.UserBoundRolesVO;
import jnpf.permission.model.user.UserInfoVO;
import jnpf.personnels.mapper.FtbPersonnelsStaffTransferPositionMapper;
import jnpf.personnels.service.*;
import jnpf.personnels.utils.PersonnelOrgUtils;
import jnpf.personnels.utils.PersonnelPerUtils;
import jnpf.salary.QuerySalaryApi;
import jnpf.store.service.StoreService;
import jnpf.util.StringUtil;
import jnpf.util.UserProvider;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class FtbPersonnelsStaffTransferPositionServiceImpl extends ServiceImpl<FtbPersonnelsStaffTransferPositionMapper, FtbPersonnelsStaffTransferPosition> implements FtbPersonnelsStaffTransferPositionService {

    @Autowired
    private FtbPersonnelsStaffRosterService staffRosterService;

    @Autowired
    private FtbPersonnelsStaffSalaryChangeLogService salaryChangeLogService;

    @Autowired
    private FtbPersonnelsStaffTransferPositionHandoverService transferPositionHandoverService;

    @Autowired
    private PersonnelOrgUtils personnelOrgUtils;

    @Autowired
    private FtbPersonnelsAuditRunTaskService auditRunTaskService;

    @Autowired
    private PersonnelPerUtils personnelPerUtils;

    @Autowired
    private FtbPersonnelsStaffGrowthLogService growthLogService;

    @Autowired
    private FtbPersonnelsAuditSubConfigService subConfigService;

    @Autowired
    private FtbPersonnelsStaffRegistrationFormDataService registrationFormDataService;

    @Autowired
    private FtbPersonnelsAuditRunTaskService ftbPersonnelsAuditRunTaskService;

    @Autowired
    FtbPersonnelsSalaryService personnelSalaryServiceImpl;

    @Autowired
    StoreService storeService;

    @Autowired
    PositionApi positionApi;

    @Resource
    private AttendanceGroupApi attendanceGroupApi;

    @Autowired
    FtbPersonnelsSalaryService salaryService;

    @Autowired
    QuerySalaryApi querySalaryApi;

    @Autowired
    RoleApi roleApi;

    @Autowired
    UserPrimaryPositionApi userPrimaryPositionApi;

    @Autowired
    UserApi userApi;

    @Override
    public PageInfo<TransferPositionDto> getPageList(QueryTransferListReq req) {
        Page<TransferPositionDto> queryPage = null;
        List<TransferPositionDto> records = new ArrayList<>();
        List<String> orgIds = personnelPerUtils.obtainPersonnelOrganizationIdDataPermissions();
        if (req.getListType() == 0) {
            queryPage = baseMapper.complatePagingQuery(Page.of(req.getCurrentPage(), req.getPageSize()), req, orgIds);
        } else if (req.getListType() == 1) {
            queryPage = baseMapper.waitCheckPagingQuery(Page.of(req.getCurrentPage(), req.getPageSize()), req, orgIds);
        }
        if (queryPage != null) {
            records = queryPage.getRecords();
        }
        if (CollectionUtil.isNotEmpty(records)) {
            fillOtherInfo(records);
            fillFormDataToTransfer(records);
        }
        //构建分页返回数据
        PageInfo<TransferPositionDto> pageInfo = new PageInfo<>();
        pageInfo.setList(records);
        pageInfo.setPageSize((int) queryPage.getSize());
        pageInfo.setPageNum((int) queryPage.getCurrent());
        pageInfo.setTotal((int) queryPage.getTotal());
        return pageInfo;
    }


    private void fillAllUserOrgInfo(List<TransferPositionDto> records) {
        List<String> userIds = records.stream().map(TransferPositionDto::getUserId).collect(Collectors.toList());
        Map<String, List<WorkerGroupDataDto>> userOrgBoundInfo = personnelOrgUtils.getUserOrgBoundInfo(userIds);
        records.forEach(item->{
            if (userOrgBoundInfo.containsKey(item.getUserId())) {
                item.setOrgList(userOrgBoundInfo.get(item.getUserId()));
            }
        });
    }

    private void fillFormDataToTransfer(List<TransferPositionDto> records) {
        List<String> rosterIds = records.stream().map(TransferPositionDto::getStaffRosterId).collect(Collectors.toList());
        Map<String, Map<String, String>> map = registrationFormDataService.querAllFormDataForRosterIds(rosterIds);
        for (TransferPositionDto record : records) {
            String staffRosterId = record.getStaffRosterId();
            if (!map.containsKey(staffRosterId)){
                continue;
            }
            Map<String, String> data = map.get(staffRosterId);
            String probationPeriod ="";
            if (data.containsKey("probationPeriod")) probationPeriod = data.get("probationPeriod");
            String planProbationaryDate ="";
            if (data.containsKey("planProbationaryDate")) planProbationaryDate =data.get("planProbationaryDate");
            if (StringUtils.isNotEmpty(probationPeriod) && probationPeriod.startsWith("{")) {
                ProbationPeriodDto bean = JSONUtil.toBean(probationPeriod, ProbationPeriodDto.class);
                record.setProbationPeriod(bean.getType());
                record.setProbationPeriodDay(bean.getDays());
            }
            if (StringUtils.isNotEmpty(planProbationaryDate)) {
                record.setPlanProbationaryDate(personnelOrgUtils.stringDateToDate(planProbationaryDate));
            }
        }
    }

    private void fillFormDataToTransferItem(TransferPositionDto record) {
        Map<String, FtbPersonnelsStaffRegistrationFormData> map = registrationFormDataService.queryAllFormData(record.getPhone(), record.getStaffRosterId());
        FtbPersonnelsStaffRegistrationFormData probationPeriod = map.get("probationPeriod");
        if (null != probationPeriod) {
            String value = probationPeriod.getValue();
            if (StringUtils.isNotEmpty(value) && value.startsWith("{")) {
                ProbationPeriodDto bean = JSONUtil.toBean(value, ProbationPeriodDto.class);
                record.setProbationPeriod(bean.getType());
                record.setProbationPeriodDay(bean.getDays());
            }
        }

        FtbPersonnelsStaffRegistrationFormData planProbationaryDate = map.get("planProbationaryDate");
        if (null != planProbationaryDate) {
            String value = planProbationaryDate.getValue();
            if (StringUtils.isNotEmpty(value)) {
                record.setPlanProbationaryDate(personnelOrgUtils.stringDateToDate(value));
            }
        }
    }


    @Override
    public PageInfo<TransferPositionDto> pageQueryMyCheckList(MyWebTransferCheckListReq req) {

        //审批状态：0、待审批  1、已审批
        String loginUserId = UserProvider.getLoginUserId();
        Page<TransferPositionDto> queryPage;
        Integer configType = FtbPersonnelsCofigEnum.POST_TRANSFER_APPROVAL_CONFIGURATION.getConfigType();
        if (0 == req.getCheckStatus()) {
            queryPage = baseMapper.pagingQueryWebMyCheckList(Page.of(req.getCurrentPage(), req.getPageSize()), loginUserId,configType);
        } else {
            queryPage = baseMapper.getApprovedList(Page.of(req.getCurrentPage(), req.getPageSize()), loginUserId,configType);
        }
        List<TransferPositionDto> records = queryPage.getRecords();
        if (CollectionUtil.isNotEmpty(records)) {
            fillOtherInfo(records);
            fillFormDataToTransfer(records);
        }
        //构建分页返回数据
        PageInfo<TransferPositionDto> pageInfo = new PageInfo<>();
        pageInfo.setList(records);
        pageInfo.setPageSize((int) queryPage.getSize());
        pageInfo.setPageNum((int) queryPage.getCurrent());
        pageInfo.setTotal((int) queryPage.getTotal());
        return pageInfo;
    }


    @Override
    public PageInfo<TransferPositionDto> getAppPageList(AppQueryTransferListReq req) {
        String loginUserId = UserProvider.getLoginUserId();
        Page<TransferPositionDto> queryPage = null;
        List<TransferPositionDto> records = null;
        if (req.getListType() == 0) {
            List<String> orgIds = personnelPerUtils.obtainPersonnelOrganizationIdDataPermissions();
            queryPage = baseMapper.appPagingQuery(Page.of(req.getCurrentPage(), req.getPageSize()), req, orgIds);
        } else if (req.getListType() == 1) {
            //1、我的审批
            Integer configType = FtbPersonnelsCofigEnum.POST_TRANSFER_APPROVAL_CONFIGURATION.getConfigType();
            if (req.getCheckStatus() == 0) {
                queryPage = baseMapper.pagingQueryWebMyCheckList(Page.of(req.getCurrentPage(), req.getPageSize()), loginUserId, configType);
            } else {
                queryPage = baseMapper.queryAccordingToTheCorrespondingStatus(Page.of(req.getCurrentPage(),
                                req.getPageSize()),
                        req.getCheckStatus(), loginUserId, configType);
            }
        } else if (req.getListType() == 2) {
            //2、抄送给我的
            queryPage = baseMapper.getListForApp(Page.of(req.getCurrentPage(), req.getPageSize()), req, loginUserId);
        } else if (req.getListType() == 3) {
            //3、我的调岗
            queryPage = baseMapper.myPagingQuery(Page.of(req.getCurrentPage(), req.getPageSize()), loginUserId);
        }
        records = queryPage.getRecords();
        if (CollectionUtil.isNotEmpty(records)) {
            fillOtherInfo(records);
            fillFormDataToTransfer(records);
        }
        return CultivatePage.coverPageInfo(queryPage);
    }

    /**
     * 查询我的待审批数量
     *
     * @return
     */
    @Override
    public TransferPositionCountDto queryAppMyCheckCount() {
        TransferPositionCountDto dto = new TransferPositionCountDto();


        String loginUserId = UserProvider.getLoginUserId();
        Integer configType = FtbPersonnelsCofigEnum.POST_TRANSFER_APPROVAL_CONFIGURATION.getConfigType();
        Page<TransferPositionDto> transferPositionDtoPage = baseMapper.pagingQueryWebMyCheckList(Page.of(1, 1), loginUserId, configType);
        dto.setWaitCount((int) transferPositionDtoPage.getTotal());

        Page<TransferPositionDto> dtoPage = baseMapper.queryAccordingToTheCorrespondingStatus(Page.of(1,
                1), 1, loginUserId, configType);
        dto.setQuantityUnderCount((int) dtoPage.getTotal());

        Page<TransferPositionDto> pass = baseMapper.queryAccordingToTheCorrespondingStatus(Page.of(1, 1), 2, loginUserId, configType);
        dto.setPassCount((int) pass.getTotal());


        Page<TransferPositionDto> noPass = baseMapper.queryAccordingToTheCorrespondingStatus(Page.of(1, 1), 3, loginUserId, configType);
        dto.setNoPassCount((int) noPass.getTotal());
        return dto;
    }

    /**
     * 查询我的抄送审批批数量
     *
     * @return
     */
    @Override
    public TransferPositionCountDto queryAppMySendCount() {
        TransferPositionCountDto dto = new TransferPositionCountDto();
        String loginUserId = UserProvider.getLoginUserId();
        AppQueryTransferListReq req = new AppQueryTransferListReq();
        req.setCheckStatus(1);
        Long count = baseMapper.getListForApp(new Page<>(), req, loginUserId).getTotal();
        dto.setQuantityUnderCount(Math.toIntExact(count));

        req.setCheckStatus(2);
        Long pass = baseMapper.getListForApp(new Page<>(), req, loginUserId).getTotal();
        dto.setPassCount(Math.toIntExact(pass));


        req.setCheckStatus(3);
        Long noPass = baseMapper.getListForApp(new Page<>(), req, loginUserId).getTotal();
        dto.setNoPassCount(Math.toIntExact(noPass));
        return dto;
    }

    @Override
    public FtbPersonnelsBubbleCountVO getListCont(String flag) {
        FtbPersonnelsBubbleCountVO covert;
        if ("1".equals(flag)) {
            TransferPositionCountDto transferPositionCountDto = queryAppMyCheckCount();
            covert = TransferPositionCountDto.covert(transferPositionCountDto);
        } else {
            TransferPositionCountDto transferPositionCountDto = queryAppMySendCount();
            covert = TransferPositionCountDto.covert(transferPositionCountDto);
        }
        return covert;
    }

    @Override
    public void clearJobTransferData(List<String> userIds) {
        LambdaQueryWrapper<FtbPersonnelsStaffTransferPosition> wrapper = Wrappers.lambdaQuery();
        wrapper.in(FtbPersonnelsStaffTransferPosition::getUserId,userIds);
        List<FtbPersonnelsStaffTransferPosition> managements = baseMapper.selectList(wrapper);
        if(CollectionUtil.isEmpty(managements)){
            return;
        }
        // 清除具有审批数据的数据
        managements.stream().filter(vo-> StringUtils.isNotEmpty(vo.getTaskInfoId()))
                .forEach (item->ftbPersonnelsAuditRunTaskService.deleteReviewProcessAndRecords(item.getTaskInfoId(),item.getId()));
        // 清楚转正数据
        LambdaUpdateWrapper<FtbPersonnelsStaffTransferPosition> lambdaed = Wrappers.lambdaUpdate();
        lambdaed.in(FtbPersonnelsStaffTransferPosition::getId,managements.stream().map(FtbPersonnelsStaffTransferPosition::getId).collect(Collectors.toList()));
        baseMapper.delete(lambdaed);
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public ActionResult<Void> dealTransferForOA(SaveTransferReq req) {
        // 重构调岗办理代码
        ActionResult<Void> actionResult = new ActionResult<Void>();
        String taskId = req.getTaskId();
        actionResult.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_PASS.getCode());
        actionResult.setMsg(FtbPersonnelsCheckStatusCodeEnum.CHECK_PASS.getMsg());
        if (req.getToMoney() == null) {
            req.setToMoney(BigDecimal.ZERO);
        }
        if (CollUtil.isNotEmpty(req.getToRoles())) req.setToRole(req.getToRoles().stream().collect(Collectors.joining(",")));
        String loginUserId = UserProvider.getLoginUserId();
        //查询用户是否已经有调岗流程
        List<String> userIds = req.getUserIds();
        String userId = userIds.get(0);
        req.setUserId(userId);
        String formMangerId = personnelOrgUtils.getLeaderInfo(req.getFromOrg(), userId, req.getFromPositionId(), req.getFromRankId());
        req.setFromManager(formMangerId);
        List<String> obUserIds = new ArrayList<>();
        // 权限用户
        String source = req.getSource();
        if(!"0".equals(source)) obUserIds = personnelPerUtils.obtainPersonnelDataPermissions();
        // 当前人不是本人申请,且权限中有当前可以办理人
        if (CollUtil.isNotEmpty(obUserIds)  && !obUserIds.contains(userId)){
            actionResult.setMsg("当前人办理人不具有该员工办理权限!");
            actionResult.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_REFUSE.getCode());
            return actionResult;
        }
        TransferPositionDto entity = baseMapper.queryNoCompleteForUserId(userId);
        if (null != entity) {
            actionResult.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_REFUSE.getCode());
            actionResult.setMsg( "用户已经存在调岗审批流程");
            return actionResult;
        }
        // 校验直属主管是否为试岗员工
        if (StringUtils.isNotEmpty(req.getToManager())){
            LambdaQueryWrapper<FtbPersonnelsStaffRoster> lambdaed = Wrappers.lambdaQuery();
            lambdaed.eq(FtbPersonnelsStaffRoster::getUserId,req.getToManager());
            FtbPersonnelsStaffRoster one = staffRosterService.getOne(lambdaed);
            if (one.getWorkerStatus().equals("306")) {
                actionResult.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_REFUSE.getCode());
                actionResult.setMsg( "试岗员工:"+one.getName()+"不能作为直属主管!");
                return actionResult;
            }
        }
        //查询用户花名册信息
        FtbPersonnelsStaffRoster rosterEntity = staffRosterService.queryRosterInfoByUserId(userId);
        if (null == rosterEntity) {
            actionResult.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_REFUSE.getCode());
            actionResult.setMsg( "用户花名册信息不存在");
            return actionResult;
        }
        if (rosterEntity.getEnabledMark() == 1) {
            actionResult.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_REFUSE.getCode());
            actionResult.setMsg( "用户花名册信息不存在");
            return actionResult;
        }
        if ("304".equals(rosterEntity.getWorkerStatus())) {
            actionResult.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_REFUSE.getCode());
            actionResult.setMsg( "员工处于离职中,不能调岗");
            return actionResult;
        }
        if ("305".equals(rosterEntity.getWorkerStatus())) {
            actionResult.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_REFUSE.getCode());
            actionResult.setMsg( "员工已经离职");
            return actionResult;
        }
        if (req.getFromOrg().equals(req.getToOrg()) &&
                req.getFromPositionId().equals(req.getToPositionId())
                && req.getFromRankId().equals(req.getToRankId())){
            actionResult.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_REFUSE.getCode());
            actionResult.setMsg( "员工调岗的组织岗位职等,无变化,不能办理调岗");
            return actionResult;
        }
        List<WorkerGroupDataDto> list = personnelOrgUtils.getUserOrgBoundInfo(userId);
        if (CollUtil.isNotEmpty(list) && list.size() > 1){
            // 员工所属组织
            for (WorkerGroupDataDto dataDto : list) {
                // 员工调岗组织岗位 都相同 不能有不同职等
                if (!( req.getToOrg().equals(req.getFromOrg())  && req.getToPositionId().equals(req.getFromPositionId()))
                        && (dataDto.getAffiliatedOrg().equals(req.getToOrg()) &&
                        dataDto.getAffiliatedPosition().equals(req.getToPositionId()))){
                    actionResult.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_REFUSE.getCode());
                    actionResult.setMsg( "您在目标组织中已所属于该岗位，不可重复选择同一组织下相同岗位！");
                    return actionResult;
                }
            }
        }
        String toRankId = req.getToRankId();
        String toPositionId = req.getToPositionId();
        String toOrg = req.getToOrg();
        if (toOrg.equals(req.getFromOrg())
                && toPositionId.equals(req.getFromPositionId())
                && toRankId.equals(req.getFromRankId())
        ) {
            actionResult.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_REFUSE.getCode());
            actionResult.setMsg( "原组织岗位职等和新组织岗位职等相同，无需调岗");
            return actionResult;
        }
        if (rosterEntity.getUserId().equals(req.getToManager())) {
            actionResult.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_REFUSE.getCode());
            actionResult.setMsg( "调岗后的直属主管不能是自己");
            return actionResult;
        }
        // v1.1 添加门店负责人校验
        // 跨组织校验
        if (!req.getFromOrg().equals(req.getToOrg())) {
            LambdaQueryWrapper<StoreEntity> storeEntityLambdaQueryWrapper = Wrappers.lambdaQuery();
            storeEntityLambdaQueryWrapper.eq(StoreEntity::getStoreheaduserid, userId);
            List<StoreEntity> storeEntities = storeService.list(storeEntityLambdaQueryWrapper);
            if (!storeEntities.isEmpty()){
                String storeNames = storeEntities.stream().map(StoreEntity::getStorename).collect(Collectors.joining(","));
                actionResult.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_REFUSE.getCode());
                actionResult.setMsg( "该人员为"+storeNames+"负责人，请为相关门店替换负责人，否则无法办理调岗。");
                return actionResult;
            }
        }
        //写入调岗表
        FtbPersonnelsStaffTransferPosition insertEntity = BeanUtil.copyProperties(req, FtbPersonnelsStaffTransferPosition.class);
        // 更新数据重新提交
        if (req.getSpecialBusinessId() != null ){
            insertEntity.setId(req.getSpecialBusinessId());
        }
        insertEntity.setEnabledMark(0);
        insertEntity.setPhone(rosterEntity.getPhone());
        insertEntity.setCheckStatus(1);
        insertEntity.setIsNeedCheck(0);
        insertEntity.setCreatorTime(new Date());
        insertEntity.setOpUser(loginUserId);
        insertEntity.setVersionNum(1);
        if ("0".equals(source)){
            insertEntity.setSource(0);
        }else if ("1".equals(source)){
            insertEntity.setSource(1);
        }
        String remarks = req.getRemarks();
        if (StringUtils.isNotEmpty(req.getSpecialBusinessId()) && StringUtils.isEmpty(remarks)){
            insertEntity.setRemarks(null);
        }else{
            insertEntity.setRemarks(remarks);
        }
        insertEntity.setOpUserName(UserProvider.getUser().getUserName());
        // 添加薪资详情
        List<FtbPersonnelsSalaryInfo> salaryStructureList = req.getSalaryStructureList();
        if (CollUtil.isEmpty(salaryStructureList)  && "1".equals(req.getIsAdjustSalary()) ){
            actionResult.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_REFUSE.getCode());
            actionResult.setMsg( "目标岗位暂无薪资结构，无法进行薪酬调整；建议选择是否调整薪酬为“否”！");
            return actionResult;
        }else if (CollUtil.isNotEmpty(salaryStructureList) && "1".equals(req.getIsAdjustSalary())) {
            insertEntity.setSalaryStructureListStr(JSONObject.toJSONString(salaryStructureList));
        }
        insertEntity.setTaskInfoId(taskId);
        if (req.getSpecialBusinessId() != null) {
            //删除工作物品交接表
            UpdateWrapper<FtbPersonnelsStaffTransferPositionHandover> updateWrapper = new UpdateWrapper<>();
            updateWrapper.lambda().set(FtbPersonnelsStaffTransferPositionHandover::getEnabledMark, 1)
                    .eq(FtbPersonnelsStaffTransferPositionHandover::getStaffTransferPositionId, req.getSpecialBusinessId());
            transferPositionHandoverService.update(updateWrapper);
        }
        // 构建主管
        UserInfoVO bossUser = userApi.getLeaderInfo(insertEntity.getFromOrg(), insertEntity.getUserId()
                ,insertEntity.getFromPositionId(),insertEntity.getFromRankId());
        if (ObjectUtil.isNotEmpty(bossUser)) insertEntity.setFromManager(bossUser.getId());
        saveOrUpdate(insertEntity);
        //写入调岗交接表
        List<FtbPersonnelsStaffTransferPositionHandover> handoverList = new ArrayList<>();
        // 工作交接
        List<String> recipientOfTheWorkUserIds = req.getRecipientOfTheWorkUserId();
        if (CollUtil.isNotEmpty(recipientOfTheWorkUserIds)) {
            String recipientOfTheWorkInfo = req.getRecipientOfTheWorkInfo();
            if (StringUtils.isNotEmpty(recipientOfTheWorkInfo) && StringUtil.length(recipientOfTheWorkInfo) > 50){
                actionResult.setMsg("调岗交接详情不能超过50字!");
                actionResult.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_REFUSE.getCode());
                return actionResult;
            }
            String recipientOfTheWorkUserId = recipientOfTheWorkUserIds.get(0);
            if( rosterEntity.getUserId().equals(recipientOfTheWorkUserId)){
                actionResult.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_REFUSE.getCode());

                actionResult.setMsg( "工作："+ recipientOfTheWorkInfo +" 的交接人不能是自己");
                return actionResult;
            }
            FtbPersonnelsStaffTransferPositionHandover handover = new FtbPersonnelsStaffTransferPositionHandover();
            handover.setStaffTransferPositionId(insertEntity.getId());
            handover.setType(1);
            handover.setName(recipientOfTheWorkInfo);
            handover.setToUserId(recipientOfTheWorkUserId);
            UserEntity userEntity = personnelOrgUtils.queryUserInfo(recipientOfTheWorkUserId);
            if (ObjectUtil.isNotEmpty(userEntity))handover.setToUserName(userEntity.getRealName());
            handover.setEnabledMark(0);
            handoverList.add(handover);
        }
        // 物品交接
        List<String> recipientOfTheItemUserIds = req.getRecipientOfTheItemUserId();
        if (CollUtil.isNotEmpty(recipientOfTheItemUserIds)) {
            String recipientOfTheItemInfo = req.getRecipientOfTheItemInfo();
            if (StringUtils.isNotEmpty(recipientOfTheItemInfo) && StringUtil.length(recipientOfTheItemInfo) > 50){
                actionResult.setMsg("调岗交接详情不能超过50字!");
                actionResult.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_REFUSE.getCode());
                return actionResult;
            }
            String recipientOfTheItemUserId = recipientOfTheItemUserIds.get(0);
            if( rosterEntity.getUserId().equals(recipientOfTheItemUserId)){
                actionResult.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_REFUSE.getCode());
                actionResult.setMsg( "物品："+recipientOfTheItemInfo+" 的接收人不能是自己");
                return actionResult;
            }
            FtbPersonnelsStaffTransferPositionHandover handover = new FtbPersonnelsStaffTransferPositionHandover();
            handover.setStaffTransferPositionId(insertEntity.getId());
            handover.setType(0);
            handover.setName(recipientOfTheItemInfo);
            handover.setToUserId(recipientOfTheItemUserId);
            UserEntity userEntity = personnelOrgUtils.queryUserInfo(recipientOfTheItemUserId);
            if (ObjectUtil.isNotEmpty(userEntity)) handover.setToUserName(userEntity.getRealName());
            handover.setEnabledMark(0);
            handoverList.add(handover);
        }
        if (CollectionUtil.isNotEmpty(handoverList)) {
            transferPositionHandoverService.saveBatch(handoverList);
        }
        //花名册设置用户调岗中
        FtbPersonnelsStaffRoster staffRoster = new FtbPersonnelsStaffRoster();
        staffRoster.setId(rosterEntity.getId());
        staffRoster.setTransferPosition(1);
        staffRosterService.updateById(staffRoster);
        return actionResult;
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public ActionResult<Void> approvalForOA(EmploymentApplyCheckDto dto) {
        ActionResult<Void> actionResult = new ActionResult<Void>();
        actionResult.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_PASS.getCode());
        actionResult.setMsg(FtbPersonnelsCheckStatusCodeEnum.CHECK_PASS.getMsg());
        LambdaQueryWrapper<FtbPersonnelsStaffTransferPosition> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(FtbPersonnelsStaffTransferPosition::getTaskInfoId,dto.getTaskId());
        FtbPersonnelsStaffTransferPosition entity = baseMapper.selectOne(queryWrapper);
        if (ObjectUtil.isNull(entity)){
            actionResult.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_REFUSE.getCode());
            actionResult.setMsg("该审批数据不存在,无法进行审批操作!");
            return actionResult;
        }
        // 校验
        // 选择通过需要校验组织是否存在
        String toRankId = entity.getToRankId();
        String toPositionId = entity.getToPositionId();
        String toOrg = entity.getToOrg();
        if (1 == dto.getIsPass()){
            // 校验岗位是否还存在
            CheckExistByPositionDTO checkExistByPositionDTO = new CheckExistByPositionDTO();
            checkExistByPositionDTO.setOrganizeId(toOrg);
            checkExistByPositionDTO.setPositionId(toPositionId);
            checkExistByPositionDTO.setPositionGradesId(toRankId);
            ActionResult<Boolean> booleanActionResult = positionApi.checkExistByPositionMore(checkExistByPositionDTO);
            if (booleanActionResult  == null || !booleanActionResult.getData()){
                actionResult.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_REFUSE.getCode());
                actionResult.setMsg( "该员工的岗位在提交调岗审批后发生了变更，无法继续审批；请选择“不通过”结束审批流程！");
                return actionResult;
            }
        }
        if (1 == dto.getIsPass()){
            // 校验岗位是否还存在
            CheckExistByPositionDTO checkExistByPositionDTO = new CheckExistByPositionDTO();
            checkExistByPositionDTO.setOrganizeId(entity.getFromOrg());
            checkExistByPositionDTO.setPositionId(entity.getFromPositionId());
            checkExistByPositionDTO.setPositionGradesId(entity.getFromRankId());
            ActionResult<Boolean> booleanActionResult = positionApi.checkExistByPositionMore(checkExistByPositionDTO);
            if (booleanActionResult  == null || !booleanActionResult.getData()){
                actionResult.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_REFUSE.getCode());
                actionResult.setMsg( "该员工的岗位在提交调岗审批后发生了变更，无法继续审批；请选择“不通过”结束审批流程！");
                return actionResult;
            }
        }
        if ( entity.getEnabledMark() == 1) {
            actionResult.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_REFUSE.getCode());
            actionResult.setMsg( "调岗信息不存在");
            return actionResult;
        }
        if (entity.getIsNeedCheck() == 1) {
            actionResult.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_REFUSE.getCode());
            actionResult.setMsg( "该员工调岗不需要审核");
            return actionResult;
        }
        if (entity.getIsNeedCheck() == 0 && entity.getCheckStatus() == 2) {
            actionResult.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_REFUSE.getCode());
            actionResult.setMsg( "该员工调岗审核已经通过");
            return actionResult;
        }
        if (entity.getIsNeedCheck() == 0 && entity.getCheckStatus() == 3) {
            actionResult.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_REFUSE.getCode());
            actionResult.setMsg( "该员工调岗审核已经不通过");
            return actionResult;
        }
        if (entity.getIsNeedCheck() == 0 && entity.getCheckStatus() == 4) {
            actionResult.setCode(FtbPersonnelsCheckStatusCodeEnum.CHECK_REFUSE.getCode());
            actionResult.setMsg( "该员工调岗审核已经撤销");
            return actionResult;
        }
        FtbPersonnelsStaffRoster roster = staffRosterService.queryRosterInfoByUserId(entity.getUserId());
        FtbPersonnelsAuditDto checkDto = new FtbPersonnelsAuditDto();
        checkDto.setBusinessId(entity.getId());
        if (ObjectUtil.isNotEmpty(dto.getIsConformSalary())) {
            checkDto.setDoesTheSalaryComplyWith(dto.getIsConformSalary());
        }
        if (ObjectUtil.isNotEmpty(dto.getMsg())) {
            checkDto.setApprovalComments(dto.getMsg());
        }
        if (ObjectUtil.isNotEmpty(dto.getIsPass())) {
            checkDto.setFlag(String.valueOf(dto.getIsPass()));
        }
        //FtbPersonnelsAuditTaskEnum code = auditRunTaskService.performReview(checkDto);

        entity.setTransferDate(new Date());
        // 添加薪资详情
        List<FtbPersonnelsSalaryInfo> salaryStructureList = dto.getSalaryStructureList();
        if (CollUtil.isEmpty(salaryStructureList)  && "1".equals(dto.getIsAdjustSalary()) ){
            actionResult.setMsg( "目标岗位暂无薪资结构，无法进行薪酬调整；建议选择是否调整薪酬为“否”！");
            actionResult.setCode( FtbPersonnelsCheckStatusCodeEnum.CHECK_REFUSE.getCode());
            return actionResult;
        }else if (CollUtil.isNotEmpty(salaryStructureList) && "1".equals(dto.getIsAdjustSalary())) {
            entity.setToMoney(dto.getToMoney());
            entity.setSalaryStructure(dto.getSalaryStructure());
            entity.setIsAdjustSalary(dto.getIsAdjustSalary());
            entity.setSalaryStructureListStr(JSONObject.toJSONString(salaryStructureList));
            entity.setReasonsForSalaryAdjustments(dto.getReasonsForSalaryAdjustments());
            entity.setPayrollEffectiveDate(dto.getPayrollEffectiveDate());
        }
        FtbPersonnelsAuditTaskEnum code = checkDto.getFlag().equals("0") ? FtbPersonnelsAuditTaskEnum.AUDIT_NOT_PASSED : FtbPersonnelsAuditTaskEnum.EXAMINATION_PASSED;
        switch (code) {
            case EXAMINATION_PASSED:
                entity.setCheckStatus(2);
                // 提出公共部分
                raisePublicPart(entity, roster, toOrg, toPositionId, toRankId);
                break;
            case AUDIT_NOT_PASSED:
                entity.setCheckStatus(3);
                roster.setTransferPosition(3);
                staffRosterService.updateById(roster);
                break;
        }
        baseMapper.updateById(entity);
        return actionResult;
    }

    private void raisePublicPart(FtbPersonnelsStaffTransferPosition entity, FtbPersonnelsStaffRoster roster, String toOrg, String toPositionId, String toRankId) {
        //写入调岗薪资变化流程
        AddSalaryChangeLogDto addSalaryChangeLogDto = new AddSalaryChangeLogDto();
        addSalaryChangeLogDto.setUserId(entity.getUserId());
        addSalaryChangeLogDto.setChangeDate(new Date());
        addSalaryChangeLogDto.setSalary(entity.getToMoney());
        addSalaryChangeLogDto.setChangeType(SalaryChangeTypeEnum.TRANSFER_POSITION.getCode());
        salaryChangeLogService.addSalaryChangeLog(addSalaryChangeLogDto);

        transferToWriteGrowth(entity.getUserId(), entity, entity.getRemarks(), roster);

        roster.setTransferPosition(2);
        roster.setCurrSalary(entity.getToMoney());
        staffRosterService.updateById(roster);
        //同步角色
        boolean flag = entity.getToOrg().equals(entity.getFromOrg());
        asyncRole(entity.getUserId(),flag);

        //修改用户组织岗位职等直属主管
        UpdateUserManagerBoundDTO updateUserManagerBoundDTO = new UpdateUserManagerBoundDTO();
        updateUserManagerBoundDTO.setUserId(entity.getUserId());
        updateUserManagerBoundDTO.setOldOrgId(entity.getFromOrg());
        updateUserManagerBoundDTO.setOldPositionId(entity.getFromPositionId());
        updateUserManagerBoundDTO.setOldPositionGradesId(entity.getFromRankId());
        updateUserManagerBoundDTO.setOldManagerId(entity.getFromManager());
        updateUserManagerBoundDTO.setOrgId(toOrg);
        updateUserManagerBoundDTO.setPositionId(toPositionId);
        updateUserManagerBoundDTO.setPositionGradesId(toRankId);
        updateUserManagerBoundDTO.setManagerId(entity.getToManager());
        personnelOrgUtils.updateSysUserBound(updateUserManagerBoundDTO);
        BaseUserPrimaryPositionDTO primaryPositionDTO = new BaseUserPrimaryPositionDTO();
        primaryPositionDTO.setUserId(entity.getUserId());
        primaryPositionDTO.setOrganizeId(entity.getFromOrg());
        primaryPositionDTO.setPositionId(entity.getFromPositionId());
        primaryPositionDTO.setPositionGradesId(entity.getFromRankId());
        primaryPositionDTO.setManagerId(entity.getFromManager());
        ActionResult<Boolean> position = userPrimaryPositionApi.isUserUserPrimaryPosition(primaryPositionDTO);
        if (position != null && position.getData()){
            // 更新用户主岗
            BaseUserPrimaryPositionDTO positionDTO = new BaseUserPrimaryPositionDTO();
            positionDTO.setUserId(entity.getUserId());
            positionDTO.setOrganizeId(entity.getToOrg());
            positionDTO.setPositionId(entity.getToPositionId());
            positionDTO.setPositionGradesId(entity.getToRankId());
            positionDTO.setManagerId(entity.getToManager());
            userPrimaryPositionApi.updateUserPrimaryPosition(positionDTO);
        }

        /**
         * 同步用户考勤组
         */
        if (StringUtils.isNotEmpty(entity.getAttendanceGroup())) {
            UserInfo userInfo = UserProvider.getUser();
            GroupUpdateByUserDTO groupUpdateByUserDTO = new GroupUpdateByUserDTO();
            groupUpdateByUserDTO.setTenantId(userInfo.getTenantId());
            groupUpdateByUserDTO.setType(3);// 1入职 2离职 3调岗
            groupUpdateByUserDTO.setToGroupId(entity.getAttendanceGroup());
            groupUpdateByUserDTO.setUserIds(List.of(entity.getUserId()));
            personnelOrgUtils.syncAttendanceGroup(groupUpdateByUserDTO);
        }

        UserInfo userInfo = UserProvider.getUser();
        staffRosterService.logout(userInfo.getTenantId(), entity.getUserId());
        // 同步薪资详情
        String salaryStructureList = entity.getSalaryStructureListStr();
        if (StringUtils.isNotEmpty(salaryStructureList) && "1".equals(entity.getIsAdjustSalary())) {
            UserInfoWithSalary userInfoWithSalary = new UserInfoWithSalary();
            PositionGradesInfoVO positionGradesInfoVO = personnelOrgUtils.queryRank(toRankId);
            PositionEntity positionEntity = personnelOrgUtils.queryPosition(toPositionId);
            OrganizeEntity organizeEntity = personnelOrgUtils.queryOrganizeInfo(toOrg);
            userInfoWithSalary.setRankName(positionGradesInfoVO.getFullName());
            userInfoWithSalary.setRankId(toRankId);
            userInfoWithSalary.setFOrgId(toOrg);
            userInfoWithSalary.setFOrgName(organizeEntity.getFullName());
            userInfoWithSalary.setPostId(toPositionId);
            userInfoWithSalary.setPostName(positionEntity.getFullName());
            // 审核通过同步数据
            List<FtbPersonnelsSalaryInfo> list = JSONUtil.toList(salaryStructureList, FtbPersonnelsSalaryInfo.class);
            salaryService.saveTheChangePayInformation(list,
                    entity.getUserId(),
                    entity.getPayrollEffectiveDate(),
                    userInfoWithSalary,
                    "1",
                    entity.getReasonsForSalaryAdjustments(),
                    "2", 0,null, "");
        }
    }

    private void transferToWriteGrowth(String entity, FtbPersonnelsStaffTransferPosition entity1, String entity2, FtbPersonnelsStaffRoster roster) {
        //写入员工成长记录
        AddGrowthLogDto addGrowthLogDto = new AddGrowthLogDto();
        addGrowthLogDto.setUserId(entity);
        addGrowthLogDto.setChangeDate(new Date());
        addGrowthLogDto.setGrowthType(GrowthLogEnum.TRANSFER_POSITION.getCode());
        TransferPositionDto positionDto = BeanUtil.copyProperties(entity1, TransferPositionDto.class);
        String json = buildTransferGrowthLogDetail(positionDto,roster.getActualStartDate());
        addGrowthLogDto.setDetail(json);
        addGrowthLogDto.setRemarks(entity2);
        addGrowthLogDto.setEmployeeId(roster.getSystemWokerId());
        addGrowthLogDto.setActualStartDate(roster.getActualStartDate());
        // 调岗的
        growthLogService.addGrowthLog(addGrowthLogDto);
    }


    /**
     * 提取相同code
     * @param records
     * @param first
     * @param second
     * @return
     */
    protected List<String> extractTheSameCode(List<TransferPositionDto> records,
                                              Function<TransferPositionDto,String> first,
                                              Function<TransferPositionDto,String> second) {
        return CollUtil.unionAll(records.stream().map(first).collect(Collectors.toList()),
                records.stream().map(second).collect(Collectors.toList()));
    }

    private void fillOtherInfo(List<TransferPositionDto> records) {
        Map<String, String> orgNames = personnelOrgUtils.getOrgNames(
                extractTheSameCode(records,TransferPositionDto::getToOrg,TransferPositionDto::getFromOrg));
        Map<String, String> postNames = personnelOrgUtils.getPostNames(
                extractTheSameCode(records,TransferPositionDto::getToPositionId,TransferPositionDto::getFromPositionId));
        Map<String, String> gradesNames = personnelOrgUtils.getGradesNames(
                extractTheSameCode(records,TransferPositionDto::getToRankId,TransferPositionDto::getFromRankId));
        Map<String, String> toManagerNames = personnelOrgUtils.getUserNames(
                extractTheSameCode(records,TransferPositionDto::getToManager,TransferPositionDto::getFromManager));
        List<String> roleIds = records.stream().map(TransferPositionDto::getToRole)
                .filter(StringUtils::isNotEmpty).collect(Collectors.toList());
        List<String> newRoleIds = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(roleIds)){
            for (String roleId : roleIds) {
                if (roleId.contains(",")){
                    newRoleIds.addAll( List.of(roleId.split(","))) ;
                }else {
                    newRoleIds.add(roleId);
                }
            }
        }
        Map<String, String> newRoleNames = personnelOrgUtils.getRoleNames(newRoleIds);
        for (TransferPositionDto info : records) {
            //补充岗位信息
            // personnelOrgUtils.fillOtherInfoForItem(info);
            if (orgNames.containsKey(info.getFromOrg())) {
                info.setFromOrgName(orgNames.get(info.getFromOrg()));
            }
            if (orgNames.containsKey(info.getToOrg())) {
                info.setToOrgName(orgNames.get(info.getToOrg()));
            }
            if (postNames.containsKey(info.getFromPositionId())) {
                info.setFromPositionIdName(postNames.get(info.getFromPositionId()));
            }
            if (postNames.containsKey(info.getToPositionId())) {
                info.setToPositionIdName(postNames.get(info.getToPositionId()));
            }

            if (gradesNames.containsKey(info.getFromRankId())) {
                info.setFromRankIdName(gradesNames.get(info.getFromRankId()));
            }
            if (gradesNames.containsKey(info.getToRankId())) {
                info.setToRankIdName(gradesNames.get(info.getToRankId()));
            }
            String toRole = info.getToRole();
            String roleName ="";
            if (StringUtils.isNotEmpty(toRole)) {
                if (toRole.contains(",")) {
                    String[] split = toRole.split(",");
                    roleName = Arrays.stream(split).map(newRoleNames::get).collect(Collectors.joining(","));
                } else {
                    roleName = newRoleNames.get(toRole);
                }
                info.setToRoleName(roleName);
            }

            if (toManagerNames.containsKey(info.getToManager())) {
                info.setToManagerName(toManagerNames.get(info.getToManager()));
            }
            if (toManagerNames.containsKey(info.getFromManager())) {
                info.setFromManagerName(toManagerNames.get(info.getFromManager()));
            }
        }
    }

    @Override
    public TransferPositionDto getInfo(String id) {
        TransferPositionDto info = baseMapper.getInfoForId(id);
        if (ObjectUtil.isNotEmpty(info)) {
            //补充交接数据
            List<FtbPersonnelsStaffTransferPositionHandover> goodList = transferPositionHandoverService.list(new QueryWrapper<FtbPersonnelsStaffTransferPositionHandover>().lambda().eq(FtbPersonnelsStaffTransferPositionHandover::getEnabledMark, 0).eq(FtbPersonnelsStaffTransferPositionHandover::getType, 0).eq(FtbPersonnelsStaffTransferPositionHandover::getStaffTransferPositionId, id));
            List<FtbPersonnelsStaffTransferPositionHandover> handovers = transferPositionHandoverService.list(new QueryWrapper<FtbPersonnelsStaffTransferPositionHandover>().lambda().eq(FtbPersonnelsStaffTransferPositionHandover::getEnabledMark, 0).eq(FtbPersonnelsStaffTransferPositionHandover::getStaffTransferPositionId, id));
            Map<String, FtbPersonnelsStaffRoster> rosterMap =new HashMap<>();
            if (CollectionUtil.isNotEmpty(handovers)) {
                LambdaQueryWrapper<FtbPersonnelsStaffRoster> lambdaed = Wrappers.lambdaQuery();
                lambdaed.in(FtbPersonnelsStaffRoster::getUserId, handovers.stream().map(FtbPersonnelsStaffTransferPositionHandover::getToUserId).collect(Collectors.toList()));
                List<FtbPersonnelsStaffRoster> staffRosters = staffRosterService.list(lambdaed);
                rosterMap= staffRosters.stream().collect(Collectors.toMap(FtbPersonnelsStaffRoster::getUserId, Function.identity(), (k1, k2) -> k1));
            }
            if (CollectionUtil.isNotEmpty(goodList)) {
                Map<String, FtbPersonnelsStaffRoster> finalRosterMap = rosterMap;
                goodList.forEach(item->{
                    if(finalRosterMap.containsKey(item.getToUserId())){
                        item.setToUserId(finalRosterMap.get(item.getToUserId()).getSystemWokerId());
                    }});
                info.setGoodsPositionHandoverList(BeanUtil.copyToList(goodList, FtbPersonnelsStaffTransferPositionHandoverDto.class));
            }
            List<FtbPersonnelsStaffTransferPositionHandover> workList = transferPositionHandoverService.list(new QueryWrapper<FtbPersonnelsStaffTransferPositionHandover>().lambda().eq(FtbPersonnelsStaffTransferPositionHandover::getEnabledMark, 0).eq(FtbPersonnelsStaffTransferPositionHandover::getType, 1).eq(FtbPersonnelsStaffTransferPositionHandover::getStaffTransferPositionId, id));
            if (CollectionUtil.isNotEmpty(workList)) {
                Map<String, FtbPersonnelsStaffRoster> finalRosterMap = rosterMap;
                workList.forEach(item->{
                    if(finalRosterMap.containsKey(item.getToUserId())) {
                        item.setToUserId(finalRosterMap.get(item.getToUserId()).getSystemWokerId());
                    }
                });
                info.setWorkerPositionHandoverList(BeanUtil.copyToList(workList, FtbPersonnelsStaffTransferPositionHandoverDto.class));
            }
            if(StringUtils.isNotEmpty(info.getSalaryStructureStr())){
                List<FtbPersonnelsSalaryInfo> parseArray = JSONObject.parseArray(info.getSalaryStructureStr(), FtbPersonnelsSalaryInfo.class);
                info.setSalaryStructureList(parseArray);
            }
            //补充岗位信息
            personnelOrgUtils.fillOtherInfoForItem(info);
            List<WorkerGroupDataDto> list = personnelOrgUtils.getUserOrgBoundInfo(info.getUserId());
            if (info.getFromManager() != null) {
                UserEntity userEntity = personnelOrgUtils.queryUserInfo(info.getFromManager());
                info.setFromManagerName(userEntity !=null ? userEntity.getRealName() : null);
            }
            info.setOrgList(list);
            fillFormDataToTransferItem(info);
            //需要审批 并且审批还没有通过时需要返回
            if (info.getIsNeedCheck() == 0) {
                FtbPersonnelsAuditInfoVO auditInfoVO = subConfigService.queryAuditSubConfig(info.getFromOrg(), FtbPersonnelsCofigEnum.POST_TRANSFER_APPROVAL_CONFIGURATION);
                info.setAuditInfo(auditInfoVO);
            }
            if (StringUtils.isNotEmpty(info.getAttendanceGroup())){
                AttendanceGroup attendanceGroup = attendanceGroupApi.queryTheNameOfTheAttendanceGroup(info.getAttendanceGroup());
                if (attendanceGroup != null) info.setAttendanceGroupName(attendanceGroup.getGroupName());
            }
            //当前薪酬
            FtbPersonnelsStaffRoster staffRoster = staffRosterService.queryRosterInfoByUserId(info.getUserId());
            List<FtbPersonnelsSalaryInfo> ftbPersonnelsSalaryInfos = personnelSalaryServiceImpl.innerGetTheCurrentPersonSSalary(staffRoster, "", "");
            BigDecimal sum = new BigDecimal(0);
            if (CollectionUtil.isNotEmpty(ftbPersonnelsSalaryInfos)) {
                for (FtbPersonnelsSalaryInfo ftbPersonnelsSalaryInfo : ftbPersonnelsSalaryInfos) {
                    if (ftbPersonnelsSalaryInfo.getFValueType().equals("1") && StringUtils.isNotEmpty(ftbPersonnelsSalaryInfo.getFSetValue())) {
                        sum = sum.add(new BigDecimal(ftbPersonnelsSalaryInfo.getFSetValue()));
                    }
                }
            }
            sum = sum.setScale(2, RoundingMode.DOWN);
            info.setCurrSalary(sum);
        }

        return info;
    }


    @SneakyThrows
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String insertData(SaveTransferReq req) {
        String returnData = "";
        if (req.getToMoney() == null) {
            req.setToMoney(BigDecimal.ZERO);
        }
        UserInfo user = UserProvider.getUser();
        String loginUserId = user.getUserId();
        if (!"0".equals(req.getSource()) && req.getUserId().equals(loginUserId)){
            throw new RuntimeException("办理调岗无法给自己进行手动调岗!");
        }
        //查询用户是否已经有调岗流程
        TransferPositionDto entity = baseMapper.queryNoCompleteForUserId(req.getUserId());
        if (null != entity) {
            throw new RuntimeException("用户已经存在调岗审批流程");
        }
        // 校验直属主管是否为试岗员工
        if (StringUtils.isNotEmpty(req.getToManager())){
            LambdaQueryWrapper<FtbPersonnelsStaffRoster> lambdaed = Wrappers.lambdaQuery();
            lambdaed.eq(FtbPersonnelsStaffRoster::getUserId,req.getToManager());
            FtbPersonnelsStaffRoster one = staffRosterService.getOne(lambdaed);
            if (one.getWorkerStatus().equals("306")) throw new RuntimeException("试岗员工:"+one.getName()+"不能作为直属主管!");
        }
        //查询用户花名册信息
        FtbPersonnelsStaffRoster rosterEntity = staffRosterService.queryRosterInfoByUserId(req.getUserId());
        if (null == rosterEntity) {
            throw new RuntimeException("用户花名册信息不存在");
        }
        if (rosterEntity.getEnabledMark() == 1) {
            throw new RuntimeException("用户花名册信息不存在");
        }
        if ("304".equals(rosterEntity.getWorkerStatus())) {
            throw new RuntimeException("员工处于离职中,不能调岗");
        }
        if ("305".equals(rosterEntity.getWorkerStatus())) {
            throw new RuntimeException("员工已经离职");
        }
        if (req.getFromOrg().equals(req.getToOrg()) &&
                req.getFromPositionId().equals(req.getToPositionId())
                && req.getFromRankId().equals(req.getToRankId())){
            throw new RuntimeException("员工调岗的组织岗位职等,无变化,不能办理调岗");
        }
        // 校验岗位是否还存在
        CheckExistByPositionDTO checkExistByPositionDTO = new CheckExistByPositionDTO();
        checkExistByPositionDTO.setOrganizeId(req.getToOrg());
        checkExistByPositionDTO.setPositionId(req.getToPositionId());
        checkExistByPositionDTO.setPositionGradesId(req.getToRankId());
        ActionResult<Boolean> booleanActionResult = positionApi.checkExistByPositionMore(checkExistByPositionDTO);
        if (booleanActionResult  == null || !booleanActionResult.getData()){
            throw new RuntimeException( "该员工调岗的目标岗位不存在，无法继续提交！");
        }
        // 校验岗位是否还存在
        CheckExistByPositionDTO checkExistByPositionDTO1 = new CheckExistByPositionDTO();
        checkExistByPositionDTO1.setOrganizeId(req.getFromOrg());
        checkExistByPositionDTO1.setPositionId(req.getFromPositionId());
        checkExistByPositionDTO1.setPositionGradesId(req.getFromRankId());
        ActionResult<Boolean> booleanActionResult2 = positionApi.checkExistByPositionMore(checkExistByPositionDTO1);
        if (booleanActionResult2  == null || !booleanActionResult2.getData()){
            throw new RuntimeException( "该员工的岗位在提交调岗后发生了变更，无法继续提交！");
        }
        List<WorkerGroupDataDto> list = personnelOrgUtils.getUserOrgBoundInfo(req.getUserId());
        if (CollUtil.isNotEmpty(list) && list.size() > 1){
            // 员工所属组织
            for (WorkerGroupDataDto dataDto : list) {
                // 员工调岗组织岗位 都相同 不能有不同职等
                if (!( req.getToOrg().equals(req.getFromOrg())  && req.getToPositionId().equals(req.getFromPositionId()))
                        && (dataDto.getAffiliatedOrg().equals(req.getToOrg()) &&
                        dataDto.getAffiliatedPosition().equals(req.getToPositionId()))){
                    throw new RuntimeException("您在目标组织中已所属于该岗位，不可重复选择同一组织下相同岗位！");
                }
            }
        }
        // ,1转正 2,调岗, 3离职, 4晋升
        String checkFlag = ftbPersonnelsAuditRunTaskService.checkWhetherTheCurrentPersonnelIsInTheReviewProcess(rosterEntity.getUserId());
        if (null != checkFlag) {
            if ("1".equals(checkFlag)) {
                throw new RuntimeException("当前用户正在办理转正,不能办理调岗");
            } else if ("2".equals(checkFlag)) {
                throw new RuntimeException("当前用户正在办理调岗,不能办理调岗");
            } else if ("3".equals(checkFlag)) {
                throw new RuntimeException("当前用户正在办理离职,不能办理调岗");
            } else if ("4".equals(checkFlag)) {
                throw new RuntimeException("当前用户正在办理晋升,不能办理调岗");
            }
        }
        String toRankId = req.getToRankId();
        String toPositionId = req.getToPositionId();
        String toOrg = req.getToOrg();
        if (toOrg.equals(req.getFromOrg())
                && toPositionId.equals(req.getFromPositionId())
                && toRankId.equals(req.getFromRankId())
        ) {
            throw new RuntimeException("原组织岗位职等和新组织岗位职等相同，无需调岗");
        }
        if (rosterEntity.getUserId().equals(req.getToManager())) {
            throw new RuntimeException("调岗后的直属主管不能是自己");
        }
        // v1.1 添加门店负责人校验
        // 跨组织校验
        if (!req.getFromOrg().equals(req.getToOrg())) {
            LambdaQueryWrapper<StoreEntity> storeEntityLambdaQueryWrapper = Wrappers.lambdaQuery();
            storeEntityLambdaQueryWrapper.eq(StoreEntity::getStoreheaduserid, req.getUserId());
            long count = storeService.count(storeEntityLambdaQueryWrapper);
            if (count > 0) return "1";
        }
        //写入调岗表
        FtbPersonnelsStaffTransferPosition insertEntity = BeanUtil.copyProperties(req, FtbPersonnelsStaffTransferPosition.class);
        // 修改id
        insertEntity.setEnabledMark(0);
        insertEntity.setPhone(rosterEntity.getPhone());
        insertEntity.setIsNeedCheck(1);
        insertEntity.setTransferDate(new Date());
        insertEntity.setCreatorTime(new Date());
        insertEntity.setOpUser(loginUserId);
        insertEntity.setSource(2);
        insertEntity.setOpUserName(UserProvider.getUser().getUserName());
        // 添加薪资详情
        List<FtbPersonnelsSalaryInfo> salaryStructureList = req.getSalaryStructureList();
        if (CollUtil.isEmpty(salaryStructureList)  && "1".equals(req.getIsAdjustSalary()) ){
            throw new RuntimeException("目标岗位暂无薪资结构，无法进行薪酬调整；建议选择是否调整薪酬为“否”！");
        }
        Integer isDelete = req.getIsDelete();
        if ("1".equals(req.getIsAdjustSalary()) && isDelete == null){
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
            String format = simpleDateFormat.format(req.getPayrollEffectiveDate());
            ActionResult<List<UserSalaryHistoryVo>> historyByChangeDate = querySalaryApi.getHistoryByChangeDate(format, req.getUserId());
            if (historyByChangeDate == null){
                throw new RuntimeException("获取薪酬数据失败!");
            }
            List<UserSalaryHistoryVo> data = historyByChangeDate.getData();
            if (CollUtil.isNotEmpty(data) &&  com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotEmpty(data.get(0).getFRemark())) return "5";
            // 没有薪酬默认不做废
            isDelete = 0;
        }
        String remarks = req.getRemarks();
        if (StringUtils.isNotEmpty(req.getId()) && StringUtils.isEmpty(remarks)){
            insertEntity.setRemarks(null);
        }else{
            insertEntity.setRemarks(remarks);
        }
        saveOrUpdate(insertEntity);
        // 调岗交接表
        raisePublicPart(req, req.getId(), rosterEntity, insertEntity);
        //是否需要审批：0、需要审批  1、不需要审批
        if ("1".equals(req.getIsAdjustSalary())) {
            UserInfoWithSalary userInfoWithSalary = new UserInfoWithSalary();
            PositionGradesInfoVO positionGradesInfoVO = personnelOrgUtils.queryRank(toRankId);
            PositionEntity positionEntity = personnelOrgUtils.queryPosition(toPositionId);
            OrganizeEntity organizeEntity = personnelOrgUtils.queryOrganizeInfo(toOrg);
            userInfoWithSalary.setRankName(positionGradesInfoVO.getFullName());
            userInfoWithSalary.setRankId(toRankId);
            userInfoWithSalary.setFOrgId(toOrg);
            userInfoWithSalary.setFOrgName(organizeEntity.getFullName());
            userInfoWithSalary.setPostId(toPositionId);
            userInfoWithSalary.setPostName(positionEntity.getFullName());
            //  薪资同步到薪酬
            salaryService.saveTheChangePayInformation(salaryStructureList,
                    req.getUserId(),
                    req.getPayrollEffectiveDate(),
                    userInfoWithSalary,
                    "1",
                    insertEntity.getReasonsForSalaryAdjustments(),
                    "2", isDelete,null, "");

        }
        //写入调岗薪资变化流程
        AddSalaryChangeLogDto addSalaryChangeLogDto = new AddSalaryChangeLogDto();
        addSalaryChangeLogDto.setUserId(req.getUserId());
        addSalaryChangeLogDto.setChangeDate(new Date());
        addSalaryChangeLogDto.setSalary(insertEntity.getToMoney());
        addSalaryChangeLogDto.setChangeType(SalaryChangeTypeEnum.TRANSFER_POSITION.getCode());
        salaryChangeLogService.addSalaryChangeLog(addSalaryChangeLogDto);
        //写入员工成长记录
        transferToWriteGrowth(req.getUserId(), insertEntity, remarks, rosterEntity);
        //修改用户组织岗位职等直属主管
        UpdateUserManagerBoundDTO updateUserManagerBoundDTO = new UpdateUserManagerBoundDTO();
        updateUserManagerBoundDTO.setUserId(rosterEntity.getUserId());
        updateUserManagerBoundDTO.setOldOrgId(insertEntity.getFromOrg());
        updateUserManagerBoundDTO.setOldPositionId(insertEntity.getFromPositionId());
        updateUserManagerBoundDTO.setOldPositionGradesId(insertEntity.getFromRankId());
        updateUserManagerBoundDTO.setOldManagerId(insertEntity.getFromManager());
        updateUserManagerBoundDTO.setOrgId(insertEntity.getToOrg());
        updateUserManagerBoundDTO.setPositionId(insertEntity.getToPositionId());
        updateUserManagerBoundDTO.setPositionGradesId(insertEntity.getToRankId());
        updateUserManagerBoundDTO.setManagerId(insertEntity.getToManager());
        personnelOrgUtils.updateSysUserBound(updateUserManagerBoundDTO);
        BaseUserPrimaryPositionDTO primaryPositionDTO = new BaseUserPrimaryPositionDTO();
        primaryPositionDTO.setUserId(rosterEntity.getUserId());
        primaryPositionDTO.setOrganizeId(insertEntity.getFromOrg());
        primaryPositionDTO.setPositionId(insertEntity.getFromPositionId());
        primaryPositionDTO.setPositionGradesId(insertEntity.getFromRankId());
        primaryPositionDTO.setManagerId(insertEntity.getFromManager());
        ActionResult<Boolean> position = userPrimaryPositionApi.isUserUserPrimaryPosition(primaryPositionDTO);
        if (position != null && position.getData()){
            // 更新用户主岗
            BaseUserPrimaryPositionDTO positionDTO = new BaseUserPrimaryPositionDTO();
            positionDTO.setUserId(rosterEntity.getUserId());
            positionDTO.setOrganizeId(insertEntity.getToOrg());
            positionDTO.setPositionId(insertEntity.getToPositionId());
            positionDTO.setPositionGradesId(insertEntity.getToRankId());
            positionDTO.setManagerId(insertEntity.getToManager());
            userPrimaryPositionApi.updateUserPrimaryPosition(positionDTO);
        }
        //修改用户角色
        boolean flag = insertEntity.getToOrg().equals(insertEntity.getFromOrg());
        asyncRole(insertEntity.getUserId(),flag);
        //修改薪资
        FtbPersonnelsStaffRoster staffRoster = new FtbPersonnelsStaffRoster();
        staffRoster.setId(rosterEntity.getId());
        staffRoster.setTransferPosition(2);
        staffRoster.setCurrSalary(insertEntity.getToMoney());
        staffRosterService.updateById(staffRoster);
        /**
         * 同步用户考勤组
         */
        if (StringUtils.isNotEmpty(req.getAttendanceGroup())) {
            GroupUpdateByUserDTO groupUpdateByUserDTO = new GroupUpdateByUserDTO();
            groupUpdateByUserDTO.setTenantId(user.getTenantId());
            groupUpdateByUserDTO.setType(3);// 1入职 2离职 3调岗
            groupUpdateByUserDTO.setToGroupId(req.getAttendanceGroup());
            groupUpdateByUserDTO.setUserIds(List.of(rosterEntity.getUserId()));
            personnelOrgUtils.syncAttendanceGroup(groupUpdateByUserDTO);
        }
        staffRosterService.logout(user.getTenantId(),rosterEntity.getUserId());

        return returnData;
    }

    private void raisePublicPart(SaveTransferReq req, String id, FtbPersonnelsStaffRoster rosterEntity, FtbPersonnelsStaffTransferPosition insertEntity) {
        if (null != id) {
            //删除工作物品交接表
            UpdateWrapper<FtbPersonnelsStaffTransferPositionHandover> updateWrapper = new UpdateWrapper<>();
            updateWrapper.lambda().set(FtbPersonnelsStaffTransferPositionHandover::getEnabledMark, 1)
                    .eq(FtbPersonnelsStaffTransferPositionHandover::getStaffTransferPositionId, id);
            transferPositionHandoverService.update(updateWrapper);
        }
        //写入调岗交接表
        List<FtbPersonnelsStaffTransferPositionHandover> handoverList = new ArrayList<>();
        List<TransferPositionHandoverReq> workerPositionHandoverList = req.getWorkerPositionHandoverList();
        if (CollectionUtil.isNotEmpty(workerPositionHandoverList)) {
            for (TransferPositionHandoverReq handoverReq : workerPositionHandoverList) {
                if(StringUtils.isNotEmpty(handoverReq.getToUserId()) && rosterEntity.getUserId().equals(handoverReq.getToUserId())){
                    throw new RuntimeException("工作："+handoverReq.getName()+" 的交接人不能是自己");
                }
                FtbPersonnelsStaffTransferPositionHandover handover = new FtbPersonnelsStaffTransferPositionHandover();
                handover.setStaffTransferPositionId(insertEntity.getId());
                handover.setType(1);
                handover.setName(handoverReq.getName());
                handover.setToUserId(handoverReq.getToUserId());
                handover.setToUserName(handoverReq.getToUserName());
                handover.setEnabledMark(0);
                handoverList.add(handover);
            }
        }
        List<TransferPositionHandoverReq> goodsPositionHandoverList = req.getGoodsPositionHandoverList();
        if (CollectionUtil.isNotEmpty(goodsPositionHandoverList)) {
            for (TransferPositionHandoverReq handoverReq : goodsPositionHandoverList) {
                if(StringUtils.isNotEmpty(handoverReq.getToUserId()) && rosterEntity.getUserId().equals(handoverReq.getToUserId())){
                    throw new RuntimeException("物品："+handoverReq.getName()+" 的接收人不能是自己");
                }
                FtbPersonnelsStaffTransferPositionHandover handover = new FtbPersonnelsStaffTransferPositionHandover();
                handover.setStaffTransferPositionId(insertEntity.getId());
                handover.setType(0);
                handover.setName(handoverReq.getName());
                handover.setToUserId(handoverReq.getToUserId());
                handover.setToUserName(handoverReq.getToUserName());
                handover.setEnabledMark(0);
                handoverList.add(handover);
            }
        }
        if (CollectionUtil.isNotEmpty(handoverList)) {
            transferPositionHandoverService.saveBatch(handoverList);
        }
    }

    /**
     * 重新审批
     *
     * @param id
     * @param req
     */
    @Override
    @Transactional
    public void reApproval(String id, SaveTransferReq req) {
        FtbPersonnelsStaffTransferPosition entity = baseMapper.selectById(id);
        // 校验直属主管是否为试岗员工
        if (StringUtils.isNotEmpty(req.getToManager())){
            LambdaQueryWrapper<FtbPersonnelsStaffRoster> lambdaed = Wrappers.lambdaQuery();
            lambdaed.eq(FtbPersonnelsStaffRoster::getUserId,req.getToManager());
            FtbPersonnelsStaffRoster one = staffRosterService.getOne(lambdaed);
            if (one.getWorkerStatus().equals("306")) throw new RuntimeException("试岗员工:"+one.getName()+"不能作为直属主管!");
        }
        // 校验
        verify(entity.getToOrg(), entity.getToPositionId(), entity.getToRankId());
        if ( entity.getEnabledMark() == 1) {
            throw new RuntimeException("调岗信息不存在");
        }
        if (entity.getIsNeedCheck() == 1) {
            throw new RuntimeException("该员工调岗不需要审核");
        }
        if (entity.getIsNeedCheck() == 0 && entity.getCheckStatus() == 2) {
            throw new RuntimeException("该员工调岗审核已经通过");
        }

        //查询用户花名册信息
        FtbPersonnelsStaffRoster rosterEntity = staffRosterService.queryRosterInfoByUserId(req.getUserId());
        if (null == rosterEntity) {
            throw new RuntimeException("用户花名册信息不存在");
        }
        if (rosterEntity.getEnabledMark() == 1) {
            throw new RuntimeException("用户花名册信息不存在");
        }
        if ("305".equals(rosterEntity.getWorkerStatus())) {
            throw new RuntimeException("员工已经离职");
        }

        //写入调岗表
        FtbPersonnelsStaffTransferPosition newEntity = BeanUtil.copyProperties(req, FtbPersonnelsStaffTransferPosition.class);
        newEntity.setEnabledMark(0);
        newEntity.setCheckStatus(0);
        newEntity.setId(entity.getId());
        newEntity.setUserId(entity.getUserId());
        if (req.getIsNeedCheck() == 1) {
            newEntity.setTransferDate(new Date());
        } else {
            newEntity.setCheckStatus(1);
            newEntity.setTransferDate(new Date());
        }

        String loginUserId = UserProvider.getLoginUserId();
        newEntity.setOpUser(loginUserId);
        newEntity.setOpUserName(UserProvider.getUser().getUserName());
        newEntity.setCreatorTime(new Date());
        //
        baseMapper.updateById(newEntity);
        //删除工作物品交接表
        UpdateWrapper<FtbPersonnelsStaffTransferPositionHandover> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().set(FtbPersonnelsStaffTransferPositionHandover::getEnabledMark, 1)
                .eq(FtbPersonnelsStaffTransferPositionHandover::getStaffTransferPositionId, newEntity.getId());
        transferPositionHandoverService.update(updateWrapper);
        //写入调岗交接表
        List<FtbPersonnelsStaffTransferPositionHandover> handoverList = new ArrayList<>();
        List<TransferPositionHandoverReq> workerPositionHandoverList = req.getWorkerPositionHandoverList();
        if (CollectionUtil.isNotEmpty(workerPositionHandoverList)) {
            for (TransferPositionHandoverReq handoverReq : workerPositionHandoverList) {
                FtbPersonnelsStaffTransferPositionHandover handover = new FtbPersonnelsStaffTransferPositionHandover();
                handover.setStaffTransferPositionId(newEntity.getId());
                handover.setType(1);
                handover.setName(handoverReq.getName());
                handover.setToUserId(handoverReq.getToUserId());
                handover.setToUserName(handoverReq.getToUserName());
                handover.setEnabledMark(0);
                handoverList.add(handover);
            }
        }
        List<TransferPositionHandoverReq> goodsPositionHandoverList = req.getGoodsPositionHandoverList();
        if (CollectionUtil.isNotEmpty(goodsPositionHandoverList)) {
            for (TransferPositionHandoverReq handoverReq : goodsPositionHandoverList) {
                FtbPersonnelsStaffTransferPositionHandover handover = new FtbPersonnelsStaffTransferPositionHandover();
                handover.setStaffTransferPositionId(newEntity.getId());
                handover.setType(0);
                handover.setName(handoverReq.getName());
                handover.setToUserId(handoverReq.getToUserId());
                handover.setToUserName(handoverReq.getToUserName());
                handover.setEnabledMark(0);
                handoverList.add(handover);
            }
        }
        if (CollectionUtil.isNotEmpty(handoverList)) {
            transferPositionHandoverService.saveBatch(handoverList);
        }

        //是否需要审批：0、需要审批  1、不需要审批
        if (req.getIsNeedCheck() == 0) {
            // 创建审批
            String runTaskId = auditRunTaskService.startTheReviewProcess(newEntity.getId(),
                    FtbPersonnelsCofigEnum.POST_TRANSFER_APPROVAL_CONFIGURATION.getConfigType(),
                    newEntity.getFromOrg(), newEntity.getUserId());
            // 同步id
            LambdaUpdateWrapper<FtbPersonnelsStaffTransferPosition> lambdaUpdate = Wrappers.lambdaUpdate();
            lambdaUpdate.eq(FtbPersonnelsStaffTransferPosition::getId, newEntity.getId());
            lambdaUpdate.set(FtbPersonnelsStaffTransferPosition::getTaskInfoId, runTaskId);
            baseMapper.update(null, lambdaUpdate);
            //花名册设置用户调岗中
            FtbPersonnelsStaffRoster staffRoster = new FtbPersonnelsStaffRoster();
            staffRoster.setId(rosterEntity.getId());
            staffRoster.setTransferPosition(1);
            staffRosterService.updateById(staffRoster);
        } else {

            //写入调岗薪资变化流程
            AddSalaryChangeLogDto addSalaryChangeLogDto = new AddSalaryChangeLogDto();
            addSalaryChangeLogDto.setUserId(req.getUserId());
            addSalaryChangeLogDto.setChangeDate(new Date());
            addSalaryChangeLogDto.setSalary(newEntity.getToMoney());
            addSalaryChangeLogDto.setChangeType(SalaryChangeTypeEnum.TRANSFER_POSITION.getCode());
            salaryChangeLogService.addSalaryChangeLog(addSalaryChangeLogDto);
            //写入员工成长记录
            transferToWriteGrowth(req.getUserId(), newEntity, req.getRemarks(), rosterEntity);
            //修改用户组织岗位职等直属主管
            UpdateUserManagerBoundDTO updateUserManagerBoundDTO = new UpdateUserManagerBoundDTO();
            updateUserManagerBoundDTO.setUserId(rosterEntity.getUserId());
            updateUserManagerBoundDTO.setOldOrgId(newEntity.getFromOrg());
            updateUserManagerBoundDTO.setOldPositionId(newEntity.getFromPositionId());
            updateUserManagerBoundDTO.setOldPositionGradesId(newEntity.getFromRankId());
            updateUserManagerBoundDTO.setOldManagerId(newEntity.getFromManager());
            updateUserManagerBoundDTO.setOrgId(newEntity.getToOrg());
            updateUserManagerBoundDTO.setPositionId(newEntity.getToPositionId());
            updateUserManagerBoundDTO.setPositionGradesId(newEntity.getToRankId());
            updateUserManagerBoundDTO.setManagerId(newEntity.getToManager());
            personnelOrgUtils.updateSysUserBound(updateUserManagerBoundDTO);
            //修改薪资
            FtbPersonnelsStaffRoster staffRoster = new FtbPersonnelsStaffRoster();
            staffRoster.setId(rosterEntity.getId());
            staffRoster.setTransferPosition(2);
            staffRoster.setCurrSalary(newEntity.getToMoney());
            staffRosterService.updateById(staffRoster);
            //修改用户角色
            boolean flag = newEntity.getToOrg().equals(newEntity.getFromOrg());
            asyncRole(newEntity.getUserId(),flag);
        }
    }

    /**
     * 同步用户角色
     *
     * @param userId
     * @param flag 标识是否跨组织
     */
    private void asyncRole(String userId, boolean flag) {
        // 更改用户角色逻辑
        // 2.1 取消调整角色字段，oa审批单同理
        // 2.2 若变更组织，组织角色需清除，全局角色不清除。不变更组
        // 织则不清除角色，维持原样
        ActionResult<List<UserBoundRolesVO>> listActionResult = roleApi.listUsersBound(List.of(userId));
        if (listActionResult == null ) throw new RuntimeException("获取用户角色失败!");
        List<UserBoundRolesVO> data = listActionResult.getData();
        // 查询用户绑定角色
        UserBoundRolesVO userBoundRolesVO = data.stream().filter(item -> userId.equals(item.getId())).findFirst().orElse(new UserBoundRolesVO());
        List<RoleListVO> roleBounds = userBoundRolesVO.getRoleBounds();
        List<String> roleIds;
        if (flag){
            roleIds = roleBounds.stream().map(RoleListVO::getId).collect(Collectors.toList());
        }else {
            // 清除跨组织的角色
            List<String> targetRoleIds = roleBounds.stream().filter(item -> item.getGlobalMark() != 1).map(RoleListVO::getId).collect(Collectors.toList());
            RemoveUserRolesDTO rolesDTO = new RemoveUserRolesDTO();
            rolesDTO.setTargetRoleIds(targetRoleIds);
            rolesDTO.setUserIds(List.of(userId));
            roleApi.removeRoleRelationBatch(rolesDTO);
            roleIds =  roleBounds.stream().filter(item -> item.getGlobalMark() == 1).map(RoleListVO::getId).collect(Collectors.toList());
        }
        // 无角色信息变更
        if (CollUtil.isEmpty(roleIds)) return;
        SynUserBoundRoleDTO dto = new SynUserBoundRoleDTO();
        dto.setUserId(userId);
        dto.setRoleIds(roleIds);
        personnelOrgUtils.sysUserRole(dto);
    }

    private String buildTransferGrowthLogDetail(TransferPositionDto entity, Date actualStartDate) {
        personnelOrgUtils.fillOtherInfoForItem(entity);
        TransferGrowthLogDto dto = TransferGrowthLogDto.covert(entity);
        dto.setActualStartDate(actualStartDate);
        return JSONUtil.toJsonStr(dto);
    }

    @Override
    public void updateData(SavePaperReq req) {

    }

    @Override
    public void deleteData(String id) {
        FtbPersonnelsStaffTransferPosition entity = baseMapper.selectById(id);
        if (null == entity) {
            throw new RuntimeException("调岗信息不存在");
        }
        if (entity.getEnabledMark() == 1) {
            throw new RuntimeException("调岗信息已经删除");
        }
        if (entity.getIsNeedCheck() == 1) {
            throw new RuntimeException("调岗信息不能删除");
        }
        if (entity.getIsNeedCheck() == 0 && (entity.getCheckStatus() == 0 || entity.getCheckStatus() == 1 || entity.getCheckStatus() == 2)) {
            throw new RuntimeException("调岗信息不能删除");
        }
        entity.setEnabledMark(1);
        baseMapper.updateById(entity);
    }

    /**
     * 审批
     *
     * @param dto
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void approval(EmploymentApplyCheckDto dto) {
        String id = dto.getId();
        FtbPersonnelsStaffTransferPosition entity = baseMapper.selectById(id);
        // 校验
        // 选择通过需要校验组织是否存在
        String toRankId = entity.getToRankId();
        String toPositionId = entity.getToPositionId();
        String toOrg = entity.getToOrg();
        if (1 == dto.getIsPass()) verify(toOrg, toPositionId, toRankId);
        if (1 == dto.getIsPass()) verify(entity.getFromOrg(), entity.getFromPositionId(), entity.getFromRankId());
        if ( entity.getEnabledMark() == 1) {
            throw new RuntimeException("调岗信息不存在");
        }
        if (entity.getIsNeedCheck() == 1) {
            throw new RuntimeException("该员工调岗不需要审核");
        }
        if (entity.getIsNeedCheck() == 0 && entity.getCheckStatus() == 2) {
            throw new RuntimeException("该员工调岗审核已经通过");
        }
        if (entity.getIsNeedCheck() == 0 && entity.getCheckStatus() == 3) {
            throw new RuntimeException("该员工调岗审核已经不通过");
        }
        if (entity.getIsNeedCheck() == 0 && entity.getCheckStatus() == 4) {
            throw new RuntimeException("该员工调岗审核已经撤销");
        }
        FtbPersonnelsStaffRoster roster = staffRosterService.queryRosterInfoByUserId(entity.getUserId());
        FtbPersonnelsAuditDto checkDto = new FtbPersonnelsAuditDto();
        checkDto.setBusinessId(entity.getId());
        if (ObjectUtil.isNotEmpty(dto.getIsConformSalary())) {
            checkDto.setDoesTheSalaryComplyWith(dto.getIsConformSalary());
        }
        if (ObjectUtil.isNotEmpty(dto.getMsg())) {
            checkDto.setApprovalComments(dto.getMsg());
        }
        if (ObjectUtil.isNotEmpty(dto.getIsPass())) {
            checkDto.setFlag(String.valueOf(dto.getIsPass()));
        }
        FtbPersonnelsAuditTaskEnum code = auditRunTaskService.performReview(checkDto);
        switch (code) {
            case PENDING:
                entity.setCheckStatus(0);
                break;
            case UNDER_REVIEW:
                entity.setCheckStatus(1);
                break;
            case EXAMINATION_PASSED:
                entity.setCheckStatus(2);
                //写入调岗薪资变化流程
                raisePublicPart(entity, roster, toOrg, toPositionId, toRankId);
                break;
            case AUDIT_NOT_PASSED:
                entity.setCheckStatus(3);
                roster.setTransferPosition(3);
                staffRosterService.updateById(roster);
                break;
            case CANCEL:
                entity.setCheckStatus(4);
                break;
            default:
                entity.setCheckStatus(3);
                break;
        }
        baseMapper.updateById(entity);

    }

    /**
     * 校验岗位是否存在
     */
    private void verify(String organizeId,String positionId,String positionGradesId) {
        // 校验岗位是否还存在
        CheckExistByPositionDTO checkExistByPositionDTO = new CheckExistByPositionDTO();
        checkExistByPositionDTO.setOrganizeId(organizeId);
        checkExistByPositionDTO.setPositionId(positionId);
        checkExistByPositionDTO.setPositionGradesId(positionGradesId);
        ActionResult<Boolean> booleanActionResult = positionApi.checkExistByPositionMore(checkExistByPositionDTO);
        if (booleanActionResult  == null || !booleanActionResult.getData()){
            throw new RuntimeException("该员工的岗位在提交调岗审批后发生了变更，无法继续审批；请选择“不通过”结束审批流程！");
        }
    }

}
