package com.yonge.cooleshow.biz.dal.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
import com.yonge.cooleshow.auth.api.dto.RealnameAuthReq;
import com.yonge.cooleshow.auth.api.entity.SysUser;
import com.yonge.cooleshow.biz.dal.dao.EmployeeDao;
import com.yonge.cooleshow.biz.dal.dao.StudentStarDao;
import com.yonge.cooleshow.biz.dal.dao.TeacherDao;
import com.yonge.cooleshow.biz.dal.dto.TeacherDto;
import com.yonge.cooleshow.biz.dal.dto.req.TeacherSubmitReq;
import com.yonge.cooleshow.biz.dal.dto.search.TeacherSearch;
import com.yonge.cooleshow.biz.dal.entity.*;
import com.yonge.cooleshow.biz.dal.enums.AuthStatusEnum;
import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
import com.yonge.cooleshow.biz.dal.enums.EUserVipType;
import com.yonge.cooleshow.biz.dal.enums.ImGroupMemberRoleType;
import com.yonge.cooleshow.biz.dal.enums.ImGroupType;
import com.yonge.cooleshow.biz.dal.enums.MessageTypeEnum;
import com.yonge.cooleshow.biz.dal.enums.TeacherTagEnum;
import com.yonge.cooleshow.biz.dal.enums.TeacherTypeEnum;
import com.yonge.cooleshow.biz.dal.enums.im.EImUserFriendSourceForm;
import com.yonge.cooleshow.biz.dal.mapper.TenantGroupMapper;
import com.yonge.cooleshow.biz.dal.mapper.UserTenantBindRecordMapper;
import com.yonge.cooleshow.biz.dal.queryInfo.TeacherQueryInfo;
import com.yonge.cooleshow.biz.dal.service.ImGroupService;
import com.yonge.cooleshow.biz.dal.service.StudentService;
import com.yonge.cooleshow.biz.dal.service.StudentStarService;
import com.yonge.cooleshow.biz.dal.service.SubjectService;
import com.yonge.cooleshow.biz.dal.service.SysConfigService;
import com.yonge.cooleshow.biz.dal.service.SysMessageService;
import com.yonge.cooleshow.biz.dal.service.TeacherAuthEntryRecordService;
import com.yonge.cooleshow.biz.dal.service.TeacherAuthMusicianRecordService;
import com.yonge.cooleshow.biz.dal.service.TeacherService;
import com.yonge.cooleshow.biz.dal.service.TeacherStyleVideoService;
import com.yonge.cooleshow.biz.dal.service.TeacherTotalService;
import com.yonge.cooleshow.biz.dal.service.UserAccountService;
import com.yonge.cooleshow.biz.dal.service.UserFirstTimeService;
import com.yonge.cooleshow.biz.dal.service.im.ImGroupCoreService;
import com.yonge.cooleshow.biz.dal.mapper.SysUserMapper;
import com.yonge.cooleshow.biz.dal.mapper.TenantAlbumMapper;
import com.yonge.cooleshow.biz.dal.mapper.TenantAlbumRefMapper;
import com.yonge.cooleshow.biz.dal.mapper.TenantUnbindHistoryMapper;
import com.yonge.cooleshow.biz.dal.mapper.TenantUnbindRecordMapper;
import com.yonge.cooleshow.biz.dal.service.*;
import com.yonge.cooleshow.biz.dal.vo.HotTeacherVo;
import com.yonge.cooleshow.biz.dal.vo.MyFens;
import com.yonge.cooleshow.biz.dal.vo.TeacherAuthEntryRecordVo;
import com.yonge.cooleshow.biz.dal.vo.TeacherHomeVo;
import com.yonge.cooleshow.biz.dal.vo.TeacherVo;
import com.yonge.cooleshow.biz.dal.wordfilter.WordFilter;
import com.yonge.cooleshow.biz.dal.wrapper.StatGroupWrapper;
import com.yonge.cooleshow.biz.dal.wrapper.TeacherFreeTimeWrapper;
import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
import com.yonge.cooleshow.biz.dal.wrapper.VipCardRecordWrapper;
import com.yonge.cooleshow.biz.dal.wrapper.im.ImGroupWrapper;
import com.yonge.cooleshow.biz.dal.wrapper.teacher.TeacherWrapper;
import com.yonge.cooleshow.common.constant.SysConfigConstant;
import com.yonge.cooleshow.common.entity.HttpResponseResult;
import com.yonge.cooleshow.common.enums.CacheNameEnum;
import com.yonge.cooleshow.common.enums.ESettlementFrom;
import com.yonge.cooleshow.common.enums.ETenantUnBindAuditStatus;
import com.yonge.cooleshow.common.enums.UserFirstTimeTypeEnum;
import com.yonge.cooleshow.common.enums.UserLockFlag;
import com.yonge.cooleshow.common.enums.UserStatusEnum;
import com.yonge.cooleshow.common.enums.YesOrNoEnum;
import com.yonge.toolset.base.exception.BizException;
import com.yonge.toolset.base.util.StringUtil;
import com.yonge.toolset.thirdparty.message.MessageSenderPluginContext;
import com.yonge.toolset.thirdparty.user.realname.RealnameAuthenticationPlugin;
import com.yonge.toolset.utils.date.DateUtil;
import com.yonge.toolset.utils.idcard.IdcardInfoExtractor;
import com.yonge.toolset.utils.string.ValueUtil;
import org.apache.commons.collections.CollectionUtils;
import org.redisson.api.RMap;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.yonge.cooleshow.biz.dal.constant.LiveRoomConstant.TEACHER_TEMP_LIVE_ROOM;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RMap;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.yonge.cooleshow.biz.dal.constant.LiveRoomConstant.TEACHER_TEMP_LIVE_ROOM;

@Service
public class TeacherServiceImpl extends ServiceImpl<TeacherDao, Teacher> implements TeacherService {

    private final static Logger log = LoggerFactory.getLogger(TeacherServiceImpl.class);

    @Autowired
    private TeacherStyleVideoService teacherStyleVideoService;
    @Resource
    private SysUserFeignService userFeignService;
    @Autowired
    private TeacherAuthEntryRecordService entryRecordService;
    @Autowired
    private TeacherAuthMusicianRecordService musicianRecordService;
    @Resource
    private EmployeeDao employeeDao;
    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private SysConfigService sysConfigService;
    @Autowired
    private WordFilter wordFilter;
    @Autowired
    private StudentStarService studentStarService;
    @Autowired
    private UserAccountService userAccountService;
    @Autowired
    private UserFirstTimeService userFirstTimeService;
    @Autowired
    private TeacherTotalService totalService;

    @Autowired
    private SubjectService subjectService;

    @Autowired
    private StudentStarDao studentStarDao;

    @Autowired
    private StudentService studentService;

    @Autowired
    private SysMessageService sysMessageService;

    @Autowired
    private ImGroupService imGroupService;

    @Autowired
    private ImGroupCoreService imGroupCoreService;

    @Autowired
    private TenantInfoService tenantInfoService;

    @Autowired
    private ImGroupMemberService imGroupMemberService;

    @Autowired
    private ImUserFriendService imUserFriendService;

    @Autowired
    private MusicSheetService musicSheetService;

    @Autowired
    private TenantUnbindRecordMapper tenantUnbindRecordMapper;

    @Autowired
    private TenantUnbindHistoryMapper tenantUnbindHistoryMapper;

    @Autowired
    private TenantAlbumMapper tenantAlbumMapper;

    @Autowired
    private TenantAlbumRefMapper tenantAlbumRefMapper;

    @Autowired
    private SmsCodeService smsCodeService;

    @Autowired
    private RealnameAuthenticationPlugin realnameAuthenticationPlugin;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private TenantGroupMapper tenantGroupMapper;

    @Autowired
    private UserTenantBindRecordMapper userTenantBindRecordMapper;

    @Autowired
    private VipCardRecordService vipCardRecordService;

    @Autowired
    private TeacherTotalService teacherTotalService;

    @Autowired
    private StudentTotalService studentTotalService;

    @Autowired
    private TeacherSubjectPriceService teacherSubjectPriceService;

    @Autowired
    private TeacherFreeTimeService teacherFreeTimeService;

    @Override
    public TeacherDao getDao() {
        return baseMapper;
    }

