package com.ningdatech.pmapi.expert.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.PhoneUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ningdatech.basic.exception.BizException;
import com.ningdatech.basic.util.CollUtils;
import com.ningdatech.pmapi.common.enumeration.BoolDisplayEnum;
import com.ningdatech.pmapi.common.model.ExpertRegionModifyDiffBO;
import com.ningdatech.pmapi.common.util.ExpertRegionInfoUtils;
import com.ningdatech.pmapi.common.util.GzipUtils;
import com.ningdatech.pmapi.expert.assembler.ExpertUserInfoAssembler;
import com.ningdatech.pmapi.expert.constant.*;
import com.ningdatech.pmapi.expert.entity.*;
import com.ningdatech.pmapi.expert.model.DictionaryFieldInfo;
import com.ningdatech.pmapi.expert.model.SensitiveModifySegment;
import com.ningdatech.pmapi.expert.model.TagFieldInfo;
import com.ningdatech.pmapi.expert.model.bo.ExpertInfoSensitiveFieldCheckBO;
import com.ningdatech.pmapi.expert.model.cmd.*;
import com.ningdatech.pmapi.expert.model.constant.ExpertAuditMsgTemplate;
import com.ningdatech.pmapi.expert.model.dto.*;
import com.ningdatech.pmapi.expert.service.*;
import com.ningdatech.pmapi.expert.utils.SensitiveModifySegmentUtils;
import com.ningdatech.pmapi.meeting.helper.YxtCallOrSmsHelper;
import com.ningdatech.pmapi.meta.constant.DictExpertInfoTypeEnum;
import com.ningdatech.pmapi.meta.constant.ExpertTagEnum;
import com.ningdatech.pmapi.meta.model.ExpertRegionInfo;
import com.ningdatech.pmapi.meta.model.entity.ExpertDictionary;
import com.ningdatech.pmapi.meta.model.entity.ExpertTag;
import com.ningdatech.pmapi.meta.service.IExpertDictionaryService;
import com.ningdatech.pmapi.meta.service.IExpertTagService;
import com.ningdatech.pmapi.sys.model.entity.Role;
import com.ningdatech.pmapi.sys.model.entity.UserRole;
import com.ningdatech.pmapi.sys.service.IRoleService;
import com.ningdatech.pmapi.sys.service.IUserRoleService;
import com.ningdatech.pmapi.user.constant.UserAvailableEnum;
import com.ningdatech.pmapi.user.entity.UserInfo;
import com.ningdatech.pmapi.user.entity.enumeration.RoleEnum;
import com.ningdatech.pmapi.user.security.auth.model.UserInfoDetails;
import com.ningdatech.pmapi.user.service.IUserInfoService;
import com.ningdatech.pmapi.user.util.LoginUserUtil;
import com.ningdatech.yxt.utils.JSONUtils;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.ningdatech.yxt.model.cmd.SendSmsCmd.SendSmsContext;

/**
 * @author liuxinxin
 * @date 2022/7/22 下午4:39
 */
@Component
@RequiredArgsConstructor
public class ExpertInfoServiceImpl implements ExpertInfoService {

    private final IExpertUserFullInfoService iExpertUserFullInfoService;
    private final IExpertTagService iExpertTagService;
    private final IExpertDictionaryService iExpertDictionaryService;
    private final IExpertAvoidCompanyService iExpertAvoidCompanyService;
    private final IExpertIntentionWorkRegionService iExpertIntentionWorkRegionService;
    private final IExpertMetaApplyService iExpertMetaApplyService;
    private final IRoleService roleService;
    private final IUserRoleService userRoleService;
    private final IExpertSensitiveInfoModifyDetailRecordService iExpertSensitiveInfoModifyDetailRecordService;
    private final IUserInfoService userInfoService;
    private final YxtCallOrSmsHelper yxtCallOrSmsHelper;

    @Value("${login.url:}")
    private String loginUrl;

