package jnpf.cultivate.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fantaibao.permission.handling.PermissionHandling;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import jnpf.authority.FtbAuthorityApi;
import jnpf.authority.service.FtbPermissionUsersService;
import jnpf.base.ActionResult;
import jnpf.base.UserInfo;
import jnpf.base.vo.PageListVO;
import jnpf.consts.DeviceType;
import jnpf.cultivate.mapper.*;
import jnpf.cultivate.service.CultivateFileService;
import jnpf.cultivate.service.TeachingRecordService;
import jnpf.cultivate.service.TeachingSkillService;
import jnpf.cultivate.service.TeachingStudentService;
import jnpf.entity.cultivate.TeachingRecord;
import jnpf.entity.cultivate.TeachingSkill;
import jnpf.entity.cultivate.TeachingStudent;
import jnpf.model.cultivate.dto.teaching.QueryTeachingRecordDto;
import jnpf.model.cultivate.dto.teaching.RecordQueryDto;
import jnpf.model.cultivate.dto.teaching.TeachingSaveDto;
import jnpf.model.cultivate.event.dto.file.FileEventDTO;
import jnpf.model.cultivate.po.teaching.CultivateFile;
import jnpf.model.cultivate.po.teaching.CultivateUserView;
import jnpf.model.cultivate.po.teaching.TeachingApprove;
import jnpf.model.cultivate.v2.enums.ApproveEnum;
import jnpf.model.cultivate.v2.teaching.model.V2Attachment;
import jnpf.model.cultivate.v2.teaching.vo.*;
import jnpf.model.cultivate.vo.teaching.*;
import jnpf.model.personnels.dto.staff.roster.FtbPersonnelsStaffRosterDto;
import jnpf.model.personnels.req.roster.StaffRosterListReq;
import jnpf.model.store.Store;
import jnpf.permission.PositionApi;
import jnpf.permission.V2UserApi;
import jnpf.permission.dto.user.QueryUserDTO;
import jnpf.permission.dto.v2.AuthUserNodeDTO;
import jnpf.permission.eum.v2.OrganizeCategoryEnums;
import jnpf.permission.eum.v2.TargetAuthEnums;
import jnpf.permission.model.position.PositionInfoNewVO;
import jnpf.permission.model.user.PartUserInfoVo;
import jnpf.permission.model.user.UserInfoByIdsPost;
import jnpf.permission.vo.v2.TargetAuthIdsVO;
import jnpf.permission.vo.v2.organzie.OrganizeGeneralDetailVO;
import jnpf.permission.vo.v2.user.UserBoundVO;
import jnpf.personnels.FtbPersonnelsRosterManagerApi;
import jnpf.store.service.StoreService;
import jnpf.util.*;
import jnpf.util.auth.V2AuthPermissionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

@Service
public class TeachingRecordServiceImpl extends ServiceImpl<TeachingRecordMapper, TeachingRecord> implements TeachingRecordService {
    @Resource
    private V2UserApi v2UserApi;
    @Resource
    private FtbPersonnelsRosterManagerApi ftbPersonnelsRosterManagerApi;
    @Resource
    private TeachingRecordMapper teachingRecordMapper;
    @Resource
    private TeachingStudentMapper teachingStudentMapper;
    @Resource
    private TeachingStudentService teachingStudentService;
    @Resource
    private StoreService storeService;
    @Autowired
    private V2UserQueryUtil v2UserQueryUtil;
    @Resource
    private PositionApi positionApi;
    @Resource
    private TeachingSkillMapper teachingSkillMapper;
    @Resource
    private TeachingSkillService teachingSkillService;
    @Resource
    private CultivateFileService cultivateFileService;
    @Resource
    private PermissionHandling permissionHandling;
    @Resource
    private TeachingApproveMapper teachingApproveMapper;
    @Autowired
    private FtbAuthorityApi ftbAuthorityApi;
    @Resource
    private RedisUtil redisUtil;
    @Resource
    private CultivateUserViewMapper cultivateUserViewMapper;
    @Resource
    private FtbPermissionUsersService permissionUsersService;
    @Resource
    private V2AuthPermissionUtils authPermissionUtils;

    /**
     * 根据用户ID生成Redis键
     *
     * @param userId 用户ID
     * @return Redis键
     */
    public static String getUserPermissionKey(String userId) {
        return "user:permission:user:" + userId;
    }

    @Override
    public List<PositionUserVo> getPostUserList(String storeId) {

        List<UserBoundVO> userBoundVOList = v2UserQueryUtil.getOrganizeChildUserList(storeId);
        if (CollectionUtil.isEmpty(userBoundVOList)) {
            return new ArrayList<>();
        }
        //数据权限过滤
        /*if (!UserProvider.getUser().getIsAdministrator()) {
            //非管理员加入数据权限筛选流程
            List<String> permissionUserIds = permissionHandling.getUserIdsByUserId(UserProvider.getLoginUserId());
            if (CollUtil.isNotEmpty(permissionUserIds)) {
                userBoundVOList = userBoundVOList.stream().filter(user -> permissionUserIds.contains(user.getId())).collect(Collectors.toList());
            }
        }*/

        Map<String, List<UserBoundVO>> dataMap = userBoundVOList.stream().collect(Collectors.groupingBy(UserBoundVO::getPositionId));
        List<PositionUserVo> positionUserVoList = new ArrayList<>();
        dataMap.forEach((k, v) -> {
            PositionUserVo positionUserVo = new PositionUserVo();
            positionUserVo.setPostId(k);
            positionUserVo.setFullName(v.get(0).getPositionName());
            List<StudentUserVo> userList = v.stream().map(user -> {
                StudentUserVo studentUserVo = new StudentUserVo();
                studentUserVo.setUserId(user.getId());
                studentUserVo.setUserName(user.getName());
                String headIcon = UploaderUtil.uploaderImg(user.getHeadIcon());
                studentUserVo.setHeadIcon(headIcon);
                return studentUserVo;
            }).collect(Collectors.toList());
            positionUserVo.setStudentUserVoList(userList);
            positionUserVoList.add(positionUserVo);
        });
        return positionUserVoList;
    }