    @Override
    public TeacherVo detail(Long userId) {
        TeacherVo detail = baseMapper.detail(userId);
        if (null == detail) {
            detail = new TeacherVo();
        }
        if (detail.getDefaultSubject() == null && StringUtils.isNotBlank(detail.getSubjectId())) {
            detail.setDefaultSubject(Long.parseLong(detail.getSubjectId().split(",")[0]));
        }

        int num = DateUtil.daysBetween(new Date(), detail.getMembershipEndTime());
        detail.setMembershipDays(Math.max(num, 0));
        List<TeacherStyleVideo> teacherStyleVideos = teacherStyleVideoService.selectListByUserId(userId);
        detail.setStyleVideo(teacherStyleVideos);
        TeacherAuthEntryRecordVo lastRecordByUserId = entryRecordService.getLastRecordByUserId(userId);
        if (null != lastRecordByUserId) {
            detail.setVerifyUser(lastRecordByUserId.getVerifyUser());
        }
        String teacherType = TeacherTypeEnum.getTeacherType(detail.getEntryFlag(), detail.getMusicianFlag());
        detail.setTeacherType(teacherType);
        Long tenantId = detail.getTenantId();
        if (tenantId != null) {
            if (tenantId == -1) {
                detail.setTenantName("平台老师");
            } else {
                TenantInfo tenantInfo = tenantInfoService.detail(tenantId);
                detail.setTenantName(tenantInfo == null ? "" : tenantInfo.getName());
            }
        }

        // 会员信息
        detail.setUserVip(vipCardRecordService.userVipInfo(detail.getUserId(), ClientEnum.TEACHER));
        List<VipCardRecordWrapper.UserVipInfo> userVipInfos = vipCardRecordService.queryUserVipInfo(Collections.singletonList(userId), ClientEnum.TEACHER.getCode());
        Map<Long, VipCardRecordWrapper.UserVipInfo> curVipMap = userVipInfos.stream().collect(Collectors.toMap(VipCardRecordWrapper.UserVipInfo::getUserId, Function.identity()));
        VipCardRecordWrapper.UserVipInfo vipType = curVipMap.getOrDefault(userId, new VipCardRecordWrapper.UserVipInfo());
        detail.setMembershipEndTime(vipType.getCurrentVipSvipEndTime());
        detail.setVipType(vipType.getCurrentVipType());

        // 设置老师帐号状态
        if(detail.getDelFlag() == YesOrNoEnum.YES){
            detail.setUserStatus(UserStatusEnum.CLOSED);
        }else{
            if(detail.getLockFlag() == UserLockFlag.LOCKED){
                detail.setUserStatus(UserStatusEnum.LOCKED);
            }else{
                detail.setUserStatus(UserStatusEnum.NORMAL);
            }
        }

        // 系统客服数量
        detail.setCustomerServiceNum(baseMapper.selectCustomerServiceV2().size());
        if (Optional.ofNullable(detail.getCustomerService()).orElse(false)) {
            // 老师本身是客服，不显示客服入口；重置客服数量为0
            detail.setCustomerServiceNum(0);
        }
        //是否设置可约课时间段
        detail.setCourseTimeFlag(teacherFreeTimeService.lambdaQuery().eq(TeacherFreeTime::getTeacherId, userId).count() > 0);

        return detail;
    }