    /**
     * 用户第一次申请修改，仅在专家用户状态为applying 状态时调用
     *
     * @param cmd
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveExpertInfo(ExpertFullInfoSaveCmd cmd) {
        Long userId = cmd.getUserId();
        List<ExpertAvoidCompanyDTO> expertAvoidCompanyList = cmd.getExpertAvoidCompanyList();
        List<ExpertDictionaryDTO> expertDictionaryList = cmd.getExpertDictionaryList();
        List<ExpertRegionDTO> expertIntentionWorkRegionInfoList = cmd.getExpertIntentionWorkRegionInfo();
        List<ExpertTagDTO> expertTagList = cmd.getExpertTagList();
        ExpertUserFullInfoDTO expertUserInfoDTO = cmd.getExpertUserInfoDTO();

        ExpertUserFullInfo expertUserFullInfo = iExpertUserFullInfoService.getByUserId(userId);

        ExpertUserFullInfo saveExpertUserFullInfo = buildSaveExpertUserFullInfo(expertUserInfoDTO);
        if (Objects.nonNull(expertUserFullInfo)) {
            // 专家信息审核通过之前，所有信息无需备份
            iExpertUserFullInfoService.removeById(expertUserFullInfo.getId());
            // 删除所有专家标签字段
            LambdaQueryWrapper<ExpertTag> expertTagRemove = Wrappers.lambdaQuery(ExpertTag.class)
                    .eq(ExpertTag::getUserId, userId);
            iExpertTagService.remove(expertTagRemove);
            // 删除所有专家字典字段
            LambdaQueryWrapper<ExpertDictionary> expertDictionaryRemove = Wrappers.lambdaQuery(ExpertDictionary.class)
                    .eq(ExpertDictionary::getUserId, userId);
            iExpertDictionaryService.remove(expertDictionaryRemove);
            // 删除所有专家履职意向申请
            // 补充审核逻辑
            LambdaQueryWrapper<ExpertMetaApply> expertMetaApplyRemove = Wrappers.lambdaQuery(ExpertMetaApply.class)
                    .eq(ExpertMetaApply::getUserId, userId)
                    .eq(ExpertMetaApply::getApplyType, ExpertApplyTypeEnum.EXPERT_INTENTION_JOIN.getKey())
                    .eq(ExpertMetaApply::getDisplayEnable, BoolDisplayEnum.N.name());
            iExpertMetaApplyService.remove(expertMetaApplyRemove);
            // 删除回避单位
            LambdaQueryWrapper<ExpertAvoidCompany> expertAvoidCompanyRemove = Wrappers.lambdaQuery(ExpertAvoidCompany.class)
                    .eq(ExpertAvoidCompany::getUserId, userId);
            iExpertAvoidCompanyService.remove(expertAvoidCompanyRemove);
        }
        saveExpertUserFullInfo.setUserId(userId);
        saveExpertUserFullInfo.setExpertAccountStatus(ExpertAccountStatusEnum.APPLYING.getKey());
        saveExpertUserFullInfo.setUserInfoStep(ExpertUserInfoStepEnum.BASIC_INFORMATION_SUBMITTED.getKey());
        saveExpertUserFullInfo.setUpdateOn(LocalDateTime.now());
        saveExpertUserFullInfo.setCreateOn(LocalDateTime.now());
        iExpertUserFullInfoService.save(saveExpertUserFullInfo);
        // 保存所有专家标签字段
        List<ExpertTag> saveExpertTagList = buildSaveExpertTagList(userId, expertTagList);
        if (CollectionUtils.isNotEmpty(saveExpertTagList)) {
            iExpertTagService.saveBatch(saveExpertTagList);
        }
        // 保存所有专家字典字段
        List<ExpertDictionary> saveExpertDictionaryList = buildSaveExpertDictionaryList(userId, expertDictionaryList);
        if (CollectionUtils.isNotEmpty(saveExpertDictionaryList)) {
            iExpertDictionaryService.saveBatch(saveExpertDictionaryList);
        }
        // 保存所有专家履职意向申请

        // 审核逻辑
        List<ExpertMetaApply> saveExpertIntentionWorkRegionApplyList = buildSaveExpertIntentionWorkRegionApplyList(userId, expertIntentionWorkRegionInfoList);
        if (CollectionUtils.isNotEmpty(saveExpertDictionaryList)) {
            iExpertMetaApplyService.saveBatch(saveExpertIntentionWorkRegionApplyList);
        }
        // 保存所有专家回避单位
        List<ExpertAvoidCompany> saveExpertAvoidCompanyList = buildSaveExpertAvoidCompanyList(userId, expertAvoidCompanyList);
        if (CollectionUtils.isNotEmpty(saveExpertAvoidCompanyList)) {
            iExpertAvoidCompanyService.saveBatch(saveExpertAvoidCompanyList);
        }
    }


    private ExpertUserFullInfo buildSaveExpertUserFullInfo(ExpertUserFullInfoDTO expertUserInfoDTO) {
        ExpertUserFullInfo expertUserFullInfo = new ExpertUserFullInfo();
        if (Objects.nonNull(expertUserInfoDTO.getIsDingUser())) {
            expertUserFullInfo.setIsDingUser(expertUserInfoDTO.getIsDingUser() ? BoolDisplayEnum.Y.name() : BoolDisplayEnum.N.name());
        }
        expertUserFullInfo.setPhoneNo(expertUserInfoDTO.getPhoneNo());
        expertUserFullInfo.setGender(expertUserInfoDTO.getGender());
        expertUserFullInfo.setExpertName(expertUserInfoDTO.getName());
        expertUserFullInfo.setAvatarFileId(expertUserInfoDTO.getAvatarFileId());
        expertUserFullInfo.setIdCard(expertUserInfoDTO.getIdCard());
        expertUserFullInfo.setOfficePhone(expertUserInfoDTO.getOfficePhone());
        expertUserFullInfo.setBirth(expertUserInfoDTO.getBirth());
        expertUserFullInfo.setBankNo(expertUserInfoDTO.getBankNo());
        expertUserFullInfo.setBank(expertUserInfoDTO.getBank());
        expertUserFullInfo.setEmail(expertUserInfoDTO.getEmail());
        expertUserFullInfo.setHometown(expertUserInfoDTO.getHometown());
        expertUserFullInfo.setNationality(expertUserInfoDTO.getNationality());

        expertUserFullInfo.setSchool(expertUserInfoDTO.getSchool());
        expertUserFullInfo.setGraduatedAt(expertUserInfoDTO.getGraduatedAt());
        expertUserFullInfo.setAcademicTitle(expertUserInfoDTO.getAcademicTitle());

        if (CollectionUtils.isNotEmpty(expertUserInfoDTO.getGraduationCertificateFileIdList())) {
            expertUserFullInfo.setGraduationCertificateFileIdList(JSONObject.toJSONString(expertUserInfoDTO.getGraduationCertificateFileIdList()));
        }
        if (CollectionUtils.isNotEmpty(expertUserInfoDTO.getDegreeCertificateFileIdList())) {
            expertUserFullInfo.setDegreeCertificateFileIdList(JSONObject.toJSONString(expertUserInfoDTO.getDegreeCertificateFileIdList()));
        }
        expertUserFullInfo.setRetiredAt(expertUserInfoDTO.getRetiredAt());
        expertUserFullInfo.setCompany(expertUserInfoDTO.getCompany());
        expertUserFullInfo.setCompanyUniqCode(expertUserInfoDTO.getCompanyUniqCode());
        expertUserFullInfo.setLegalEntityCode(expertUserInfoDTO.getLegalEntityCode());
        expertUserFullInfo.setAdministrativeDuties(expertUserInfoDTO.getAdministrativeDuties());
        expertUserFullInfo.setStartWorkAt(expertUserInfoDTO.getStartWorkAt());
        expertUserFullInfo.setAddress(expertUserInfoDTO.getAddress());
        expertUserFullInfo.setExperience(expertUserInfoDTO.getExperience());

        expertUserFullInfo.setTechnicalTitles(expertUserInfoDTO.getTechnicalTitles());
        if (CollectionUtils.isNotEmpty(expertUserInfoDTO.getTitleCertificateFileIdList())) {
            expertUserFullInfo.setTitleCertificateFileIdList(JSONObject.toJSONString(expertUserInfoDTO.getTitleCertificateFileIdList()));
        }
        expertUserFullInfo.setAwards(expertUserInfoDTO.getAwards());
        expertUserFullInfo.setRecognitionReward(expertUserInfoDTO.getRecognitionReward());

        expertUserFullInfo.setRegionCode(expertUserInfoDTO.getRegionCode());
        expertUserFullInfo.setRegionLevel(expertUserInfoDTO.getRegionLevel());
        if (CollectionUtils.isNotEmpty(expertUserInfoDTO.getRecommendationProofFileIdList())) {
            expertUserFullInfo.setRecommendationProofFileIdList(JSONObject.toJSONString(expertUserInfoDTO.getRecommendationProofFileIdList()));
        }
        expertUserFullInfo.setRemark(expertUserInfoDTO.getRemark());
        expertUserFullInfo.setCompanyUniqCode(expertUserFullInfo.getCompanyUniqCode());
        return expertUserFullInfo;
    }


    private List<ExpertTag> buildSaveExpertTagList(Long userId, List<ExpertTagDTO> expertTagList) {
        if (CollectionUtils.isEmpty(expertTagList)) {
            return new ArrayList<>();
        }
        return expertTagList.stream().map(r -> {
            ExpertTag expertTag = new ExpertTag();
            expertTag.setExpertInfoField(r.getExpertInfoField());
            expertTag.setTagCode(r.getTagCode());
            expertTag.setCreateOn(LocalDateTime.now());
            expertTag.setUpdateOn(LocalDateTime.now());
            expertTag.setUserId(userId);
            return expertTag;
        }).collect(Collectors.toList());
    }

    private List<ExpertDictionary> buildSaveExpertDictionaryList(Long userId, List<ExpertDictionaryDTO> expertDictionaryList) {
        if (CollectionUtils.isEmpty(expertDictionaryList)) {
            return new ArrayList<>();
        }
        return expertDictionaryList.stream().map(r -> {
            ExpertDictionary expertDictionary = new ExpertDictionary();
            expertDictionary.setUserId(userId);
            expertDictionary.setExpertInfoField(r.getExpertInfoField());
            expertDictionary.setDictionaryCode(r.getDictionaryCode());
            expertDictionary.setUpdateOn(LocalDateTime.now());
            expertDictionary.setCreateOn(LocalDateTime.now());
            return expertDictionary;
        }).collect(Collectors.toList());
    }


    private List<ExpertAvoidCompany> buildSaveExpertAvoidCompanyList(Long userId, List<ExpertAvoidCompanyDTO> expertAvoidCompanyList) {
        if (CollectionUtils.isEmpty(expertAvoidCompanyList)) {
            return new ArrayList<>();
        }
        return expertAvoidCompanyList.stream().map(r -> {
            ExpertAvoidCompany expertAvoidCompany = new ExpertAvoidCompany();
            expertAvoidCompany.setCompanyName(r.getCompanyName());
            expertAvoidCompany.setUserId(userId);
            expertAvoidCompany.setCompanyUniqCode(r.getCompanyUniqCode());
            expertAvoidCompany.setCreateOn(LocalDateTime.now());
            expertAvoidCompany.setUpdateOn(LocalDateTime.now());
            return expertAvoidCompany;
        }).collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long expertRecommendProofSave(ExpertRecommendProofSaveCmd cmd) {
        // 保存专家证明材料
        Long userId = cmd.getUserId();
        ExpertUserFullInfo expertUserFullInfo = iExpertUserFullInfoService.getByUserId(userId);
        expertUserFullInfo.setRecommendationProofFileIdList(JSONObject.toJSONString(cmd.getRecommendationProofFileIdList()));
        expertUserFullInfo.setUpdateOn(LocalDateTime.now());
        expertUserFullInfo.setUserInfoStep(ExpertUserInfoStepEnum.EVIDENCE_HAS_BEEN_SUBMITTED.getKey());
        iExpertUserFullInfoService.saveOrUpdate(expertUserFullInfo);

        List<ExpertDictionaryDTO> recommendedWayList = cmd.getRecommendedWay();
        if (CollectionUtils.isNotEmpty(recommendedWayList)) {
            List<ExpertDictionary> saveExpertDictionaryList = recommendedWayList.stream().map(r -> {
                ExpertDictionary expertDictionary = new ExpertDictionary();
                expertDictionary.setUserId(userId);
                expertDictionary.setExpertInfoField(r.getExpertInfoField());
                expertDictionary.setDictionaryCode(r.getDictionaryCode());
                expertDictionary.setUpdateOn(LocalDateTime.now());
                expertDictionary.setCreateOn(LocalDateTime.now());
                return expertDictionary;
            }).collect(Collectors.toList());
            iExpertDictionaryService.saveBatch(saveExpertDictionaryList);
        }

        // 创建入库申请
        ExpertMetaApply expertRegionApply = new ExpertMetaApply();
        expertRegionApply.setApplyType(ExpertApplyTypeEnum.EXPERT_STORAGE.getKey());
        expertRegionApply.setApplyStatus(ExpertApplyStatusEnum.PENDING_REVIEW.getKey());
        expertRegionApply.setRegionCode(expertUserFullInfo.getRegionCode());
        expertRegionApply.setRegionLevel(expertUserFullInfo.getRegionLevel());
        expertRegionApply.setUserId(userId);
        expertRegionApply.setDisplayEnable(BoolDisplayEnum.Y.name());
        if (LoginUserUtil.isLogin()) {
            expertRegionApply.setCreateBy(LoginUserUtil.getUserId());
        }
        expertRegionApply.setCreateOn(LocalDateTime.now());
        iExpertMetaApplyService.save(expertRegionApply);

        return expertRegionApply.getId();
    }

    @Override
    public ExpertFullInfoAllDTO getExpertUserFullInfoAll(Long userId) {
        ExpertUserFullInfo expertUserFullInfo = iExpertUserFullInfoService.getByUserId(userId);
        if (Objects.isNull(expertUserFullInfo)) {
            return null;
        }
        // 所有专家标签字段
        List<ExpertTag> expertTagList = iExpertTagService
                .list(Wrappers.lambdaQuery(ExpertTag.class).eq(ExpertTag::getUserId, userId));
        // 所有专家字典字段
        List<ExpertDictionary> expertDictionaryList = iExpertDictionaryService
                .list(Wrappers.lambdaQuery(ExpertDictionary.class).eq(ExpertDictionary::getUserId, userId));
        // 专家履职意向列表
        List<ExpertIntentionWorkRegion> expertIntentionWorkRegionList = iExpertIntentionWorkRegionService
                .list(Wrappers.lambdaQuery(ExpertIntentionWorkRegion.class).eq(ExpertIntentionWorkRegion::getUserId, userId));
        // 专家履职意向申请列表
        List<ExpertMetaApply> expertMetaApplyList = iExpertMetaApplyService.list(Wrappers.lambdaQuery(ExpertMetaApply.class)
                .eq(ExpertMetaApply::getUserId, userId)
                .eq(ExpertMetaApply::getApplyStatus, ExpertApplyStatusEnum.PENDING_REVIEW.getKey())
                .in(ExpertMetaApply::getApplyType, ExpertApplyTypeEnum.EXPERT_INTENTION_JOIN.getKey(), ExpertApplyTypeEnum.EXPERT_INTENTION_LEAVE.getKey()));
        // 所有专家回避单位
        List<ExpertAvoidCompany> expertAvoidCompanyList = iExpertAvoidCompanyService
                .list(Wrappers.lambdaQuery(ExpertAvoidCompany.class).eq(ExpertAvoidCompany::getUserId, userId));

        return ExpertUserInfoAssembler.buildExpertFullInfoAllDTO(expertUserFullInfo, expertTagList, expertDictionaryList
                , expertIntentionWorkRegionList, expertMetaApplyList, expertAvoidCompanyList);

    }


    private List<ExpertMetaApply> buildSaveExpertIntentionWorkRegionApplyList(Long userId, List<ExpertRegionDTO> expertIntentionWorkRegionInfoList) {
        if (CollectionUtils.isEmpty(expertIntentionWorkRegionInfoList)) {
            return new ArrayList<>();
        }
        return expertIntentionWorkRegionInfoList.stream().map(r -> {
            ExpertMetaApply expertMetaApply = new ExpertMetaApply();
            expertMetaApply.setApplyType(ExpertApplyTypeEnum.EXPERT_INTENTION_JOIN.getKey());
            expertMetaApply.setApplyStatus(ExpertApplyStatusEnum.PENDING_REVIEW.getKey());
            expertMetaApply.setRegionCode(r.getRegionCode());
            expertMetaApply.setRegionLevel(r.getRegionLevel());
            expertMetaApply.setUserId(userId);
            expertMetaApply.setDisplayEnable(BoolDisplayEnum.N.name());
            expertMetaApply.setUpdateOn(LocalDateTime.now());
            expertMetaApply.setCreateOn(LocalDateTime.now());
            return expertMetaApply;
        }).collect(Collectors.toList());
    }


    @Override
    public void expertIntentionApplyDeal(ExpertIntentionApplyDealCmd cmd) {
        Boolean applyResult = cmd.getApplyResult();
        ExpertApplyTypeEnum applyTypeEnum = cmd.getApplyTypeEnum();
        String expertRegionCode = cmd.getExpertRegionCode();
        Integer expertRegionLevel = cmd.getExpertRegionLevel();
        Long expertUserId = cmd.getExpertUserId();

        if (applyResult) {
            switch (applyTypeEnum) {
                case EXPERT_INTENTION_JOIN: {
                    // 新增履职意向地
                    LambdaQueryWrapper<ExpertIntentionWorkRegion> query = Wrappers.lambdaQuery(ExpertIntentionWorkRegion.class)
                            .eq(ExpertIntentionWorkRegion::getUserId, expertUserId)
                            .eq(ExpertIntentionWorkRegion::getRegionCode, expertRegionCode)
                            .eq(ExpertIntentionWorkRegion::getRegionLevel, expertRegionLevel);
                    ExpertIntentionWorkRegion one = iExpertIntentionWorkRegionService.getOne(query);
                    if (Objects.isNull(one)) {
                        ExpertIntentionWorkRegion intentionWorkRegion = new ExpertIntentionWorkRegion();
                        intentionWorkRegion.setCreateOn(LocalDateTime.now());
                        intentionWorkRegion.setUpdateOn(LocalDateTime.now());
                        intentionWorkRegion.setRegionCode(expertRegionCode);
                        intentionWorkRegion.setRegionLevel(expertRegionLevel);
                        intentionWorkRegion.setUserId(expertUserId);
                        iExpertIntentionWorkRegionService.save(intentionWorkRegion);
                    }
                }
                break;
                case EXPERT_INTENTION_LEAVE: {
                    // 删除履职意向地
                    LambdaUpdateWrapper<ExpertIntentionWorkRegion> query = Wrappers.lambdaUpdate(ExpertIntentionWorkRegion.class)
                            .eq(ExpertIntentionWorkRegion::getUserId, expertUserId)
                            .eq(ExpertIntentionWorkRegion::getRegionCode, expertRegionCode)
                            .eq(ExpertIntentionWorkRegion::getRegionLevel, expertRegionLevel);
                    iExpertIntentionWorkRegionService.remove(query);
                }
                break;
                default:
                    throw new BizException("illegal request");
            }
        }
    }

    /**
     * 专家入库审核
     *
     * @param cmd \
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void expertStorageDeal(ExpertStorageDealCmd cmd) {
        Long expertUserId = cmd.getExpertUserId();
        ExpertUserFullInfo expertInfo = iExpertUserFullInfoService.getByUserId(expertUserId);
        UserInfoDetails userDetail = LoginUserUtil.loginUserDetail();
        String smsContent;
        if (cmd.getApplyResult()) {
            // 修改专家状态为可用
            expertInfo.setExpertAccountStatus(ExpertAccountStatusEnum.AVAILABLE.getKey());
            expertInfo.setRemark(cmd.getRemark());
            expertInfo.setRegionCode(cmd.getJoinRegionCode());
            expertInfo.setRegionLevel(cmd.getJoinRegionLevel());
            // 账号启用
            LambdaUpdateWrapper<UserInfo> userInfoUpdate = Wrappers.lambdaUpdate(UserInfo.class)
                    .eq(UserInfo::getId, expertUserId)
                    .set(UserInfo::getAvailable, UserAvailableEnum.ENABLE);
            userInfoService.update(userInfoUpdate);

            // 保存所有专家标签字段
            List<ExpertTag> saveExpertTagList = buildSaveExpertTagList(expertUserId, cmd.getOther());
            iExpertTagService.saveBatch(saveExpertTagList);
            // 保存所有专家字典字段
            List<ExpertDictionaryDTO> expertType = cmd.getExpertType();
            if (CollUtil.isNotEmpty(expertType)) {
                expertType.forEach(r -> r.setExpertInfoField(DictExpertInfoTypeEnum.EXPERT_TYPE.getKey()));
                List<ExpertDictionary> saveExpertDictList = buildSaveExpertDictionaryList(expertUserId, expertType);
                iExpertDictionaryService.saveBatch(saveExpertDictList);
            }
            // 补充专家 专家角色
            Role role = roleService.getOne(Wrappers.lambdaQuery(Role.class).eq(Role::getCode, RoleEnum.EXPERT));
            if (Objects.nonNull(role)) {
                UserRole one = userRoleService.getOne(expertUserId, role.getId());
                if (Objects.isNull(one)) {
                    UserRole saveUserRole = new UserRole();
                    saveUserRole.setUserId(expertUserId);
                    saveUserRole.setRoleId(role.getId());
                    userRoleService.save(saveUserRole);
                }
            }
            smsContent = String.format(ExpertAuditMsgTemplate.EXPERT_AUDIT_PASS_MSG, expertInfo.getExpertName(), userDetail.getRealName(), userDetail.getMobile());
        } else {
            expertInfo.setUserInfoStep(ExpertUserInfoStepEnum.INFORMATION_TO_BE_SUBMITTED.getKey());
            smsContent = String.format(ExpertAuditMsgTemplate.EXPERT_AUDIT_FAIL_MSG, expertInfo.getExpertName(), loginUrl, userDetail.getRealName(), userDetail.getMobile());
        }
        iExpertUserFullInfoService.saveOrUpdate(expertInfo);
        if (PhoneUtil.isMobile(expertInfo.getPhoneNo())) {
            SendSmsContext smsCtx = new SendSmsContext();
            smsCtx.setContent(smsContent);
            smsCtx.setReceiveNumber(expertInfo.getPhoneNo());
            yxtCallOrSmsHelper.sendSms(smsCtx);
        }
    }


    @Override
    public List<ExpertFullInfoAllDTO> listExpertUserFullInfoAll(List<Long> userIds) {
        List<ExpertUserFullInfo> expertUserFullInfos = iExpertUserFullInfoService.listByUserIds(userIds);
        // 所有专家标签字段
        List<ExpertTag> expertTagList = iExpertTagService.list(Wrappers.lambdaQuery(ExpertTag.class)
                .in(ExpertTag::getUserId, userIds));
        Map<Long, List<ExpertTag>> expertTagListMap = CollUtils.group(expertTagList, ExpertTag::getUserId);
        // 所有专家字典字段
        List<ExpertDictionary> expertDictionaryList = iExpertDictionaryService.list(Wrappers.lambdaQuery(ExpertDictionary.class)
                .in(ExpertDictionary::getUserId, userIds));
        Map<Long, List<ExpertDictionary>> expertDictMap = CollUtils.group(expertDictionaryList, ExpertDictionary::getUserId);
        // 专家履职意向列表
        List<ExpertIntentionWorkRegion> expertIntentionWorkRegionList = iExpertIntentionWorkRegionService
                .list(Wrappers.lambdaQuery(ExpertIntentionWorkRegion.class)
                        .in(ExpertIntentionWorkRegion::getUserId, userIds));
        Map<Long, List<ExpertIntentionWorkRegion>> intentionRegionMap = CollUtils.group(expertIntentionWorkRegionList, ExpertIntentionWorkRegion::getUserId);
        // 专家履职意向申请列表
        List<ExpertMetaApply> expertMetaApplyList = iExpertMetaApplyService.list(Wrappers.lambdaQuery(ExpertMetaApply.class)
                .in(ExpertMetaApply::getUserId, userIds)
                .eq(ExpertMetaApply::getApplyStatus, ExpertApplyStatusEnum.PENDING_REVIEW.getKey())
                .in(ExpertMetaApply::getApplyType, ExpertApplyTypeEnum.EXPERT_INTENTION_JOIN.getKey(), ExpertApplyTypeEnum.EXPERT_INTENTION_LEAVE.getKey()));
        Map<Long, List<ExpertMetaApply>> metaApplyMap = CollUtils.group(expertMetaApplyList, ExpertMetaApply::getUserId);
        // 所有专家回避单位
        List<ExpertAvoidCompany> expertAvoidCompanyList = iExpertAvoidCompanyService.list(Wrappers.lambdaQuery(ExpertAvoidCompany.class)
                .in(ExpertAvoidCompany::getUserId, userIds));
        Map<Long, List<ExpertAvoidCompany>> avoidInfoMap = CollUtils.group(expertAvoidCompanyList, ExpertAvoidCompany::getUserId);
        return expertUserFullInfos.stream().map(w -> ExpertUserInfoAssembler.buildExpertFullInfoAllDTO(w,
                        expertTagListMap.getOrDefault(w.getUserId(), Collections.emptyList()),
                        expertDictMap.getOrDefault(w.getUserId(), Collections.emptyList()),
                        intentionRegionMap.getOrDefault(w.getUserId(), Collections.emptyList()),
                        metaApplyMap.getOrDefault(w.getUserId(), Collections.emptyList()),
                        avoidInfoMap.getOrDefault(w.getUserId(), Collections.emptyList())))
                .collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<Long> adminModifyExpertInfo(ExpertInfoModifyCmd cmd, Long adminUserId) {
        Long userId = cmd.getUserId();
        List<ExpertAvoidCompanyDTO> expertAvoidCompanyList = cmd.getExpertAvoidCompanyList();
        List<ExpertDictionaryDTO> expertDictionaryList = cmd.getExpertDictionaryList();
        List<ExpertTagDTO> expertTagList = cmd.getExpertTagList();
        ExpertUserFullInfoDTO expertUserInfoDTO = cmd.getExpertUserInfoDTO();
        List<Long> applyIdList = new ArrayList<>();

        ExpertUserFullInfo originalExpertUserFullInfo = iExpertUserFullInfoService.getByUserId(userId);
        ExpertUserFullInfo saveExpertUserFullInfo = buildSaveExpertUserFullInfo(expertUserInfoDTO);
        if (Objects.nonNull(originalExpertUserFullInfo)) {
            saveExpertUserFullInfo.setId(originalExpertUserFullInfo.getId());
            // 删除所有专家字典字段(需审核敏感字段不删除)
            LambdaQueryWrapper<ExpertDictionary> expertDictionaryRemove = Wrappers.lambdaQuery(ExpertDictionary.class)
                    .eq(ExpertDictionary::getUserId, userId)
                    .notIn(ExpertDictionary::getExpertInfoField, ExpertUserInfoSensitiveFieldEnum.getSensitiveDictionaryList());
            iExpertDictionaryService.remove(expertDictionaryRemove);


            // 保存专家来源标签
            if (CollUtil.isNotEmpty(expertTagList)) {
                // 删除专家来源标签 重新存入
                iExpertTagService.remove(Wrappers.lambdaQuery(ExpertTag.class)
                        .eq(ExpertTag::getUserId, userId)
                        .eq(ExpertTag::getExpertInfoField, ExpertTagEnum.EXPERT_SOURCE.getKey()));

                List<ExpertTag> saveExpertTagList = buildSaveExpertTagList(userId, expertTagList);
                saveExpertTagList = saveExpertTagList.stream()
                        .filter(r -> ExpertTagEnum.EXPERT_SOURCE.getKey().equals(r.getExpertInfoField()))
                        .collect(Collectors.toList());
                if (CollUtil.isNotEmpty(saveExpertTagList)) {
                    iExpertTagService.saveBatch(saveExpertTagList);
                }
            }
        }

        saveExpertUserFullInfo.setRecommendationProofFileIdList(JSONObject.toJSONString(expertUserInfoDTO.getRecommendationProofFileIdList()));
        saveExpertUserFullInfo.setUserId(userId);
        // 专家提交修改,以下字段需要审批后才能更新
        saveExpertUserFullInfo.setPhoneNo(null);
        saveExpertUserFullInfo.setEmail(null);
        saveExpertUserFullInfo.setRegionLevel(null);
        saveExpertUserFullInfo.setRegionCode(null);
        saveExpertUserFullInfo.setCompany(null);
        saveExpertUserFullInfo.setCompanyUniqCode(null);
        saveExpertUserFullInfo.setLegalEntityCode(null);
        iExpertUserFullInfoService.saveOrUpdate(saveExpertUserFullInfo);

        // 保存所有专家字典字段
        List<ExpertDictionary> saveExpertDictionaryList = buildSaveExpertDictionaryList(userId, expertDictionaryList);
        saveExpertDictionaryList = saveExpertDictionaryList
                .stream().filter(r -> !ExpertUserInfoSensitiveFieldEnum.getSensitiveDictionaryList().contains(r.getExpertInfoField()))
                .collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(saveExpertDictionaryList)) {
            iExpertDictionaryService.saveBatch(saveExpertDictionaryList);
        }

        // 保存所有专家回避单位
        List<ExpertAvoidCompany> saveExpertAvoidCompanyList = buildSaveExpertAvoidCompanyList(userId, expertAvoidCompanyList);
        if (CollectionUtils.isNotEmpty(saveExpertAvoidCompanyList)) {
            // 删除回避单位
            LambdaQueryWrapper<ExpertAvoidCompany> expertAvoidCompanyRemove = Wrappers.lambdaQuery(ExpertAvoidCompany.class)
                    .eq(ExpertAvoidCompany::getUserId, userId);
            iExpertAvoidCompanyService.remove(expertAvoidCompanyRemove);
            // 重新保存
            iExpertAvoidCompanyService.saveBatch(saveExpertAvoidCompanyList);
        }
        // 敏感字段申请
        ExpertInfoSensitiveFieldCheckBO expertInfoSensitiveFieldCheckBO = cmd.getExpertInfoSensitiveFieldCheckBO();
        ModifyApplyExtraInfoDTO modifyApplyExtraInfo = cmd.getModifyApplyExtraInfo();
        if (expertInfoSensitiveFieldCheckBO.getHasModify()) {
            // TODO 提交审核前判断是否已经有审核未审核，如果有，无法创建新的审核请求
            if (expertInfoSensitiveFieldCheckBO.getIsExpertSensitiveInfoModify()) {
                // 创建信息修改审核
                List<SensitiveModifySegment> expertSensitiveInfoFieldSegmentList = expertInfoSensitiveFieldCheckBO.getExpertSensitiveInfoFieldSegmentList();
                Long expertInfoModifyApplyId = createExpertInfoModifyApply(expertSensitiveInfoFieldSegmentList, originalExpertUserFullInfo, modifyApplyExtraInfo);
                applyIdList.add(expertInfoModifyApplyId);
            }
            if (expertInfoSensitiveFieldCheckBO.getIsExpertRegionModify()) {
                // 创建层级变更审核
                List<SensitiveModifySegment> expertRegionFieldSegmentList = expertInfoSensitiveFieldCheckBO.getExpertRegionFieldSegmentList();
                Long expertRegionModifyApplyId = createExpertRegionModifyApply(expertRegionFieldSegmentList, originalExpertUserFullInfo, modifyApplyExtraInfo);
                applyIdList.add(expertRegionModifyApplyId);
            }

            if (expertInfoSensitiveFieldCheckBO.getIsExpertIntentionModify()) {
                // 创建专家履职意向变更审核
                List<SensitiveModifySegment> expertIntentionFieldSegmentList = expertInfoSensitiveFieldCheckBO.getExpertIntentionFieldSegmentList();
                SensitiveModifySegment segment = expertIntentionFieldSegmentList.get(0);
                List<ExpertRegionInfo> apply = (List<ExpertRegionInfo>) segment.getApply();
                List<ExpertRegionInfo> original = (List<ExpertRegionInfo>) segment.getOriginal();
                ExpertRegionModifyDiffBO expertRegionModifyDiffBO = ExpertRegionInfoUtils.modifyDiff(original, apply);
                List<ExpertRegionInfo> addList = expertRegionModifyDiffBO.getAddList();
                List<ExpertRegionInfo> removeList = expertRegionModifyDiffBO.getRemoveList();

                for (ExpertRegionInfo expertRegionInfo : addList) {
                    Long expertIntentionModifyApplyId = createExpertIntentionModifyApply(originalExpertUserFullInfo.getUserId()
                            , modifyApplyExtraInfo, expertRegionInfo, ExpertApplyTypeEnum.EXPERT_INTENTION_JOIN);
                    applyIdList.add(expertIntentionModifyApplyId);
                }
                for (ExpertRegionInfo expertRegionInfo : removeList) {
                    Long expertIntentionModifyApplyId = createExpertIntentionModifyApply(originalExpertUserFullInfo.getUserId()
                            , modifyApplyExtraInfo, expertRegionInfo, ExpertApplyTypeEnum.EXPERT_INTENTION_LEAVE);
                    applyIdList.add(expertIntentionModifyApplyId);
                }
            }
            // 专家管理修改批量通过审核
            // 专家批量通过审核由 facade层调用其他逻辑实现
        }
        return applyIdList;
    }


    /**
     * 创建信息修改审核
     */
    @Transactional(rollbackFor = Exception.class)
    public Long createExpertInfoModifyApply(List<SensitiveModifySegment> expertSensitiveInfoFieldSegmentList
            , ExpertUserFullInfo originalExpertUserFullInfo, ModifyApplyExtraInfoDTO modifyApplyExtraInfo) {
        expertSensitiveInfoFieldSegmentList = expertSensitiveInfoFieldSegmentList.stream().filter(r -> !r.isValueEquals()).collect(Collectors.toList());
        String compressedModifyJsonStr = GzipUtils.compress(JSONObject.toJSONString(expertSensitiveInfoFieldSegmentList));

        ExpertMetaApply expertMetaApply = new ExpertMetaApply();
        expertMetaApply.setApplyType(ExpertApplyTypeEnum.EXPERT_INFO_MODIFY.getKey());
        expertMetaApply.setApplyStatus(ExpertApplyStatusEnum.PENDING_REVIEW.getKey());
        expertMetaApply.setRegionCode(originalExpertUserFullInfo.getRegionCode());
        expertMetaApply.setRegionLevel(originalExpertUserFullInfo.getRegionLevel());
        expertMetaApply.setUserId(originalExpertUserFullInfo.getUserId());
        expertMetaApply.setDisplayEnable(BoolDisplayEnum.Y.name());
        expertMetaApply.setCreateOn(LocalDateTime.now());
        expertMetaApply.setCreateBy(LoginUserUtil.getUserId());
        if (Objects.nonNull(modifyApplyExtraInfo)) {
            expertMetaApply.setExtraMaterial(JSONObject.toJSONString(modifyApplyExtraInfo));
        }
        iExpertMetaApplyService.save(expertMetaApply);

        ExpertSensitiveInfoModifyDetailRecord expertSensitiveInfoModifyDetailRecord = new ExpertSensitiveInfoModifyDetailRecord();
        expertSensitiveInfoModifyDetailRecord.setCreateOn(LocalDateTime.now());
        expertSensitiveInfoModifyDetailRecord.setUpdateOn(LocalDateTime.now());
        expertSensitiveInfoModifyDetailRecord.setMetaApplyId(expertMetaApply.getId());
        expertSensitiveInfoModifyDetailRecord.setUserId(originalExpertUserFullInfo.getUserId());
        expertSensitiveInfoModifyDetailRecord.setOriginalJson(compressedModifyJsonStr);
        expertSensitiveInfoModifyDetailRecord.setModifyJson(compressedModifyJsonStr);
        if (Objects.nonNull(modifyApplyExtraInfo)) {
            expertSensitiveInfoModifyDetailRecord.setExtraMaterial(JSONObject.toJSONString(modifyApplyExtraInfo));
        }
        iExpertSensitiveInfoModifyDetailRecordService.save(expertSensitiveInfoModifyDetailRecord);
        return expertMetaApply.getId();
    }