    @Override
    public PageInfo<TeachingRecordVo> page(QueryTeachingRecordDto queryTeachingRecordDto) {
        String device = UserProvider.getDeviceForAgent().getDevice();

        String userId = device.equals(DeviceType.APP.getDevice()) ? UserProvider.getLoginUserId() : null;
        if (ObjectUtil.isNotNull(queryTeachingRecordDto.getFilterLogin()) && !queryTeachingRecordDto.getFilterLogin()) {
            //是否过滤当前登录人
            userId = null;
        }
        // 技能点分类过滤
        List<String> skillIds = teachingSkillService.querySkillIds(queryTeachingRecordDto.getCategoryId());
        if (skillIds == null) {
            return new PageInfo<>();
        }
        QueryWrapper<TeachingRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(TeachingRecord::getDeleteMark, 0)
                .eq(TeachingRecord::getType, 1)
                .eq(StrUtil.isNotBlank(userId), TeachingRecord::getUserId, userId)
                .eq(StrUtil.isNotBlank(queryTeachingRecordDto.getStoreId()), TeachingRecord::getStoreId, queryTeachingRecordDto.getStoreId())
                .in(CollectionUtil.isNotEmpty(skillIds), TeachingRecord::getSkillId, skillIds)
                // 兼容web端门店条件查询
                .in(CollectionUtil.isNotEmpty(queryTeachingRecordDto.getStoreIdList()), TeachingRecord::getStoreId, queryTeachingRecordDto.getStoreIdList())
                .between(StrUtil.isNotBlank(queryTeachingRecordDto.getStartDate()) && StrUtil.isNotBlank(queryTeachingRecordDto.getEndDate()), TeachingRecord::getDate,
                        queryTeachingRecordDto.getStartDate() + " 00:00:00", queryTeachingRecordDto.getEndDate() + " 23:59:59");
        if (StrUtil.isNotBlank(queryTeachingRecordDto.getKeyword())) {
            //技能点模糊查询数据
            QueryWrapper<TeachingSkill> skillQueryWrapper = new QueryWrapper<>();
            skillQueryWrapper.lambda()
                    .like(TeachingSkill::getName, queryTeachingRecordDto.getKeyword());
            List<TeachingSkill> teachingSkillList = teachingSkillMapper.selectList(skillQueryWrapper);

            List<String> skillIdList = teachingSkillList.stream().map(TeachingSkill::getId).collect(Collectors.toList());
            if (CollectionUtil.isEmpty(skillIdList)) {
                skillIdList.add("-1");
            }
            //学员模糊查询数据
            QueryWrapper<TeachingStudent> studentQueryWrapper = new QueryWrapper<>();
            studentQueryWrapper.lambda()
                    .like(TeachingStudent::getUsername, queryTeachingRecordDto.getKeyword());
            List<TeachingStudent> teachingStudents = teachingStudentMapper.selectList(studentQueryWrapper);
            List<String> studentRecordIds = teachingStudents.stream().map(TeachingStudent::getRecordId).collect(Collectors.toList());
            if (CollectionUtil.isEmpty(studentRecordIds)) {
                studentRecordIds.add("-1");
            }
            if (device.equals(DeviceType.APP.getDevice())) {
                //app端模糊查询
                queryWrapper.lambda()
                        .and(q -> {
                            q.in(TeachingRecord::getSkillId, skillIdList)
                                    .or()
                                    .in(TeachingRecord::getId, studentRecordIds);
                        });
            } else {
                // web端模糊查询
                queryWrapper.lambda()
                        .and(q -> {
                            q.like(TeachingRecord::getUserName, queryTeachingRecordDto.getKeyword())
                                    .or().like(TeachingRecord::getPostName, queryTeachingRecordDto.getKeyword());
                        });
            }

        }
        if (queryTeachingRecordDto.getIsDataPermission() && !UserProvider.getUser().getIsAdministrator()) {
            UserInfo loginUser = UserProvider.getUser();
            String hashValue = getValidatedHashValue(UserProvider.getLoginUserId(), ServletUtil.getHeader("module"));
            String scope = hashValue.split("#")[0];
            if ("3".equals(scope)) {
                //权限为仅下属 就只看学员是“我的下属”的人
                List<String> studentUserIds = loginUser.getIsAdministrator() ? null : permissionHandling.getUserIdsByUserId(UserProvider.getLoginUserId());
                if (studentUserIds != null && studentUserIds.isEmpty()) {
                    return new PageInfo<>();
                }
                QueryWrapper<TeachingStudent> studentQueryWrapper = new QueryWrapper<>();
                studentQueryWrapper.lambda()
                        .eq(TeachingStudent::getDeleteMark, 0)
                        .in(CollectionUtil.isNotEmpty(studentUserIds), TeachingStudent::getUserId, studentUserIds);
                List<TeachingStudent> studentList = teachingStudentMapper.selectList(studentQueryWrapper);
                if (CollectionUtil.isEmpty(studentList)) {
                    return new PageInfo<>();
                }
                List<String> recordIdList = studentList.stream().map(TeachingStudent::getRecordId).collect(Collectors.toList());
                queryWrapper.lambda()
                        .in(TeachingRecord::getId, recordIdList);
            } else {
                List<String> authStoreIdList = getAuthStoreIdList();
                List<String> permissionStoreIdList = CollectionUtil.isEmpty(authStoreIdList) ? List.of("-1") : authStoreIdList;
                //获取数据权限用户id集合

                List<String> queryStoreIdList = loginUser.getIsAdministrator() ? null : permissionStoreIdList;
                queryWrapper.lambda()
                        .in(CollectionUtil.isNotEmpty(queryStoreIdList), TeachingRecord::getStoreId, queryStoreIdList);
            }

        }
        queryWrapper.lambda()
                .orderByDesc(TeachingRecord::getDate)
                .orderByDesc(TeachingRecord::getCreatorTime);
        PageHelper.startPage((int) queryTeachingRecordDto.getCurrentPage(), (int) queryTeachingRecordDto.getPageSize());
        List<TeachingRecord> teachingRecords = teachingRecordMapper.selectList(queryWrapper);
        PageInfo<TeachingRecord> pageInfo = new PageInfo<>(teachingRecords);
        if (CollectionUtil.isEmpty(teachingRecords)) {
            return new PageInfo<>();
        }

        List<String> ids = teachingRecords.stream().map(TeachingRecord::getId).collect(Collectors.toList());

        //查询记录学员
        QueryWrapper<TeachingStudent> studentQueryWrapper = new QueryWrapper<>();
        studentQueryWrapper.lambda()
                .in(TeachingStudent::getRecordId, ids);
        List<TeachingStudent> teachingStudents = teachingStudentMapper.selectList(studentQueryWrapper);
        Map<String, List<TeachingStudent>> studentMap = teachingStudents.stream().collect(Collectors.groupingBy(TeachingStudent::getRecordId));
        List<TeachingRecordVo> voList = JsonUtil.getJsonToList(teachingRecords, TeachingRecordVo.class);
        // 技能点查询
        List<String> skillIdList = voList.stream().map(TeachingRecordVo::getSkillId).collect(Collectors.toList());
        QueryWrapper<TeachingSkill> skillQueryWrapper = new QueryWrapper<>();
        skillQueryWrapper.lambda()
                .in(TeachingSkill::getId, skillIdList);
        List<TeachingSkill> teachingSkillList = teachingSkillMapper.selectList(skillQueryWrapper);
        Map<String, TeachingSkill> skillMap = teachingSkillList.stream().collect(Collectors.toMap(TeachingSkill::getId, Function.identity()));
        for (TeachingRecordVo teachingRecordVo : voList) {
            List<TeachingStudent> recordStuList = studentMap.get(teachingRecordVo.getId());
            if (CollectionUtil.isNotEmpty(recordStuList)) {
                List<String> stuNameList = recordStuList.stream().map(TeachingStudent::getUsername).collect(Collectors.toList());
                String stus = CollectionUtil.join(stuNameList, "、");
                teachingRecordVo.setStudents(stus);
            }
            //拼接封面
            String cover = teachingRecordVo.getVideoPath() + ".0.jpg";
            teachingRecordVo.setVideoCover(cover);
            TeachingSkill teachingSkill = skillMap.get(teachingRecordVo.getSkillId());
            teachingRecordVo.setSkillName(teachingSkill.getName());
        }
        PageInfo<TeachingRecordVo> voPageInfo = new PageInfo<>();
        BeanUtil.copyProperties(pageInfo, voPageInfo);
        voPageInfo.setList(voList);

        return voPageInfo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(TeachingSaveDto teachingSaveDto) {
        TeachingRecord teachingRecord = JsonUtil.getJsonToBean(teachingSaveDto, TeachingRecord.class);
        teachingRecord.setCreatorTime(new Date());
        String recordId = RandomUtil.uuId();
        teachingRecord.setId(recordId);
        teachingRecord.setCreatorUserId(UserProvider.getLoginUserId());
        teachingRecord.setStoreId(teachingSaveDto.getStoreId());
        Store info = storeService.getInfo(teachingSaveDto.getStoreId());
        teachingRecord.setStoreName(info.getStoreName());
        String loginUserId = UserProvider.getLoginUserId();
        ActionResult<UserBoundVO> actionResult = v2UserApi.infoAndCopy(UserProvider.getUser().getUserId());
        Assert.isTrue(actionResult.getCode().equals(200), "查询登录用户主岗信息异常");
        UserBoundVO userInfo = actionResult.getData();
        Assert.notNull(userInfo, "未查询到登录用户的主岗信息");
        teachingRecord.setUserId(loginUserId);
        teachingRecord.setUserName(userInfo.getUserName());
        teachingRecord.setPostId(userInfo.getPositionId());
        teachingRecord.setDeleteMark(0);
        teachingRecord.setPostName(ObjectUtil.isNull(userInfo.getPositionName()) ? null : userInfo.getPositionName());
        teachingRecordMapper.insert(teachingRecord);
        //学员入库
        List<String> studentUserIds = teachingSaveDto.getStudentUserIds();
        batchAddStuList(studentUserIds, recordId);
        // 新增附件信息
        if (null != teachingSaveDto.getFileList() && !teachingSaveDto.getFileList().isEmpty()) {
            List<CultivateFile> fileList = changeToFileList(recordId, teachingSaveDto.getFileList(), UserProvider.getLoginUserId(), FileEventDTO.FileType.TEACHING);
            cultivateFileService.saveBatch(fileList);
        }
        // 新增审核
        if (teachingSaveDto.getType().equals(1)) {
            TeachingApprove approve = new TeachingApprove(FtbUtil.getId(), teachingRecord.getId(), ApproveEnum.WAIT.getCode());
            teachingApproveMapper.insert(approve);
        }
    }

    @Override
    public List<CultivateFile> changeToFileList(String recordId, List<V2Attachment> fileList, String userId, FileEventDTO.FileType fileType) {

        List<CultivateFile> list = new ArrayList<>();
        fileList.forEach(file -> {
            CultivateFile f = new CultivateFile();
            f.setId(FtbUtil.getId());
            f.setBusinessId(recordId);
            f.setFileName(file.getFileName());
            f.setUrl(file.getUrl());
            f.setSize(file.getSize());
            f.setExtension(file.getExtension());
            f.setType(fileType.getType());
            f.setVideoActionType(file.getVideoActionType());
            f.setCreatorUserId(userId);
            f.setLastModifyUserId(userId);
            list.add(f);
        });
        return list;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void update(TeachingSaveDto teachingSaveDto) {
        TeachingRecord teachingRecord = JsonUtil.getJsonToBean(teachingSaveDto, TeachingRecord.class);
        teachingRecord.setStoreId(teachingSaveDto.getStoreId());
        Store info = storeService.getInfo(teachingSaveDto.getStoreId());
        teachingRecord.setStoreName(info.getStoreName());
        teachingRecord.setLastModifyTime(new Date());
        teachingRecord.setLastModifyUserId(UserProvider.getLoginUserId());
        teachingRecord.setDeleteMark(0);
        teachingRecordMapper.updateById(teachingRecord);
        //先删除已存在的学员
        UpdateWrapper<TeachingStudent> deleteWrapper = new UpdateWrapper<>();
        deleteWrapper.lambda()
                .eq(TeachingStudent::getRecordId, teachingRecord.getId());
        teachingStudentMapper.delete(deleteWrapper);
        batchAddStuList(teachingSaveDto.getStudentUserIds(), teachingRecord.getId());
        // 更新附件信息
        updateFileInfo(teachingSaveDto.getId(), teachingSaveDto.getFileList(), FileEventDTO.FileType.TEACHING);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateFileInfo(String bizId, List<V2Attachment> fileList, FileEventDTO.FileType fileType) {
        // 查询附件列表
        LambdaQueryWrapper<CultivateFile> fileQuery = new LambdaQueryWrapper<CultivateFile>()
                .eq(CultivateFile::getBusinessId, bizId);
        List<CultivateFile> list = cultivateFileService.list(fileQuery);
        if (!list.isEmpty()) {
            List<String> collect = list.stream().map(CultivateFile::getId).collect(Collectors.toList());
            cultivateFileService.removeBatchByIds(collect);
        }
        // 新增附件信息
        if (null != fileList && !fileList.isEmpty()) {
            List<CultivateFile> fList = changeToFileList(bizId, fileList, UserProvider.getLoginUserId(), fileType.TEACHING);
            cultivateFileService.saveBatch(fList);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(String id) {
        teachingRecordMapper.deleteById(id);
        //删除所有学员
        UpdateWrapper<TeachingStudent> deleteWrapper = new UpdateWrapper<>();
        deleteWrapper.lambda()
                .eq(TeachingStudent::getRecordId, id);
        teachingStudentMapper.delete(deleteWrapper);
    }

    @Override
    public PageInfo<TeachingRecordVo> queryMyTeachingRecordList(QueryTeachingRecordDto queryTeachingRecordDto) {
        // 技能点模糊查询
        QueryWrapper<TeachingSkill> skillQueryWrapper = new QueryWrapper<>();
        skillQueryWrapper.lambda()
                .like(StrUtil.isNotBlank(queryTeachingRecordDto.getKeyword()), TeachingSkill::getName, queryTeachingRecordDto.getKeyword());
        List<TeachingSkill> teachingSkills = teachingSkillMapper.selectList(skillQueryWrapper);
        List<String> skillIds = teachingSkills.stream().map(TeachingSkill::getId).collect(Collectors.toList());
        if (CollectionUtil.isEmpty(skillIds)) {
            skillIds.add("-1");
        }
        // 查询学员记录
        QueryWrapper<TeachingStudent> studentQueryWrapper = new QueryWrapper<>();
        studentQueryWrapper.lambda()
                .eq(TeachingStudent::getDeleteMark, 0)
                .eq(TeachingStudent::getUserId, UserProvider.getLoginUserId());
        List<TeachingStudent> teachingStudents = teachingStudentMapper.selectList(studentQueryWrapper);
        if (CollectionUtil.isEmpty(teachingStudents)) {
            return new PageInfo<>();
        }
        List<String> recordIdList = teachingStudents.stream().map(TeachingStudent::getRecordId).collect(Collectors.toList());
        // 查询带教记录
        String keyword = queryTeachingRecordDto.getKeyword();
        QueryWrapper<TeachingRecord> recordQueryWrapper = new QueryWrapper<>();
        recordQueryWrapper.lambda()
                .eq(TeachingRecord::getDeleteMark, 0)
                .in(CollectionUtil.isNotEmpty(queryTeachingRecordDto.getStoreIdList()), TeachingRecord::getStoreId, queryTeachingRecordDto.getStoreIdList())
                .in(TeachingRecord::getId, recordIdList)
                .between(StrUtil.isNotBlank(queryTeachingRecordDto.getStartDate()) && StrUtil.isNotBlank(queryTeachingRecordDto.getEndDate()), TeachingRecord::getDate,
                        queryTeachingRecordDto.getStartDate() + " 00:00:00", queryTeachingRecordDto.getEndDate() + " 23:59:59")
                .and(StrUtil.isNotBlank(keyword), q -> {
                    q.like(TeachingRecord::getUserName, keyword)
                            .or()
                            .in(TeachingRecord::getSkillId, skillIds);
                }).orderByDesc(TeachingRecord::getDate)
                .orderByDesc(TeachingRecord::getCreatorTime);
        PageHelper.startPage((int) queryTeachingRecordDto.getCurrentPage(), (int) queryTeachingRecordDto.getPageSize());
        List<TeachingRecord> teachingRecords = teachingRecordMapper.selectList(recordQueryWrapper);
        if (CollectionUtil.isEmpty(teachingRecords)) {
            return new PageInfo<>();
        }
        PageInfo<TeachingRecord> pageInfo = new PageInfo<>(teachingRecords);
        List<TeachingRecordVo> teachingRecordVos = toRecordVo(teachingRecords);
        // 查询附件信息
        List<String> collect = teachingRecordVos.stream().map(TeachingRecordVo::getId).collect(Collectors.toList());
        Map<String, List<V2Attachment>> fileMap = cultivateFileService.getFileListByBizIds(collect);
        // 查询是否浏览
        Set<String> viewedSet = getViewedSet(collect, UserProvider.getLoginUserId());
        teachingRecordVos.forEach(v -> {
            v.setFileList(fileMap.getOrDefault(v.getId(), List.of()));
            if (viewedSet.contains(v.getId())) {
                v.setViewed(true);
            }
        });
        PageInfo<TeachingRecordVo> voPageInfo = new PageInfo<>();
        BeanUtil.copyProperties(pageInfo, voPageInfo);
        voPageInfo.setList(teachingRecordVos);
        return voPageInfo;
    }

    @Override
    public Set<String> getViewedSet(List<String> bizIds, String userId) {

        if (null == bizIds || bizIds.isEmpty()) {
            return new HashSet<>();
        }
        LambdaQueryWrapper<CultivateUserView> queryWrapper = new LambdaQueryWrapper<CultivateUserView>()
                .eq(CultivateUserView::getUserId, userId)
                .eq(CultivateUserView::getDeleteMark, ConstantUtil.NUM_FALSE)
                .in(CultivateUserView::getBizId, bizIds);
        List<CultivateUserView> list = cultivateUserViewMapper.selectList(queryWrapper);
        if (list.isEmpty()) {
            return new HashSet<>();
        }
        return list.stream().map(CultivateUserView::getBizId).collect(Collectors.toSet());
    }

    @Override
    public PageInfo<TeachingDataListVo> teachingStudentDataCount(QueryTeachingRecordDto queryTeachingRecordDto) {
        List<String> storeIdList = queryTeachingRecordDto.getStoreIdList();
        List<String> teachingUserIds = queryTeachingRecordDto.getTeachingUserIds();
        QueryWrapper<TeachingRecord> recordQueryWrapper = new QueryWrapper<>();
        recordQueryWrapper.lambda()
                .eq(TeachingRecord::getType, 1)
                .eq(TeachingRecord::getDeleteMark, 0)
                .in(CollectionUtil.isNotEmpty(storeIdList), TeachingRecord::getStoreId, storeIdList)
                .in(CollectionUtil.isNotEmpty(teachingUserIds), TeachingRecord::getUserId, teachingUserIds)
                .between(StrUtil.isNotBlank(queryTeachingRecordDto.getStartDate()) && StrUtil.isNotBlank(queryTeachingRecordDto.getEndDate()), TeachingRecord::getDate,
                        queryTeachingRecordDto.getStartDate() + " 00:00:00", queryTeachingRecordDto.getEndDate() + " 23:59:59");

        List<TeachingRecord> teachingRecords = teachingRecordMapper.selectList(recordQueryWrapper);
        if (CollectionUtil.isEmpty(teachingRecords)) {
            return new PageInfo<>();
        }
        List<String> recordIdList = teachingRecords.stream().map(TeachingRecord::getId).collect(Collectors.toList());
        PageHelper.startPage((int) queryTeachingRecordDto.getCurrentPage(), (int) queryTeachingRecordDto.getPageSize());
        queryTeachingRecordDto.setRecordIds(recordIdList);
        List<TeachingDataListVo> teachingDataListVos = teachingStudentMapper.queryTeachingDataList(queryTeachingRecordDto);

        List<SkillKeyVo> skillKeyVos = teachingStudentMapper.querySkillKeyList(queryTeachingRecordDto);
        Map<String, List<SkillKeyVo>> skillKeyMap = skillKeyVos.stream().collect(Collectors.groupingBy(SkillKeyVo::getSkillKey));
        setSkillName(teachingDataListVos, skillKeyMap);
        PageInfo<TeachingDataListVo> voPageInfo = new PageInfo<>(teachingDataListVos);
        if (CollectionUtil.isEmpty(teachingDataListVos)) {
            return new PageInfo<>();
        }

        List<TeachingDataListVo> allData = teachingStudentMapper.queryTeachingDataList(queryTeachingRecordDto);
        dataVoSkillGroupCount(teachingDataListVos, allData, skillKeyVos, 2);
        // Map<String, String> lastPost = getLastStudentPost(recordIdList);
        Set<String> set = new HashSet<>();
        voPageInfo.getList().forEach(v -> {
            set.add(v.getTeachingUserId());
            set.add(v.getUserId());
        });
        StaffRosterListReq staffRosterListReq = new StaffRosterListReq();
        staffRosterListReq.setPageSize(-1);
        staffRosterListReq.setIsQueryAuth("0");
        staffRosterListReq.setUserIds(new ArrayList<>(set));
        ActionResult<PageListVO<FtbPersonnelsStaffRosterDto>> pageListVOActionResult = ftbPersonnelsRosterManagerApi.postWithSalary(staffRosterListReq);
        Map<String, FtbPersonnelsStaffRosterDto> userMap;
        if (null == pageListVOActionResult || !pageListVOActionResult.getCode().equals(200)
                || pageListVOActionResult.getData() == null || CollUtil.isEmpty(pageListVOActionResult.getData().getList())) {
            userMap = new HashMap<>();
        } else {
            userMap = pageListVOActionResult.getData().getList().stream().collect(Collectors.toMap(FtbPersonnelsStaffRosterDto::getUserId, Function.identity()));
        }
        for (TeachingDataListVo vo : voPageInfo.getList()) {
            FtbPersonnelsStaffRosterDto teachUser = userMap.get(vo.getTeachingUserId());
            FtbPersonnelsStaffRosterDto user = userMap.get(vo.getUserId());
            if (null == teachUser) {
                vo.setTeachingUsername("--");
            } else {
                vo.setTeachingUsername(teachUser.getName());
            }
            if (null == user) {
                vo.setUsername("--");
                vo.setStoreId(null);
                vo.setStoreName(null);
                vo.setPostName(null);
            } else {
                vo.setUsername(user.getName());
                vo.setStoreId(user.getCurrOrg());
                vo.setStoreName(user.getCurrOrgName());
                vo.setPostName(StringUtil.isEmpty(user.getCurrPositionName()) ? "--" : user.getCurrPositionName());
            }
        }
        setSkillName(allData, skillKeyMap);
        return voPageInfo;
    }

    private void dataVoSkillGroupCount(List<TeachingDataListVo> teachingDataListVos, List<TeachingDataListVo> allData, List<SkillKeyVo> skillKeyVos, Integer countType) {
        if (CollectionUtil.isEmpty(teachingDataListVos) || CollectionUtil.isEmpty(allData)) {
            return;
        }

        List<String> allSkillNameList = skillKeyVos.stream()
                .map(SkillKeyVo::getSkillName)
                .distinct().collect(Collectors.toList());

        Map<String, List<SkillKeyVo>> skillCountGroupMap = skillKeyVos.stream().collect(Collectors.groupingBy(SkillKeyVo::getSkillKey));

        for (TeachingDataListVo teachingDataListVo : teachingDataListVos) {
            String userId = "";
            if (countType == 1) {
                userId = teachingDataListVo.getTeachingUserId();
            } else {
                userId = teachingDataListVo.getUserId();
            }
            List<SkillKeyVo> skillCountList = skillCountGroupMap.get(userId + teachingDataListVo.getStoreId());
            if (ObjectUtil.isNull(skillCountList)) {
                skillCountList = new ArrayList<>();
            }
            Map<String, List<SkillKeyVo>> skillNameMap = skillCountList.stream().collect(Collectors.groupingBy(SkillKeyVo::getSkillName));
            List<SkillCountVo> skillCountVoList = new ArrayList<>();
            //找到学员带教记录中对应的技能点
            for (String skillName : allSkillNameList) {
                List<SkillKeyVo> skillVoList = skillNameMap.get(skillName);
                SkillCountVo countVo = new SkillCountVo();
                countVo.setName(skillName);
                countVo.setCount(CollectionUtil.size(skillVoList));
                skillCountVoList.add(countVo);
            }
            teachingDataListVo.setSkillList(skillCountVoList);

        }
    }

    @Override
    public List<SkillCountVo> queryMyTeachingData(QueryTeachingRecordDto queryTeachingRecordDto) {
        // 查询学员记录
        QueryWrapper<TeachingStudent> studentQueryWrapper = new QueryWrapper<>();
        studentQueryWrapper.lambda()
                .eq(TeachingStudent::getDeleteMark, 0)
                .eq(TeachingStudent::getUserId, UserProvider.getLoginUserId());
        List<TeachingStudent> teachingStudents = teachingStudentMapper.selectList(studentQueryWrapper);
        if (CollectionUtil.isEmpty(teachingStudents)) {
            return new ArrayList<>();
        }
        List<String> recordIdList = teachingStudents.stream().map(TeachingStudent::getRecordId).collect(Collectors.toList());
        QueryWrapper<TeachingRecord> recordQueryWrapper = new QueryWrapper<>();
        recordQueryWrapper.lambda()
                .eq(TeachingRecord::getDeleteMark, 0)
                .in(TeachingRecord::getId, recordIdList)
                .in(CollectionUtil.isNotEmpty(queryTeachingRecordDto.getStoreIdList()), TeachingRecord::getStoreId, queryTeachingRecordDto.getStoreIdList())
                .in(CollectionUtil.isNotEmpty(queryTeachingRecordDto.getTeachingUserIds()), TeachingRecord::getUserId, queryTeachingRecordDto.getTeachingUserIds())
                .between(StrUtil.isNotBlank(queryTeachingRecordDto.getStartDate()) && StrUtil.isNotBlank(queryTeachingRecordDto.getEndDate()), TeachingRecord::getDate,
                        queryTeachingRecordDto.getStartDate() + " 00:00:00", queryTeachingRecordDto.getEndDate() + " 23:59:59");
        List<TeachingRecord> teachingRecords = teachingRecordMapper.selectList(recordQueryWrapper);
        if (CollectionUtil.isEmpty(teachingRecords)) {
            return new ArrayList<>();
        }
        List<String> recordIds = teachingRecords.stream().map(TeachingRecord::getId).collect(Collectors.toList());
        return teachingRecordMapper.skillCount(recordIds);
    }

    @Override
    public List<TeachingUserVo> teachingSelectList(QueryTeachingRecordDto queryTeachingRecordDto) {
        // 查询权限下的门店
        TargetAuthIdsVO targetAuthIdsVO = authPermissionUtils.processAuthIds();
        if (null != targetAuthIdsVO && targetAuthIdsVO.getTargetAuthEnums().equals(TargetAuthEnums.NONE)) {
            return List.of();
        }
        //取交集
        if (CollectionUtil.isNotEmpty(queryTeachingRecordDto.getStoreIdList())) {
            if (null == targetAuthIdsVO) {
                queryTeachingRecordDto.setStoreIdList(queryTeachingRecordDto.getStoreIdList());
            } else {
                Collection<String> intersection = CollectionUtil.intersection(targetAuthIdsVO.getIds(), queryTeachingRecordDto.getStoreIdList());
                queryTeachingRecordDto.setStoreIdList(new ArrayList<>(intersection));
            }
        } else {
            queryTeachingRecordDto.setStoreIdList(null == targetAuthIdsVO ? List.of() : targetAuthIdsVO.getIds());
        }
        QueryWrapper<TeachingRecord> recordQueryWrapper = new QueryWrapper<>();
        recordQueryWrapper.lambda()
                .eq(TeachingRecord::getDeleteMark, 0)
                .eq(TeachingRecord::getType, 1)
                .in(CollectionUtil.isNotEmpty(queryTeachingRecordDto.getStoreIdList()), TeachingRecord::getStoreId, queryTeachingRecordDto.getStoreIdList())
                .between(StrUtil.isNotBlank(queryTeachingRecordDto.getStartDate()) && StrUtil.isNotBlank(queryTeachingRecordDto.getEndDate()), TeachingRecord::getDate,
                        queryTeachingRecordDto.getStartDate() + " 00:00:00", queryTeachingRecordDto.getEndDate() + " 23:59:59")
                .groupBy(TeachingRecord::getUserId)
                .orderByDesc(TeachingRecord::getCreatorTime);
        List<TeachingRecord> teachingRecords = teachingRecordMapper.selectList(recordQueryWrapper);
        teachingRecords = teachingRecords.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(TeachingRecord::getUserId))), ArrayList::new));
        List<TeachingUserVo> teachingUserVoList = JsonUtil.getJsonToList(teachingRecords, TeachingUserVo.class);
        if (CollectionUtil.isEmpty(teachingUserVoList)) {
            return teachingUserVoList;
        }
        List<String> userIds = teachingUserVoList.stream().map(TeachingUserVo::getUserId).collect(Collectors.toList());
        Map<String, UserBoundVO> userMap = getUserMap(userIds);
        for (TeachingUserVo teachingUserVo : teachingUserVoList) {
            //头像填充
            UserBoundVO user = userMap.get(teachingUserVo.getUserId());
            if (null != user) {
                teachingUserVo.setHeadIcon(UploaderUtil.uploaderImg(user.getHeadIcon()));
                teachingUserVo.setUserName(user.getUserName());
                teachingUserVo.setPostName(user.getPositionName());
            }
        }
        return teachingUserVoList;
    }

    @Override
    public List<TeachingUserVo> teachingSuperiorSelectList(QueryTeachingRecordDto queryTeachingRecordDto) {
        //查询当前登录人的学员记录
        QueryWrapper<TeachingStudent> studentQueryWrapper = new QueryWrapper<>();
        studentQueryWrapper.lambda()
                .eq(TeachingStudent::getDeleteMark, 0)
                .eq(TeachingStudent::getUserId, UserProvider.getLoginUserId());
        List<TeachingStudent> studentList = teachingStudentMapper.selectList(studentQueryWrapper);
        if (CollectionUtil.isEmpty(studentList)) {
            return new ArrayList<>();
        }

        List<String> recordIds = studentList.stream().map(TeachingStudent::getRecordId).collect(Collectors.toList());
        //查询对应带教记录
        QueryWrapper<TeachingRecord> recordQueryWrapper = new QueryWrapper<>();
        recordQueryWrapper.lambda()
                .eq(TeachingRecord::getType, 1)
                .eq(TeachingRecord::getDeleteMark, 0)
                .in(TeachingRecord::getId, recordIds)
                .between(StrUtil.isNotBlank(queryTeachingRecordDto.getStartDate()) && StrUtil.isNotBlank(queryTeachingRecordDto.getEndDate()), TeachingRecord::getDate,
                        queryTeachingRecordDto.getStartDate() + " 00:00:00", queryTeachingRecordDto.getEndDate() + " 23:59:59");
        List<TeachingRecord> teachingRecords = teachingRecordMapper.selectList(recordQueryWrapper);
        //带教员userId去重
        teachingRecords = teachingRecords.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(TeachingRecord::getUserId))), ArrayList::new));

        List<TeachingUserVo> teachingUserVoList = JsonUtil.getJsonToList(teachingRecords, TeachingUserVo.class);
        if (CollectionUtil.isEmpty(teachingUserVoList)) {
            return teachingUserVoList;
        }
        List<String> userIds = teachingUserVoList.stream().map(TeachingUserVo::getUserId).collect(Collectors.toList());
        UserInfoByIdsPost userInfoByIdsPost = new UserInfoByIdsPost();
        userInfoByIdsPost.setUserIds(userIds);
        userInfoByIdsPost.setTenantId(UserProvider.getUser().getTenantId());