    @Override
    public IPage<TeacherVo> selectPage(IPage<TeacherVo> page, TeacherSearch search) {
        List<TeacherVo> teacherVos = baseMapper.selectPage(page, search);

        for (TeacherVo record : teacherVos) {
            EUserVipType vipType = record.getVipType();
            if (EUserVipType.NORMAL.equals(vipType)) {
                record.setMembershipEndTime(Optional.ofNullable(record.getVipEndTime()).orElse(record.getSvipEndTime()));
            }
            if (EUserVipType.SVIP.equals(vipType)) {
                Date perSvipEndTime = record.getPerSvipEndTime();
                if (perSvipEndTime != null) {
                    // 永久会员
                    record.setMembershipEndTime(null);
                } else {
                    record.setMembershipEndTime(record.getSvipEndTime());
                }
            }
            if (EUserVipType.VIP.equals(vipType)) {
                record.setMembershipEndTime(record.getVipEndTime());
            }
        }

        if (CollectionUtils.isEmpty(teacherVos)) {
            return page.setRecords(teacherVos);
        }
        //设置声部
        List<Long> subjectIds =
                teacherVos.stream().filter(o -> o.getSubjectId() != null).flatMap(o -> Arrays.stream(o.getSubjectId().split(","))).map(Long::parseLong).collect(Collectors.toList());
        List<Subject> subjects = subjectService.findBySubjectByIdList(subjectIds);

        Map<Long, String> subjectMap = subjects.stream().collect(Collectors.toMap(Subject::getId, Subject::getName));

        List<Long> userIds = teacherVos.stream().map(Teacher::getUserId).distinct().collect(Collectors.toList());

        List<MusicSheet> musicSheets = musicSheetService.lambdaQuery()
                .in(MusicSheet::getUserId, userIds)
                .eq(MusicSheet::getDelFlag, false)
                .eq(MusicSheet::getState, 1)
                .eq(MusicSheet::getSourceType, "TEACHER").list();

        Map<Long, List<MusicSheet>> groupByUserId = musicSheets.stream().collect(Collectors.groupingBy(MusicSheet::getUserId));

        // 添加小组信息
        Map<Long, List<TenantGroup>> groupByAdminId = new HashMap<>();
        List<Long> teacherIds = teacherVos.stream().map(Teacher::getUserId).distinct().collect(Collectors.toList());
        if(!teacherIds.isEmpty()){
            QueryWrapper<TenantGroup> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().in(TenantGroup::getAdminId,teacherIds);
            List<TenantGroup> tenantGroups = tenantGroupMapper.selectList(queryWrapper);
            Map<Long, List<TenantGroup>> groupBy = tenantGroups.stream().collect(Collectors.groupingBy(TenantGroup::getAdminId));
            groupByAdminId.putAll(groupBy);
        }


        for (TeacherVo teacherVo : teacherVos) {
            List<String> groups = groupByAdminId.getOrDefault(teacherVo.getUserId(), new ArrayList<>())
                    .stream().map(TenantGroup::getName).collect(Collectors.toList());
            teacherVo.setTenantGroupName(String.join(",", groups));

            List<MusicSheet> musicSheetList = groupByUserId.getOrDefault(teacherVo.getUserId(), new ArrayList<>());
            teacherVo.setMusicSheetCount(musicSheetList.size());
            List<String> names = musicSheetList.stream().map(MusicSheet::getMusicSheetName).collect(Collectors.toList());
            teacherVo.setMusicSheetName(String.join(",", names));
            if (null == teacherVo.getSubjectId()) {
                continue;
            }

            String subjectNames = Arrays.stream(teacherVo.getSubjectId().split(",")).map(Long::parseLong).map(o -> {
                String subjectName = subjectMap.get(o);
                if (!StringUtil.isEmpty(subjectName)) {
                    return subjectName;
                }
                return null;
            }).filter(Objects::nonNull).collect(Collectors.joining(","));
            teacherVo.setSubjectName(subjectNames);
        }




        return page.setRecords(teacherVos);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public HttpResponseResult<Boolean> submit(TeacherSubmitReq teacherSubmitReq) throws BizException {
        Long tenantId = teacherSubmitReq.getTenantId();
        Boolean customerService = teacherSubmitReq.getCustomerService();
        if (tenantId != null && tenantId > 0 && Boolean.TRUE.equals(customerService)) {
            throw new BizException("客服不能有机构老师身份");
        }

        if (null == teacherSubmitReq.getUserId()) {

            if (StringUtils.isNoneBlank(teacherSubmitReq.getPhone(), teacherSubmitReq.getCode())) {
                // 验证手机验证码是否正确
                if (!smsCodeService.verifyValidCode(teacherSubmitReq.getPhone(), teacherSubmitReq.getCode(),
                        "REGISTER")) {
                    throw new BizException("验证码错误");
                }
            }
            //创建
            return doCreate(teacherSubmitReq);
        } else {
            //修改
            return doUpdate(teacherSubmitReq);
        }
    }

    @Override
    public HttpResponseResult<TeacherHomeVo> queryUserInfo(Long userId) {
        TeacherVo teacher = detail(userId);
        if (null == teacher) {
            return HttpResponseResult.failed("未查询到老师信息");
        }
        TeacherHomeVo teacherHomeVo = new TeacherHomeVo();
        BeanUtils.copyProperties(teacher, teacherHomeVo);

        try {
            ImGroupWrapper.ImUserInfo register = imGroupCoreService.register(teacher.getUserId().toString(),
                    ClientEnum.TEACHER.getCode(),
                    teacher.getUsername(),
                    teacher.getAvatar());
            teacherHomeVo.setImToken(register.getImToken());
        } catch (Exception e) {
            throw new BizException("获取IMToken失败");
        }

        // 设置IM用户ID
        teacherHomeVo.setImUserId(imGroupService.getImUserId(userId.toString(),ClientEnum.TEACHER.getCode()));

        teacherHomeVo.setDegreeDate(teacher.getDegreeDate());
        teacherHomeVo.setTeacherDate(teacher.getTeacherDate());
        teacherHomeVo.setCustomerService(teacher.getCustomerService());
        //身份证号、手机号脱敏
        teacherHomeVo.setIdCardNo(ValueUtil.fuzzyIdCard(teacherHomeVo.getIdCardNo()));
//        teacherHomeVo.setPhone(ValueUtil.fuzzyMobile(teacherHomeVo.getPhone()));
        teacherHomeVo.setHeardUrl(teacher.getAvatar());
        teacherHomeVo.setIsVip(teacher.getIsVip());
        int num = DateUtil.daysBetween(new Date(), teacher.getMembershipEndTime());
        teacherHomeVo.setMembershipDays(Math.max(num, 0));
        if (YesOrNoEnum.YES.equals(teacher.getEntryFlag())) {
            teacherHomeVo.setEntryStatus(AuthStatusEnum.PASS);
        } else {
            TeacherAuthEntryRecordVo entryRecord = entryRecordService.getLastRecordByUserId(userId);
            if (null == entryRecord) {
                teacherHomeVo.setEntryStatus(AuthStatusEnum.UNPAALY);
            } else {
                teacherHomeVo.setEntryStatus(entryRecord.getTeacherAuthStatus());
            }
        }
        // 设置默认查询声部名称
        if (teacher.getDefaultSubject() != null) {
            Subject subject = subjectService.get(teacher.getDefaultSubject());
            if (subject != null) {
                teacherHomeVo.setDefaultSubjectName(subject.getName());
            }
        }

        // 会员信息

        teacherHomeVo.setUserVip(vipCardRecordService.userVipInfo(teacherHomeVo.getUserId(), ClientEnum.TEACHER));


        if (YesOrNoEnum.YES.equals(teacher.getMusicianFlag())) {
            teacherHomeVo.setMusicianAuthStatus(AuthStatusEnum.PASS);
        } else {
            TeacherAuthMusicianRecord musicianRecord = musicianRecordService.getLastRecordByUserId(userId);
            if (null == musicianRecord) {
                teacherHomeVo.setMusicianAuthStatus(AuthStatusEnum.UNPAALY);
            } else {
                teacherHomeVo.setMusicianAuthStatus(musicianRecord.getTeacherAuthStatus());
            }
        }

        TeacherTotal total = totalService.getTotalById(userId);

        if (null == total) {
            total = new TeacherTotal();
        }
        teacherHomeVo.setStarGrade(null == total.getStarGrade() ? 0 : total.getStarGrade().intValue());
        teacherHomeVo.setFansNum(null == total.getFansNum() ? 0 : total.getFansNum());
        teacherHomeVo.setExpTime(null == total.getExpTime() ? 0 : total.getExpTime());
        teacherHomeVo.setUnExpTime(null == total.getUnExpTime() ? 0 : total.getUnExpTime());
        teacherHomeVo.setMusicAlbumNum(null == total.getMusicAlbumNum() ? 0 : total.getMusicAlbumNum());
        teacherHomeVo.setMusicSheetNum(null == total.getMusicSheetNum() ? 0 : total.getMusicSheetNum());

        // 老师所属机构信息
        teacherHomeVo.setTenantAlbumStatus(0);
        TenantInfo tenantInfo = tenantInfoService.detail(teacher.getTenantId());
        if (tenantInfo != null) {
            teacherHomeVo.setTenantName(tenantInfo.getName());
            List<Long> tenantAlbumIds = tenantAlbumRefMapper.selectList(Wrappers.<TenantAlbumRef>lambdaQuery()
                            .eq(TenantAlbumRef::getTenantId, tenantInfo.getId())).stream()
                    .map(TenantAlbumRef::getTenantAlbumId).collect(Collectors.toList());
            if (!tenantAlbumIds.isEmpty()) {
                List<TenantAlbum> tenantAlbums = tenantAlbumMapper.selectList(Wrappers.<TenantAlbum>lambdaQuery()
                        .in(TenantAlbum::getId, tenantAlbumIds)
                        .eq(TenantAlbum::getDelFlag, false).eq(TenantAlbum::getStatus, true));
                if (!tenantAlbums.isEmpty()) {
                    teacherHomeVo.setTenantAlbumStatus(2);
                    teacherHomeVo.setTenantAlbumFlag(YesOrNoEnum.YES);
                }
            }
        }

        // 老师学生人数统计
        List<Long> teacherIds = Lists.newArrayList(userId);
        Map<Long, Integer> studentNumsMap = getBaseMapper().selectTeacherStudentNumberStatInfo(teacherIds).stream()
                .collect(Collectors.toMap(StatGroupWrapper::getId, StatGroupWrapper::getTotal, (o, n) -> n));

        teacherHomeVo.setStudentNums(studentNumsMap.getOrDefault(userId, 0));

        //取直播缓存
        RMap<Long, String> liveMap = redissonClient.getMap(TEACHER_TEMP_LIVE_ROOM);
        String roomUid = liveMap.get(userId);
        if (!StringUtil.isEmpty(roomUid)) {
            teacherHomeVo.setLiveing(YesOrNoEnum.YES);
            teacherHomeVo.setRoomUid(roomUid);
        } else {
            teacherHomeVo.setLiveing(YesOrNoEnum.NO);
        }
        return HttpResponseResult.succeed(teacherHomeVo);
    }

    @Override
    public HttpResponseResult<Boolean> openLive(Long id) {
        TeacherTotal teacherTotal =
                (TeacherTotal) redissonClient.getBucket(CacheNameEnum.TEACHER_TOTAL.getRedisKey(id)).get();
        if (null == teacherTotal) {
            teacherTotal = new TeacherTotal();
        }

        //开通直播需要粉丝数
        Integer fansNum =
                Integer.parseInt(sysConfigService.findByParamName(SysConfigConstant.OPEN_LIVE_FANS_NUM).getParamValue());
        //开通直播需要已完成课时数
        Integer overClass =
                Integer.parseInt(sysConfigService.findByParamName(SysConfigConstant.OPEN_LIVE_OVER_CLASS).getParamValue());
        //根据老师规则，判断老师直播权限
        if (teacherTotal.getFansNum() >= fansNum && teacherTotal.getExpTime() >= overClass) {
            Teacher teacher = new Teacher();
            teacher.setUserId(id);
            teacher.setLiveFlag(YesOrNoEnum.YES);
            teacher.setLiveDate(new Date());
            teacher.setUpdateTime(new Date());
            baseMapper.updateById(teacher);

            // 添加标签
            this.setTeacherTag(id, TeacherTagEnum.LIVE);

            //记录首次开通直播时间
            userFirstTimeService.recordTime(id, ClientEnum.TEACHER, UserFirstTimeTypeEnum.LIVEING);
            return HttpResponseResult.status(true);
        } else {
            return HttpResponseResult.failed("不满足开通条件");
        }
    }

    @Override
    public List<Subject> querySubject(Long userId) {
        List<Subject> subjects = baseMapper.querySubject(userId);
        return subjects;
    }


    private HttpResponseResult<Boolean> doCreate(TeacherSubmitReq teacherSubmitReq) throws BizException {
        //更新sys_user
        SysUser sysUser = employeeDao.querySysUserByPhone(teacherSubmitReq.getPhone());
        if (null == sysUser) {
            //设置默认头像
            if (StringUtil.isEmpty(teacherSubmitReq.getAvatar())) {
                String defaultHeard = sysConfigService.findConfigValue(SysConfigConstant.TEACHER_AVATAR);
                teacherSubmitReq.setAvatar(defaultHeard);
            }
            sysUser = insertSysUser(teacherSubmitReq);
            teacherSubmitReq.setUserId(sysUser.getId());
        } else {
            String userType = sysUser.getUserType();
            List<String> userTypes = Arrays.stream(userType.split(",")).collect(Collectors.toList());
            if (userTypes.contains(ClientEnum.TEACHER.getCode())) {
                Teacher teacher = this.getById(sysUser.getId());
                // 机构邀请平台老师注册
                if(Optional.ofNullable(teacher.getTenantId()).orElse(-1L) == -1 && Optional.ofNullable(teacherSubmitReq.getTenantId()).orElse(-1L)>-1){
                    teacherSubmitReq.setSettlementFrom(ESettlementFrom.TENANT);
                }else {
                    throw new BizException("该手机号已经注册老师账号");
                }
            }
            teacherSubmitReq.setUserId(sysUser.getId());
            updateSysUser(teacherSubmitReq);
        }
        //新增修改老师表
        Teacher teacher = insertOrUpdateTeacher(teacherSubmitReq);

        // 机构老师与学生互加好友关系
        if (Optional.ofNullable(teacher.getTenantId()).orElse(-1L) > 0) {
            // 自动与机构学生成为好友
            Set<Long> collect = studentService.lambdaQuery()
                    .eq(Student::getTenantId, teacher.getTenantId()).list().stream()
                    .map(Student::getUserId).collect(Collectors.toSet());

            imUserFriendService.saveUserFriend(teacher.getUserId(), collect, EImUserFriendSourceForm.TEACHER);

        }

        return HttpResponseResult.succeed(true);
    }

    private HttpResponseResult<Boolean> doUpdate(TeacherSubmitReq teacherSubmitReq) {
        //更新sys_user
        updateSysUser(teacherSubmitReq);
        //新增修改老师表
        insertOrUpdateTeacher(teacherSubmitReq);
        return HttpResponseResult.succeed(true);
    }

    private SysUser insertSysUser(TeacherSubmitReq teacherSubmitReq) {
        SysUser sysUser = new SysUser();
        sysUser = getUserDetil(sysUser, teacherSubmitReq);
        //初始密码，klx+手机号四位
        String password = "klx" + sysUser.getPhone().substring(sysUser.getPhone().length() - 4);
        sysUser.setPassword(new BCryptPasswordEncoder().encode(password));
        //插入
        int num = employeeDao.insertSysUser(sysUser);
        if (num <= 0) {
            throw new BizException("插入用户信息失败");
        }
        //设置昵称
        if (StringUtils.isEmpty(sysUser.getUsername())) {
            sysUser.setUsername("游客" + sysUser.getId());
        }
        employeeDao.updateSysUser(sysUser);
        return sysUser;
    }

    private SysUser updateSysUser(TeacherSubmitReq teacherSubmitReq) {
        //判断手机号
        SysUser sysUser = employeeDao.querySysUserByPhone(teacherSubmitReq.getPhone());
        if (null != sysUser && !teacherSubmitReq.getUserId().equals(sysUser.getId())) {
            throw new BizException("该手机号已经被注册");
        }
        sysUser = employeeDao.querySysUserById(teacherSubmitReq.getUserId());
        if (null == sysUser) {
            throw new BizException("未找到用户");
        }
        sysUser = getUserDetil(sysUser, teacherSubmitReq);
        sysUser.setUpdateTime(new Date());
        employeeDao.updateSysUser(sysUser);
        employeeDao.updateSysUserIdCard(sysUser.getId(),teacherSubmitReq.getIdCardNo());

        return sysUser;
    }

    private Teacher insertOrUpdateTeacher(TeacherSubmitReq teacherSubmitReq) {
        if(ESettlementFrom.NO.equals(teacherSubmitReq.getSettlementFrom())){
            teacherSubmitReq.setIsSettlement(false);
        }else {
            teacherSubmitReq.setIsSettlement(true);
        }
        Teacher teacher = baseMapper.selectById(teacherSubmitReq.getUserId());
        if (null == teacher) {
            teacher = new Teacher();
            teacher.setUserId(teacherSubmitReq.getUserId());
            teacher.setEntryFlag(YesOrNoEnum.NO);
            teacher.setMusicianFlag(YesOrNoEnum.NO);
            getTeacherDetil(teacher, teacherSubmitReq);
            baseMapper.insert(teacher);

            // 导入IM账号到三方
            try {
                imGroupCoreService.register(String.valueOf(teacher.getUserId()), ClientEnum.TEACHER.getCode(),
                        teacherSubmitReq.getUsername(), teacher.getAvatar());
            } catch (Exception e) {
                log.error("导入IM账号到三方 teacherId={}", teacher.getUserId(), e);
            }

            //插入老师账户表
            UserAccount oldAcc = userAccountService.getById(teacherSubmitReq.getUserId());
            if (null == oldAcc) {
                UserAccount userAccount = new UserAccount();
                userAccount.setUserId(teacherSubmitReq.getUserId());
                userAccountService.save(userAccount);
            }
            // 机构老师添加机构绑定记录
            addBindUnBindRecord(teacher.getUserId(),teacher.getTenantId(),true);
            sendBindUnBindSMS(teacher.getUserId(), teacherSubmitReq.getPhone(), MessageTypeEnum.TEACHER_BIND_TENANT, teacher.getTenantId());

            //  与客服建立好友
            /*if (!Boolean.TRUE.equals(teacher.getCustomerService())) {
                List<TeacherWrapper.TeacherFriend> customerServiceFriendNums = this.getBaseMapper().getCustomerServiceFriendNums();
                if (!customerServiceFriendNums.isEmpty()) {
                    Long teacherId = customerServiceFriendNums.get(0).getTeacherId();
                    imUserFriendService.registerUserBindCustomerService(teacher.getUserId(),
                            Collections.singletonList(teacherId), ClientEnum.TEACHER);
                }
            }*/
        } else {
            // 客服状态变更,移交好友信息
            Boolean customerService = teacher.getCustomerService();
            //List<TeacherWrapper.CustomerServiceSendMsg2User> customerServiceSendMsg2User = new ArrayList<>();
            if (Boolean.TRUE.equals(customerService) && Boolean.FALSE.equals(teacherSubmitReq.getCustomerService())) {
                //customerServiceSendMsg2User.addAll(transferFriendV2(teacher.getUserId(), true));

                // 清除客服绑定关系
                clearUserCustomerRelation(teacherSubmitReq.getUserId());

                // 重置客服关系
                this.update(null, new UpdateWrapper<Teacher>().lambda()
                        .set(Teacher::getCustomerId, null)
                        .set(Teacher::getImCustomerId, "")
                        .eq(Teacher::getUserId, teacherSubmitReq.getUserId()));
            }
            // 如果机构解绑，更新机构ID为-1
            if (Boolean.TRUE.equals(teacherSubmitReq.getBindTenant())) {
                teacherSubmitReq.setTenantId(-1L);
            }
            if (!teacher.getTenantId().equals(teacherSubmitReq.getTenantId())) {
                if (teacherSubmitReq.getTenantId().equals(-1L)) {
                    // 平台老师处理流程
                    if (ESettlementFrom.TENANT.equals(teacherSubmitReq.getSettlementFrom())) {
                        // 解绑后，结算方式如果是机构，默认调整为老师
                        teacherSubmitReq.setSettlementFrom(ESettlementFrom.TEACHER);
                        teacherSubmitReq.setIsSettlement(true);
                    }
                }

                TeacherWrapper.UpdateTenant updateTenant = new TeacherWrapper.UpdateTenant();
                updateTenant.setTeacherId(teacher.getUserId());
                updateTenant.setTenantId(teacherSubmitReq.getTenantId());
                updateTenant(updateTenant, teacherSubmitReq.getUpdateBy());
            }

            teacher.setUpdateTime(new Date());
            teacher = getTeacherDetil(teacher, teacherSubmitReq);
            if (null == teacher.getEntryAuthDate() || null == teacher.getMusicianDate()) {
                baseMapper.update(teacher, Wrappers.<Teacher>lambdaUpdate()
                        .set(Teacher::getEntryAuthDate, teacher.getEntryAuthDate())
                        .set(Teacher::getMusicianDate, teacher.getMusicianDate())
                        .eq(Teacher::getUserId, teacher.getUserId())
                );
            }
            // 老师头像
            teacher.setAvatar(Optional.ofNullable(teacherSubmitReq.getAvatar()).orElse(teacher.getAvatar()));
            baseMapper.updateById(teacher);


            // 交接后的客服发送消息
            /*if (Boolean.TRUE.equals(customerService) && Boolean.FALSE.equals(teacherSubmitReq.getCustomerService())) {
                String customerMessage = sysConfigService.findConfigValue(SysConfigConstant.CUSTOMER_SERVICE_ADD_MSG);
                String customerTitle = sysConfigService.findConfigValue(SysConfigConstant.CUSTOMER_SERVICE_ADD_MSG_TITLE);
                for (TeacherWrapper.CustomerServiceSendMsg2User serviceSendMsg2User : customerServiceSendMsg2User) {
                    imUserFriendService.sendCustomerServiceAddFriendMessage(serviceSendMsg2User.getCustomerId(), customerTitle, customerMessage, serviceSendMsg2User.getTeacherIds(),
                            ClientEnum.TEACHER);
                    imUserFriendService.sendCustomerServiceAddFriendMessage(serviceSendMsg2User.getCustomerId(), customerTitle, customerMessage, serviceSendMsg2User.getStudentIds(),
                            ClientEnum.STUDENT);
                }
            }*/

        }

        return teacher;
    }

    // 清除专属客服信息
    private void clearUserCustomerRelation(Long userId) {

        String imCustomerServiceId = imGroupCoreService.getImUserId(String.valueOf(userId), ClientEnum.TEACHER.getCode());

        // 重置老师关联客服绑定
        this.update(null, new UpdateWrapper<Teacher>().lambda()
                .eq(Teacher::getImCustomerId, imCustomerServiceId)
                .set(Teacher::getImCustomerId, "")
                .set(Teacher::getCustomerId, null));

        // 重置学生关联客服绑定
        studentService.update(null, new UpdateWrapper<Student>().lambda()
                .eq(Student::getImCustomerId, imCustomerServiceId)
                .set(Student::getImCustomerId, "")
                .set(Student::getCustomerId, null));
    }

    /*private List<TeacherWrapper.CustomerServiceSendMsg2User> transferFriendV2(Long userId, boolean saveGroupFriend){
        List<TeacherWrapper.CustomerServiceSendMsg2User> result = new ArrayList<>();
        // 所有的好友
        List<ImUserFriend> userFriendList = imUserFriendService.lambdaQuery()
                .eq(ImUserFriend::getUserId, userId)
                .eq(ImUserFriend::getClientType, ClientEnum.TEACHER)
                .list();

        // 好友保留
        userFriendList.stream().filter(n -> Boolean.FALSE.equals(saveGroupFriend) || EImUserFriendSourceForm.CUSTOMER.equals(n.getSourceForm()))
                .collect(Collectors.groupingBy(ImUserFriend::getFriendType)).forEach((client, friends) -> {
                    List<Long> friendIds = friends.stream().map(ImUserFriend::getFriendId).collect(Collectors.toList());
                    imUserFriendService.lambdaUpdate()
                            .eq(ImUserFriend::getUserId, userId)
                            .eq(ImUserFriend::getClientType, ClientEnum.TEACHER)
                            .in(ImUserFriend::getFriendId, friendIds)
                            .eq(ImUserFriend::getFriendType, client)
                            .remove();

                    imUserFriendService.lambdaUpdate()
                            .eq(ImUserFriend::getFriendId, userId)
                            .eq(ImUserFriend::getFriendType, ClientEnum.TEACHER)
                            .in(ImUserFriend::getUserId, friendIds)
                            .eq(ImUserFriend::getClientType, client)
                            .remove();
                });

        // 其他客服
        List<TeacherWrapper.TeacherFriend> customerServiceFriendNums = this.getBaseMapper().getCustomerServiceFriendNums();
        customerServiceFriendNums.removeIf(n -> n.getTeacherId().equals(userId));
        List<Long> customerIds = customerServiceFriendNums.stream().map(TeacherWrapper.TeacherFriend::getTeacherId).collect(Collectors.toList());
        userFriendList.removeIf(n -> customerIds.contains(n.getFriendId()) && ClientEnum.TEACHER.equals(n.getFriendType()));
        if (userFriendList.isEmpty()) { // 没有好友
            return result;
        }

        if (customerIds.isEmpty()) {
            return result;
        }

        // 好友分配
        // 存在专属客服的好友不需要分配
        List<ImUserFriend> teacherFriends = userFriendList.stream().filter(n -> ClientEnum.TEACHER.equals(n.getFriendType())).collect(Collectors.toList());
        if (!teacherFriends.isEmpty()) {
            List<Long> teacherFriendIds = teacherFriends.stream().map(ImUserFriend::getFriendId).distinct().collect(Collectors.toList());
            List<Long> existFriendIds = this.lambdaQuery()
                    .in(Teacher::getUserId, teacherFriendIds)
                    .list()
                    .stream()
                    .filter(n -> customerIds.contains(n.getCustomerId()))
                    .map(Teacher::getUserId)
                    .collect(Collectors.toList());
            userFriendList.removeIf(n -> ClientEnum.TEACHER.equals(n.getFriendType()) && existFriendIds.contains(n.getFriendId()));
        }

        List<ImUserFriend> studentFriends = userFriendList.stream().filter(n -> ClientEnum.STUDENT.equals(n.getFriendType())).collect(Collectors.toList());
        if (!studentFriends.isEmpty()) {
            List<Long> studentFriendIds = studentFriends.stream().map(ImUserFriend::getFriendId).distinct().collect(Collectors.toList());
            List<Long> existFriendIds = studentService.lambdaQuery()
                    .in(Student::getUserId, studentFriendIds)
                    .list()
                    .stream()
                    .filter(n -> customerIds.contains(n.getCustomerId()))
                    .map(Student::getUserId)
                    .collect(Collectors.toList());
            userFriendList.removeIf(n -> ClientEnum.STUDENT.equals(n.getFriendType()) && existFriendIds.contains(n.getFriendId()));
        }

        if (userFriendList.isEmpty()) {
            return result;
        }

        // 好友交接
        Map<Long, Set<Long>> teacherFriendMap = new LinkedHashMap<>();
        Map<Long, Set<Long>> studentFriendMap = new LinkedHashMap<>();
        for (ImUserFriend imUserFriend : userFriendList) {
            TeacherWrapper.TeacherFriend teacherFriend = customerServiceFriendNums.get(0);
            if (ClientEnum.TEACHER.equals(imUserFriend.getFriendType())) {
                Set<Long> set = teacherFriendMap.getOrDefault(teacherFriend.getTeacherId(), new HashSet<>());
                set.add(imUserFriend.getFriendId());
                teacherFriendMap.put(teacherFriend.getTeacherId(), set);
            } else if (ClientEnum.STUDENT.equals(imUserFriend.getFriendType())) {
                Set<Long> set = studentFriendMap.getOrDefault(teacherFriend.getTeacherId(), new HashSet<>());
                set.add(imUserFriend.getFriendId());
                studentFriendMap.put(teacherFriend.getTeacherId(), set);
            }
            teacherFriend.setFriendNums(teacherFriend.getFriendNums() + 1);
            Collections.sort(customerServiceFriendNums);
        }

        teacherFriendMap.forEach((teacherId, teacherIds) -> {
            List<Long> sameTenant = getSameTenant(teacherId, teacherIds, ClientEnum.TEACHER);
            Set<Long> same = teacherIds.stream().filter(sameTenant::contains).collect(Collectors.toSet());
            if (!same.isEmpty()) {
                imUserFriendService.saveUserTeacherFriend(teacherId, same, EImUserFriendSourceForm.TEACHER);
                imUserFriendService.refreshCustomer(teacherId, ClientEnum.TEACHER, new ArrayList<>(same), ClientEnum.TEACHER);
            }
            Set<Long> notSame = teacherIds.stream().filter(n->!sameTenant.contains(n)).collect(Collectors.toSet());
            imUserFriendService.saveUserTeacherFriend(teacherId, notSame, EImUserFriendSourceForm.CUSTOMER);

            this.lambdaUpdate().set(Teacher::getCustomerId,teacherId).in(Teacher::getUserId,teacherIds).update();
            // 发送消息
            TeacherWrapper.CustomerServiceSendMsg2User customerServiceSendMsg2User = new TeacherWrapper.CustomerServiceSendMsg2User();
            customerServiceSendMsg2User.setCustomerId(teacherId);
            customerServiceSendMsg2User.getTeacherIds().addAll(teacherIds);
            result.add(customerServiceSendMsg2User);
//            imUserFriendService.sendCustomerServiceAddFriendMessage(teacherId, customerTitle, customerMessage, new ArrayList<>(teacherIds), ClientEnum.TEACHER);
        });
        studentFriendMap.forEach((teacherId, studentIds) -> {
            List<Long> sameTenant = getSameTenant(teacherId, studentIds, ClientEnum.STUDENT);
            Set<Long> same = studentIds.stream().filter(sameTenant::contains).collect(Collectors.toSet());
            if (!same.isEmpty()) {
                imUserFriendService.saveUserFriend(teacherId, same, EImUserFriendSourceForm.TEACHER);
                imUserFriendService.refreshCustomer(teacherId, ClientEnum.TEACHER, new ArrayList<>(same), ClientEnum.STUDENT);
            }
            Set<Long> notSame = studentIds.stream().filter(n->!sameTenant.contains(n)).collect(Collectors.toSet());
            imUserFriendService.saveUserFriend(teacherId, notSame, EImUserFriendSourceForm.CUSTOMER);

            studentService.lambdaUpdate().set(Student::getCustomerId, teacherId).in(Student::getUserId, studentIds).update();
            TeacherWrapper.CustomerServiceSendMsg2User customerServiceSendMsg2User = new TeacherWrapper.CustomerServiceSendMsg2User();
            customerServiceSendMsg2User.setCustomerId(teacherId);
            customerServiceSendMsg2User.getStudentIds().addAll(studentIds);
            result.add(customerServiceSendMsg2User);
//            imUserFriendService.sendCustomerServiceAddFriendMessage(teacherId, customerTitle, customerMessage, new ArrayList<>(studentIds), ClientEnum.STUDENT);
        });
        return result;
    }*/

    /*private List<Long> getSameTenant(Long teacherId, Set<Long> userIds, ClientEnum clientEnum) {
        Teacher teacher = this.getById(teacherId);
        Long tenantId = teacher.getTenantId();
        if (tenantId == null || tenantId <= 0) {
            return new ArrayList<>();
        }
        if (ClientEnum.STUDENT.equals(clientEnum)) {
            return studentService.lambdaQuery().in(Student::getUserId, userIds).list()
                    .stream().filter(n -> tenantId.equals(n.getTenantId()))
                    .map(Student::getUserId).collect(Collectors.toList());
        }
        if (ClientEnum.TEACHER.equals(clientEnum)) {
            return this.lambdaQuery().in(Teacher::getUserId, userIds).list()
                    .stream().filter(n -> tenantId.equals(n.getTenantId()))
                    .map(Teacher::getUserId).collect(Collectors.toList());
        }
        return new ArrayList<>();
    }*/

    /***
     * 封装用户信息
     * @author liweifan
     * @updateTime 2022/3/23 17:23
     */
    private SysUser getUserDetil(SysUser sysUser, TeacherSubmitReq teacherSubmitReq) throws BizException {

        sysUser.setRealName(teacherSubmitReq.getRealName());
        sysUser.setIdCardNo(teacherSubmitReq.getIdCardNo());
        if (!StringUtil.isEmpty(sysUser.getIdCardNo())) {

            //实名信息
            RealnameAuthReq realNameAuthDto = new RealnameAuthReq();
            realNameAuthDto.setIdCardNo(teacherSubmitReq.getIdCardNo());
            realNameAuthDto.setRealName(teacherSubmitReq.getRealName());
            realNameAuthDto.setSave(false);

            if (!StringUtil.isEmpty(teacherSubmitReq.getIdCardNo()) &&
                !realnameAuthenticationPlugin.verify(realNameAuthDto.getRealName(),realNameAuthDto.getIdCardNo())) {
                throw new BizException("实名认证未通过");
            }

            if (!StringUtil.isEmpty(teacherSubmitReq.getIdCardNo()) ) {
                //通过身份证号获取身份信息
                IdcardInfoExtractor idcardInfo = new IdcardInfoExtractor(realNameAuthDto.getIdCardNo(), false);
                //身份证解析信息
                sysUser.setGender(idcardInfo.getGender());
                sysUser.setBirthdate(idcardInfo.getBirthday());
                sysUser.setRealName(teacherSubmitReq.getRealName());
                sysUser.setIdCardNo(teacherSubmitReq.getIdCardNo());
            }
        }
        if (StringUtil.isEmpty(sysUser.getUserType())) {
            sysUser.setUserType("TEACHER");
        } else if (!sysUser.getUserType().contains("TEACHER")) {
            sysUser.setUserType(sysUser.getUserType() + ",TEACHER");
        }
        sysUser.setAvatar(teacherSubmitReq.getAvatar());
        sysUser.setUsername(teacherSubmitReq.getUsername());
        sysUser.setPhone(teacherSubmitReq.getPhone());
        return sysUser;
    }

    /***
     * 封装老师信息
     * @author liweifan
     * @param: teacherSubmitReq
     * @updateTime 2022/3/23 17:27
     * @return: com.yonge.cooleshow.biz.dal.entity.Teacher
     */
    private Teacher getTeacherDetil(Teacher teacher, TeacherSubmitReq teacherSubmitReq) {
        teacher.setSubjectId(teacherSubmitReq.getSubjectId());
        teacher.setIsSettlement(teacherSubmitReq.getIsSettlement());
        teacher.setIsTestUser(teacherSubmitReq.getIsTestUser());
        teacher.setSettlementFrom(teacherSubmitReq.getSettlementFrom());
        teacher.setTenantId(teacherSubmitReq.getTenantId() == null ? -1L : teacherSubmitReq.getTenantId());
        teacher.setAvatar(Optional.ofNullable(teacherSubmitReq.getAvatar()).orElse(teacher.getAvatar()));
        teacher.setCustomerService(teacherSubmitReq.getCustomerService());
        if (StringUtil.isEmpty(teacherSubmitReq.getTeacherType())) {
            return teacher;
        }
        String[] teacherTypes = teacherSubmitReq.getTeacherType().split(",");
        for (String teacherType : teacherTypes) {
            if (TeacherTypeEnum.ENTRY.getCode().equals(teacherType)) {
                teacher.setEntryFlag(YesOrNoEnum.YES);
                if (teacher.getTeacherDate() == null) {
                    teacher.setEntryAuthDate(new Date());
                }
            }
            if (TeacherTypeEnum.MUSICIAN.getCode().equals(teacherType)) {
                teacher.setMusicianFlag(YesOrNoEnum.YES);
                if (teacher.getMusicDate() == null) {
                    teacher.setMusicianDate(new Date());
                }
            }
        }
        return teacher;
    }

    @Override
    public Integer setSubject(Long id, String subjectIds) {
        Integer integer = baseMapper.setSubject(id, subjectIds);
        //清除老师声部缓存
        redissonClient.getBucket(CacheNameEnum.TEACHER_SUBJECT_ITEM.getRedisKey(id)).delete();
        return integer;
    }

    @Override
    public HttpResponseResult<TeacherHomeVo> queryTeacherHome(Long studentId, Long teacherId) {
        TeacherHomeVo data = queryUserInfo(teacherId).getData();
        if (null == data) {
            return HttpResponseResult.failed("未查询到用户信息");
        }

        if (null != studentId) {
            StudentStar studentStar = studentStarService.getByStudentIdAndTeacherId(studentId, teacherId);
            if (null == studentStar) {
                data.setIsStar(YesOrNoEnum.NO);
            } else {
                data.setIsStar(YesOrNoEnum.YES);
            }
        }
        return HttpResponseResult.succeed(data);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public HttpResponseResult saveTeacherStyle(TeacherDto teacherDto) {
        //校验敏感词
        if (wordFilter.include(teacherDto.getIntroduction(), 3)) {
            throw new BizException("文本包含敏感信息");
        }
        //获取已经配置的vip、趣纠课声部
        List<TeacherSubjectPrice> subjectPrices = teacherSubjectPriceService.lambdaQuery()
                .eq(TeacherSubjectPrice::getTeacherId, teacherDto.getUserId())
                .list();
        if(CollectionUtils.isNotEmpty(subjectPrices)){
            Map<Long,String> map = new HashMap<>();
            List<Long> newSubjectIds = Arrays.stream(teacherDto.getSubjectId().split(",")).map(Long::parseLong).collect(Collectors.toList());
            for (TeacherSubjectPrice subjectPrice : subjectPrices) {
                if (!newSubjectIds.contains(subjectPrice.getSubjectId())) {
                    map.put(subjectPrice.getSubjectId(),subjectPrice.getSubjectName());
                }
            }
            if(!map.isEmpty()){
                String subjectNames = String.join(",", map.values());
                return HttpResponseResult.failed(HttpStatus.NO_CONTENT,map,subjectNames + "存在售卖中的课程，暂不支持修改");
            }
        }

        int i = baseMapper.updateById(teacherDto);
        List<TeacherStyleVideo> styleVideo = teacherDto.getStyleVideo();

        Map<Long, TeacherStyleVideo> oldMap = teacherStyleVideoService.list(Wrappers.<TeacherStyleVideo>lambdaQuery()
                        .eq(TeacherStyleVideo::getUserId, teacherDto.getUserId()))
                .stream().collect(Collectors.toMap(TeacherStyleVideo::getId, o -> o));

        List<TeacherStyleVideo> createList = styleVideo.stream().filter(o -> o.getId() == null)
                .collect(Collectors.toList());


        createList.forEach(o -> {
            o.setUserId(teacherDto.getUserId());
            o.setAuthStatus(AuthStatusEnum.DOING);
            o.setAuditVersion(YesOrNoEnum.NO);
        });

        List<Long> oldIds = styleVideo.stream().filter(o -> o.getId() != null)
                .map(TeacherStyleVideo::getId).collect(Collectors.toList());
        //删除旧视频
        teacherStyleVideoService.removeByUserIdAndOldIds(teacherDto.getUserId(), oldIds);
        //保存新视频
        teacherStyleVideoService.batchAddStyleVideo(createList);

        styleVideo.removeAll(createList);

        //修改视频封面
        styleVideo.forEach(o -> {
            TeacherStyleVideo old = oldMap.get(o.getId());
            if (old != null && !o.getCover().equals(old.getCover())) {
                teacherStyleVideoService.update(Wrappers.<TeacherStyleVideo>lambdaUpdate()
                        .set(TeacherStyleVideo::getCover, o.getCover())
                        .set(TeacherStyleVideo::getAuthStatus, AuthStatusEnum.DOING)
                        .set(TeacherStyleVideo::getEntryFlag, YesOrNoEnum.NO)
                        .eq(TeacherStyleVideo::getId, o.getId()));
            }
        });

        return HttpResponseResult.succeed(detail(teacherDto.getUserId()));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateStyleVideo(Long userId, List<TeacherStyleVideo> styleVideo, String message) {

        if (styleVideo == null) {
            styleVideo = new ArrayList<TeacherStyleVideo>();
        }
        //修改老师信息

        List<TeacherStyleVideo> teacherStyleVideoList =
                teacherStyleVideoService.list(Wrappers.<TeacherStyleVideo>lambdaQuery()
                        .eq(TeacherStyleVideo::getUserId, userId));

        Map<Long, TeacherStyleVideo> oldMap =
                teacherStyleVideoList.stream().collect(Collectors.toMap(TeacherStyleVideo::getId, o -> o));

        List<TeacherStyleVideo> createList = styleVideo.stream().filter(o -> o.getId() == null)
                .collect(Collectors.toList());


        createList.forEach(o -> {
            o.setUserId(userId);
            o.setAuthStatus(AuthStatusEnum.PASS);
        });

        List<Long> oldIds = styleVideo.stream().filter(o -> o.getId() != null)
                .map(TeacherStyleVideo::getId).collect(Collectors.toList());

        for (TeacherStyleVideo tv : teacherStyleVideoList) {
            if (tv.getAuthStatus() == AuthStatusEnum.DOING) {
                oldIds.add(tv.getId());
            }
        }
        //删除旧视频
        teacherStyleVideoService.removeByUserIdAndOldIds(userId, oldIds);
        //保存新视频
        teacherStyleVideoService.batchAddStyleVideo(createList);

        styleVideo.removeAll(createList);

        //修改视频封面
        styleVideo.forEach(o -> {
            TeacherStyleVideo old = oldMap.get(o.getId());
            if (!o.getCover().equals(old.getCover())) {
                teacherStyleVideoService.update(Wrappers.<TeacherStyleVideo>lambdaUpdate()
                        .set(TeacherStyleVideo::getCover, o.getCover())
                        .set(TeacherStyleVideo::getAuthStatus, AuthStatusEnum.PASS)
                        .eq(TeacherStyleVideo::getId, o.getId()));
            }
        });

        //发送推送
        try {
            //  发送消息
            SysUser user = userFeignService.queryUserById(userId);

            Map<Long, String> receivers = new HashMap<>();
            receivers.put(userId, user.getPhone());

            sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG,
                    MessageTypeEnum.CUSTOME_MESSAGE_PUSH, receivers, null, 0,
                    null, ClientEnum.TEACHER.getCode(), message);

        } catch (Exception e) {
            log.error("[老师风采修改]发送消息失败--> {}", e.fillInStackTrace());
        }

        return true;
    }

    @Override
    public HttpResponseResult<Boolean> addHomeBrowse(Long userId) {
        Integer num = baseMapper.addHomeBrowse(userId);
        return HttpResponseResult.succeed(num > 0);
    }

    @Override
    public List<Subject> querySubjectItem(Long userId, String type) {
        //先查询自己的声部
        List<Subject> subjectList = querySubject(userId);

        List<Subject> cacheByType = getCacheByType(userId, type);
        if (CollectionUtils.isNotEmpty(cacheByType)) {
            subjectList.addAll(cacheByType);
        }
        return subjectList;
    }

    private List<Subject> getCacheByType(Long userId, String type) {
        RMap<String, List<Subject>> map = redissonClient.getMap(CacheNameEnum.TEACHER_SUBJECT_ITEM.getRedisKey(userId));
        //设置过期时间
        map.expire(CacheNameEnum.TEACHER_SUBJECT_ITEM.getDuration().toMinutes(),
                TimeUnit.MINUTES);

        if (StringUtil.isEmpty(type)) {
            List<Subject> subjectList = map.get("ALL");
            if (CollectionUtils.isEmpty(subjectList)) {
                subjectList = baseMapper.querySubjectItem(userId, null);
                map.put("ALL", subjectList);
            }
            return subjectList;
        } else {
            List<Subject> subjectList = map.get(type);
            if (CollectionUtils.isEmpty(subjectList)) {
                subjectList = baseMapper.querySubjectItem(userId, type);
                map.put(type, subjectList);
            }
            return subjectList;
        }
    }


    @Override
    public IPage<MyFens> queryMyFans(IPage<MyFens> page, Long teacherId) {
        List<MyFens> teacherVos = baseMapper.queryMyFans(page,
                TeacherQueryInfo.FansQuery.builder().teacherId(teacherId).build());
        setVip(teacherVos);
        return page.setRecords(teacherVos);
    }

    /**
     * 老师粉丝查询
     *
     * @param page  IPage<MyFens>
     * @param query TeacherQueryInfo.FansQuery
     * @return IPage<MyFens>
     */
    @Override
    public IPage<MyFens> queryMyFans(IPage<MyFens> page, TeacherQueryInfo.FansQuery query) {

        List<MyFens> teacherVos = baseMapper.queryMyFans(page, query);
        setVip(teacherVos);
        return page.setRecords(teacherVos);
    }

    @Override
    public void setTeacherTag(Long userId, TeacherTagEnum teacherTagEnum) {
        TeacherVo teacherVo = this.detail(userId);
        if (teacherVo == null) {
            return;
        }
        if (StringUtil.isEmpty(teacherVo.getTag())) {
            teacherVo.setTag(teacherTagEnum.getCode());
            setTagTime(teacherTagEnum, teacherVo);
        } else if (teacherVo.getTag().contains(teacherTagEnum.getCode())) {
            return;
        } else {
            teacherVo.setTag(teacherVo.getTag() + "," + teacherTagEnum.getCode());
            setTagTime(teacherTagEnum, teacherVo);
        }


        this.updateById(teacherVo);
    }

    @Override
    public List<HotTeacherVo> queryHotTeacherList(Long userId) {
        List<Long> watchTeacherIdList = new ArrayList<Long>();

        List<StudentStar> studentStarList = studentStarDao.queryByStudentId(userId);
        if (studentStarList != null && studentStarList.size() > 0) {
            watchTeacherIdList = studentStarList.stream().map(StudentStar::getTeacherId).collect(Collectors.toList());
        }

        Student student = studentService.getById(userId);
        Long subjectId = -1L;
        if (student !=null && student.getSubjectId() != null) {
            subjectId = Long.parseLong(student.getSubjectId());
        }

        List<HotTeacherVo> hotTeacherList = baseMapper.queryHotTeacherList(subjectId);
        for (HotTeacherVo vo : hotTeacherList) {
            if (watchTeacherIdList.contains(vo.getUserId())) {
                vo.setWatch(true);
            }
        }

        return hotTeacherList;
    }

    private void setTagTime(TeacherTagEnum teacherTagEnum, TeacherVo teacherVo) {
        if (teacherTagEnum.equals(TeacherTagEnum.LIVE)) {
            teacherVo.setLiveDate(new Date());
        } else if (teacherTagEnum.equals(TeacherTagEnum.MUSIC)) {
            teacherVo.setLiveDate(new Date());
        } else if (teacherTagEnum.equals(TeacherTagEnum.STYLE)) {
            teacherVo.setLiveDate(new Date());
        } else if (teacherTagEnum.equals(TeacherTagEnum.VIDEO)) {
            teacherVo.setLiveDate(new Date());
        }
    }


    /**
     * 老师详情信息
     *
     * @param teacherId 用户ID
     * @return TeacherVo
     */
    @Override
    public TeacherVo findTeacherDetailInfo(Long teacherId) {

        // 用户详情基本信息
        TeacherVo teacherInfo = detail(teacherId);

        if (Objects.nonNull(teacherInfo)) {

            // 设置默认数据
            teacherInfo
                    .starGrade(0)
                    .fansNum(0)
                    .expTime(0)
                    .unExpTime(0)
                    .musicSheetNum(0)
                    .musicAlbumNum(0)
                    .studentNums(0);

            // 老师相关统计信息
            TeacherTotal total = totalService.getTotalById(teacherId);

            if (Objects.nonNull(total)) {

                teacherInfo
                        .starGrade(total.getStarGrade().intValue())
                        .fansNum(total.getFansNum())
                        .expTime(total.getExpTime())
                        .unExpTime(total.getUnExpTime())
                        .musicAlbumNum(total.getMusicAlbumNum())
                        .musicSheetNum(total.getMusicSheetNum());
            }

            // 老师学生人数统计
            Map<Long, Integer> studentNumsMap =
                    getBaseMapper().selectTeacherStudentNumberStatInfo(Lists.newArrayList(teacherId)).stream()
                            .collect(Collectors.toMap(StatGroupWrapper::getId, StatGroupWrapper::getTotal,
                                    (o, n) -> n));

            teacherInfo.setStudentNums(studentNumsMap.getOrDefault(teacherId, 0));
        }
        return teacherInfo;
    }

    /**
     * 老师统计指标信息
     *
     * @param userId 用户ID
     * @return TeacherWrapper.TeacherStatInfo
     */
    @Override
    public TeacherWrapper.TeacherStatInfo findTeacherStatInfoById(Long userId) {

        TeacherWrapper.TeacherStatInfo wrapper = TeacherWrapper.TeacherStatInfo.builder()
                .fansNum(0)
                .studentNums(0)
                .starGrade(0)
                .expTime(0)
                .unExpTime(0)
                .musicAlbumNum(0)
                .musicSheetNum(0)
                .build();

        // 查询老师统计指标
        TeacherTotal total = totalService.getTotalById(userId);
        if (Objects.nonNull(total)) {

            wrapper.starGrade(total.getStarGrade().intValue())
                    .fansNum(total.getFansNum())
                    .expTime(total.getExpTime())
                    .unExpTime(total.getUnExpTime())
                    .musicAlbumNum(total.getMusicAlbumNum())
                    .musicSheetNum(total.getMusicSheetNum());
        }

        // 老师学生端人数统计
        List<Long> teacherIds = Lists.newArrayList(userId);
        Map<Long, Integer> studentNumsMap = getBaseMapper().selectTeacherStudentNumberStatInfo(teacherIds).stream()
                .collect(Collectors.toMap(StatGroupWrapper::getId, StatGroupWrapper::getTotal, (o, n) -> n));

        wrapper.setStudentNums(studentNumsMap.getOrDefault(userId, 0));

        return wrapper;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateTenant(TeacherWrapper.UpdateTenant updateTenant,Long userId) {
        Teacher teacher = this.getById(updateTenant.getTeacherId());
        if (teacher.getTenantId().equals(updateTenant.getTenantId())) {
            return;
        }
        Long oldTenantId = teacher.getTenantId();
        if (oldTenantId != -1L) {
            // 判断是否存在机构小组群主身份
            QueryWrapper<TenantGroup> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda()
                    .eq(TenantGroup::getTenantId, oldTenantId)
                    .eq(TenantGroup::getAdminId, teacher.getUserId());
            Integer count = tenantGroupMapper.selectCount(queryWrapper);
            if (count > 0) {
                throw new BizException("该老师存在机构小组负责人身份，请先更换老师或者退出小组");
            }

            // 机构老师处理流程
            List<String> imGroupIds = imGroupMemberService.lambdaQuery()
                    .eq(ImGroupMember::getUserId, teacher.getUserId())
                    .eq(ImGroupMember::getIsAdmin, true)
                    .eq(ImGroupMember::getRoleType, ImGroupMemberRoleType.TEACHER)
                    .list().stream().map(ImGroupMember::getGroupId).distinct().collect(Collectors.toList());
            if (!imGroupIds.isEmpty()) {
                List<ImGroup> imGroups = imGroupService.lambdaQuery()
                        .in(ImGroup::getId, imGroupIds)
                        .eq(ImGroup::getType, ImGroupType.ORG)
                        .list();
                imGroups.forEach(next -> {
                    try {
                        imGroupService.dismiss(next.getId());
                    } catch (Exception e) {
                        log.error("老师修改机构，解散机构群失败：{}", e.getMessage());
                    }
                });
            }
            // 删除好友关系
            imUserFriendService.delStudentFriendByTenantId(teacher.getTenantId(), teacher.getUserId(), ClientEnum.TEACHER.getCode());
            addBindUnBindRecord(teacher.getUserId(), teacher.getTenantId(), false);
            SysUser sysUser = sysUserMapper.getByUserId(teacher.getUserId());
            sendBindUnBindSMS(teacher.getUserId(), sysUser.getPhone(), MessageTypeEnum.TEACHER_UNBIND_TENANT, teacher.getTenantId());

        }

        long tenantId = Optional.ofNullable(updateTenant.getTenantId()).orElse(-1L);
        if (tenantId == -1L) {
            // 平台老师处理流程
            if (ESettlementFrom.TENANT.equals(teacher.getSettlementFrom())) {
                // 解绑后，结算方式如果是机构，默认调整为老师
                teacher.setSettlementFrom(ESettlementFrom.TEACHER);
                teacher.setIsSettlement(true);
            }
        }else {
            // 机构老师与学生互加好友关系
            // 自动与机构学生成为好友
            Set<Long> collect = studentService.lambdaQuery()
                    .eq(Student::getTenantId, updateTenant.getTenantId()).list().stream()
                    .map(Student::getUserId)
                    .collect(Collectors.toSet());

            if (!collect.isEmpty()) {
                imUserFriendService.saveUserFriend(teacher.getUserId(), collect, EImUserFriendSourceForm.TEACHER);
                //imUserFriendService.refreshCustomer(teacher.getUserId(), ClientEnum.TEACHER, new ArrayList<>(collect), ClientEnum.STUDENT);
            }
            addBindUnBindRecord(teacher.getUserId(),updateTenant.getTenantId(),true);
            SysUser sysUser = sysUserMapper.getByUserId(teacher.getUserId());
            sendBindUnBindSMS(teacher.getUserId(), sysUser.getPhone(), MessageTypeEnum.TEACHER_BIND_TENANT, updateTenant.getTenantId());
        }

        teacher.setTenantId(updateTenant.getTenantId());
        this.updateById(teacher);

        Optional<TenantUnbindRecord> first = tenantUnbindRecordMapper.getRecord(oldTenantId,
                        updateTenant.getTeacherId(), "TEACHER").stream()
                .filter(next -> next.getStatus().equals(ETenantUnBindAuditStatus.DOING)).findFirst();
        if (first.isPresent()) {
            TenantUnbindRecord tenantUnbindRecord = first.get();
            tenantUnbindRecord.setStatus(ETenantUnBindAuditStatus.CLOSE);
            tenantUnbindRecord.setReason("机构发生变更，关闭申请");
            tenantUnbindRecord.setVerifyUserId(userId);
            tenantUnbindRecord.setInterveneTime(new Date());
            tenantUnbindRecordMapper.updateById(tenantUnbindRecord);

            TenantUnbindHistory history = JSON.parseObject(JSON.toJSONString(tenantUnbindRecord),
                    TenantUnbindHistory.class);
            tenantUnbindHistoryMapper.insert(history);
        }

    }

    @Override
    public UserPaymentOrderWrapper.AccountTenantTo teacherSettlementFrom(Long teacherId, Long recomUserId) {
        // 判断分润给机构 还是给老师


        UserPaymentOrderWrapper.AccountTenantTo accountTenantTo = new UserPaymentOrderWrapper.AccountTenantTo();

        if (teacherId != null) {
            Teacher teacher = getById(teacherId);
            if (teacher.getIsSettlement() !=null && !teacher.getIsSettlement()) {
                accountTenantTo.setIncomeTenant(0L);
            } else if (teacher.getTenantId() != null && teacher.getTenantId() > 0) {
                accountTenantTo.setIncomeTenant(teacher.getTenantId());
                if (ESettlementFrom.TEACHER.equals(teacher.getSettlementFrom())) {
                    accountTenantTo.setIncomeTeacher(true);
                }
            } else {
                // 分润给老师
                accountTenantTo.setIncomeTenant(-1L);
                accountTenantTo.setIncomeTeacher(true);
            }
        }


        if (recomUserId != null) {
            Teacher teacher = getById(recomUserId);
            if (teacher.getIsSettlement() !=null && !teacher.getIsSettlement()) {
                accountTenantTo.setShareTenant(0L);
            } else if (teacher.getTenantId() != null && teacher.getTenantId() > 0) {
                accountTenantTo.setShareTenant(teacher.getTenantId());
                if (ESettlementFrom.TEACHER.equals(teacher.getSettlementFrom())) {
                    accountTenantTo.setShareTeacher(true);
                }
            } else {
                // 分润给老师
                accountTenantTo.setShareTenant(-1L);
                accountTenantTo.setShareTeacher(true);
            }
        }

        return accountTenantTo;
    }

    @Override
    public Map<Long, Teacher> getMapByIds(List<Long> teacherIds) {

        if (CollectionUtils.isEmpty(teacherIds)) {
            return Collections.emptyMap();
        }

        List<Teacher> teachers = getBaseMapper().selectBatchIds(teacherIds);
        if (CollectionUtils.isEmpty(teachers)) {
            return Collections.emptyMap();
        }

        return teachers.stream().collect(Collectors.toMap(Teacher::getUserId, o -> o, (o, n) -> n));
    }

    private void addBindUnBindRecord(Long teacherId, Long tenantId, Boolean bind) {
        UserTenantBindRecord bindRecord = new UserTenantBindRecord();
        bindRecord.setUserId(teacherId);
        bindRecord.setUserType("TEACHER");
        bindRecord.setTenantId(tenantId);
        bindRecord.setBindStatus(bind);
        bindRecord.setBindTime(new Date());
        userTenantBindRecordMapper.add(bindRecord);
    }

    private void sendBindUnBindSMS(Long userId, String phone, MessageTypeEnum messageType, Long tenantId) {
        if (tenantId == null ){
            return;
        }
        TenantInfo tenantInfo = tenantInfoService.getById(tenantId);
        if (tenantInfo == null) {
            return;
        }
        Map<Long, String> receivers = new HashMap<>();
        receivers.put(userId, phone);
        sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.AWSMS, messageType,
                receivers, null, 0, null, ClientEnum.SYSTEM.getCode(), tenantInfo.getName());
    }

    private void setVip(List<MyFens> teacherVos) {
        if (CollectionUtils.isEmpty(teacherVos)) {
            return;
        }
        List<Long> studentIds = teacherVos.stream().map(n -> Long.valueOf(n.getUserId())).collect(Collectors.toList());
        Map<Long, EUserVipType> vipMap = vipCardRecordService.queryUserVipInfo(studentIds, ClientEnum.STUDENT.getCode()).stream()
                .collect(Collectors.toMap(VipCardRecordWrapper.UserVipInfo::getUserId, VipCardRecordWrapper.UserVipInfo::getCurrentVipType));

        for (MyFens teacherVo : teacherVos) {
            EUserVipType vipType = vipMap.getOrDefault(Long.valueOf(teacherVo.getUserId()), EUserVipType.NORMAL);
            teacherVo.setIsVip(EUserVipType.NORMAL.equals(vipType) ? YesOrNoEnum.NO : YesOrNoEnum.YES);
            teacherVo.setVipType(vipType);
        }
    }

    /**
     * 获取学生好友最少的一个客服
     * @return 客服
     */
    private Teacher getCustomerServiceByFriendLeast() {
        return this.getBaseMapper().getCustomerServiceByFriendLeast();
    }

    @Override
    public List<Teacher> getCustomerService() {
        return this.lambdaQuery()
                .eq(Teacher::getCustomerService, true)
                .eq(Teacher::getLockFlag, false)
                .list();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateLock(SysUser sysUser, Long teacherId) {
        Teacher teacher = this.getById(teacherId);
        if (teacher == null) {
            throw new BizException("无效的老师账号");
        }
        Long tenantId = teacher.getTenantId();
        Boolean customerService = teacher.getCustomerService();
        if (tenantId != null && tenantId > 0 && Boolean.TRUE.equals(customerService)) {
            throw new BizException("客服不能有机构老师身份");
        }

        // 冻结客服，移交好友给其他客服
        if (UserLockFlag.NORMAL.equals(teacher.getLockFlag()) && Boolean.TRUE.equals(customerService)) {
            // List<TeacherWrapper.CustomerServiceSendMsg2User> customerServiceSendMsg2User = transferFriendV2(teacherId, false);

            // 清除客服绑定关系
            clearUserCustomerRelation(teacherId);

            // 重置数据
            this.update(null, new UpdateWrapper<Teacher>().lambda()
                    .set(Teacher::getCustomerId, null)
                    .set(Teacher::getImCustomerId, "")
                    .eq(Teacher::getUserId, teacherId));

            /*for (TeacherWrapper.CustomerServiceSendMsg2User serviceSendMsg2User : customerServiceSendMsg2User) {
                String customerMessage = sysConfigService.findConfigValue(SysConfigConstant.CUSTOMER_SERVICE_ADD_MSG);
                String customerTitle = sysConfigService.findConfigValue(SysConfigConstant.CUSTOMER_SERVICE_ADD_MSG_TITLE);
                imUserFriendService.sendCustomerServiceAddFriendMessage(serviceSendMsg2User.getCustomerId(), customerTitle, customerMessage, serviceSendMsg2User.getTeacherIds(),
                        ClientEnum.TEACHER);
                imUserFriendService.sendCustomerServiceAddFriendMessage(serviceSendMsg2User.getCustomerId(), customerTitle, customerMessage, serviceSendMsg2User.getStudentIds(),
                        ClientEnum.STUDENT);
            }*/
        }
        teacher.setLockFlag(UserLockFlag.NORMAL.equals(teacher.getLockFlag()) ? UserLockFlag.LOCKED : UserLockFlag.NORMAL);
        this.updateById(teacher);
    }

    /**
     * 系统默认客服用户
     *
     * @return List<Teacher>
     */
    @Override
    public List<Teacher> getCustomerServiceV2() {
        return baseMapper.selectCustomerServiceV2();
    }

    /**
     * 查询客服好友数量
     *
     * @return List<StatGroupWrapper>
     */
    @Override
    public List<StatGroupWrapper> getCustomerServiceMemberNums() {
        return baseMapper.countCustomerServiceMemberNum();
    }

    /**
     * 更新用户客服
     *
     * @param userId 用户ID
     * @return String
     */
    @Override
    public String updateUserCustomerService(Long userId) {

        TeacherVo teacher = detail(userId);
        if (Objects.isNull(teacher)) {
            throw new BizException("老师不存在");
        }

        // 学生已绑定客服，直接近回
        if (StringUtils.isNotBlank(teacher.getImCustomerId())) {
            return teacher.getImCustomerId();
        }

        // 随机分配系统客服
        String imCustomerServiceId = imGroupCoreService.getSysRandomCustomerService();
        if (StringUtils.isBlank(imCustomerServiceId)) {
            throw new BizException("系统客服不存在");
        }
        String customerServiceId = imGroupCoreService.analysisImUserId(imCustomerServiceId);

        // 更新用户绑定客服
        lambdaUpdate()
            .eq(Teacher::getUserId, userId)
            .set(Teacher::getCustomerId, customerServiceId)
            .set(Teacher::getImCustomerId, imCustomerServiceId)
            .update();

        return imCustomerServiceId;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delFans(Long studentId, Long teacherId) {
        studentStarDao.delFans(studentId,teacherId);
        teacherTotalService.totalTeacherTotalById(teacherId);
        studentTotalService.totalStudentTotalById(studentId);
    }

    @Override
    public TeacherFreeTimeWrapper.TeacherFreeConfig queryTeacherTime() {
        TeacherFreeTimeWrapper.TeacherFreeConfig teacherFreeConfig = new TeacherFreeTimeWrapper.TeacherFreeConfig();
        teacherFreeConfig.setStartTime(sysConfigService.findConfigValue(SysConfigConstant.COURSE_START_SETTING));
        teacherFreeConfig.setEndTime(sysConfigService.findConfigValue(SysConfigConstant.COURSE_END_SETTING));
        List<TeacherFreeTimeWrapper.CourseConfigDto> vipCourseTime = JSON.parseArray(sysConfigService.findConfigValue(SysConfigConstant.VIP_COURSE_TIMES_SETTING),TeacherFreeTimeWrapper.CourseConfigDto.class);
        vipCourseTime.addAll(JSON.parseArray(sysConfigService.findConfigValue(SysConfigConstant.PRACTICE_TIMES_SETTING),TeacherFreeTimeWrapper.CourseConfigDto.class));
        //获取空闲时间 + 课程时间 两者之和最大的时间
        int maxTime = vipCourseTime.stream().mapToInt(o -> o.getCourseMinutes() + o.getFreeMinutes()).max().orElse(0);
        teacherFreeConfig.setIntervalTime(maxTime);
        return teacherFreeConfig;
    }
}