    private Long createExpertIntentionModifyApply(Long expertUserId, ModifyApplyExtraInfoDTO modifyApplyExtraInfo
            , ExpertRegionInfo expertIntention, ExpertApplyTypeEnum applyTypeEnum) {
        ExpertMetaApply expertMetaApply = new ExpertMetaApply();
        expertMetaApply.setApplyType(applyTypeEnum.getKey());
        expertMetaApply.setApplyStatus(ExpertApplyStatusEnum.PENDING_REVIEW.getKey());
        expertMetaApply.setRegionCode(expertIntention.getRegionCode());
        expertMetaApply.setRegionLevel(expertIntention.getRegionLevel());
        expertMetaApply.setUserId(expertUserId);
        expertMetaApply.setDisplayEnable(BoolDisplayEnum.Y.name());
        if (Objects.nonNull(modifyApplyExtraInfo)) {
            expertMetaApply.setExtraMaterial(JSONObject.toJSONString(modifyApplyExtraInfo));
        }
        iExpertMetaApplyService.save(expertMetaApply);

        ExpertSensitiveInfoModifyDetailRecord expertSensitiveInfoModifyDetailRecord = new ExpertSensitiveInfoModifyDetailRecord();
        expertSensitiveInfoModifyDetailRecord.setCreateOn(LocalDateTime.now());
        expertSensitiveInfoModifyDetailRecord.setUserId(expertUserId);
        expertSensitiveInfoModifyDetailRecord.setUpdateOn(LocalDateTime.now());
        expertSensitiveInfoModifyDetailRecord.setMetaApplyId(expertMetaApply.getId());
        if (Objects.nonNull(modifyApplyExtraInfo)) {
            expertSensitiveInfoModifyDetailRecord.setExtraMaterial(JSONObject.toJSONString(modifyApplyExtraInfo));
        }
        iExpertSensitiveInfoModifyDetailRecordService.save(expertSensitiveInfoModifyDetailRecord);
        return expertMetaApply.getId();
    }