//        List<PartUserInfoVo> allUserList = userApi.getInfoByIdsManyAndCopyPost(userInfoByIdsPost);
        List<PartUserInfoVo> allUserList = v2UserQueryUtil.getUserListAndCopy(userIds, UserProvider.getUser().getTenantId());
        Map<String, PartUserInfoVo> userMap = allUserList.stream().collect(Collectors.toMap(PartUserInfoVo::getUserId, Function.identity()));

        Map<String, String> lastPost = getLastPost(queryTeachingRecordDto);
        String storeId = queryTeachingRecordDto.getStoreIdList().get(0);
        for (TeachingUserVo teachingUserVo : teachingUserVoList) {
            //头像填充
            PartUserInfoVo partUserInfoVo = userMap.get(teachingUserVo.getUserId());
            teachingUserVo.setHeadIcon(ObjectUtil.isNull(partUserInfoVo) ? "" : UploaderUtil.uploaderImg(partUserInfoVo.getHeadIcon()));
            String key = storeId + teachingUserVo.getUserId();
            teachingUserVo.setPostName(lastPost.get(key));
        }
        return teachingUserVoList;
    }

    /**
     * 获取带教记录详情（修改时回显）
     * @param id 带教记录id
     * @return TeachingRecordDetailVo
     */
    @Override
    public TeachingRecordDetailVo getTeachingDetail(String id) {
        TeachingRecord teachingRecord = teachingRecordMapper.selectById(id);
        TeachingRecordDetailVo detailVo = JsonUtil.getJsonToBean(teachingRecord, TeachingRecordDetailVo.class);
        TeachingSkill teachingSkill = teachingSkillMapper.selectById(detailVo.getSkillId());
        detailVo.setSkillName(teachingSkill.getName());
        detailVo.setSkillDesc(teachingSkill.getDescription());

        //视频封面
        String videoCover = teachingRecord.getVideoPath() + ".0.jpg";
        detailVo.setVideoCover(videoCover);

        //查询所属学员
        QueryWrapper<TeachingStudent> studentQueryWrapper = new QueryWrapper<>();
        studentQueryWrapper.lambda()
                .eq(TeachingStudent::getDeleteMark, 0)
                .eq(TeachingStudent::getRecordId, id);
        List<TeachingStudent> studentList = teachingStudentMapper.selectList(studentQueryWrapper);
        if (CollectionUtil.isEmpty(studentList)) {
            return detailVo;
        }
        List<String> studentIdList = studentList.stream().map(TeachingStudent::getUserId).collect(Collectors.toList());
        detailVo.setStudentIdList(studentIdList);

        List<String> studentNames = studentList.stream().map(TeachingStudent::getUsername).collect(Collectors.toList());
        String studentName = CollectionUtil.join(studentNames, "、");
        detailVo.setStudents(studentName);
        return detailVo;
    }

    @Override
    public List<TeachingStoreListVo> getTeachingStoreList() {
        UserInfo loginUser = UserProvider.getUser();
        List<String> permissionStoreIds = loginUser.getIsAdministrator() ? null : permissionHandling.getStoreIdsByUserId(UserProvider.getLoginUserId());
        QueryWrapper<TeachingRecord> recordQueryWrapper = new QueryWrapper<>();
        recordQueryWrapper.lambda()
                .eq(TeachingRecord::getDeleteMark, 0)
                .eq(TeachingRecord::getType, 1)
                .in(CollectionUtil.isNotEmpty(permissionStoreIds), TeachingRecord::getStoreId, permissionStoreIds)
                .groupBy(TeachingRecord::getStoreId);
        List<TeachingRecord> teachingRecords = teachingRecordMapper.selectList(recordQueryWrapper);
        return JsonUtil.getJsonToList(teachingRecords, TeachingStoreListVo.class);
    }

    @Override
    public PageInfo<TeachingDataListVo> teachingSummaryPage(QueryTeachingRecordDto queryTeachingRecordDto) {
        // 获取数据权限用户id
        TargetAuthIdsVO targetAuthIdsVO = authPermissionUtils.processAuthIds();
        if (null != targetAuthIdsVO && targetAuthIdsVO.getTargetAuthEnums().equals(TargetAuthEnums.NONE)) {
            return new PageInfo<>();
        }
        //取交集
        if (CollectionUtil.isNotEmpty(queryTeachingRecordDto.getStoreIdList())) {
            if (null == targetAuthIdsVO) {
                queryTeachingRecordDto.setStoreIdList(queryTeachingRecordDto.getStoreIdList());
            } else {
                Collection<String> intersection = CollectionUtil.intersection(targetAuthIdsVO.getIds(), queryTeachingRecordDto.getStoreIdList());
                queryTeachingRecordDto.setStoreIdList(new ArrayList<>(intersection));
            }
        } else {
            queryTeachingRecordDto.setStoreIdList(null == targetAuthIdsVO ? List.of() : targetAuthIdsVO.getIds());
        }
        // Map<String, String> lastPostMap = getLastPost(queryTeachingRecordDto);
        //先查询技能点
        List<SkillKeyVo> skillNameList = teachingRecordMapper.queryCountSkillList(queryTeachingRecordDto);
        PageHelper.startPage((int) queryTeachingRecordDto.getCurrentPage(), (int) queryTeachingRecordDto.getPageSize());
        List<TeachingDataListVo> teachingDataListVos = teachingRecordMapper.teachingSummaryQuery(queryTeachingRecordDto);
        PageInfo<TeachingDataListVo> pageInfo = new PageInfo<>(teachingDataListVos);
        //查询所有技能点
        List<TeachingDataListVo> allData = teachingRecordMapper.teachingSummaryQuery(queryTeachingRecordDto);
        dataVoSkillGroupCount(teachingDataListVos, allData, skillNameList, 1);
        List<String> userIds = pageInfo.getList().stream().map(TeachingDataListVo::getTeachingUserId).collect(Collectors.toList());
        Map<String, UserBoundVO> userMap = getUserMap(userIds);
        //时间范围内最新岗位
        for (TeachingDataListVo teachingDataListVo : pageInfo.getList()) {
            // String postName = lastPostMap.get(teachingDataListVo.getStoreId() + teachingDataListVo.getTeachingUserId());
            // teachingDataListVo.setPostName(postName);
            UserBoundVO user = userMap.get(teachingDataListVo.getTeachingUserId());
            if (null != user) {
                teachingDataListVo.setTeachingUsername(user.getUserName());
                teachingDataListVo.setPostName(StringUtil.isEmpty(user.getPositionName()) ? "--" : user.getPositionName());
                teachingDataListVo.setUsername(user.getUserName());
            }
        }
        return pageInfo;
    }

    private Map<String, UserBoundVO> getUserMap(List<String> userIds) {

        List<UserBoundVO> list;
        if (userIds.isEmpty()) {
            list = new ArrayList<>();
        } else {
            list = v2UserApi.userListAndCopy(userIds, null, UserProvider.getUser().getTenantId());
        }
        return list.stream().collect(Collectors.toMap(UserBoundVO::getId, Function.identity()));
    }

    @Override
    public void summaryTeachExport(QueryTeachingRecordDto queryTeachingRecordDto) {
        queryTeachingRecordDto.setCurrentPage(1);
        queryTeachingRecordDto.setPageSize(10000);
        PageInfo<TeachingDataListVo> pageInfo = teachingSummaryPage(queryTeachingRecordDto);
        List<TeachingDataListVo> list = pageInfo.getList();
        String filename = "汇总-带教" + DateUtil.format(new Date(), "yyyyMMddHHmmss") + ".xlsx";
        EasyExcelUtil.dynamicTableExport(getHeadList(list, List.of("门店名称", "带教员", "带教员岗位", "带教总次数")), getExportDataList(list), filename, "汇总带教");
    }

    @Override
    public void studentDetailExport(QueryTeachingRecordDto queryTeachingRecordDto) {
        queryTeachingRecordDto.setCurrentPage(1);
        queryTeachingRecordDto.setPageSize(10000);
        PageInfo<TeachingDataListVo> voPageInfo = teachingStudentDataCount(queryTeachingRecordDto);
        List<List<String>> headList = getHeadList(voPageInfo.getList(), List.of("带教员", "学员", "学员岗位", "带教总次数"));
        List<List<String>> exportDataList = getSummaryDetailExportDataList(voPageInfo.getList());
        String filename = "汇总-带教" + DateUtil.format(new Date(), "yyyyMMddHHmmss") + ".xlsx";
        EasyExcelUtil.dynamicTableExport(headList, exportDataList, filename, "汇总学员详情");
    }

    @Override
    public PageInfo<TeachingRecordVo> teachingItemPage(QueryTeachingRecordDto queryTeachingRecordDto) {
        return page(queryTeachingRecordDto);
    }

    @Override
    public void detailItemTeachExport(QueryTeachingRecordDto queryTeachingRecordDto) {
        queryTeachingRecordDto.setCurrentPage(1);
        queryTeachingRecordDto.setPageSize(10000);
        queryTeachingRecordDto.setIsDataPermission(true);
        PageInfo<TeachingRecordVo> page = page(queryTeachingRecordDto);
        List<TeachingRecordVo> list = page.getList();
        List<List<String>> headList = getHeadList(null, List.of(
                "门店名称",
                "带教员",
                "带教员岗位",
                "学员",
                "技能点",
                "日期"
        ));
        List<List<String>> teachingDetailItemExportData = getTeachingDetailItemExportData(list);
        String filename = "汇总-明细" + DateUtil.format(new Date(), "yyyyMMddHHmmss") + ".xlsx";
        EasyExcelUtil.dynamicTableExport(headList, teachingDetailItemExportData, filename, "带教明细");
    }

    /**
     * 带教明细-批量删除
     * @param ids 记录id集合
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void batchDeleteRecord(List<String> ids) {
        UpdateWrapper<TeachingRecord> recordDeleteWrapper = new UpdateWrapper<>();
        recordDeleteWrapper.lambda()
                .in(TeachingRecord::getId, ids);
        teachingRecordMapper.delete(recordDeleteWrapper);

        //删除对应学员
        UpdateWrapper<TeachingStudent> stuDeleteWrapper = new UpdateWrapper<>();
        stuDeleteWrapper.lambda()
                .in(TeachingStudent::getRecordId, ids);
        teachingStudentMapper.delete(stuDeleteWrapper);
    }

    /**
     * 店长界面带教统计
     * @param storeId 门店id
     * @return TeachingStoreCountVo
     */
    @Override
    public TeachingStoreCountVo storeTeachingCount(String storeId) {
        String loginUserId = UserProvider.getLoginUserId();
        //查询我的带教记录
        QueryWrapper<TeachingRecord> recordQueryWrapper = new QueryWrapper<>();
        recordQueryWrapper.lambda()
                .eq(TeachingRecord::getStoreId, storeId)
                .eq(TeachingRecord::getDeleteMark, 0)
                .eq(TeachingRecord::getType, 1)
                .eq(TeachingRecord::getUserId, loginUserId)
                .apply("DATE_FORMAT(F_Date,'%Y-%m') = DATE_FORMAT(NOW(),'%Y-%m')");
        List<TeachingRecord> teachingRecords = teachingRecordMapper.selectList(recordQueryWrapper);
        TeachingStoreCountVo teachingStoreCountVo = new TeachingStoreCountVo();
        if (CollectionUtil.isEmpty(teachingRecords)) {
            teachingStoreCountVo.setTeachingCount(0L);
            teachingStoreCountVo.setStudentCount(0L);
            return teachingStoreCountVo;
        }
        teachingStoreCountVo.setTeachingCount((long) teachingRecords.size());
        //查询学员
        List<String> recordIds = teachingRecords.stream().map(TeachingRecord::getId).collect(Collectors.toList());
        QueryWrapper<TeachingStudent> studentQueryWrapper = new QueryWrapper<>();
        studentQueryWrapper.lambda()
                .eq(TeachingStudent::getDeleteMark, 0)
                .in(TeachingStudent::getRecordId, recordIds);
        List<TeachingStudent> teachingStudents = teachingStudentMapper.selectList(studentQueryWrapper);
        teachingStudents = teachingStudents.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(TeachingStudent::getUserId))), ArrayList::new));
        teachingStoreCountVo.setStudentCount(CollectionUtil.isEmpty(teachingStudents) ? 0 : (long) teachingStudents.size());
        return teachingStoreCountVo;
    }

    @Override
    public TeachingCountVo teachingCount(QueryTeachingRecordDto queryTeachingRecordDto) {
        TeachingCountVo teachingCountVo = new TeachingCountVo();
        QueryWrapper<TeachingRecord> recordQueryWrapper = new QueryWrapper<>();
        recordQueryWrapper.lambda()
                .eq(TeachingRecord::getDeleteMark, 0)
                .eq(TeachingRecord::getType, 1)
                .in(CollectionUtil.isNotEmpty(queryTeachingRecordDto.getTeachingUserIds()), TeachingRecord::getUserId, queryTeachingRecordDto.getTeachingUserIds())
                .eq(StrUtil.isNotBlank(queryTeachingRecordDto.getStoreId()), TeachingRecord::getStoreId, queryTeachingRecordDto.getStoreId())
                // 兼容web端门店条件查询
                .in(CollectionUtil.isNotEmpty(queryTeachingRecordDto.getStoreIdList()), TeachingRecord::getStoreId, queryTeachingRecordDto.getStoreIdList())
                .between(StrUtil.isNotBlank(queryTeachingRecordDto.getStartDate()) && StrUtil.isNotBlank(queryTeachingRecordDto.getEndDate()), TeachingRecord::getDate,
                        queryTeachingRecordDto.getStartDate() + " 00:00:00", queryTeachingRecordDto.getEndDate() + " 23:59:59");
        List<TeachingRecord> teachingRecords = teachingRecordMapper.selectList(recordQueryWrapper);
        if (CollectionUtil.isEmpty(teachingRecords)) {
            teachingCountVo.setTeachingCount(0L);
            teachingCountVo.setTeachingPersonCount(0L);
            return teachingCountVo;
        }
        //带教总次数
        long count = teachingRecords.size();
        teachingCountVo.setTeachingCount(count);
        //带教总人数
        List<String> recordIds = teachingRecords.stream().map(TeachingRecord::getId).collect(Collectors.toList());

        QueryWrapper<TeachingStudent> studentQueryWrapper = new QueryWrapper<>();
        studentQueryWrapper.lambda()
                .eq(TeachingStudent::getDeleteMark, 0)
                .in(TeachingStudent::getRecordId, recordIds)
                .groupBy(TeachingStudent::getUserId);
        List<TeachingStudent> teachingStudents = teachingStudentMapper.selectList(studentQueryWrapper);
        teachingCountVo.setTeachingPersonCount(CollectionUtil.isEmpty(teachingStudents) ? 0 : (long) teachingStudents.size());

        return teachingCountVo;
    }

    @Override
    public SuperiorTeachingSummaryVo getSuperiorTeachingSummary(String storeId) {
        return this.baseMapper.getSuperiorTeachingSummary(storeId, UserProvider.getLoginUserId());
    }

    @Override
    public List<StoreTeachingVo> getStoreRecordCount(RecordQueryDto queryDto) {

        // 如果关键字差查询不为空, 先过滤出满足条件的recordId
        List<String> recordIds = null;
        if (StringUtil.isNotEmpty(queryDto.getKeyword())) {
            recordIds = teachingStudentMapper.getRecordIdByKeyword(queryDto.getKeyword());
            if (recordIds == null) {
                return List.of();
            }
        }
        return this.baseMapper.getStoreRecordCount(queryDto, recordIds);
    }

    @Override
    public PageInfo<V2TeachingRecordVo> getStoreRecordPage(RecordQueryDto queryDto) {

        List<String> recordIds = null;
        if (StringUtil.isNotEmpty(queryDto.getKeyword())) {
            recordIds = teachingStudentMapper.getRecordIdByKeyword(queryDto.getKeyword());
            if (recordIds == null) {
                return new PageInfo<>();
            }
        }
        PageHelper.startPage((int) queryDto.getCurrentPage(), (int) queryDto.getPageSize());
        PageInfo<V2TeachingRecordVo> page = new PageInfo<>(baseMapper.getStoreRecordList(queryDto, recordIds, UserProvider.getLoginUserId()));
        if (page.getList().isEmpty()) {
            return new PageInfo<>();
        }
        // 查询学员信息
        List<String> recordIdList = page.getList().stream().map(V2TeachingRecordVo::getId).collect(Collectors.toList());
        Map<String, List<TeachingStudent>> stuMap = getStuMap(recordIdList);
        // 查询附件信息
        Map<String, List<CultivateFile>> fileMap = getFileMap(recordIdList);
        page.getList().forEach(v -> setStudentAndFile(v, stuMap, fileMap));
        return page;
    }

    private void setStudentAndFile(V2TeachingRecordVo v, Map<String, List<TeachingStudent>> stuMap, Map<String, List<CultivateFile>> fileMap) {

        List<TeachingStudent> students = stuMap.get(v.getId());
        if (null != students && !students.isEmpty()) {
            List<StudentInfoVo> studentList = JsonUtil.getJsonToList(students, StudentInfoVo.class);
            v.setStudentList(studentList);
        }
        List<CultivateFile> files = fileMap.get(v.getId());
        if (null != files && !files.isEmpty()) {
            List<V2Attachment> attachments = new ArrayList<>();
            files.forEach(file -> {
                V2Attachment v2Attachment = cultivateFileService.convertToV2Attachment(file);
                attachments.add(v2Attachment);
            });
            v.setAttachments(attachments);
        }
    }

    @Override
    public Map<String, List<CultivateFile>> getFileMap(List<String> recordIds) {

        LambdaQueryWrapper<CultivateFile> fileQuery = new LambdaQueryWrapper<CultivateFile>()
                .in(CultivateFile::getBusinessId, recordIds)
                .orderByDesc(CultivateFile::getCreatorTime)
                .orderByDesc(CultivateFile::getId);
        List<CultivateFile> fileList = cultivateFileService.list(fileQuery);
        return fileList.stream().collect(Collectors.groupingBy(CultivateFile::getBusinessId));
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void removeAllOldFile() {
        // 查询所有旧文件
        List<TeachingRecord> list = this.list(new LambdaQueryWrapper<TeachingRecord>()
                .eq(TeachingRecord::getDeleteMark, ConstantUtil.NUM_FALSE)
                .isNotNull(TeachingRecord::getVideoPath));
        if (list.isEmpty()) {
            return;
        }
        List<CultivateFile> fileList = new ArrayList<>();
        list.forEach(v -> {
            CultivateFile f = new CultivateFile();
            String fileName = v.getVideoPath().substring(v.getVideoPath().lastIndexOf("/") + 1);
            String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
            f.setId(FtbUtil.getId());
            f.setBusinessId(v.getId());
            f.setFileName(fileName);
            f.setUrl(v.getVideoPath());
            f.setExtension(suffix);
            f.setType(v.getType().equals(1) ? FileEventDTO.FileType.TEACHING.getType() : FileEventDTO.FileType.PRACTICE.getType());
            f.setVideoActionType(v.getVideoActionType());
            fileList.add(f);
        });
        if (!fileList.isEmpty()) {
            cultivateFileService.saveBatch(fileList);
        }
    }

    private Map<String, List<TeachingStudent>> getStuMap(List<String> recordIds) {

        LambdaQueryWrapper<TeachingStudent> stuQuery = new LambdaQueryWrapper<TeachingStudent>()
                .eq(TeachingStudent::getDeleteMark, ConstantUtil.NUM_FALSE)
                .in(TeachingStudent::getRecordId, recordIds)
                .orderByDesc(TeachingStudent::getCreatorTime)
                .orderByDesc(TeachingStudent::getId);
        List<TeachingStudent> stuList = teachingStudentMapper.selectList(stuQuery);
        return stuList.stream().collect(Collectors.groupingBy(TeachingStudent::getRecordId));
    }

    @Override
    public TeachingDetailVo getTeachingDetailById(String bizId) {

        TeachingDetailVo vo = baseMapper.getTeachingDetailById(bizId);
        // 设置头像
        List<UserBoundVO> list = v2UserApi.userListAndCopy(List.of(vo.getUserId()), null, UserProvider.getUser().getTenantId());
        if (null != list && !list.isEmpty()) {
            vo.setHeadIcon(list.get(0).getHeadIcon());
        }
        // 设置学员
        Map<String, List<TeachingStudent>> stuMap = getStuMap(List.of(bizId));
        List<TeachingStudent> students = stuMap.get(bizId);
        if (null != students && !students.isEmpty()) {
            List<StudentInfoVo> studentList = JsonUtil.getJsonToList(students, StudentInfoVo.class);
            vo.setStudentList(studentList);
        }
        // 设置附件
        Map<String, List<CultivateFile>> fileMap = getFileMap(List.of(bizId));
        List<CultivateFile> files = fileMap.get(bizId);
        if (null != files && !files.isEmpty()) {
            List<V2Attachment> attachments = new ArrayList<>();
            files.forEach(file -> {
                V2Attachment v2Attachment = cultivateFileService.convertToV2Attachment(file);
                attachments.add(v2Attachment);
            });
            vo.setFileList(attachments);
        }
        // 设置审批
        LambdaQueryWrapper<TeachingApprove> approveQuery = new LambdaQueryWrapper<TeachingApprove>()
                .eq(TeachingApprove::getTeachId, bizId);
        TeachingApprove teachingApprove = teachingApproveMapper.selectOne(approveQuery);
        TeachingApproveVo approveVo = JsonUtil.getJsonToBean(teachingApprove, TeachingApproveVo.class);
        List<CultivateFile> fileListApprove;
        if (null == approveVo) {
            fileListApprove = new ArrayList<>();
        } else {
            Map<String, List<CultivateFile>> approveFileMap = getFileMap(List.of(approveVo.getId()));
            fileListApprove = approveFileMap.getOrDefault(approveVo.getId(), List.of());
        }
        // 查询审批附件
        if (!fileListApprove.isEmpty()) {
            List<V2Attachment> attachments = new ArrayList<>();
            fileListApprove.forEach(file -> {
                V2Attachment v2Attachment = cultivateFileService.convertToV2Attachment(file);
                attachments.add(v2Attachment);
            });
            approveVo.setFileList(attachments);
        }
        vo.setTeachingApprove(approveVo);
        return vo;
    }

    private Map<String, String> getLastPost(QueryTeachingRecordDto queryTeachingRecordDto) {
        QueryWrapper<TeachingRecord> postRecordQuery = new QueryWrapper<>();
        postRecordQuery.lambda()
                .eq(TeachingRecord::getDeleteMark, 0)
                .eq(TeachingRecord::getType, 1)
                .between(StrUtil.isNotBlank(queryTeachingRecordDto.getStartDate()) && StrUtil.isNotBlank(queryTeachingRecordDto.getEndDate()), TeachingRecord::getDate,
                        queryTeachingRecordDto.getStartDate() + " 00:00:00", queryTeachingRecordDto.getEndDate() + " 23:59:59");
        List<TeachingRecord> teachingRecords = teachingRecordMapper.selectList(postRecordQuery);
        if (CollectionUtil.isEmpty(teachingRecords)) {
            return new HashMap<>();
        }
        Map<String, String> map = new HashMap<>();
        Map<String, List<TeachingRecord>> groupMap = teachingRecords.stream().collect(Collectors.groupingBy(
                teachingRecord -> teachingRecord.getStoreId() + teachingRecord.getUserId()));
        groupMap.forEach((key, recordList) -> {
            recordList.stream().max(Comparator.comparing(TeachingRecord::getCreatorTime))
                    .ifPresent(teachingRecord -> map.put(key, teachingRecord.getPostName()));
        });
        return map;
    }

    private Map<String, String> getLastStudentPost(List<String> recordIds) {
        QueryWrapper<TeachingStudent> postRecordQuery = new QueryWrapper<>();
        postRecordQuery.lambda()
                .eq(TeachingStudent::getDeleteMark, 0)
                .in(TeachingStudent::getRecordId, recordIds);
        List<TeachingStudent> teachingRecords = teachingStudentMapper.selectList(postRecordQuery);
        if (CollectionUtil.isEmpty(teachingRecords)) {
            return new HashMap<>();
        }
        Map<String, String> map = new HashMap<>();
        Map<String, List<TeachingStudent>> groupMap = teachingRecords.stream().collect(Collectors.groupingBy(new Function<TeachingStudent, String>() {
            @Override
            public String apply(TeachingStudent teachingRecord) {
                return teachingRecord.getUserId();
            }
        }));
        groupMap.forEach((key, recordList) -> {
            TeachingStudent teachingStudent = recordList.stream().max(Comparator.comparing(TeachingStudent::getCreatorTime)).orElse(null);
            if (teachingStudent == null) {
                return;
            }
            map.put(key, teachingStudent.getPostName());
        });
        return map;
    }

    /**
     * 获取带教明细导出数据
     * @return List<List < String>> 导出excel所使用的数据
     */
    private List<List<String>> getTeachingDetailItemExportData(List<TeachingRecordVo> list) {
        List<List<String>> dataList = new ArrayList<>();
        if (CollectionUtil.isEmpty(list)) {
            return dataList;
        }
        for (TeachingRecordVo teachingRecordVo : list) {
            List<String> voDataList = new ArrayList<>();
            voDataList.add(teachingRecordVo.getStoreName());
            voDataList.add(teachingRecordVo.getUserName());
            voDataList.add(teachingRecordVo.getPostName());
            voDataList.add(teachingRecordVo.getStudents());
            voDataList.add(teachingRecordVo.getSkillName());
            voDataList.add(DateUtil.formatDate(teachingRecordVo.getDate()));
            dataList.add(voDataList);
        }
        return dataList;
    }

    public List<List<String>> getHeadList(List<TeachingDataListVo> list, List<String> preFixHeadList) {
        List<List<String>> headList = new ArrayList<>();
        for (String head : preFixHeadList) {
            headList.add(List.of(head));
        }
        if (CollectionUtil.isEmpty(list)) {
            return headList;
        }
        List<List<SkillCountVo>> skillList = list.stream().map(TeachingDataListVo::getSkillList).collect(Collectors.toList());
        if (CollectionUtil.isEmpty(skillList)) {
            return headList;
        }
        List<SkillCountVo> skillCountVoList = skillList.stream()
                .max(Comparator.comparingInt(List::size))
                .orElse(Collections.emptyList());
        for (SkillCountVo skillCountVo : skillCountVoList) {
            List<String> head = new ArrayList<>();
            head.add(skillCountVo.getName());
            headList.add(head);
        }
        return headList;
    }

    public List<List<String>> getExportDataList(List<TeachingDataListVo> list) {
        List<List<String>> dataList = new ArrayList<>();
        if (CollectionUtil.isEmpty(list)) {
            return dataList;
        }
        List<List<SkillCountVo>> skillList = list.stream()
                .filter(Objects::nonNull)
                .map(TeachingDataListVo::getSkillList)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
        List<SkillCountVo> skillCountVoList = skillList.stream()
                .max(Comparator.comparingInt(List::size))
                .orElse(Collections.emptyList());
        for (TeachingDataListVo teachingDataListVo : list) {
            List<String> voDataList = new ArrayList<>();
            voDataList.add(teachingDataListVo.getStoreName());
            voDataList.add(teachingDataListVo.getUsername());
            voDataList.add(teachingDataListVo.getPostName());
            voDataList.add(String.valueOf(teachingDataListVo.getTeachingCount()));
            List<SkillCountVo> voSkillList = teachingDataListVo.getSkillList();
            Map<String, SkillCountVo> skillCountVoMap = voSkillList.stream().collect(Collectors.toMap(SkillCountVo::getName, Function.identity()));
            for (SkillCountVo skillCountVo : skillCountVoList) {
                SkillCountVo countVo = skillCountVoMap.get(skillCountVo.getName());
                if (ObjectUtil.isNull(countVo)) {
                    voDataList.add("0");
                } else {
                    voDataList.add(String.valueOf(countVo.getCount()));
                }
            }
            dataList.add(voDataList);
        }
        return dataList;
    }

    public List<List<String>> getSummaryDetailExportDataList(List<TeachingDataListVo> list) {
        List<List<String>> dataList = new ArrayList<>();
        if (CollectionUtil.isEmpty(list)) {
            return dataList;
        }
        List<List<SkillCountVo>> skillList = list.stream()
                .filter(Objects::nonNull)
                .map(TeachingDataListVo::getSkillList)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
        List<SkillCountVo> skillCountVoList = skillList.stream()
                .max(Comparator.comparingInt(List::size))
                .orElse(Collections.emptyList());
        for (TeachingDataListVo teachingDataListVo : list) {
            List<String> voDataList = new ArrayList<>();
            voDataList.add(teachingDataListVo.getTeachingUsername());
            voDataList.add(teachingDataListVo.getUsername());
            voDataList.add(teachingDataListVo.getPostName());
            voDataList.add(String.valueOf(teachingDataListVo.getTeachingCount()));
            List<SkillCountVo> voSkillList = teachingDataListVo.getSkillList();
            Map<String, SkillCountVo> skillCountVoMap = voSkillList.stream().collect(Collectors.toMap(SkillCountVo::getName, Function.identity()));
            for (SkillCountVo skillCountVo : skillCountVoList) {
                SkillCountVo countVo = skillCountVoMap.get(skillCountVo.getName());
                if (ObjectUtil.isNull(countVo)) {
                    voDataList.add("0");
                } else {
                    voDataList.add(String.valueOf(countVo.getCount()));
                }
            }
            dataList.add(voDataList);
        }
        return dataList;
    }

    /**
     * 批量新增学员
     * @param studentUserIds 学员id集合
     * @param recordId 记录id
     */
    private void batchAddStuList(List<String> studentUserIds, String recordId) {
        if (CollectionUtil.isEmpty(studentUserIds)) {
            return;
        }
        QueryUserDTO queryUserDTO = new QueryUserDTO();
        queryUserDTO.setUserIds(studentUserIds);
        List<PartUserInfoVo> infoByIdsPost = v2UserQueryUtil.getUserListToPartUserInfoVo(studentUserIds);
        Map<String, PartUserInfoVo> userInfoVoMap = infoByIdsPost.stream().collect(Collectors.toMap(PartUserInfoVo::getUserId, Function.identity()));
        //查询用户岗位
        List<String> postIdList = infoByIdsPost.stream().map(PartUserInfoVo::getPositionId).collect(Collectors.toList());
        ActionResult<List<PositionInfoNewVO>> positionListByIds = positionApi.getPositionListByIds(postIdList);
        List<PositionInfoNewVO> postList = positionListByIds.getData();
        Map<String, PositionInfoNewVO> postMap = postList.stream().collect(Collectors.toMap(PositionInfoNewVO::getId, Function.identity()));
        List<TeachingStudent> addStudentList = new ArrayList<>();
        for (String studentUserId : studentUserIds) {
            TeachingStudent teachingStudent = new TeachingStudent();
            teachingStudent.setId(RandomUtil.uuId());
            teachingStudent.setRecordId(recordId);
            teachingStudent.setCreatorTime(new Date());
            teachingStudent.setDeleteMark(0);
            teachingStudent.setCreatorUserId(UserProvider.getLoginUserId());
            teachingStudent.setUserId(studentUserId);
            PartUserInfoVo partUserInfoVo = userInfoVoMap.get(studentUserId);
            teachingStudent.setUsername(partUserInfoVo.getRealName());
            PositionInfoNewVO positionInfoNewVO = postMap.get(partUserInfoVo.getPositionId());
            teachingStudent.setPostId(partUserInfoVo.getPositionId());
            teachingStudent.setPostName(positionInfoNewVO.getFullName());
            addStudentList.add(teachingStudent);
        }
        teachingStudentService.saveBatch(addStudentList);
    }

    private List<TeachingRecordVo> toRecordVo(List<TeachingRecord> teachingRecords) {
        List<String> ids = teachingRecords.stream().map(TeachingRecord::getId).collect(Collectors.toList());
        //查询记录学员
        QueryWrapper<TeachingStudent> studentQueryWrapper = new QueryWrapper<>();
        studentQueryWrapper.lambda()
                .in(TeachingStudent::getRecordId, ids);
        List<TeachingStudent> teachingStudents = teachingStudentMapper.selectList(studentQueryWrapper);
        Map<String, List<TeachingStudent>> studentMap = teachingStudents.stream().collect(Collectors.groupingBy(TeachingStudent::getRecordId));
        List<TeachingRecordVo> voList = JsonUtil.getJsonToList(teachingRecords, TeachingRecordVo.class);
        // 技能点
        List<String> skillIds = teachingRecords.stream().map(TeachingRecord::getSkillId).collect(Collectors.toList());
        QueryWrapper<TeachingSkill> skillQueryWrapper = new QueryWrapper<>();
        skillQueryWrapper.lambda()
                .in(TeachingSkill::getId, skillIds);
        List<TeachingSkill> teachingSkills = teachingSkillMapper.selectList(skillQueryWrapper);
        Map<String, TeachingSkill> skillMap = teachingSkills.stream().collect(Collectors.toMap(TeachingSkill::getId, Function.identity()));
        for (TeachingRecordVo teachingRecordVo : voList) {
            List<TeachingStudent> recordStuList = studentMap.get(teachingRecordVo.getId());
            List<String> stuNameList = recordStuList.stream().map(TeachingStudent::getUsername).collect(Collectors.toList());
            String stus = CollectionUtil.join(stuNameList, "、");
            teachingRecordVo.setStudents(stus);
            //拼接封面
            String cover = teachingRecordVo.getVideoPath() + ".0.jpg";
            teachingRecordVo.setVideoCover(cover);
            //技能点名称
            TeachingSkill teachingSkill = skillMap.get(teachingRecordVo.getSkillId());
            teachingRecordVo.setSkillName(ObjectUtil.isNull(teachingSkill) ? null : teachingSkill.getName());
        }
        return voList;
    }

    /**
     * 获取当前用户权限过滤后的门店id集合
     * @return 门店id
     */
    private List<String> getAuthStoreIdList() {
        AuthUserNodeDTO authUserNodeDTO = new AuthUserNodeDTO();
        authUserNodeDTO.setHavaAuth(true);
        authUserNodeDTO.setTenantId(UserProvider.getUser().getTenantId());
        authUserNodeDTO.setOrganizeCategoryEnums(List.of(OrganizeCategoryEnums.STORE));
        ActionResult<List<OrganizeGeneralDetailVO>> listActionResult = ftbAuthorityApi.authOrganizesByUserBound(List.of(OrganizeCategoryEnums.STORE));
        List<OrganizeGeneralDetailVO> organizeGeneralDetailVOList = listActionResult.getData();
        return organizeGeneralDetailVOList.stream().map(OrganizeGeneralDetailVO::getId).collect(Collectors.toList());
    }

    private Boolean isOnlyUnderling() {
        String hashValue = getValidatedHashValue(UserProvider.getLoginUserId(), ServletUtil.getHeader("Module"));
        return "3".equals(hashValue.split("#")[0]);
    }

    private String getValidatedHashValue(String userId, String module) {
        String hashValue = redisUtil.getHashValues(getUserPermissionKey(userId), module);
        if (StrUtil.isBlank(hashValue)) {
            throw new RuntimeException("当前用户暂未设置此模块数据权限适用范围");
        }
        return hashValue;
    }

    private void setSkillName(List<TeachingDataListVo> allData, Map<String, List<SkillKeyVo>> skillKeyMap) {

        for (TeachingDataListVo allDatum : allData) {
            String key = "";
            //查学员
            key = allDatum.getUserId() + allDatum.getStoreId();
            List<SkillKeyVo> skillKeyVos = skillKeyMap.get(key);
            if (CollectionUtil.isNotEmpty(skillKeyVos)) {
                List<String> nameList = skillKeyVos.stream().map(SkillKeyVo::getSkillName).collect(Collectors.toList());
                allDatum.setSkillNameList(CollectionUtil.join(nameList, ","));
            }
        }
    }
}