    /**
     * 创建层级变更审核
     *
     * @param expertRegionFieldSegmentList
     * @param originalExpertUserFullInfo
     * @param modifyApplyExtraInfo
     */
    private Long createExpertRegionModifyApply(List<SensitiveModifySegment> expertRegionFieldSegmentList
            , ExpertUserFullInfo originalExpertUserFullInfo, ModifyApplyExtraInfoDTO modifyApplyExtraInfo) {
        String compressedModifyJsonStr = GzipUtils.compress(JSONObject.toJSONString(expertRegionFieldSegmentList));
        SensitiveModifySegment segment = expertRegionFieldSegmentList.get(0);
        ExpertRegionInfo apply = (ExpertRegionInfo) segment.getApply();

        ExpertMetaApply expertMetaApply = new ExpertMetaApply();
        expertMetaApply.setApplyType(ExpertApplyTypeEnum.EXPERT_STORAGE.getKey());
        expertMetaApply.setApplyStatus(ExpertApplyStatusEnum.PENDING_REVIEW.getKey());
        expertMetaApply.setRegionCode(apply.getRegionCode());
        expertMetaApply.setRegionLevel(apply.getRegionLevel());
        expertMetaApply.setUserId(originalExpertUserFullInfo.getUserId());
        expertMetaApply.setCreateOn(LocalDateTime.now());
        expertMetaApply.setCreateBy(LoginUserUtil.getUserId());
        expertMetaApply.setDisplayEnable(BoolDisplayEnum.Y.name());
        if (Objects.nonNull(modifyApplyExtraInfo)) {
            expertMetaApply.setExtraMaterial(JSONObject.toJSONString(modifyApplyExtraInfo));
        }
        iExpertMetaApplyService.save(expertMetaApply);

        ExpertSensitiveInfoModifyDetailRecord expertSensitiveInfoModifyDetailRecord = new ExpertSensitiveInfoModifyDetailRecord();
        expertSensitiveInfoModifyDetailRecord.setCreateOn(LocalDateTime.now());
        expertSensitiveInfoModifyDetailRecord.setUpdateOn(LocalDateTime.now());
        expertSensitiveInfoModifyDetailRecord.setUserId(originalExpertUserFullInfo.getUserId());
        expertSensitiveInfoModifyDetailRecord.setMetaApplyId(expertMetaApply.getId());
        expertSensitiveInfoModifyDetailRecord.setOriginalJson(compressedModifyJsonStr);
        expertSensitiveInfoModifyDetailRecord.setModifyJson(compressedModifyJsonStr);
        if (Objects.nonNull(modifyApplyExtraInfo)) {
            expertSensitiveInfoModifyDetailRecord.setExtraMaterial(JSONObject.toJSONString(modifyApplyExtraInfo));
        }
        iExpertSensitiveInfoModifyDetailRecordService.save(expertSensitiveInfoModifyDetailRecord);
        return expertMetaApply.getId();
    }


    @Override
    public void expertInfoModifyDeal(ExpertInfoModifyApplyDealCmd expertInfoModifyApplyDealCmd) {
        Boolean applyResult = expertInfoModifyApplyDealCmd.getApplyResult();
        Long expertUserId = expertInfoModifyApplyDealCmd.getExpertUserId();
        Long applyId = expertInfoModifyApplyDealCmd.getApplyId();
        if (applyResult) {
            ExpertUserFullInfo originalExpertUserFullInfo = iExpertUserFullInfoService.getByUserId(expertUserId);

            LambdaQueryWrapper<ExpertSensitiveInfoModifyDetailRecord> recordQuery = Wrappers.lambdaQuery(ExpertSensitiveInfoModifyDetailRecord.class)
                    .eq(ExpertSensitiveInfoModifyDetailRecord::getUserId, expertUserId)
                    .eq(ExpertSensitiveInfoModifyDetailRecord::getMetaApplyId, applyId);
            ExpertSensitiveInfoModifyDetailRecord record = iExpertSensitiveInfoModifyDetailRecordService.getOne(recordQuery);
            String modifyJson = record.getModifyJson();
            if (StringUtils.isNotEmpty(modifyJson)) {
                modifyJson = GzipUtils.uncompress(modifyJson);
            }
            List<SensitiveModifySegment> sensitiveModifySegments = JSONUtils.parseArray(modifyJson, SensitiveModifySegment.class);
            Map<ExpertUserInfoSensitiveFieldEnum, SensitiveModifySegment> collectMap = sensitiveModifySegments
                    .stream().collect(Collectors.toMap(SensitiveModifySegment::getFieldName, Function.identity()));

            // 更新专家基 expert_user_full_info  表中数据
            assemblerExpertUserFullInfoSensitiveFieldSaveRecord(originalExpertUserFullInfo, ExpertUserInfoSensitiveFieldEnum.phone_no, collectMap);
            assemblerExpertUserFullInfoSensitiveFieldSaveRecord(originalExpertUserFullInfo, ExpertUserInfoSensitiveFieldEnum.email, collectMap);
            assemblerExpertUserFullInfoSensitiveFieldSaveRecord(originalExpertUserFullInfo, ExpertUserInfoSensitiveFieldEnum.company, collectMap);
            assemblerExpertUserFullInfoSensitiveFieldSaveRecord(originalExpertUserFullInfo, ExpertUserInfoSensitiveFieldEnum.company_uniq_code, collectMap);
            assemblerExpertUserFullInfoSensitiveFieldSaveRecord(originalExpertUserFullInfo, ExpertUserInfoSensitiveFieldEnum.legal_entity_code, collectMap);
            iExpertUserFullInfoService.saveOrUpdate(originalExpertUserFullInfo);

            // 更新专家字典字段
            executeExpertUserFullInfoDictionaryInfoUpdate(expertUserId, collectMap
                    , ExpertUserInfoSensitiveFieldEnum.administrative_rank
                    , ExpertUserInfoSensitiveFieldEnum.title_level);

            // 更新专家标签字段列表
            executeExpertUserFullInfoTagInfoUpdate(expertUserId, collectMap, ExpertUserInfoSensitiveFieldEnum.good_at
                    , ExpertUserInfoSensitiveFieldEnum.technical_expertise
                    , ExpertUserInfoSensitiveFieldEnum.industry_sector
                    , ExpertUserInfoSensitiveFieldEnum.other);

        }

    }

    private void executeExpertUserFullInfoDictionaryInfoUpdate(Long expertUserId, Map<ExpertUserInfoSensitiveFieldEnum
            , SensitiveModifySegment> collectMap, ExpertUserInfoSensitiveFieldEnum... sensitiveFieldEnumArr) {
        for (ExpertUserInfoSensitiveFieldEnum sensitiveFieldEnum : sensitiveFieldEnumArr) {
            switch (sensitiveFieldEnum) {
                case administrative_rank:
                case title_level: {
                    SensitiveModifySegment segment = collectMap.get(sensitiveFieldEnum);
                    if (Objects.nonNull(segment)) {
                        List<DictionaryFieldInfo> dictionaryFieldInfoList = SensitiveModifySegmentUtils.getDictionaryFieldInfoListApply(segment);
                        updateExpertDictionaryList(expertUserId, dictionaryFieldInfoList, sensitiveFieldEnum.getKey());
                    }
                }
                break;
                default:
                    break;
            }
        }
    }


    private void executeExpertUserFullInfoTagInfoUpdate(Long expertUserId, Map<ExpertUserInfoSensitiveFieldEnum
            , SensitiveModifySegment> collectMap, ExpertUserInfoSensitiveFieldEnum... sensitiveFieldEnumArr) {
        for (ExpertUserInfoSensitiveFieldEnum sensitiveFieldEnum : sensitiveFieldEnumArr) {
            switch (sensitiveFieldEnum) {
                case good_at:
                case technical_expertise:
                case industry_sector:
                case other: {
                    SensitiveModifySegment segment = collectMap.get(sensitiveFieldEnum);
                    if (Objects.nonNull(segment)) {
                        List<TagFieldInfo> tagFieldInfoList = SensitiveModifySegmentUtils.getTagFieldInfoListApply(segment);
                        updateExpertTagList(expertUserId, tagFieldInfoList, sensitiveFieldEnum.getKey());
                    }
                }
                break;
                default:
                    break;
            }
        }
    }

    /**
     * 信息修改审核通过后 装配更新用户信息敏感字段
     *
     * @param originalInfo /
     * @param fieldEnum    /
     * @param collectMap   /
     */
    private void assemblerExpertUserFullInfoSensitiveFieldSaveRecord(ExpertUserFullInfo originalInfo, ExpertUserInfoSensitiveFieldEnum fieldEnum
            , Map<ExpertUserInfoSensitiveFieldEnum, SensitiveModifySegment> collectMap) {
        SensitiveModifySegment segment = collectMap.get(fieldEnum);
        if (Objects.nonNull(segment)) {
            String segmentApplyValue = (String) segment.getApply();
            switch (fieldEnum) {
                case phone_no:
                    originalInfo.setPhoneNo(segmentApplyValue);
                    break;
                case email:
                    originalInfo.setEmail(segmentApplyValue);
                    break;
                case company:
                    originalInfo.setCompany(segmentApplyValue);
                    break;
                case company_uniq_code:
                    originalInfo.setCompanyUniqCode(segmentApplyValue);
                    break;
                case legal_entity_code:
                    originalInfo.setLegalEntityCode(segmentApplyValue);
                    break;
                default:
                    break;
            }
        }
    }

    private void updateExpertTagList(Long expertUserId, List<TagFieldInfo> tagFieldInfoList, String... tagExpertInfoTypeArr) {
        if (CollectionUtils.isNotEmpty(tagFieldInfoList)) {
            // 删除专家字典字段
            LambdaQueryWrapper<ExpertTag> expertTagRemove = Wrappers.lambdaQuery(ExpertTag.class)
                    .eq(ExpertTag::getUserId, expertUserId)
                    .in(tagExpertInfoTypeArr.length > 0, ExpertTag::getExpertInfoField, tagExpertInfoTypeArr);
            iExpertTagService.remove(expertTagRemove);
            List<ExpertTag> expertDictionarySaveList = tagFieldInfoList.stream().map(r -> {
                ExpertTag expertTag = new ExpertTag();
                expertTag.setUpdateOn(LocalDateTime.now());
                expertTag.setUserId(expertUserId);
                expertTag.setExpertInfoField(r.getTagFieldName());
                expertTag.setTagCode(r.getTagCode());
                return expertTag;
            }).collect(Collectors.toList());
            iExpertTagService.saveBatch(expertDictionarySaveList);
        }
    }

    private void updateExpertDictionaryList(Long expertUserId, List<DictionaryFieldInfo> dictionaryFieldInfoList, String... dictionaryExpertInfoTypeArr) {
        if (CollectionUtils.isNotEmpty(dictionaryFieldInfoList)) {
            // 删除专家字典字段
            LambdaQueryWrapper<ExpertDictionary> expertDictionaryRemove = Wrappers.lambdaQuery(ExpertDictionary.class)
                    .eq(ExpertDictionary::getUserId, expertUserId)
                    .in(dictionaryExpertInfoTypeArr.length > 0, ExpertDictionary::getExpertInfoField, dictionaryExpertInfoTypeArr);
            iExpertDictionaryService.remove(expertDictionaryRemove);
            List<ExpertDictionary> expertDictionarySaveList = dictionaryFieldInfoList.stream().map(r -> {
                ExpertDictionary expertDictionary = new ExpertDictionary();
                expertDictionary.setUpdateOn(LocalDateTime.now());
                expertDictionary.setCreateOn(LocalDateTime.now());
                expertDictionary.setUserId(expertUserId);
                expertDictionary.setExpertInfoField(r.getDictionaryFieldName());
                expertDictionary.setDictionaryCode(r.getDictionaryCode());
                return expertDictionary;
            }).collect(Collectors.toList());
            iExpertDictionaryService.saveBatch(expertDictionarySaveList);
        }
    }


}
