package com.ssj.service.kmt.exercisesys;

import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.ssj.bean.common.files.domain.FileInfo;
import com.ssj.bean.kmt.kmt.domain.*;
import com.ssj.bean.sys.cardinfo.domain.TbCardInfo;
import com.ssj.bean.sys.fx.domain.Merchant;
import com.ssj.bean.sys.wallet.domain.Bank;
import com.ssj.bean.weixin.WeixinOauth2Token;
import com.ssj.bean.weixin.libmy.domain.TbLibJoin;
import com.ssj.bean.weixin.libmy.domain.TbLibManager;
import com.ssj.bean.weixin.libmy.domain.TbLibManagerAudit;
import com.ssj.bean.weixin.user.domain.User;
import com.ssj.dao.kmt.correctsys.OneDayAndOneMonthDao;
import com.ssj.dao.weixin.library.dao.IBookManagerDao;
import com.ssj.es.service.ExerciseQuestionSearchService;
import com.ssj.es.service.base.BaseSearchService;
import com.ssj.es.utils.ElasticUtil;
import com.ssj.framework.basic.config.bean.Config;
import com.ssj.framework.basic.config.service.ConfigService;
import com.ssj.framework.basic.utils.DateHelper;
import com.ssj.framework.core.persistence.PagingHibernateJdbcDao;
import com.ssj.framework.core.security.manager.TokenManager;
import com.ssj.framework.core.util.*;
import com.ssj.framework.files.service.FileInfoService;
import com.ssj.framework.idworker.IdWorker;
import com.ssj.framework.weixin.util.DateUtil;
import com.ssj.service.conch.parents.service.ParentService;
import com.ssj.service.conch.utils.MapUtils;
import com.ssj.service.kmt.constant.KnowledgeVersion;
import com.ssj.service.kmt.correctsys.dto.CheckTeacherDetailDto;
import com.ssj.service.kmt.correctsys.request.ApplyOperateReq;
import com.ssj.service.kmt.dto.ExerciseBookCourseClassDto;
import com.ssj.service.kmt.dto.ExerciseQuetionDto;
import com.ssj.service.kmt.dto.KmtExerciseLibExportDto;
import com.ssj.service.kmt.dto.exercise.ExerciseBookAndLibExportDto;
import com.ssj.service.kmt.dto.exercise.KmtExerciseBookLibDto;
import com.ssj.service.kmt.exercisesys.dto.*;
import com.ssj.service.kmt.exercisesys.enums.ExerciseBookStatusEnum;
import com.ssj.service.kmt.exercisesys.enums.ExportExerciseBookStatusEnum;
import com.ssj.service.kmt.exercisesys.request.*;
import com.ssj.service.kmt.exercisesys.service.KmtExerciseSysService;
import com.ssj.service.kmt.request.KmtExerciseBookLibReq;
import com.ssj.service.kmt.service.*;
import com.ssj.service.mapper.KmtExerciseMapper;
import com.ssj.service.mapper.KmtQuestionMapper;
import com.ssj.service.mapper.LibManagerAuditMapper;
import com.ssj.service.mapper.LibManagerMapper;
import com.ssj.service.sys.cardinfo.service.ICardInfoService;
import com.ssj.service.sys.push.service.SconPushMessageService;
import com.ssj.service.sys.push.service.task.UpdateExerciseQuestionThreadTask;
import com.ssj.service.sys.role.service.AdminService;
import com.ssj.service.sys.wallet.service.BankService;
import com.ssj.service.task.SyncRefreshExerciseBookDistributionCountTask;
import com.ssj.service.weixin.library.service.IBookManagerService;
import com.ssj.service.weixin.library.service.ILibJoinService;
import com.ssj.service.weixin.library.service.LibManagerAuditService;
import com.ssj.service.weixin.user.service.UserAccountService;
import com.ssj.service.weixin.user.service.UserService;
import com.ssj.taskthread.ThreadPool;
import com.ssj.utils.Paging;
import com.ssj.weixin.utils.LoginWxUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermsQueryBuilder;
import org.elasticsearch.script.Script;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.ParsedStringTerms;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.metrics.ParsedSum;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Mount Liu
 * @date 2020/3/18
 */
@Service(version = "1.0")
@Transactional
public class KmtExerciseSysServiceImpl implements KmtExerciseSysService {
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    final static int SUCCESS = 1;
    final static int FAIL = 2;

    @Autowired
    private UserService userService;

    @Autowired
    private ParentService parentService;

    @Autowired
    private TokenManager tokenManager;

    @Autowired
    private IBookManagerService managerService;
    @Autowired
    private LibManagerMapper libManagerMapper;

    @Autowired
    private LibManagerAuditService libManagerAuditService;

    @Autowired
    private BankService bankService;

    @Autowired
    private ICardInfoService cardInfoService;

    @Autowired
    private OneDayAndOneMonthDao oneDayAndOneMonthDao;
    @Autowired
    private KmtExerciseMapper kmtExerciseMapper;
    @Autowired
    private BaseSearchService baseSearchService;
    @Autowired
    private PagingHibernateJdbcDao pagingHibernateJdbcDao;

    @Autowired
    private ExerciseQuestionSearchService exerciseQuestionSearchService;

    @Autowired
    private KmtExerciseMapperService kmtExerciseMapperService;

    @Autowired
    private KmtQuestionMapper kmtQuestionMapper;
    @Autowired
    private KnowledgeVersion knowledgeVersion;
    @Autowired
    private KmtExerciseQuestionService kmtExerciseQuestionService;

    @Autowired
    private LibManagerAuditMapper managerAuditMapper;
    @Autowired
    private AdminService adminService;
    @Autowired
    private FileInfoService fileInfoService;

    @Autowired
    private KmtExerciseBookService kmtExerciseBookService;

    @Autowired
    private ConfigService configService;

    @Autowired
    private KmtExerciseBookLibService KmtExerciseBookLibService;

    @Autowired
    private ILibJoinService libJoinService;

    @Autowired
    private IBookManagerDao bookManagerDao;

    @Autowired
    private KmtExerciseTeacherRecordService kmtExerciseTeacherRecordService;

    @Autowired
    private SconPushMessageService sconPushMessageService;

    @Autowired
    private UserAccountService userAccountService;

    @Autowired
    private KmtExerciseLibPriorityService kmtExerciseLibPriorityService;

    @Autowired
    private KmtExerciseService kmtExerciseService;

    @Autowired
    private KmtQualityQuestionsService kmtQualityQuestionsService;

    @Autowired
    private RedisUtil redisUtil;

    @Override
    public ResponseEntity getVerificationCode(String phone, int type, String userId) throws Exception {
        ResponseEntity responseEntity = new ResponseEntity();
        User phoneUser = userService.findByMobile(phone);
        //短信类型 1：用户注册；2：忘记密码；3：换绑手机号
        //忘记密码
        if (type == 1) {
            if (phoneUser != null) {
                return responseEntity.failure(ResponseConstant.CODE_000, "已存在该用户，请直接登录");
            }
        } else if (type == 2) {
            if (phoneUser == null) {
                return responseEntity.failure(ResponseConstant.CODE_000, "不存在此手机号码用户");
            }
        } else if (type == 3) {
            if (StringUtil.isNotBlank(userId)) {
                User user = userService.getById(userId);
                if (user != null && phone.equals(user.getMobile())) {
                    return responseEntity.failure(ResponseConstant.CODE_000, "请换绑新号码");
                }
            }
            if (phoneUser != null) {
                return responseEntity.failure(ResponseConstant.CODE_000, "此手机号码已存在");
            }
        }
        parentService.sendSms(phone, 1);
        return responseEntity.success("验证码发送成功,请注意接收短信！");
    }

    @Override
    public ResponseEntity verifyCode(String phone, String code) throws Exception {
        ResponseEntity responseEntity = parentService.confirmSms(phone, code);
        if (responseEntity.getCode().equals("999")) {
            //清除验证码
            tokenManager.delString(phone);
        }
        return responseEntity;
    }

    @Override
    public ResponseEntity accountLogin(String loginName, String password) {
        ResponseEntity responseEntity = new ResponseEntity();
        if (adminService.loginLocking(loginName, "KMT_SYS")) {
            return responseEntity.failure("您的账号已被锁定，请30分钟后重试");
        }
        User user = userService.findByMobile(loginName);
        if (user == null) {
            responseEntity.failure(ResponseConstant.CODE_000, "用户名或密码错误");
            return responseEntity;
        } else {
            User loginUser = userService.getUserByPassword(loginName, password);
            if (loginUser != null) {
                String userLoginToken = tokenManager.getToken(user.getId(), "PC");
                if (StringUtils.isBlank(userLoginToken)) {
                    userLoginToken = tokenManager.createToken(null, user.getId(), "PC");
                }
                Map<String, Object> data = new HashMap<>(18);
                data.put("accessToken", userLoginToken);
                data.put("binded", 0);
                //有unionid是绑定过微信的账户
                if (StringUtil.isNotBlank(loginUser.getUnionid())){
                    data.put("binded", 1);
                }

                responseEntity.success(data, "登录成功");
                tokenManager.clearPasswordWrongRecord(loginName);
            } else {
                int wrongCount = tokenManager.recordPasswordWrong(loginName, "KMT_SYS");
                if (wrongCount >= 5) {
                    responseEntity.failure("用户名或密码错误，您的账号已被锁定，请30分钟后重试");
                } else if (wrongCount >= 2) {
                    responseEntity.failure(String.format("您再输错%s次账号将会锁定", 5 - wrongCount));
                } else {
                    responseEntity.failure("用户名或密码错误，请重新输入");
                }
            }
        }
        return responseEntity;
    }

    @Override
    public ResponseEntity setPassword(SetPasswordReq req) {
        ResponseEntity responseEntity = new ResponseEntity();
        if (req.getPassword().equals(req.getPhone())) {
            return responseEntity.failure("密码不能和用户名一致");
        }
        if (!PasswordUtil.checkRule(req.getPassword())) {
            return responseEntity.failure(PasswordUtil.CHECK_FAIL_MESSAGE);
        }
        User user = userService.findByMobile(req.getPhone());
        if (user == null) {
            user = new User();
            String userId = IdWorker.generateId();
            user.setId(userId);
            user.setCreateTime(new Date());
            user.setSubscribe(0);
        }
        user.setMobile(req.getPhone());
        String pwdSalt = PasswordUtil.generateSalt();
        String password = PasswordUtil.initPassword(req.getPassword(), pwdSalt);
        user.setPwdSalt(pwdSalt);
        user.setPassword(password);
        userService.save(user);
        return responseEntity.success("注册成功");
    }

    @Override
    public ResponseEntity resetPassword(ResetPasswordReq req, String userId) {
        ResponseEntity responseEntity = new ResponseEntity();
        User user = userService.getById(userId);
        if (!userService.verificationPassword(userId, req.getOldPassword())) {
            return responseEntity.failure("原始密码错误");
        }
        if (req.getNewPassword().equals(user.getMobile())) {
            return responseEntity.failure("密码不能和用户名一致");
        }
        if (PasswordUtil.verificationPassword(req.getNewPassword(), user.getPassword(), user.getPwdSalt())) {
            return responseEntity.failure("新密码不能与旧密码一致");
        }
        if (!PasswordUtil.checkRule(req.getNewPassword())) {
            return responseEntity.failure(PasswordUtil.CHECK_FAIL_MESSAGE);
        }
        userService.updateByResetPassword(user.getId(), req.getNewPassword());
        return responseEntity.success("重置成功");
    }


    @Override
    public ResponseEntity forgetPassword(ForgetPasswordReq req) throws Exception {
        ResponseEntity responseEntity = new ResponseEntity();
        User user = userService.findByMobile(req.getPhone());
        if (user == null) {
            return responseEntity.failure("此手机号码，非本站用户");
        }
        responseEntity = parentService.confirmSms(req.getPhone(), req.getVcode());
        if (!responseEntity.getCode().equals("999")) {
            return responseEntity.failure("验证码错误");
        }
        if (req.getPassword().equals(user.getMobile())) {
            return responseEntity.failure("密码不能和用户名一致");
        }
        if (PasswordUtil.verificationPassword(req.getPassword(), user.getPassword(), user.getPwdSalt())) {
            return responseEntity.failure("新密码不能与旧密码一致");
        }
        if (!PasswordUtil.checkRule(req.getPassword())) {
            return responseEntity.failure(PasswordUtil.CHECK_FAIL_MESSAGE);
        }
        String pwdSalt = PasswordUtil.generateSalt();
        String password = PasswordUtil.initPassword(req.getPassword(), pwdSalt);
        user.setPwdSalt(pwdSalt);
        user.setPassword(password);
        userService.save(user);
        //清除验证码
        tokenManager.delString(req.getPhone());
        return responseEntity.success("设置成功");
    }

    /**
     * 换绑手机号
     *
     * @return
     */
    @Override
    public ResponseEntity updateBindPhone(ForgetPasswordReq req, String userId) throws Exception {
        ResponseEntity responseEntity = parentService.confirmSms(req.getPhone(), req.getVcode());
        if (!responseEntity.getCode().equals("999")) {
            return responseEntity.failure("验证码错误");
        }
        if (!userService.verificationPassword(userId, req.getPassword())) {
            return responseEntity.failure("原始密码错误");
        }
        //照看此手机号是否已被别的用户绑定
        User phoneUser = userService.findByMobile(req.getPhone());
        if (phoneUser != null) {
            return responseEntity.failure(ResponseConstant.CODE_000, "此手机号码已存在");
        }
        User user = userService.getById(userId);
        user.setMobile(req.getPhone());
        userService.save(user);
        //清除验证码
        tokenManager.delString(req.getPhone());
        return responseEntity.success("换绑成功");
    }

    @Override
    public ResponseEntity saveInfo(String userId, SaveInfoExesysReq req) {
        ResponseEntity responseEntity = new ResponseEntity();
        //所有同名的老师
        String sameNameUserId = libManagerMapper.findExerciseTeacherByName(req.getName());
        List <TbLibManager> list = managerService.findAllByUserIdAndTypeAndStatus(userId, 17);
        TbLibManager tbLibManager=null;
        if(CollectionUtils.isNotEmpty(list)){
            tbLibManager=list.get(0);
        }
        if (StringUtil.isNotBlank(sameNameUserId) && !userId.equals(sameNameUserId)) {
            return responseEntity.failure("您的姓名与已有老师重复，可改为XXX1，XXX2等");
        }

        if ((req.getType().contains("7") || req.getType().contains("8")) && req.getType().length() > 1) {
            return responseEntity.failure("老师类型选择错误");
        }
        Map<String, Object> map = new HashMap<>(16);
        Date now = new Date();
        if (tbLibManager == null) {
            tbLibManager = new TbLibManager();
            //设为无效
            tbLibManager.setState(2);
            //录题管理员
            tbLibManager.setType(17);
            tbLibManager.setUserId(userId);
            tbLibManager.setCreateTime(now);
        }else{
            //查找所有审批中的记录
            List<TbLibManagerAudit> auditList = libManagerAuditService.findByLibManagerIdAndStatus(tbLibManager.getId(), 3);
            if (CollectionUtils.isNotEmpty(auditList)) {
                return responseEntity.failure("你已提交过资料，请勿重复提交");
            }
        }
        //设置头像
        if (StringUtil.isNotBlank(req.getImgUrl())) {
            tbLibManager.settPhoto(req.getImgUrl());
        } else {
            User user = userService.getById(userId);
            tbLibManager.settPhoto(user.getPhoto());
        }
        //提交资料则设置为下线
        tbLibManager.setIsOnline(0);
        managerService.save(tbLibManager);
        TbLibManagerAudit tbLibManagerAudit = new TbLibManagerAudit();
        tbLibManagerAudit.setUserId(userId);
        tbLibManagerAudit.setSex(req.getSex());
        tbLibManagerAudit.setMajor(req.getMajor());
        tbLibManagerAudit.setAuthority(req.getType());
        tbLibManagerAudit.setLibManagerId(tbLibManager.getId());
        tbLibManagerAudit.setName(req.getName());
        tbLibManagerAudit.setTelephone(req.getPhone());
        tbLibManagerAudit.setSchool(req.getSchool());
        tbLibManagerAudit.setImgUrl(req.getImgUrl());
        tbLibManagerAudit.setIdNum(req.getIdNumber());
        tbLibManagerAudit.setIdCon(req.getIdCon());
        tbLibManagerAudit.setIdFace(req.getIdFace());
        tbLibManagerAudit.setCertification(req.getCertification());
        //银行卡相关
        tbLibManagerAudit.setBankcardFace(req.getBankcardFace());
        tbLibManagerAudit.setBankcardCon(req.getBankcardCon());
        tbLibManagerAudit.setBankName(req.getBankName());
        tbLibManagerAudit.setBankIcon(req.getBankIcon());
        tbLibManagerAudit.setCardholder(req.getCardholder());
        tbLibManagerAudit.setCardNumber(req.getCardNumber());
        tbLibManagerAudit.setBankBranch(req.getBankBranch());
        //同tb_lib_manager.type
        tbLibManagerAudit.setType(17);
        //状态：审核中
        tbLibManagerAudit.setStatus(3);
        tbLibManagerAudit.setCreateTime(now);
        tbLibManagerAudit.setSubject(req.getSubject());
        //保存审批老师信息
        libManagerAuditService.save(tbLibManagerAudit);
        //清除PC用户token
        String accessToken = tokenManager.getToken(userId, "PC");
        if (StringUtils.isNotBlank(accessToken)) {
            tokenManager.removeToken(accessToken, "PC");
            //提交资料后强制下线，给前端的标识
            tokenManager.setString("invalid_reason_" + accessToken, "3");
        }
        responseEntity.success(map, "成功");
        return responseEntity;
    }

    @Override
    public ResponseEntity bindWxUnionId2PhoneUser (String code, String userId){
        ResponseEntity responseEntity = new ResponseEntity();
        responseEntity.success("绑定成功，请关注私塾家公众号");
        if(StringUtil.isNotBlank(code)) {
            User  phoneUser = userService.getById(userId);
            if (phoneUser != null && StringUtil.isNotBlank(phoneUser.getMobile())){
                if (StringUtil.isBlank(phoneUser.getAccount()) || StringUtil.isBlank(phoneUser.getUnionid())){
                    WeixinOauth2Token token = LoginWxUtil.getOauth2AccessToken(code,PropertiesUtil.getValue("weixin_aipc_appId"),
                            PropertiesUtil.getValue("weixin_aipc_appSecret"));
                    logger.info("从KMT---WeixinOauth2Token获取  ---openid----)" + token.getOpenId());
                    logger.info("从KMT---WeixinOauth2Token获取  ---uunion----)" + token.getUnionId());
                    if(StringUtil.isNotBlank(token.getUnionId())){
                        User user = userService.getUserByUnionid(token.getUnionId());
                        //微信用户记录的手机号为空， 需要删除微信记录, 清除tb_user_account的对应记录， 手机号不为空且不等于手机用户的手机号码，返回错误给前端，微信用户已绑定其他手机号，需要解绑
                        if(user != null){
                            if (StringUtil.isBlank(user.getMobile())){
                                if (StringUtil.isNotBlank(user.getAccount())){
                                    phoneUser.setAccount(user.getAccount());
                                }
                                //清除废弃用户token信息
                                tokenManager.delToken(user.getId());
                                tokenManager.batchDel("user_id" + user.getUnionid() + "*");
                                String sb = "合并校长端微信授权+手机注册用户信息:" + "微信用户userid(" +
                                        user.getId() + ")" + "--->" +
                                        "手机用户userid(" + phoneUser.getId() + ")";
                                sconPushMessageService.savePushMessage(user.getId(), Constant.SCHOOL_MASTER_PLATFORM_TYPE, null, sb, "SYSTEM");
                                user.setAccount(null);
                                user.setUnionid(null);
                                user.setUserName(user.getUserName() + "(已废弃)");
                                userService.save(user);
                                //清除tb_user_account
                                userAccountService.updateByUserId(user.getId(), phoneUser.getId());
                            } else if (!user.getMobile().equals(phoneUser.getMobile())){
                                responseEntity.failure("微信用户已绑定其他手机号，绑定失败");
                                return responseEntity;
                            }
                        }
                        //保存手机用户
                        //phoneUser.setAccount(token.getOpenId());
                        phoneUser.setUnionid(token.getUnionId());
                        userService.save(phoneUser);
                    } else {
                        responseEntity.failure("扫码获取信息失败， 请重新扫码");
                    }
                } else {
                    responseEntity.success("该用户已绑定微信");
                }
            } else {
                responseEntity.failure("非手机用户，请先用手机号注册登录");
            }
        }
        return responseEntity;
    }

    @Override
    public ResponseEntity getMyInfo(String userId) {
        ResponseEntity responseEntity = new ResponseEntity();
        UserDto dto = new UserDto();
        TbLibManager libManager;
        User user = userService.getById(userId);
        if (user == null) {
            return responseEntity.failure("未找到该用户");
        }
        //17 录题老师,18录题管理员
        int[] type = {17, 18};
        //是否是新注册的用户
        boolean isNewUser = true;
        //包含无效的数据,注销的数据
        List<TbLibManager> libManagerList = managerService.findAllByUserIdAndTypeIn(userId, type);
        if (libManagerList.size() > 0) {
            //单角色，多权限
            libManager = libManagerList.get(0);
            //如果是注销用户，则看有没有重新提交资料
            if (libManager.getIsCancelled() == 1) {
                //最新的审批记录
                TbLibManagerAudit audit = libManagerAuditService.findNewestOneByLibManagerId(libManager.getId());
                //审核中状态
                if (audit != null && audit.getStatus() == 3) {
                    isNewUser = false;
                }
            } else {
                isNewUser = false;
            }
            if(!isNewUser){
                //没有头像自动更新头像
                if (StringUtil.isBlank(libManager.gettPhoto())) {
                    libManager.settPhoto(user.getPhoto());
                    managerService.save(libManager);
                }
                if (libManager.getType() == 17) {
                    this.getTeacherInfo(libManager, dto);
                } else if (libManager.getType() == 18) {
                    this.getManagerInfo(libManager, dto);
                    return responseEntity.success(dto, "成功");
                }
            }
        }
        //注册
        if(isNewUser){
            dto.setImgUrl(user.getPhoto());
            //第一次审核
            dto.setIsFirst(1);
            //未审核
            dto.setApproveStatus(0);
        }
        dto.setUserId(userId);
        Sort sort = new Sort("bankName");
        List<Bank> bankList = bankService.findAll(sort);
        List<UserDto.Bank> bankDtoList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(bankList)) {
            for (Bank bank : bankList) {
                UserDto.Bank bankDto = dto.new Bank();
                bankDto.setBankName(bank.getBankName());
                bankDto.setBankIcon(bank.getBankIcon());
                bankDtoList.add(bankDto);
            }
        }
        dto.setBankList(bankDtoList);
        responseEntity.success(dto, "成功");
        return responseEntity;
    }

    private void getTeacherInfo(TbLibManager libManager, UserDto dto) {
        TbLibManagerAudit auditManager = null;
        //审批记录信息
        List<TbLibManagerAudit> auditList = libManagerAuditService.findByLibManagerId(libManager.getId());
        //isFirst=1的情况：审批记录是“审批拒绝”和“审核中”（所有审批记录都是被拒绝；审批记录有且只有一条为“审核中”）
        int isFirst = 0;
        int approveStatus = 0;
        int i = 0;
        if (auditList != null && auditList.size() > 0) {
            for (TbLibManagerAudit audit : auditList) {
                if (audit.getStatus() == 1) {
                    i++;
                }
            }
            //第2种情况
            if (i == 0) {
                isFirst = 1;
            }
            auditManager = auditList.get(0);
            approveStatus = auditManager.getStatus();
            dto.setReason(auditManager.getReason());
        }
        dto.setIsFirst(isFirst);
        dto.setApproveStatus(approveStatus);
        //审批中和审批拒绝，显示填写的审批的数据
        if (dto.getApproveStatus() == 3 || dto.getApproveStatus() == 2) {
            dto.setImgUrl(auditManager.getImgUrl());
            dto.setName(auditManager.getName());
            dto.setSex(auditManager.getSex());
            dto.setSchool(auditManager.getSchool());
            dto.setMajor(auditManager.getMajor());
            dto.setPhone(auditManager.getTelephone());
            dto.setType(auditManager.getAuthority());
            //银行卡相关信息
            dto.setBankcardFace(auditManager.getBankcardFace());
            dto.setBankcardCon(auditManager.getBankcardCon());
            dto.setBankName(auditManager.getBankName());
            dto.setBankIcon(auditManager.getBankIcon());
            dto.setCardholder(auditManager.getCardholder());
            dto.setCardNumber(auditManager.getCardNumber());
            dto.setBankBranch(auditManager.getBankBranch());
            //身份证、证件
            dto.setIdNumber(auditManager.getIdNum());
            dto.setIdFace(auditManager.getIdFace());
            dto.setIdCon(auditManager.getIdCon());
            dto.setCertification(auditManager.getCertification());
            dto.setSubject(auditManager.getSubject());
        } else {
            dto.setImgUrl(libManager.gettPhoto());
            dto.setName(libManager.getName());
            dto.setSex(libManager.getSex());
            dto.setSchool(libManager.getSchool());
            dto.setMajor(libManager.getMajor());
            dto.setPhone(libManager.getTelephone());
            dto.setType(libManager.getAuthority());
            //银行卡相关信息
            TbCardInfo cardInfo = cardInfoService.findByUserIdValid(libManager.getUserId());
            if (cardInfo == null) {
                cardInfo = new TbCardInfo();
            }
            dto.setBankcardFace(cardInfo.getBankcardFace());
            dto.setBankcardCon(cardInfo.getBankcardCon());
            dto.setBankName(cardInfo.getCardBank());
            dto.setBankIcon(cardInfo.getBankIcon());
            dto.setCardholder(cardInfo.getCardName());
            dto.setCardNumber(cardInfo.getCardNum());
            dto.setBankBranch(cardInfo.getSubbranch());
            //身份证、证件
            dto.setIdNumber(libManager.getIdNum());
            dto.setIdFace(libManager.getIdFace());
            dto.setIdCon(libManager.getIdCon());
            dto.setCertification(libManager.getCertification());
            dto.setSubject(libManager.getCourseName());
        }
        //注册日期
        dto.setCreateDate(DateHelper.format(libManager.getCreateTime(),"yyyy.MM.dd"));
        dto.setIsBanned(libManager.getIsBanned());
        dto.setRole(libManager.getType());
    }

    private void getManagerInfo(TbLibManager libManager, UserDto dto) {
        dto.setUserId(libManager.getUserId());
        dto.setName(libManager.getName());
        dto.setImgUrl(libManager.gettPhoto());
        dto.setRole(libManager.getType());
    }


    @Override
    public ResponseEntity queryAllRegisterTeacher(ExercisePageReq req, Pageable pageable){
        ResponseEntity responseEntity=new ResponseEntity();
        Map<String,Object> param=new HashMap<>();
        List<ApplyRegisterTeacherDto> list=new ArrayList<>();
        Map<String,Object> data=new HashMap<>();
        param.put("EQ_status",3);
        param.put("EQ_type",17);
        String name=null;
        String author=null;
        if(StringUtils.isNotBlank(req.getName())){
            name=req.getName();
            if(StringUtils.isNotBlank(this.getExerciseTeacherType(req.getName()))){
               author=this.getExerciseTeacherType(req.getName()).toString();
          }
        }
        com.baomidou.mybatisplus.extension.plugins.pagination.Page page =
                new com.baomidou.mybatisplus.extension.plugins.pagination.Page(req.getPageNo(), req.getPageSize());

         List<TbLibManagerAudit> libManagerAuditList= managerAuditMapper.findPageByName(page,name,name, author);

       libManagerAuditList.forEach(it->{
            ApplyRegisterTeacherDto dto=new ApplyRegisterTeacherDto();
            dto.setTeacherId(it.getUserId());
            dto.setImgUrl(it.getImgUrl());
            dto.setName(it.getName());
            dto.setSex(it.getSex());
            dto.setSchool(it.getSchool());
            dto.setTelephone(it.getTelephone());
            dto.setProfession(it.getMajor());
            dto.setAuthority(it.getAuthority());
            dto.setIdFace(it.getIdFace());
            dto.setIdCon(it.getIdCon());
            dto.setIdNumber(it.getIdNum());
            dto.setStudentNum(it.getCertification());
            dto.setBankName(it.getBankName());
            dto.setBankFace(it.getBankcardFace());
            dto.setBankCon(it.getBankcardCon());
            dto.setCardHolder(it.getCardholder());
            dto.setCardNumber(it.getCardNumber());
            dto.setBankBranch(it.getBankBranch());
            dto.setBankIcon(it.getBankIcon());
            dto.setRegisTime(DateUtil.format_yyyyMMddHHmmss(it.getCreateTime()));
            dto.setSubject(it.getSubject());
            list.add(dto);
        });
        data.put("total",(int) page.getTotal());
        data.put("pages",page.getPages());
        data.put("pageNo",req.getPageNo());
        data.put("pageSize",req.getPageSize());
        data.put("list",list);
        return responseEntity.success(data,"成功");

    }

    private StringBuilder getExerciseTeacherType(String name){
        List<String> list=new ArrayList<>();
        StringBuilder str=new StringBuilder();
        list.add("1练习册加工");
        list.add("2练习册审核");
        list.add("3练习册解析");
        list.add("4练习册解审");
        list.add("5题库迁移");
        list.add("6题库审核");
        list.add("7题库录入");
        list.add("8答案校对");
        HashMap<String,Object> map=new HashMap<>();
        list= list.stream().filter(it->it.contains(name)).collect(Collectors.toList());
        if(CollectionUtils.isNotEmpty(list)){
            list.forEach(it->{
                str.append(it.substring(0,1));
            });
        }
        return  str;
    }
    @Override
    public ResponseEntity applyExerciseTeacherOperate(ApplyOperateReq req){

        ResponseEntity responseEntity = new ResponseEntity();
        TbLibManagerAudit audit = libManagerAuditService.findByUserIdAndTypeAndStatus(req.getApplicantId(),17,3);
        if (audit == null) {
            responseEntity.failure("无审批记录，失败");
            return responseEntity;
        }
        //审批通过
        if (SUCCESS == req.getOperate()) {
            TbLibManager teacher = managerService.findAllByUserIdAndTypeAndCancelled(req.getApplicantId(), 17);
            if (teacher == null) {
                responseEntity.failure("不存在该老师，请联系管理员");
                return responseEntity;
            }
            //将注销了的老师设置为失效
            managerService.updateByUserIdAndTypeAndCancelled(req.getApplicantId(),17,1);
            teacher.setSex(audit.getSex());
            teacher.setName(audit.getName());
            teacher.setTelephone(audit.getTelephone());
            teacher.setSchool(audit.getSchool());
            teacher.setMajor(audit.getMajor());
            teacher.setAuthority(audit.getAuthority());
            teacher.settPhoto(audit.getImgUrl());
            teacher.setState(1);
            teacher.setType(audit.getType());
            teacher.setIdNum(audit.getIdNum());
            teacher.setIdFace(audit.getIdFace());
            teacher.setIdCon(audit.getIdCon());
            teacher.setCertification(audit.getCertification());
            teacher.setCourseName(audit.getSubject());
            //如果有注销的设置为非注销的
            teacher.setIsCancelled(0);
            managerService.save(teacher);
            //插入银行卡相关信息
            TbCardInfo cardInfo = cardInfoService.findByUserIdValid(teacher.getUserId());
            if (cardInfo == null) {
                cardInfo = new TbCardInfo();
                cardInfo.setUserId(teacher.getUserId());
                cardInfo.setState(1);
            }
            cardInfo.setCardBank(audit.getBankName());
            cardInfo.setBankcardCon(audit.getBankcardCon());
            cardInfo.setBankcardFace(audit.getBankcardFace());
            cardInfo.setBankIcon(audit.getBankIcon());
            cardInfo.setCardName(audit.getCardholder());
            cardInfo.setCardNum(audit.getCardNumber());
            cardInfo.setSubbranch(audit.getBankBranch());
            cardInfoService.save(cardInfo);
            audit.setStatus(SUCCESS);
        } else if (FAIL == req.getOperate()) {
            //审批拒绝
            audit.setStatus(FAIL);
            audit.setReason(req.getReason());
        }
        libManagerAuditService.save(audit);

        String token = tokenManager.getToken(audit.getUserId(), "APP_TEACHER");
        if (StringUtils.isNotBlank(token)) {
            tokenManager.removeToken(token, "APP_TEACHER");
        }
        //清除PC用户token
        String accessToken = tokenManager.getToken(req.getApplicantId(), "PC");
        if (StringUtils.isNotBlank(accessToken)) {
            tokenManager.removeToken(accessToken, "PC");
        }

        responseEntity.success("成功");
        return responseEntity;

    }
    @Override
    public ResponseEntity findTeacherInfoList(MonthPageReq req, Pageable pageable){
        ResponseEntity responseEntity=new ResponseEntity();
        Map<String,Object> param=new HashMap<>();
        List<ExerciseTeachersDTo> list=new ArrayList<>();
        Map<String,Object> data=new HashMap<>();
        param.put("month",req.getMonth());
        if(StringUtils.isNotBlank(req.getName())){
            param.put("name",req.getName());
        }
        Page<Map<String, Object>> page = oneDayAndOneMonthDao.findAllExreciseTeacherInfo(pageable, param);
        for (Map<String, Object> pages : page) {
            MapGetterTool mapGetterTool = new MapGetterTool(pages);
            ExerciseTeachersDTo teacherInfoDto = new ExerciseTeachersDTo();
            teacherInfoDto.setTeacherId(mapGetterTool.getString("user_id"));
            teacherInfoDto.setImgUrl(mapGetterTool.getString("t_photo"));
            teacherInfoDto.setIdNumber(mapGetterTool.getString("id_num"));
            teacherInfoDto.setTelephone(mapGetterTool.getString("telephone"));
            teacherInfoDto.setName(mapGetterTool.getString("name"));
            teacherInfoDto.setSchool(mapGetterTool.getString("school"));
            teacherInfoDto.setProfession(mapGetterTool.getString("major"));
            teacherInfoDto.setType(mapGetterTool.getString("authority"));
            teacherInfoDto.setIdFace(mapGetterTool.getString("id_face"));
            teacherInfoDto.setIdCon(mapGetterTool.getString("id_con"));
            teacherInfoDto.setBankName(mapGetterTool.getString("card_bank"));
            teacherInfoDto.setIdNumber(mapGetterTool.getString("id_num"));
            teacherInfoDto.setStudentNum(mapGetterTool.getString("certification"));
            teacherInfoDto.setBankBranch(mapGetterTool.getString("subbranch"));
            teacherInfoDto.setBankFace(mapGetterTool.getString("bankcard_face"));
            teacherInfoDto.setBankCon(mapGetterTool.getString("bankcard_con"));
            teacherInfoDto.setBankIcon(mapGetterTool.getString("bank_icon"));
            teacherInfoDto.setCardHolder(mapGetterTool.getString("card_name"));
            teacherInfoDto.setCardNumber(mapGetterTool.getString("card_num"));
            teacherInfoDto.setSex(mapGetterTool.getInteger("sex"));
            teacherInfoDto.setSubject(mapGetterTool.getString("course_name"));
            teacherInfoDto.setRegisTime(Optional.ofNullable(DateUtil.format_yyyyMMddHHmmss(mapGetterTool.getDate("create_time"))).orElse(""));
            int workStatus=0;
            if (Objects.equals(mapGetterTool.getInteger("is_cancelled"), 1)) {
                workStatus = 4;
            } else if (Objects.equals(mapGetterTool.getInteger("is_banned"), 1)) {
                workStatus = 3;
            } else if (Objects.equals(mapGetterTool.getInteger("is_formal"), 1)) {
                workStatus = 2;
            } else {
                workStatus = 1;
            }
            teacherInfoDto.setWorkStatus(workStatus);

            list.add(teacherInfoDto);

        }
        //查询未注册审核的老师数量
        int unapplyOperateNum=  libManagerAuditService.countUnOperateNum();
        data.put("unapplyOperateNum",unapplyOperateNum);
        data.put("pages",page.getTotalPages());
        data.put("total",page.getTotalElements());
        data.put("pageNo",pageable.getPageNumber());
        data.put("pageSize",pageable.getPageSize());
        data.put("list",list);
        return responseEntity.success(data,"成功");
    }

    @Override
    public ResponseEntity findLastInsertMonth(){
        ResponseEntity responseEntity=new ResponseEntity();
        String month=null;
        Map<String,Object> data=new HashMap<>();
        TbLibManager tbLibManager=managerService.findByTypeAndState(17,1);
        if(null==tbLibManager){
            month= DateFormatUtils.format(new Date(),"yyyy-MM-dd");
        }
         month=DateFormatUtils.format(tbLibManager.getCreateTime(),"yyyy-MM-dd");
        data.put("month",month);
       return responseEntity.success(data,"成功");
    }

    @Override
    public ResponseEntity findExerciseTeacherList(ExerciseTeacherListReq req) {
        ResponseEntity responseEntity = new ResponseEntity();

        try {
            DateUtil.parse_yyyyMMddHHmmss(req.getMaxCreateTime());
        } catch (Exception e) {
            return responseEntity.failure("最大创建时间格式错误");
        }
        com.baomidou.mybatisplus.extension.plugins.pagination.Page page =
                new com.baomidou.mybatisplus.extension.plugins.pagination.Page(req.getPageNo(), req.getPageSize());
        List<ExerciseTeacherDTO> list1=new ArrayList<>();
        List<TbLibManager> list=libManagerMapper.findTbLibManagersByCreateTime(page,req);
        list.forEach(a->{
            ExerciseTeacherDTO dto=new ExerciseTeacherDTO();
           String userId=a.getUserId();
           Map<String,Object> map=libManagerMapper.findKmtTeacherLists(userId);
           int unFinishCount=0;
           int totalCount=0;
           if(null!=map){
                unFinishCount= Integer.parseInt(map.get("unFinishCount").toString());
                totalCount= Integer.parseInt(map.get("totalCount").toString());
           }
           dto.setTeacherId(a.getUserId());
           dto.setImage(a.gettPhoto());
           dto.setName(a.getName());
           dto.setSubject(a.getCourseName());
           dto.setAuthority(a.getAuthority());
           dto.setTeacherTypeStr(dto.getTeacherTypeStr());
           dto.setTeacherWorkingType(dto.getTeacherWorkingType());
           dto.setUnFinishCount(unFinishCount);
           dto.setTotalCount(totalCount);
           list1.add(dto);
        });
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("pageNo", page.getCurrent());
        resultMap.put("pageSize", page.getSize());
        resultMap.put("pages", page.getPages());
        resultMap.put("total", page.getTotal());
        resultMap.put("list", list1);

        return responseEntity.success(resultMap, "查询成功");
    }

    @Override
    public List<ExerciseTeachersDTo> findAllExerciseTeachersDto(String month, Pageable pageable){

        Map<String,Object> params=new HashMap<>();
        List<ExerciseTeachersDTo> list=new ArrayList<>();
        params.put("month",month);
        params.put("type",17);
        Page<Map<String, Object>> page = oneDayAndOneMonthDao.findAllExreciseTeacherInfo(pageable, params);
        for (Map<String, Object> pages : page) {
            MapGetterTool mapGetterTool = new MapGetterTool(pages);
            ExerciseTeachersDTo teacherInfoDto = new ExerciseTeachersDTo();
            teacherInfoDto.setName(mapGetterTool.getString("name"));
            teacherInfoDto.setSchool(mapGetterTool.getString("school"));
            teacherInfoDto.setSex(mapGetterTool.getInteger("sex"));
            teacherInfoDto.setProfession(mapGetterTool.getString("major"));
            teacherInfoDto.setTelephone(mapGetterTool.getString("telephone"));
            teacherInfoDto.setType(mapGetterTool.getString("authority"));
            teacherInfoDto.setBankName(mapGetterTool.getString("card_bank"));
            teacherInfoDto.setIdNumber(mapGetterTool.getString("id_num"));
            teacherInfoDto.setBankBranch(mapGetterTool.getString("subbranch"));
            teacherInfoDto.setCardHolder(mapGetterTool.getString("card_name"));
            teacherInfoDto.setCardNumber(mapGetterTool.getString("card_num"));
            teacherInfoDto.setRegisTime(Optional.ofNullable(DateUtil.format_yyyyMMddHHmmss(mapGetterTool.getDate("create_time"))).orElse(""));
            list.add(teacherInfoDto);

        }
        return list;
    }

    @Override
    public ResponseEntity findKmtTeacherList(FindKmtTeacherListReq req) {
        ResponseEntity responseEntity = new ResponseEntity();
        com.baomidou.mybatisplus.extension.plugins.pagination.Page page = new com.baomidou.mybatisplus.extension.plugins.pagination.Page(req.getPageNo(), req.getPageSize());
        List<ExerciseTeacherDTO> list = libManagerMapper.findKmtTeacherList(req.getSubject(), req.getType(), 2, req.getTeacherName(), page);

        StringBuilder teacherTypeStr;
        for (ExerciseTeacherDTO item : list){
            teacherTypeStr = new StringBuilder();
            if (item.getAuthority().contains("5")){
                teacherTypeStr.append("加工、");
            }
            if (item.getAuthority().contains("6")){
                teacherTypeStr.append("审核、");
            }
            if (teacherTypeStr.length() > 0) {
                teacherTypeStr.deleteCharAt(teacherTypeStr.length() - 1);
            }
            item.setTeacherTypeStr(teacherTypeStr.toString());
        }
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("pageNo", page.getCurrent());
        resultMap.put("pageSize", page.getSize());
        resultMap.put("pages", page.getPages());
        resultMap.put("total", page.getTotal());
        resultMap.put("list", list);

        return responseEntity.success(resultMap, "查询成功");
    }

    @Override
    public ResponseEntity changeTeacherWorkingStatus(ChangeTeacherWorkingStatusReq req) {
        ResponseEntity responseEntity = new ResponseEntity();
        TbLibManager libManager = managerService.findByUserIdAndType(req.getTeacherId(), 17);

        if (libManager != null){
            //1解冻账号， 2转正，3冻结账号，4注销账号
            switch (req.getTeacherWorkingType()) {
                case 1:
                    libManager.setIsBanned(0);
                    break;
                case 2:
                    libManager.setIsFormal("1");
                    break;
                case 3:
                    libManager.setIsBanned(1);
                    //将老师设置为下线
                    String accessToken=tokenManager.getToken(req.getTeacherId(),"PC");
                    if(StringUtils.isNotBlank(accessToken)){
                        tokenManager.removeToken(accessToken,"PC");
                        tokenManager.setString("invalid_reason_"+accessToken,"1");
                    }
                    //更改在线状态
                    bookManagerDao.updateTeacherOnlineStatusByTeacherid(req.getTeacherId());
                    break;
                //注销账号如果有资料审批，则设置为审批拒绝
                case 4:
                    libManager.setIsCancelled(1);
                    //如果是校对中的老师，校对中的校对id为空
                    kmtExerciseMapper.updateKmtExerciseBookAnswerCorrecterId(req.getTeacherId());
                    TbLibManagerAudit audit = libManagerAuditService.findNewestOneByLibManagerId(libManager.getId());
                    if (audit != null && audit.getStatus() == 3) {
                        audit.setStatus(2);
                        audit.setReason("用户被注销，自动设置为拒绝");
                        libManagerAuditService.save(audit);
                    }
                    //将老师设置为下线
                    String accessToken1=tokenManager.getToken(req.getTeacherId(),"PC");
                    if(StringUtils.isNotBlank(accessToken1)){
                        tokenManager.removeToken(accessToken1,"PC");
                        tokenManager.setString("invalid_reason_"+accessToken1,"1");
                    }
                    //更改在线状态
                    bookManagerDao.updateTeacherOnlineStatusByTeacherid(req.getTeacherId());
                    break;
            }
            managerService.save(libManager);
            responseEntity.success(ResponseConstant.CODE_999, "操作成功");
        } else {
            responseEntity.success(ResponseConstant.CODE_000, "用户已注销");
        }
        return responseEntity;
    }

    @Override
    public ResponseEntity findKmtTeacherReviseQuestions(FindTeacherReviseQuestionsReq req) {
        ResponseEntity responseEntity = new ResponseEntity();
        Map<String, String> param = new HashMap<>();
        param.put("detailId", req.getDetailId());
        param.put("bookId", req.getBookId());
        param.put("teacherId", req.getTeacherId());
        //es的题目数据
        List<Map> list = exerciseQuestionSearchService.findKmtRollbackQuestions(param);
        List<ExerciseQuetionDto> questions = kmtQualityQuestionsService.parseMapToExerciseQuestionList(list);
        questions = kmtExerciseMapperService.findAndAppendBigQuestion2List(questions);

        Map<String, Object> data = new HashMap<>();
        data.put("list", kmtExerciseQuestionService.getQuestionGroupList(questions, false));
        return  responseEntity.success(data, "查询成功");
    }

    @Override
    public ResponseEntity findKmtTeacherDetails(FindKmtTeacherDetailReq req) {
        ResponseEntity responseEntity = new ResponseEntity();
        com.baomidou.mybatisplus.extension.plugins.pagination.Page page = new com.baomidou.mybatisplus.extension.plugins.pagination.Page(req.getPageNo(), req.getPageSize());
        List<KmtTeacherDetailDto> list = kmtQuestionMapper.findKmtTeacherDetails(req.getTeacherId(), req.getDetailName(), 4, page);

        for (KmtTeacherDetailDto item : list){
            item.setVersionName(knowledgeVersion.getVersionNameBySubjectAndVersionNum(item.getCourseName(), item.getVersionType()));
            item.setUnFinishCount(item.getTotalCount().intValue() - item.getUnFinishCount().intValue());
        }
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("pageNo", page.getCurrent());
        resultMap.put("pageSize", page.getSize());
        resultMap.put("pages", page.getPages());
        resultMap.put("total", page.getTotal());
        resultMap.put("list", list);
        return responseEntity.success(resultMap, "查询成功");
    }

    @Override
    public ResponseEntity findExerciseTeacherDetails(ExerciseTeacherDetailReq req) {
        ResponseEntity responseEntity = new ResponseEntity();

        try {
            DateUtil.parse_yyyyMMddHHmmss(req.getMaxCreateTime());
        } catch (Exception e) {
            return responseEntity.failure("最大创建时间格式错误");
        }

        IPage<ExerciseTeacherDetailDTO> page = new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(req.getPageNo(), req.getPageSize());
        libManagerMapper.findExerciseTeacherDetails(page, req);

        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("pageNo", page.getCurrent());
        resultMap.put("pageSize", page.getSize());
        resultMap.put("pages", page.getPages());
        resultMap.put("total", page.getTotal());
        resultMap.put("list", page.getRecords());

        return responseEntity.success(resultMap, "查询成功");
    }

    @Override
    public int refreshBookStatus(List<String> selectedExerciseBookIdList) {
        int offset = 0;
        int pageSize = 50;
        int updateCount = 0;

        List<KmtExerciseBook> kmtExerciseBookList;
        List<KmtExerciseBookCount> kmtExerciseBookCountList = new ArrayList<>(pageSize);
        KmtExerciseBookCount kmtExerciseBookCount;
        Map<String, List<KmtExerciseBook>> listMap;
        Set<String> exerciseBookIdSet;
        SearchRequest searchRequest = null;
        SearchResponse searchResponse;
        ParsedStringTerms groupByExerciseBookId;
        ParsedStringTerms groupByUnitId;
        do {
            kmtExerciseBookList = kmtExerciseMapper.findAllExerciseBookPage(selectedExerciseBookIdList, offset, pageSize);

            if (kmtExerciseBookList.isEmpty()) {
                break;
            }

            if (searchRequest == null) {
                // es统计联系测题目状态
                searchRequest = new SearchRequest("kmt_exercise_questions");
                searchRequest.source(SearchSourceBuilder.searchSource());
                searchRequest.source()
                        .aggregation(AggregationBuilders.terms("group_by_exerciseBookId")
                                .field("exerciseBookId.keyword")
                                .size(pageSize)
                                .subAggregation(AggregationBuilders.terms("groupByUnitId_handle")
                                        .field("unitId.keyword")
                                        .size(200)
                                        .subAggregation(AggregationBuilders.sum("unprocessedCount")
                                                .script(new Script("if(doc['dealStatus'].value == 0){return 1}else{return 0}")))
                                        .subAggregation(AggregationBuilders.sum("processedCount")
                                                .script(new Script("if(doc['dealStatus'].value > 1){return 1}else{return 0}")))
                                        .subAggregation(AggregationBuilders.sum("repulseCount")
                                                .script(new Script("if(doc['dealStatus'].value == 1){return 1}else{return 0}"))))
                                .subAggregation(AggregationBuilders.terms("groupByUnitId_handleAudit")
                                        .field("unitId.keyword")
                                        .size(200)
                                        .subAggregation(AggregationBuilders.sum("unprocessedCount")
                                                .script(new Script("if(doc['dealStatus'].value < 4){return 1}else{return 0}")))
                                        .subAggregation(AggregationBuilders.sum("processedCount")
                                                .script(new Script("if(doc['dealStatus'].value > 3 && doc['dealStatus'].value != 7){return 1}else{return 0}")))
                                        .subAggregation(AggregationBuilders.sum("repulseCount")
                                                .script(new Script("if(doc['dealStatus'].value == 7){return 1}else{return 0}"))))
                                .subAggregation(AggregationBuilders.terms("groupByUnitId_analysis")
                                        .field("unitId.keyword")
                                        .size(200)
                                        .subAggregation(AggregationBuilders.sum("unprocessedCount")
                                                .script(new Script("if(doc['dealStatus'].value < 8){return 1}else{return 0}")))
                                        .subAggregation(AggregationBuilders.sum("processedCount")
                                                .script(new Script("if(doc['dealStatus'].value > 8){return 1}else{return 0}")))
                                        .subAggregation(AggregationBuilders.sum("repulseCount")
                                                .script(new Script("if(doc['dealStatus'].value == 8){return 1}else{return 0}"))))
                                .subAggregation(AggregationBuilders.terms("groupByUnitId_analysisAudit")
                                        .field("unitId.keyword")
                                        .size(200)
                                        .subAggregation(AggregationBuilders.sum("unprocessedCount")
                                                .script(new Script("if(doc['dealStatus'].value < 10){return 1}else{return 0}")))
                                        .subAggregation(AggregationBuilders.sum("processedCount")
                                                .script(new Script("if(doc['dealStatus'].value == 11){return 1}else{return 0}")))
                                        .subAggregation(AggregationBuilders.sum("repulseCount")
                                                .script(new Script("if(doc['dealStatus'].value == 10){return 1}else{return 0}")))));
            }

            // 查询每本练习册更新，加工状态
            listMap = kmtExerciseBookList.stream().collect(Collectors.groupingBy(KmtExerciseBook::getId));
            exerciseBookIdSet = kmtExerciseBookList.stream()
                    .map(KmtExerciseBook::getId)
                    .collect(Collectors.toSet());
            searchRequest.source()
                    .query(QueryBuilders.boolQuery()
                            .filter(new TermsQueryBuilder("exerciseBookId.keyword", exerciseBookIdSet))
                            .mustNot(new TermsQueryBuilder("dealStatus", Arrays.asList(2, 6))));
            searchResponse = baseSearchService.search(searchRequest, null);
            if (searchResponse != null) {
                // 解析es查询结果
                groupByExerciseBookId = searchResponse.getAggregations().get("group_by_exerciseBookId");
                String exerciseBookId;
                for (Terms.Bucket groupByExerciseBookIdBucket : groupByExerciseBookId.getBuckets()) {
                    exerciseBookId = groupByExerciseBookIdBucket.getKeyAsString();
                    if (StringUtils.isBlank(exerciseBookId)) {
                        continue;
                    }

                    groupByUnitId = groupByExerciseBookIdBucket.getAggregations().get("groupByUnitId_handle");
                    kmtExerciseBookCount = this.parseAndSaveExerciseBookCount(exerciseBookId, 1, groupByUnitId.getBuckets(), listMap);
                    if (kmtExerciseBookCount != null) {
                        kmtExerciseBookCountList.add(kmtExerciseBookCount);
                    }

                    groupByUnitId = groupByExerciseBookIdBucket.getAggregations().get("groupByUnitId_handleAudit");
                    kmtExerciseBookCount = this.parseAndSaveExerciseBookCount(exerciseBookId, 2, groupByUnitId.getBuckets(), listMap);
                    if (kmtExerciseBookCount != null) {
                        kmtExerciseBookCountList.add(kmtExerciseBookCount);
                    }

                    groupByUnitId = groupByExerciseBookIdBucket.getAggregations().get("groupByUnitId_analysis");
                    kmtExerciseBookCount = this.parseAndSaveExerciseBookCount(exerciseBookId, 3, groupByUnitId.getBuckets(), listMap);
                    if (kmtExerciseBookCount != null) {
                        kmtExerciseBookCountList.add(kmtExerciseBookCount);
                    }

                    groupByUnitId = groupByExerciseBookIdBucket.getAggregations().get("groupByUnitId_analysisAudit");
                    kmtExerciseBookCount = this.parseAndSaveExerciseBookCount(exerciseBookId, 4, groupByUnitId.getBuckets(), listMap);
                    if (kmtExerciseBookCount != null) {
                        kmtExerciseBookCountList.add(kmtExerciseBookCount);
                    }
                }

                if (CollectionUtils.isNotEmpty(kmtExerciseBookCountList)) {
                    pagingHibernateJdbcDao.batchUpdate(kmtExerciseBookCountList);
                    updateCount += kmtExerciseBookCountList.size();
                    kmtExerciseBookCountList.clear();
                }
            }

            offset += pageSize;
        } while (kmtExerciseBookList.size() >= pageSize);

        return updateCount;
    }

    /**
     * 解析并保存练习册加工状态 kmt_exercise_book_count
     * @param exerciseBookId 练习册id
     * @param type 老师身份类型
     * @param bucketList es统计结果
     * @param listMap kmtExerciseBook
     * @return 更新记录数
     */
    private KmtExerciseBookCount parseAndSaveExerciseBookCount(String exerciseBookId, int type, List<? extends Terms.Bucket> bucketList,
                                                               Map<String, List<KmtExerciseBook>> listMap) {
        List<KmtExerciseBook> tempKmtExerciseBookList = listMap.get(exerciseBookId);
        if (CollectionUtils.isEmpty(tempKmtExerciseBookList)) {
            return null;
        }
        KmtExerciseBook kmtExerciseBook = tempKmtExerciseBookList.get(0);

        if (CollectionUtils.isEmpty(bucketList)) {
            return null;
        }

        String userId;
        switch (type) {
            case 1:
                userId = kmtExerciseBook.getHandleUserId();
                break;
            case 2:
                userId = kmtExerciseBook.getAuditingUserId();
                break;
            case 3:
                userId = kmtExerciseBook.getAnalysisUserId();
                break;
            case 4:
                userId = kmtExerciseBook.getAnalysisAuditerId();
                break;
            default:
                return null;
        }
        if (StringUtils.isBlank(userId)) {
            return null;
        }
        String unitId;
        ParsedSum unprocessedCountParsedSum;
        double unprocessedCount = 0.0;
        ParsedSum processedCountParsedSum;
        double processedCount = 0.0;
        ParsedSum repulseCountParsedSum;
        double repulseCount = 0.0;
        int bookStatus = 0;
        int unfinishedUnitCount = 0;
        int totalUnitCount = 0;
        long accuracy = 10000;
        List<KmtExerciseBookCount> kmtExerciseBookCountList = new ArrayList<>(bucketList.size());
        try {
            KmtExerciseBookCount kmtExerciseBookCount;
            Date now = new Date();
            // 遍历每个单元，统计未加工、打回、已加工的题目数，统计未完成、已完成单元数
            for (Terms.Bucket groupByUnitIdBucket : bucketList) {
                unitId = groupByUnitIdBucket.getKeyAsString();
                if (StringUtils.isBlank(unitId)) {
                    continue;
                }

                unprocessedCountParsedSum = groupByUnitIdBucket.getAggregations().get("unprocessedCount");
                unprocessedCount += unprocessedCountParsedSum.getValue();
                processedCountParsedSum = groupByUnitIdBucket.getAggregations().get("processedCount");
                processedCount += processedCountParsedSum.getValue();
                repulseCountParsedSum = groupByUnitIdBucket.getAggregations().get("repulseCount");
                repulseCount += repulseCountParsedSum.getValue();

                if (unprocessedCountParsedSum.getValue() > 0 || repulseCountParsedSum.getValue() > 0) {
                    unfinishedUnitCount++;
                }
                totalUnitCount++;
            }

            // 判断练习册当前加工状态
            if (repulseCount > 0) {
                // 打回
                bookStatus = 2;
            } else if (unprocessedCount > 0 && processedCount > 0) {
                // 加工中
                bookStatus = 3;
            } else if (unprocessedCount < 1 && processedCount > 0) {
                // 已加工
                bookStatus = 4;
            } else if (unprocessedCount > 0 && processedCount < 1) {
                // 未加工
                bookStatus = 1;
            }

            // 正确率计算，百分比的整数部分
            int errorCount = kmtExerciseMapper.countQuestionErrorCountByExerciseBookId(userId, exerciseBookId, type);
            if (errorCount > 0) {
                BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery().must(QueryBuilders.termQuery("exerciseBookId.keyword", exerciseBookId));
                SearchSourceBuilder searchSourceBuilder = ElasticUtil.initSearchSourceBuilder(queryBuilder);
                long totalQuestions = exerciseQuestionSearchService.count("kmt_exercise_questions", searchSourceBuilder);
                accuracy = Math.round((totalQuestions - errorCount) * 10000 / (float) totalQuestions);
            }

            // 插入或更新数据
            kmtExerciseBookCount =
                    kmtExerciseMapper.findKmtExerciseBookCountByExerciseBookIdAndType(exerciseBookId, type);
            if (kmtExerciseBookCount == null) {
                kmtExerciseBookCount = new KmtExerciseBookCount();
                kmtExerciseBookCount.setExerciseBookId(exerciseBookId);
                kmtExerciseBookCount.setBookId(kmtExerciseBook.getBookId());
                kmtExerciseBookCount.setBookName(kmtExerciseBook.getBookName());
                kmtExerciseBookCount.setCourseName(kmtExerciseBook.getCourseName());
                kmtExerciseBookCount.setGrade(kmtExerciseBook.getGrade());
                kmtExerciseBookCount.setSemester(kmtExerciseBook.getSemester());
                kmtExerciseBookCount.setVersion(kmtExerciseBook.getVersion());
                kmtExerciseBookCount.setBookType(kmtExerciseBook.getBookType());
                kmtExerciseBookCount.setType(type);
                kmtExerciseBookCount.setCreateTime(now);
            }
            kmtExerciseBookCount.setUserId(userId);
            kmtExerciseBookCount.setUnprocessedCount((int) unprocessedCount);
            kmtExerciseBookCount.setRepulseCount((int) repulseCount);
            kmtExerciseBookCount.setProcessedCount((int) processedCount);
            kmtExerciseBookCount.setUnfinishedUnitCount(unfinishedUnitCount);
            kmtExerciseBookCount.setTotalUnitCount(totalUnitCount);
            kmtExerciseBookCount.setBookStatus(bookStatus);
            kmtExerciseBookCount.setAccuracy((int) accuracy);
            kmtExerciseBookCount.setUpdateTime(now);
            kmtExerciseBookCountList.add(kmtExerciseBookCount);

            return kmtExerciseBookCount;
        } catch (Exception e) {
            logger.error("kmtExerciseBookCountList={}", kmtExerciseBookCountList);
            logger.error("插入或更新异常", e);
        }

        return null;
    }

    @Override
    public ResponseEntity findTeacherStatusDetail(TeacherInfoStatusDetailReq req) {
        ResponseEntity responseEntity = new ResponseEntity();

        TeacherInfoStatusDetailDTO teacherInfoStatusDetailDTO = libManagerMapper.findTeacherStatusDetail(req.getTeacherId());
        if (teacherInfoStatusDetailDTO == null) {
            responseEntity.failure("老师不存在");
        }

        return responseEntity.success(teacherInfoStatusDetailDTO, "查询成功");
    }


    @Override
    public ResponseEntity findOrgRecordRateList(KmtExerciseBookLibReq req) {
        ResponseEntity responseEntity = new ResponseEntity();
        Map<String, Object> data = new HashMap<>();
        List<ExerciseBookAndLibExportDto> list0=new ArrayList<>();
        String key=null;
        if("语文".equals(req.getSubject())){
             key="yuwen"+DateUtil.format_yyyyMMdd(new Date());
        }
        if("数学".equals(req.getSubject())){
             key="shuxue"+DateUtil.format_yyyyMMdd(new Date());
        }
        if("英语".equals(req.getSubject())){
             key="yingyu"+DateUtil.format_yyyyMMdd(new Date());
        }
        if(redisUtil.exists(key)){
            String result = redisUtil.get(key);
            List<ExerciseBookAndLibExportDto> list = JSON.parseArray(result, ExerciseBookAndLibExportDto.class);
            Paging paging = Paging.pagination(list.size(), req.getPageSize(), req.getPageNo());
            int fromIndex = paging.getQueryIndex();
            int toIndex = 0;
            if (fromIndex + paging.getPageSize() >= list.size()) {
                toIndex = list.size();
            } else {
                toIndex = fromIndex + paging.getPageSize();
            }
            list0=new ArrayList<>(list.subList(fromIndex, toIndex));
            data.put("total", (int) paging.getTotalNum());
            data.put("pages", paging.getTotalPage());
        }else {
            data.put("total", 0);
            data.put("pages", 0);
        }
        data.put("pageNo", req.getPageNo());
        data.put("pageSize", req.getPageSize());
        data.put("list", list0);
        return responseEntity.success(data, "成功");
    }


    @Override
    public ResponseEntity uploadForm(String userId, int type, List<MultipartFile> files) {
        //0: 随机文件； 1: 练习册分配表格； 2：kmt分配表格； 3：练习册导入文件； 4：练习册表格
        ResponseEntity responseEntity = new ResponseEntity();
        List<FileInfo> fileInfos = null;
        if (type > 0){
            fileInfos = uploadFormByType(userId, type, files);
        } else {
            fileInfos = fileInfoService.uploadFilePicture(userId,files);
        }
        if (files.size() == fileInfos.size()) {
            Map<String, Object> data = new HashMap<String, Object>();
            data.put("pics", fileInfos);
            responseEntity.success(data, "上传图片成功 ");
        } else {
            responseEntity.failure(ResponseConstant.CODE_000, "上传图片失败");
        }

        return responseEntity;
    }

    /**
     * 上传文件 1: 练习册分配表格； 2：kmt分配表格； 3：练习册导入文件； 4：练习册表格
     * @param userId
     * @param type
     * @return
     */
    private List<FileInfo> uploadFormByType (String userId, int type, List<MultipartFile> fileList){
        String dir;
        switch (type){
            case 1: dir = "/www/files/data/upload/bak/exercise/distribute-teacher/exercise/teacher/"; break;
            case 2: dir = "/www/files/data/upload/bak/exercise/distribute-teacher/kmt-questions/teacher/"; break;
            case 3: dir = "/www/files/data/upload/bak/exercise/import-exercise/temp/"; break;
            case 4: dir = "/www/files/data/upload/bak/exercise/import-exercise/exercise_book_list/"; break;
            default: dir = "/www/files/data/upload/bak/exercise/import-exercise/temp/"; break;
        }
        String[] filePaths = new String[fileList.size()];
        String[] fileNames = new String[fileList.size()];
        String[] fileCodes = new String[fileList.size()];
        MultipartFile fileItem;
        for (int i = 0; i < fileList.size(); i++) {
            fileItem = fileList.get(i);
            //图片保存文件名
            filePaths[i] = dir + IdWorker.generateId() + "-" + fileItem.getOriginalFilename();
            fileNames[i] = fileItem.getOriginalFilename();
            ImageTools.uploadFile(filePaths[i], fileItem);
        }
        List<FileInfo> fileInfoList = new ArrayList<>();
        if (filePaths != null && filePaths.length > 0){
            fileInfoList = fileInfoService.saveFilePicture(userId, filePaths, fileNames);
        }
        return fileInfoList;
    }

    @Override
    public ResponseEntity findExerciseList(ExerciseListReq req) {
        ResponseEntity responseEntity = new ResponseEntity();
        com.baomidou.mybatisplus.extension.plugins.pagination.Page page = null;
        if (req.getPageNo() != null && req.getPageSize() != null) {
            page = new com.baomidou.mybatisplus.extension.plugins.pagination.Page(req.getPageNo(), req.getPageSize());
        }else{
            page = new com.baomidou.mybatisplus.extension.plugins.pagination.Page(1, Integer.MAX_VALUE);
        }
        Map<String, Object> params = new HashMap<>(16);
        //params.put("bookType", "in (0,1,3)");
        params.put("progress", req.getProgress());
        params.put("subject", req.getSubject());
        params.put("grade", req.getGrade());
        params.put("bookName", req.getBookName());
        params.put("versionName", req.getVersionName());
        params.put("semester", req.getSemester());
        params.put("bookType", req.getBookType());
        params.put("bookYear", req.getBookYear());

        List<Exercise1Dto> list = kmtExerciseMapper.findExerciseList(page, params);
        Map<String, Object> resultMap = new HashMap<>(16);
        resultMap.put("pageNo", page.getCurrent());
        resultMap.put("pageSize", page.getSize());
        resultMap.put("pages", page.getPages());
        resultMap.put("total", page.getTotal());
        resultMap.put("list", list);
        return responseEntity.success(resultMap, "成功");
    }

    @Override
    public ResponseEntity addOrEditExerciseBook(AddOrEditExerciseReq req, String userId) {
        ResponseEntity responseEntity = new ResponseEntity();
        KmtExerciseBook exerciseBook;
        boolean existsBook = kmtExerciseBookService.findSameBook(req.getBookName(), req.getGrade(), req.getSubject(), req.getSemester(), req.getVersion(), req.getUseYear(), req.getBookType()) != null ? true : false;
        //存在修改
        boolean existsModify = true;
        Date now = new Date();
        //机构数
        int orgNums = 0;
        if (StringUtil.isNotBlank(req.getExerciseBookId())) {
            exerciseBook = kmtExerciseBookService.getById(req.getExerciseBookId());
            existsModify = !(req.getBookName().equals(exerciseBook.getBookName()) && req.getGrade().equals(exerciseBook.getGrade())
                    && req.getSemester() == exerciseBook.getSemester() && req.getVersion() == exerciseBook.getVersion()
                    && req.getUseYear() == exerciseBook.getBookYear() && req.getBookType() == exerciseBook.getBookType());
        } else {
            exerciseBook = new KmtExerciseBook();
            exerciseBook.setCreateTime(now);
            exerciseBook.setPartFlag(3);
            exerciseBook.setBookId(IdWorker.generateId());
        }
        if (existsBook && existsModify) {
            return responseEntity.failure("此练习册系统已有，请查对后重试");
        }
        exerciseBook.setUrl1(req.getUrl1());
        exerciseBook.setUrl2(req.getUrl2());
        exerciseBook.setBookName(req.getBookName());
        exerciseBook.setPress(req.getPress());
        exerciseBook.setCourseName(req.getSubject());
        exerciseBook.setGrade(req.getGrade());
        exerciseBook.setVersion(req.getVersion());
        exerciseBook.setVersionName(req.getVersionName());
        exerciseBook.setSemester(req.getSemester());
        exerciseBook.setPrintYear(req.getPrintYear());
        exerciseBook.setBookYear(req.getUseYear());
        exerciseBook.setProgress(req.getProgress());
        exerciseBook.setBookType(req.getBookType());
        exerciseBook.setTotalGradePriority(req.getPriority());
        exerciseBook.setAssignedBatch(req.getAssignedBatch());
        //编辑人
        User user = userService.getById(userId);
        exerciseBook.setUserId(userId);
        exerciseBook.setUpdatedTime(now);
        exerciseBook.setUserName(user.getUserName());
        //关联机构列表
        List<KmtExerciseBookLib> exerciseLibList = KmtExerciseBookLibService.findByExerciseBookId(req.getExerciseBookId());
        if (CollectionUtils.isNotEmpty(exerciseLibList)) {
            //软删除
            exerciseLibList.forEach(e -> e.setIsDelete(1));
            KmtExerciseBookLibService.save(exerciseLibList);
        }
        if (CollectionUtils.isNotEmpty(req.getLibList())) {
            orgNums = req.getLibList().size();
        }
        exerciseBook.setOrgNums(orgNums);
        kmtExerciseBookService.save(exerciseBook);
        if (orgNums > 0) {
            exerciseBook.setOrgNums(req.getLibList().size());
            req.getLibList().forEach(libId -> {
                KmtExerciseBookLib exerciseBookLib = new KmtExerciseBookLib();
                exerciseBookLib.setExerciseBookId(exerciseBook.getId());
                exerciseBookLib.setLibId(libId);
                KmtExerciseBookLibService.save(exerciseBookLib);
                //实时将统计数据记录到库
                kmtExerciseLibPriorityService.deleteOrgCountByLibIdAndSubject(libId,req.getSubject());
                        List<KmtExerciseBookLibDto> list=kmtExerciseMapperService.findOrgCount(libId,req.getSubject());
                        int totalCount=(int)list.stream().filter(a->!Objects.equals("未购买",a.getProgress())).count();
                        int recogeCount=(int)list.stream().filter(a->Objects.equals("已发布",a.getProgress())).count();
                        int unrecogeCount=(int)list.stream().filter(a->!Objects.equals("未购买",a.getProgress())&&!Objects.equals("已发布",a.getProgress())).count();
                        int unPurchaseCount=(int)list.stream().filter(a->Objects.equals("未购买",a.getProgress())).count();
                        KmtExerciseLibPriority kmtExerciseLibPriority=new KmtExerciseLibPriority();
                        kmtExerciseLibPriority.setLibId(libId);
                        kmtExerciseLibPriority.setSubject(req.getSubject());
                        kmtExerciseLibPriority.setRecogeNum(recogeCount);
                        kmtExerciseLibPriority.setTotalNum(totalCount);
                        kmtExerciseLibPriority.setUnrecogeNum(unrecogeCount);
                        kmtExerciseLibPriority.setUnpurchaNum(unPurchaseCount);
                        String chineseRecogeRate="0.00%";
                if(0!=totalCount){
                    chineseRecogeRate=new BigDecimal(recogeCount).multiply(new BigDecimal(100)).divide(new BigDecimal(totalCount),2,BigDecimal.ROUND_HALF_UP) +"%";
                }
                 kmtExerciseLibPriority.setRecogeRate(chineseRecogeRate);
                kmtExerciseLibPriorityService.save(kmtExerciseLibPriority);

            });
        }
        Map<String, Object> resultMap = new HashMap<>(16);
        resultMap.put("exerciseBookId", exerciseBook.getId());
        return responseEntity.success(resultMap, "成功");
    }

    @Override
    public ResponseEntity findExerciseDetail(ExerciseDetailReq req){
        ResponseEntity responseEntity = new ResponseEntity();
        KmtExerciseBook exerciseBook = kmtExerciseBookService.getById(req.getExerciseBookId());
        Exercise2Dto dto = new Exercise2Dto();
        dto.setUrl1(exerciseBook.getUrl1());
        dto.setUrl2(exerciseBook.getUrl2());
        dto.setBookName(exerciseBook.getBookName());
        dto.setPress(exerciseBook.getPress());
        dto.setSubject(exerciseBook.getCourseName());
        dto.setGrade(exerciseBook.getGrade());
        dto.setVersion(exerciseBook.getVersion());
        dto.setVersionName(exerciseBook.getVersionName());
        dto.setSemester(exerciseBook.getSemester());
        dto.setPrintYear(exerciseBook.getPrintYear());
        dto.setUseYear(exerciseBook.getBookYear()+"");
        dto.setStatus(exerciseBook.getStatus());
        dto.setProgress(exerciseBook.getProgress());
        dto.setPriority(exerciseBook.getTotalGradePriority());
        dto.setIdentifiedNums(exerciseBook.getIdentifiedNums());
        dto.setEditName(exerciseBook.getUserName());
        dto.setBookType(exerciseBook.getBookType());
        dto.setUpdateTime(exerciseBook.getUpdatedTime() != null ? DateHelper.format(exerciseBook.getUpdatedTime(), "yyyy-MM-dd HH:mm:ss") : null);
        //机构相关
        List<KmtExerciseBookLib> exerciseLibList = KmtExerciseBookLibService.findByExerciseBookId(req.getExerciseBookId());
        List<Exercise2Dto.Library> libraryList = new ArrayList<>();
        exerciseLibList.forEach(e -> {
            Exercise2Dto.Library library = dto.new Library();
            TbLibJoin libJoin = libJoinService.getById(e.getLibId());
            if (libJoin != null) {
                library.setLibId(libJoin.getId());
                library.setLibName(libJoin.getLeagueName());
            }
            libraryList.add(library);
        });
        dto.setLibList(libraryList);
        return responseEntity.success(dto, "成功");
    }

    @Override
    public ResponseEntity findLibList(FindLibReq req){
        ResponseEntity responseEntity = new ResponseEntity();
        com.baomidou.mybatisplus.extension.plugins.pagination.Page page = null;
        if (req.getPageNo() != null && req.getPageSize() != null) {
            page = new com.baomidou.mybatisplus.extension.plugins.pagination.Page(req.getPageNo(), req.getPageSize());
        }
        Map<String,Object> params = new HashMap<>(16);
        params.put("name",req.getName());
        List<TbLibJoin> list = kmtExerciseMapper.findLibList(page, params);
        List<LibraryDto> dtoList = new ArrayList<>();
        list.forEach(e -> {
            LibraryDto dto = new LibraryDto();
            dto.setLibId(e.getId());
            dto.setLibName(e.getLeagueName());
            dtoList.add(dto);
        });
        Map<String, Object> resultMap = new HashMap<>(16);
        if (page != null) {
            resultMap.put("pageNo", page.getCurrent());
            resultMap.put("pageSize", page.getSize());
            resultMap.put("pages", page.getPages());
            resultMap.put("total", page.getTotal());
        } else {
            resultMap.put("pageNo", 0);
            resultMap.put("pageSize", 0);
            resultMap.put("pages", 0);
            resultMap.put("total", list.size());
        }
        resultMap.put("list", dtoList);
        return responseEntity.success(resultMap, "成功");
    }

    @Override
    public ResponseEntity findPressList() {
        ResponseEntity responseEntity = new ResponseEntity();
        String key = "exercise_press";
        Map<String, Object> resultMap = new HashMap<>(16);
        List<String> list = tokenManager.getList(key, String.class);
        if (list == null || list.size() == 0) {
            Config config = configService.findConfigByParamCode(key);
            tokenManager.setString(key, config.getParamVal());
            list = tokenManager.getList(key, String.class);
        }
        resultMap.put("list", list);
        return responseEntity.success(resultMap, "成功");
    }

    @Override
    public int refreshExerciseBookCount(List<String> selectedExerciseBookIdList) {
        int offset = 0;
        int pageSize = 500;
        int updateCount = 0;

        List<KmtExerciseBook> kmtExerciseBookList;
        List<KmtExerciseBook> tempKmtExerciseBookList;
        KmtExerciseBook kmtExerciseBook;
        int status;
        int dataStatus;
        Map<String, List<KmtExerciseBook>> listMap;
        Set<String> exerciseBookIdSet;
        SearchRequest searchRequest = null;
        SearchResponse searchResponse;
        ParsedStringTerms groupByExerciseBookId;
        ParsedSum parsedSum;
        StringBuilder statusSb = new StringBuilder();
        do {
            kmtExerciseBookList = kmtExerciseMapper.findAllExerciseBookPage(selectedExerciseBookIdList, offset, pageSize);

            if (kmtExerciseBookList.isEmpty()) {
                break;
            }

            if (searchRequest == null) {
                // es统计练习册题目状态
                searchRequest = new SearchRequest("kmt_exercise_questions");
                searchRequest.source(SearchSourceBuilder.searchSource());
                searchRequest.source()
                        .aggregation(AggregationBuilders.terms("group_by_exerciseBookId")
                                .field("exerciseBookId.keyword")
                                .size(pageSize)
                                .subAggregation(AggregationBuilders.sum(ExerciseBookStatusEnum.Repulse2AI.getName())
                                        .script(new Script("if(doc['dealStatus'].value == 2){return 1}else{return 0}")))
                                .subAggregation(AggregationBuilders.sum(ExerciseBookStatusEnum.Processing.getName())
                                        .script(new Script("if(doc['dealStatus'].value == 0){return 1}else{return 0}")))
                                .subAggregation(AggregationBuilders.sum(ExerciseBookStatusEnum.Repulse2Process.getName())
                                        .script(new Script("if(doc['dealStatus'].value == 1){return 1}else{return 0}")))
                                .subAggregation(AggregationBuilders.sum(ExerciseBookStatusEnum.Auditing.getName())
                                        .script(new Script("if(doc['dealStatus'].value == 3){return 1}else{return 0}")))
                                .subAggregation(AggregationBuilders.sum(ExerciseBookStatusEnum.Repulse2Audit.getName())
                                        .script(new Script("if(doc['dealStatus'].value == 7){return 1}else{return 0}")))
                                .subAggregation(AggregationBuilders.sum(ExerciseBookStatusEnum.QuestionPublished.getName())
                                        .script(new Script("if(doc['dealStatus'].value == 4){return 1}else{return 0}")))
                                .subAggregation(AggregationBuilders.sum(ExerciseBookStatusEnum.AnalysisProcessing.getName())
                                        .script(new Script("if(doc['dealStatus'].value == 5){return 1}else{return 0}")))
                                .subAggregation(AggregationBuilders.sum(ExerciseBookStatusEnum.Repulse2AnalysisProcessing.getName())
                                        .script(new Script("if(doc['dealStatus'].value == 8){return 1}else{return 0}")))
                                .subAggregation(AggregationBuilders.sum(ExerciseBookStatusEnum.AnalysisAuditing.getName())
                                        .script(new Script("if(doc['dealStatus'].value == 9){return 1}else{return 0}")))
                                .subAggregation(AggregationBuilders.sum(ExerciseBookStatusEnum.Repulse2AnalysisAuditing.getName())
                                        .script(new Script("if(doc['dealStatus'].value == 10){return 1}else{return 0}")))
                                .subAggregation(AggregationBuilders.sum(ExerciseBookStatusEnum.AnalysisPublished.getName())
                                        .script(new Script("if(doc['dealStatus'].value == 11){return 1}else{return 0}"))));
            }

            // 查询每本练习册更新，加工状态
            listMap = kmtExerciseBookList.stream().collect(Collectors.groupingBy(KmtExerciseBook::getId));
            exerciseBookIdSet = kmtExerciseBookList.stream()
                    .map(KmtExerciseBook::getId)
                    .collect(Collectors.toSet());
            searchRequest.source()
                    .query(QueryBuilders.boolQuery()
                            .filter(new TermsQueryBuilder("exerciseBookId.keyword", exerciseBookIdSet)));
            searchResponse = baseSearchService.search(searchRequest, null);
            if (searchResponse != null) {
                // 解析es查询结果
                groupByExerciseBookId = searchResponse.getAggregations().get("group_by_exerciseBookId");
                String exerciseBookId;
                for (Terms.Bucket groupByExerciseBookIdBucket : groupByExerciseBookId.getBuckets()) {
                    exerciseBookId = groupByExerciseBookIdBucket.getKeyAsString();
                    if (StringUtils.isBlank(exerciseBookId)) {
                        continue;
                    }
                    tempKmtExerciseBookList = listMap.get(exerciseBookId);
                    if (CollectionUtils.isEmpty(tempKmtExerciseBookList)) {
                        continue;
                    }
                    kmtExerciseBook = tempKmtExerciseBookList.get(0);
                    if (kmtExerciseBook == null) {
                        continue;
                    }

                    for (Aggregation aggregation : groupByExerciseBookIdBucket.getAggregations().asList()) {
                        parsedSum = (ParsedSum) aggregation;
                        dataStatus = parsedSum.getValue() > 0 ? 1 : 0;
                        status = this.saveOrUpdateKmtExerciseBookStatusCount(parsedSum.getName(), dataStatus, kmtExerciseBook);
                        updateCount ++;
                        if (dataStatus == 1) {
                            if (statusSb.length() > 0) {
                                statusSb.append(",");
                            }
                            statusSb.append(status);
                        }
                    }
                    kmtExerciseBookService.updateExerciseBookStatus(exerciseBookId, statusSb.toString());
                    statusSb = new StringBuilder();
                }
            }

            offset += pageSize;
        } while (kmtExerciseBookList.size() >= pageSize);

        return updateCount;
    }

    @Override
    public ResponseEntity findExerciseBookCount() {
        ResponseEntity responseEntity = new ResponseEntity();
        return responseEntity.success(Collections.singletonMap("list", kmtExerciseMapper.findExerciseBookCount()), "成功");
    }

    @Override
    public ResponseEntity findExerciseBookCountSubjectDetail(ExerciseBookCountSubjectDetailReq req) {
        ResponseEntity responseEntity = new ResponseEntity();

        IPage<ExerciseBookCountSubjectDetailDTO> page =
                new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(req.getPageNo(), req.getPageSize());
        page = kmtExerciseMapper.findExerciseBookCountSubjectDetail(page, req);

        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("pageNo", page.getCurrent());
        resultMap.put("pageSize", page.getSize());
        resultMap.put("pages", page.getPages());
        resultMap.put("total", page.getTotal());
        resultMap.put("list", page.getRecords());

        return responseEntity.success(resultMap, "成功");
    }

    /**
     * 保存或更新练习册状态统计数据
     *
     * @param statusName 状态名
     * @param dataStatus 数据状态（0无效，1有效）
     * @param kmtExerciseBook 练习册
     *
     * @return 练习册状态
     */
    private int saveOrUpdateKmtExerciseBookStatusCount(String statusName, int dataStatus, KmtExerciseBook kmtExerciseBook) {
        int status = ExerciseBookStatusEnum.getCodeByName(statusName);
        KmtExerciseBookStatusCount kmtExerciseBookStatusCount =
                kmtExerciseMapper.findKmtExerciseBookStatusCountByExerciseBookIdAndStatus(kmtExerciseBook.getId(), status);
        if (kmtExerciseBookStatusCount == null) {
            kmtExerciseBookStatusCount = new KmtExerciseBookStatusCount();
            kmtExerciseBookStatusCount.setCreateTime(new Date());
        }
        kmtExerciseBookStatusCount.setExerciseBookId(kmtExerciseBook.getId());
        kmtExerciseBookStatusCount.setBookId(kmtExerciseBook.getBookId());
        kmtExerciseBookStatusCount.setBookName(kmtExerciseBook.getBookName());
        kmtExerciseBookStatusCount.setBookYear(kmtExerciseBook.getBookYear());
        kmtExerciseBookStatusCount.setCourseName(kmtExerciseBook.getCourseName());
        kmtExerciseBookStatusCount.setStatus(status);
        kmtExerciseBookStatusCount.setDataStatus(dataStatus);

        pagingHibernateJdbcDao.batchUpdate(Collections.singletonList(kmtExerciseBookStatusCount));

        return status;
    }

    @Override
    public List<ExerciseBookAndLibExportDto> findAllExportExerciseLib(String subject){
        List<ExerciseBookAndLibExportDto> list0=new ArrayList<>();
        List<Map<String,Object>> list=kmtExerciseMapper.findAllExportLib(subject);
        if(CollectionUtils.isNotEmpty(list)){
            list.forEach(it->{
                ExerciseBookAndLibExportDto exerciseBookAndLibExportDto=new ExerciseBookAndLibExportDto();
                Map<String,Object> map=new HashMap<>();
                String leagueLet=it.get("leagueLet").toString();
                String leagueLng=it.get("leagueLng").toString();
                Map addressMap = MapUtils.regeoByAmapApi(Double.valueOf(leagueLng), Double.valueOf(leagueLet));
                String address=addressMap.get("address").toString();
                String leagueName=it.get("leagueName").toString();
                int signService=Integer.parseInt(it.get("signService").toString());
                List<KmtExerciseBookLibDto>list1=kmtExerciseMapper.findAllExerciseBook(it.get("libId").toString(),subject);
                Map<String,List<KmtExerciseBookLibDto>> map1=list1.stream().collect(Collectors.groupingBy(p->p.getExerciseName()+"_"+p.getVersion()+"_"+p.getSemester()+"_"+p.getPriority()));
                List<KmtExerciseLibExportDto> exportList=    map1.keySet().stream().map(key->{
                    String [] u=key.split("_");
                    String exerciseName=u[0];
                    String version=u[1];
                    String semester=u[2];
                    String priority=u[3];
                   if(Objects.equals(priority,"null")){
                       priority="";
                   }
                    KmtExerciseLibExportDto kmt=new KmtExerciseLibExportDto();
                    kmt.setExerciseName(exerciseName);
                    kmt.setVersion(version);
                    kmt.setSemester(semester);
                    kmt.setPriority(priority);
                    List<KmtExerciseBookLibDto> exerciseBookLibDtos=map1.get(key);
                    kmt=this.getKmtList(exerciseBookLibDtos,exerciseName,version,semester,priority);
                    return kmt;
                }).collect(Collectors.toList());
                long totalCount=list1.stream().filter(a->!Objects.equals("未购买",a.getProgress())).count();
                long recogeCount=list1.stream().filter(a->Objects.equals("已发布",a.getProgress())).count();
                long unrecogeCount=list1.stream().filter(a->!Objects.equals("未购买",a.getProgress())&&!Objects.equals("已发布",a.getProgress())).count();
                long unPurchaseCount=list1.stream().filter(a->Objects.equals("未购买",a.getProgress())).count();
                String chineseRecogeRate="0.00%";
                if(0!=totalCount){
                    chineseRecogeRate=new BigDecimal(recogeCount).multiply(new BigDecimal(100)).divide(new BigDecimal(totalCount),2,BigDecimal.ROUND_HALF_UP) +"%";
                }
                exerciseBookAndLibExportDto.setLibName(leagueName);
                exerciseBookAndLibExportDto.setLibArea(address);
                exerciseBookAndLibExportDto.setSignService(signService);
                exerciseBookAndLibExportDto.setTotalCount(totalCount);
                exerciseBookAndLibExportDto.setRecogeCount(recogeCount);
                exerciseBookAndLibExportDto.setUnrecogeCount(unrecogeCount);
                exerciseBookAndLibExportDto.setUnPurchaseCount(unPurchaseCount);
                exerciseBookAndLibExportDto.setChineseRecogeRate(chineseRecogeRate);
                exerciseBookAndLibExportDto.setLibExportDtoList(exportList);
                list0.add(exerciseBookAndLibExportDto);
            });
        }
        List<ExerciseBookAndLibExportDto>list1= list0.stream().collect(Collectors.collectingAndThen( Collectors.toCollection(() -> new TreeSet<>(
                Comparator.comparing(
                        ExerciseBookAndLibExportDto::getLibName))), ArrayList::new));
        return list1;
    }


    private KmtExerciseLibExportDto getKmtList(List<KmtExerciseBookLibDto> list, String exerciseName, String version, String semester, String priority){
        KmtExerciseLibExportDto dto=new KmtExerciseLibExportDto();
        list.forEach(it->{
            String grade=it.getGrade();
            String progress=it.getProgress();
            if(Objects.equals("一年级",grade)){
                dto.setGradeOne(progress);
            }
            if(Objects.equals("二年级",grade)){
                dto.setGradeTwo(progress);
            }
            if(Objects.equals("三年级",grade)){
                dto.setGradeThree(progress);
            }
            if(Objects.equals("四年级",grade)){
               dto.setGradeFour(progress);
            }
            if(Objects.equals("五年级",grade)){
                dto.setGradeFive(progress);
            }
            if(Objects.equals("六年级",grade)){
              dto.setGradeSix(progress);
            }


        });
        dto.setExerciseName(exerciseName);
        dto.setVersion(version);
        dto.setSemester(semester);
        dto.setPriority(priority);
        return dto;

    }

    /*@Override
    public String getPriority(){
        //查询所有的练习册及其关联到的馆
        List<ExercisePriorityDto> list= kmtExerciseMapper.findLibSignCount();
        Map<String,IntSummaryStatistics> list1=list.stream().collect(Collectors.groupingBy(ExercisePriorityDto::getExerciseBookId,Collectors.summarizingInt(ExercisePriorityDto::getSignService)));
        list1.forEach((key,value)->{
            int totalNum=(int)value.getSum();
            kmtExerciseMapper.updateKmtExerciseBookByExerciseBookId(totalNum,key);
        });
        List<KmtExerciseBook> list2=kmtExerciseMapper.findAllExerciseBookBySignNum();
        Map<String,List<KmtExerciseBook>> map0=list2.stream()
                .collect(Collectors.groupingBy(p->p.getBookName()+"_"+p.getVersionName()+"_"+p.getSemester()+"_"+p.getCourseName()));
        Map<String,Integer> map1=list2.stream()
                .collect(Collectors.groupingBy(p->p.getBookName()+"_"+p.getVersionName()+"_"+p.getSemester()+"_"+p.getCourseName(),
                        LinkedHashMap::new, Collectors.summingInt(a->a.getExerciseRelevancyNum())));
        Map<String, Integer> result = new LinkedHashMap<>();
        map1.entrySet().stream()
                .sorted(Map.Entry.<String, Integer>comparingByValue()
                        .reversed()).forEachOrdered(e -> result.put(e.getKey(), e.getValue()));
        String [] str1=result.keySet().toArray(new String[map0.keySet().size()]);
        BigDecimal db1=new BigDecimal(result.size());
        Map<String,String> priorityMap=new HashMap<>();
        result.keySet().forEach(b->{
            List<KmtExerciseBook> list4=map0.get(b);
            String priority;
            int index1=this.searchEle1(str1,b);
            if(0==index1){
                priority="P0";
                priorityMap.put(b,priority);
            }else {
                int sum=result.get(b);
                BigDecimal db3=new BigDecimal(index1);
                if(sum==result.get(str1[index1-1])){
                    priority=priorityMap.get(str1[index1-1]);
                    priorityMap.put(b,priority);
                }else {
                    BigDecimal db4=db3.divide(db1,2,BigDecimal.ROUND_HALF_UP);
                    priority=this.getPriorityByPercent(db4);
                    priorityMap.put(b,priority);
                }

            }
            list4.forEach(m->{

                String id=m.getId();
                kmtExerciseMapper.updateKmtExerciseBookByPriority(priority,id);
            });
        });
        return null;
    }*/

    @Override
    public ResponseEntity findEnterTeacherList(FindKmtTeacherListReq req) {
        ResponseEntity responseEntity = new ResponseEntity();
        com.baomidou.mybatisplus.extension.plugins.pagination.Page page = new com.baomidou.mybatisplus.extension.plugins.pagination.Page(req.getPageNo(), req.getPageSize());
        List<ExerciseTeacherDTO> list = libManagerMapper.findKmtTeacherList(req.getSubject(), "7", 5, req.getTeacherName(), page);
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("pageNo", page.getCurrent());
        resultMap.put("pageSize", page.getSize());
        resultMap.put("pages", page.getPages());
        resultMap.put("total", page.getTotal());
        resultMap.put("list", list);

        return responseEntity.success(resultMap, "查询成功");
    }

    @Override
    public ResponseEntity findEnterTeacherDetails(FindKmtTeacherDetailReq req) {
        ResponseEntity responseEntity = new ResponseEntity();
        com.baomidou.mybatisplus.extension.plugins.pagination.Page page = new com.baomidou.mybatisplus.extension.plugins.pagination.Page(req.getPageNo(), req.getPageSize());
        List<KmtTeacherDetailDto> list = kmtQuestionMapper.findKmtTeacherDetails(req.getTeacherId(), req.getDetailName(), 6, page);
        list.forEach(item -> {
            item.setVersionName(knowledgeVersion.getVersionNameBySubjectAndVersionNum(item.getCourseName(), item.getVersionType()));
        });
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("pageNo", page.getCurrent());
        resultMap.put("pageSize", page.getSize());
        resultMap.put("pages", page.getPages());
        resultMap.put("total", page.getTotal());
        resultMap.put("list", list);
        return responseEntity.success(resultMap, "查询成功");
    }

    @Override
    public ResponseEntity findCheckTeacherList(FindCheckTeacherListReq req) {
        req.setType(8);
        return  findTeacherListByType(req);
    }

    @Override
    public ResponseEntity findTeacherListByType(FindCheckTeacherListReq req) {
        ResponseEntity responseEntity = new ResponseEntity();
        com.baomidou.mybatisplus.extension.plugins.pagination.Page page = new com.baomidou.mybatisplus.extension.plugins.pagination.Page(req.getPageNo(), req.getPageSize());
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("teacherList", libManagerMapper.findCheckTeacherList(req.getTeacherName(), req.getType(), req.getSubjects(), page));
        resultMap.put("pageNo", page.getCurrent());
        resultMap.put("pageSize", page.getSize());
        resultMap.put("pages", page.getPages());
        resultMap.put("total", page.getTotal());
        return responseEntity.success(resultMap, "查询成功");
    }

    @Override
    public ResponseEntity allotCheckTeacher(AllotCheckTeacherReq req) {
        ResponseEntity responseEntity = new ResponseEntity();
        if(CollectionUtils.isNotEmpty(req.getExerciseBookIdList())) {
            //更新练习册表答案校对员id
            kmtExerciseBookService.updateAnswerCorrecterIdByIds(req.getTeacherId(),req.getExerciseBookIdList());
            //异步更新练习册题目表答案校对员id
            ExerciseTeacherClassRequest request = new ExerciseTeacherClassRequest();
            request.setTeacherId(req.getTeacherId());
            request.setType(8);
            ThreadPool.getInstance().addTask(new UpdateExerciseQuestionThreadTask(Collections.singletonList(request), req.getExerciseBookIdList(), kmtExerciseQuestionService));
            //更新练习册题目表答案校对员id
            //kmtExerciseQuestionService.updateAnswerCorrecterIdByExerciseBookIds(req.getTeacherId(),req.getExerciseBookIdList());
            //kmtExerciseQuestionService.bulkBookExerciseQuestions(req.getExerciseBookIdList());
        }
        return responseEntity.success();
    }

    @Override
    public ResponseEntity findAnswerProofreadExerciseBookList(AnswerProofreadExerciseBookListReq req) {
        ResponseEntity responseEntity = new ResponseEntity();

        IPage<AnswerProofreadExerciseBookDTO> page =
                new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(req.getPageNo(), req.getPageSize());
        page = kmtExerciseMapper.findAnswerProofreadExerciseBookList(page, req);

        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("pageNo", page.getCurrent());
        resultMap.put("pageSize", page.getSize());
        resultMap.put("pages", page.getPages());
        resultMap.put("total", page.getTotal());
        resultMap.put("bookList", page.getRecords());

        return responseEntity.success(resultMap, "成功");
    }

    @Override
    public ResponseEntity findAnswerProofreadQuestionList(AnswerProofreadQuestionListReq req) {
        ResponseEntity responseEntity = new ResponseEntity();

        IPage<ExerciseQuetionDto> page =
                new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(req.getPageNo(), req.getPageSize());
        page = kmtExerciseMapper.findQuestionListAnswerWrong(page, req);
        //从文件读取大字段
        List<ExerciseQuetionDto> records = page.getRecords();
        kmtExerciseService.appendQuestionDtoDataFromJSONFile(records);
        List<ExerciseBookCourseClassDto> exerciseBookCourseClassDtoList =
                kmtExerciseQuestionService.getQuestionGroupList(records, true);

        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("pageNo", page.getCurrent());
        resultMap.put("pageSize", page.getSize());
        resultMap.put("pages", page.getPages());
        resultMap.put("total", page.getTotal());
        resultMap.put("list", exerciseBookCourseClassDtoList);

        return responseEntity.success(resultMap, "成功");
    }

    //获取数组中某个元素的位置
     private int searchEle(Integer[] arr,Integer target){
         for(int i = 0;i<arr.length;i++){
        if(arr[i]==target){
        return i; }
        }
     return -1;
      }

    //获取数组中某个元素的位置
    private int searchEle1(String[] arr,String target){
        for(int i = 0;i<arr.length;i++){
            if(arr[i]==target){
                return i; }
        }
        return -1;
    }

    //获取数组中某个元素的位置
    private int searchEle2(Long[] arr,Long target){
        for(int i = 0;i<arr.length;i++){
            if(arr[i]==target){
                return i; }
        }
        return -1;
    }


    private int sum(Long a[], int n){
        int mun = 0;
        for (int i = 0; i < n; i++) {
            mun+=a[i];
        }
        return mun;
 }

    //通过百分比判断等级
    private String getPriorityByPercent(BigDecimal bigDecimal){
        BigDecimal db1=new BigDecimal("0.80");
        BigDecimal db2=new BigDecimal("0.50");
        BigDecimal db3=new BigDecimal("0.20");
        if(bigDecimal.compareTo(db1)==1){
            return "P3";
        }else if(bigDecimal.compareTo(db2)==1){
            return  "P2";
        }else if(bigDecimal.compareTo(db3)==1){
            return  "P1";
        }else {
            return "P0";
        }
    }

    @Override
    public ResponseEntity findUncheckedExerciseBookList(CheckExerciseBookReq req) {
        ResponseEntity responseEntity = new ResponseEntity();
        com.baomidou.mybatisplus.extension.plugins.pagination.Page page = new com.baomidou.mybatisplus.extension.plugins.pagination.Page(req.getPageNo(), req.getPageSize());
        Map<String, Object> params = new HashMap<>(16);
        params.put("proofreadStatus", "0");
        params.put("subject", req.getSubject());
        params.put("grade", req.getGrade());
        params.put("bookName", req.getBookName());
        params.put("semester", Objects.equals(req.getSemester(), 1) || Objects.equals(req.getSemester(), 2) ? req.getSemester() : null);
        List<Exercise1Dto> list = kmtExerciseMapper.findExerciseList(page, params);
        List<Exercise3Dto> exerciseDtoList = new ArrayList<>();
        list.forEach(entity -> {
            Exercise3Dto exerciseDto = new Exercise3Dto();
            exerciseDto.setBookName(entity.getBookName());
            exerciseDto.setBookType(entity.getBookType() == 3 ? 0 : entity.getBookType());
            exerciseDto.setExerciseBookId(entity.getExerciseBookId());
            exerciseDto.setGrade(entity.getGrade());
            exerciseDto.setSemester(entity.getSemester());
            exerciseDto.setSubject(entity.getSubject());
            exerciseDto.setVersionName(entity.getVersionName());
            exerciseDtoList.add(exerciseDto);
        });
        Map<String, Object> resultMap = new HashMap<>(16);
        resultMap.put("pageNo", page.getCurrent());
        resultMap.put("pageSize", page.getSize());
        resultMap.put("pages", page.getPages());
        resultMap.put("total", page.getTotal());
        resultMap.put("list", exerciseDtoList);
        return responseEntity.success(resultMap, "成功");
    }

    @Override
    public ResponseEntity findCheckExerciseBookList(CheckExerciseBookReq req) {
        ResponseEntity responseEntity = new ResponseEntity();
        com.baomidou.mybatisplus.extension.plugins.pagination.Page page = new com.baomidou.mybatisplus.extension.plugins.pagination.Page(req.getPageNo(), req.getPageSize());
        Map<String, Object> params = new HashMap<>(16);
        params.put("type", req.getType() + "");
        params.put("teacherName", req.getTeacherName());
        List<Exercise1Dto> list = kmtExerciseMapper.findTeacherExerciseList(page, params);
        List<Map<String, Object>> dtoList = new ArrayList<>();
        Map<String, List<Exercise3Dto>> exerciseMap = new LinkedHashMap<>();
        list.forEach(entity -> {
            List<Exercise3Dto> exerciseDtoList;
            String key = entity.getTeacherName() == null ? "" : entity.getTeacherName();
            if (exerciseMap.get(key) == null) {
                exerciseDtoList = new ArrayList<>();
            } else {
                exerciseDtoList = exerciseMap.get(key);
            }
            Exercise3Dto exerciseDto = new Exercise3Dto();
            exerciseDto.setBookName(entity.getBookName());
            exerciseDto.setBookType(entity.getBookType() == 3 ? 0 : entity.getBookType());
            exerciseDto.setExerciseBookId(entity.getExerciseBookId());
            exerciseDto.setGrade(entity.getGrade());
            exerciseDto.setSemester(entity.getSemester());
            exerciseDto.setSubject(entity.getSubject());
            exerciseDto.setVersionName(entity.getVersionName());
            exerciseDtoList.add(exerciseDto);
            exerciseMap.put(key, exerciseDtoList);
        });
        exerciseMap.forEach((key, value) -> {
            Map<String, Object> teacherMap = new LinkedHashMap<>();
            teacherMap.put("teacherName", key);
            teacherMap.put("bookList", value);
            dtoList.add(teacherMap);
        });

        Map<String, Object> resultMap = new HashMap<>(16);
        resultMap.put("pageNo", page.getCurrent());
        resultMap.put("pageSize", page.getSize());
        resultMap.put("pages", page.getPages());
        resultMap.put("total", page.getTotal());
        resultMap.put("teacherList", dtoList);
        return responseEntity.success(resultMap, "成功");
    }

    @Override
    public ResponseEntity findCheckedExerciseBookList(CheckedExerciseBookReq req) {
        ResponseEntity responseEntity = new ResponseEntity();
        com.baomidou.mybatisplus.extension.plugins.pagination.Page page;
        if (req.getPageNo() != null && req.getPageSize() != null) {
            page = new com.baomidou.mybatisplus.extension.plugins.pagination.Page(req.getPageNo(), req.getPageSize());
        }else{
            page = new com.baomidou.mybatisplus.extension.plugins.pagination.Page(1, Integer.MAX_VALUE);
        }
        Map<String, Object> params = new HashMap<>(16);
        params.put("type", "2");
        params.put("beginTime",req.getBeginTime());
        if(StringUtils.isNotBlank(req.getEndTime())){
            req.setEndTime(req.getEndTime()+" "+"24:00:00");
        }
        params.put("endTime",req.getEndTime());
        params.put("teacherName", req.getTeacherName());
        params.put("exerciseName", req.getExerciseName());
        List<Exercise1Dto> list = kmtExerciseMapper.findTeacherExerciseList(page, params);
        List<Exercise5Dto> exerciseDtoList = new ArrayList<>();
        list.forEach(entity -> {
            Exercise5Dto exerciseDto = new Exercise5Dto();
            exerciseDto.setBookName(entity.getBookName());
            exerciseDto.setBookType(entity.getBookType() == 3 ? 0 : entity.getBookType());
            exerciseDto.setExerciseBookId(entity.getExerciseBookId());
            exerciseDto.setGrade(entity.getGrade());
            exerciseDto.setSemester(entity.getSemester());
            exerciseDto.setSubject(entity.getSubject());
            exerciseDto.setVersionName(entity.getVersionName());
            exerciseDto.setTeacherName(entity.getTeacherName());
            exerciseDto.setCheckedTime(DateHelper.format(entity.getCheckTime(),"yyyy.MM.dd"));
            exerciseDto.setUseYear(entity.getBookYear());
            exerciseDto.setAiRollbackImport(entity.getAiRollbackImport());
            exerciseDtoList.add(exerciseDto);
        });
        Map<String, Object> resultMap = new HashMap<>(16);
        resultMap.put("pageNo", page.getCurrent());
        resultMap.put("pageSize", page.getSize());
        resultMap.put("pages", page.getPages());
        resultMap.put("total", page.getTotal());
        resultMap.put("list", exerciseDtoList);
        return responseEntity.success(resultMap, "成功");
    }

   @Override
    public List<Exercise4Dto> exportCheckExerciseBookList(CheckExerciseBookReq req){
       com.baomidou.mybatisplus.extension.plugins.pagination.Page page;
       if (req.getPageNo() != null && req.getPageSize() != null) {
           page = new com.baomidou.mybatisplus.extension.plugins.pagination.Page(req.getPageNo(), req.getPageSize());
       }else{
           page = new com.baomidou.mybatisplus.extension.plugins.pagination.Page(1, Integer.MAX_VALUE);
       }
       Map<String, Object> params = new HashMap<>(16);
       params.put("type", req.getType() + "");
       params.put("teacherName", req.getTeacherName());
       List<Exercise1Dto> list = kmtExerciseMapper.findTeacherExerciseList(page, params);
       Map<String, List<Exercise3Dto>> exerciseMap = new LinkedHashMap<>();
       list.forEach(entity -> {
           List<Exercise3Dto> exerciseDtoList;
           String key = entity.getTeacherName() == null ? "" : entity.getTeacherName();
           if (exerciseMap.get(key) == null) {
               exerciseDtoList = new ArrayList<>();
           } else {
               exerciseDtoList = exerciseMap.get(key);
           }
           Exercise3Dto exerciseDto = new Exercise3Dto();
           exerciseDto.setBookName(entity.getBookName());
           exerciseDto.setBookType(entity.getBookType() == 3 ? 0 : entity.getBookType());
           exerciseDto.setExerciseBookId(entity.getId());
           exerciseDto.setGrade(entity.getGrade());
           exerciseDto.setSemester(entity.getSemester());
           exerciseDto.setSubject(entity.getSubject());
           exerciseDto.setVersionName(entity.getVersionName());
           exerciseDtoList.add(exerciseDto);
           exerciseMap.put(key, exerciseDtoList);
       });
       List<Exercise4Dto> exercise4DtoList=new ArrayList<>();
       exerciseMap.forEach((key, value) -> {
           Exercise4Dto exercise4Dto = new Exercise4Dto();
           exercise4Dto.setTeacherName(key);
           exercise4Dto.setExercise3DtoList(value);
           exercise4DtoList.add(exercise4Dto);
       });
       return  exercise4DtoList;
   }
    @Override
    public ResponseEntity findRoleHistoryList(String userId) {
        ResponseEntity responseEntity = new ResponseEntity();
        TbLibManager teacher = managerService.findTopByUserIdAndTypeIn(userId, new int[]{17});
        if (teacher == null) {
            return responseEntity.failure("不存在该老师");
        }
        Map<String, Object> data = new HashMap<>(16);
        List<Map<String, String>> list = new ArrayList<>();
        //所有审批通过的记录
        List<TbLibManagerAudit> auditList = libManagerAuditService.findByLibManagerIdAndStatus(teacher.getId(), 1);
        auditList.forEach(e -> {
            Map<String, String> roleMap = new HashMap<>(16);
            roleMap.put("time",DateHelper.format(e.getCreateTime(),"yyyy.MM.dd"));
            roleMap.put("role",this.getRole(e.getAuthority()));
            list.add(roleMap);
        });
        data.put("list", list);
        return responseEntity.success(data, "成功");
    }

    @Override
    public ResponseEntity findExerciseTeacherReviseQuestions(ExerciseTeacherReviseQuestionReq req) {
        ResponseEntity responseEntity = new ResponseEntity();

        TbLibManager libManager = managerService.findByUserIdAndType(req.getTeacherId(), 17);
        if (libManager == null || StringUtils.isBlank(libManager.getAuthority())) {
            return responseEntity.failure("该老师还没有录题权限");
        }
        List<String> authorityList = Arrays.asList(libManager.getAuthority().split(","));
        List<Integer> dealStatusList = new ArrayList<>();
        if (authorityList.contains("1")) {
            dealStatusList.add(1);
        }
        if (authorityList.contains("2")) {
            dealStatusList.add(7);
        }
        if (authorityList.contains("3")) {
            dealStatusList.add(8);
        }
        if (authorityList.contains("4")) {
            dealStatusList.add(10);
        }
        if (CollectionUtils.isEmpty(dealStatusList)) {
            return responseEntity.failure("该老师还没有录题权限");
        }

        List<ExerciseQuetionDto> exerciseQuestionDtoList = kmtExerciseMapper.findRepulsedQuestion(req, dealStatusList);
        kmtExerciseService.appendQuestionDtoDataFromJSONFile(exerciseQuestionDtoList);
        List<ExerciseBookCourseClassDto> exerciseBookCourseClassDtoList =
                kmtExerciseQuestionService.getQuestionGroupList(exerciseQuestionDtoList, true);

        return responseEntity.success(Collections.singletonMap("list", exerciseBookCourseClassDtoList), "成功");
    }

    @Override
    public ResponseEntity findDistributionCount() {
        ExerciseDistributionCountDTO exerciseDistributionCountDTO = kmtExerciseMapper.findDistributionCount();
        return new ResponseEntity().success(exerciseDistributionCountDTO, "查询成功");
    }

    @Override
    public ResponseEntity findDistributionExerciseBookFilterOption() {
        JSONObject resultObject = JSON.parseObject("{\"gradeOptionList\":[{\"optionName\":\"全部\",\"value\":\"\"},{\"optionName\":\"一年级\",\"value\":\"一年级\"},{\"optionName\":\"二年级\",\"value\":\"二年级\"},{\"optionName\":\"三年级\",\"value\":\"三年级\"},{\"optionName\":\"四年级\",\"value\":\"四年级\"},{\"optionName\":\"五年级\",\"value\":\"五年级\"},{\"optionName\":\"六年级\",\"value\":\"六年级\"}],\"semesterOptionList\":[{\"optionName\":\"全部\",\"value\":0},{\"optionName\":\"上册\",\"value\":1},{\"optionName\":\"下册\",\"value\":2}],\"halfBookOptionList\":[{\"optionName\":\"全部\",\"value\":-1},{\"optionName\":\"整本\",\"value\":0},{\"optionName\":\"上半本\",\"value\":1},{\"optionName\":\"下半本\",\"value\":2},{\"optionName\":\"不同\",\"value\":3}],\"handlerOptionList\":[{\"optionName\":\"全部\",\"value\":0},{\"optionName\":\"无加工人\",\"value\":1}],\"handleAuditUserOptionList\":[{\"optionName\":\"全部\",\"value\":0},{\"optionName\":\"无加审人\",\"value\":1}],\"analyserOptionList\":[{\"optionName\":\"全部\",\"value\":0},{\"optionName\":\"无解析人\",\"value\":1}],\"analysisAuditUserOptionList\":[{\"optionName\":\"全部\",\"value\":0},{\"optionName\":\"无解审人\",\"value\":1}]}");

        // 科目-版本选项
        List<Map<String, Object>> subjectOptionList = new ArrayList<>();
        resultObject.put("subjectOptionList", subjectOptionList);
        // 全部
        Map<String, Object> subjectOptionMap = new HashMap<>();
        subjectOptionMap.put("optionName", "全部");
        subjectOptionMap.put("value", "");
        Map<String, Object> versionOptionMap = new HashMap<>();
        versionOptionMap.put("name", "全部");
        versionOptionMap.put("type", 0);
        List<Map<String, Object>> versionOptionMapList = new ArrayList<>();
        versionOptionMapList.add(versionOptionMap);
        subjectOptionMap.put("versionOptionList", versionOptionMapList);
        subjectOptionList.add(subjectOptionMap);
        // 系统内科目
        List<String> subjectList = Arrays.asList("语文", "数学", "英语");
        for (String subject : subjectList) {
            subjectOptionMap = new LinkedHashMap<>();
            subjectOptionMap.put("optionName", subject);
            subjectOptionMap.put("value", subject);
            subjectOptionMap.put("versionOptionList", knowledgeVersion.getVersionListBySubject(subject));
            subjectOptionList.add(subjectOptionMap);
        }

        return new ResponseEntity().success(resultObject, "查询成功");
    }

    @Override
    public ResponseEntity findDistributionExerciseBookList(DistributionExerciseBookListReq req) {
        int totalCount = kmtExerciseMapper.countDistributionExerciseBook(req);
        Integer pageSize = req.getPageSize();
        Integer pageNo = req.getPageNo();
        List<DistributionExerciseBookDTO> distributionExerciseBookDTOList =
                kmtExerciseMapper.findDistributionExerciseBookList(req, (pageNo - 1) * pageSize, pageSize);
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("pageNo", pageNo);
        resultMap.put("pageSize", pageSize);
        resultMap.put("pages", (totalCount - 1) / pageSize + 1);
        resultMap.put("total", totalCount);
        resultMap.put("bookList", distributionExerciseBookDTOList);

        return new ResponseEntity().success(resultMap, "查询成功");
    }

    private String getRole(String authority) {
        StringBuilder exerciseTeacherTypeBuilder = new StringBuilder("");
        if (authority.contains("1")) {
            exerciseTeacherTypeBuilder.append("加工、");
        }
        if (authority.contains("2")) {
            exerciseTeacherTypeBuilder.append("加审、");
        }
        if (authority.contains("3")) {
            exerciseTeacherTypeBuilder.append("解析、");
        }
        if (authority.contains("4")) {
            exerciseTeacherTypeBuilder.append("解审、");
        }
        if (exerciseTeacherTypeBuilder.length() > 0) {
            exerciseTeacherTypeBuilder.deleteCharAt(exerciseTeacherTypeBuilder.length() - 1);
        }
        StringBuilder kmtTeacherTypeBuilder = new StringBuilder("");
        if (authority.contains("5")) {
            kmtTeacherTypeBuilder.append("加工、");
        }
        if (authority.contains("6")) {
            kmtTeacherTypeBuilder.append("审核、");
        }
        if (kmtTeacherTypeBuilder.length() > 0) {
            kmtTeacherTypeBuilder.deleteCharAt(kmtTeacherTypeBuilder.length() - 1);
        }
        String teacherTypeStr = (exerciseTeacherTypeBuilder.length() > 0 ? String.format("练习册（%s）   ", exerciseTeacherTypeBuilder.toString()) : "") +
                (kmtTeacherTypeBuilder.length() > 0 ? String.format("KMT （%s）", kmtTeacherTypeBuilder.toString()) : "");
        if (authority.contains("7")) {
            teacherTypeStr = "题库录入老师";
        }
        if (authority.contains("8")) {
            teacherTypeStr = "答案校对老师";
        }
        return teacherTypeStr;
    }

  /*
     * 更新练习册
     */

   @Override
   public void updateExerciseAnwerStatus(){
         List<Map<String,Object>> list=kmtExerciseMapper.findUnproofreadExerciseId();
         if(CollectionUtils.isNotEmpty(list)){
             list.forEach(a->{
                 String value=a.get("id").toString();
                 //查询练习册id判断练习册状态
                 List<KmtExerciseQuestion> list1=kmtExerciseMapper.findExerciseStatusByBookId(value);
                 int bookStatus=0;
                 if(CollectionUtils.isNotEmpty(list1)){
                     List<Integer> statusList=list1.stream().map(KmtExerciseQuestion::getProofreadStatus).collect(Collectors.toList());
                     if(statusList.contains(2)){
                         bookStatus=2;
                     }else {
                         if(statusList.contains(3)){
                             bookStatus=3;
                         }else {
                             if(statusList.contains(1)){
                                 bookStatus=1;
                             }else {
                                 bookStatus=0;
                             }
                         }
                     }
                 }
           kmtExerciseMapper.updateExerciseBookStatusByIdAndStatus(bookStatus,value);

             });
         }

  }

   @Override
    public ResponseEntity findCheckTeacherDetailsList(CheckTeacherDetailsRequest request){
       ResponseEntity responseEntity=new ResponseEntity();
        Map<String,Object> data=new HashMap<>();
        com.baomidou.mybatisplus.extension.plugins.pagination.Page page = new com.baomidou.mybatisplus.extension.plugins.pagination.Page(request.getPageNo(), request.getPageSize());
        List<Map<String,Object>> list=libManagerMapper.findCheckTeacherDetailsList(request.getTeacherId(),request.getMaxCreateTime(),page);
        List<CheckTeacherDetailDto> checkList=new ArrayList<>();
        list.forEach(a->{
            CheckTeacherDetailDto dto=new CheckTeacherDetailDto();
            dto.setBookId(Optional.ofNullable(a.get("bookId")).orElse("").toString());
            dto.setBookName(Optional.ofNullable(a.get("bookName")).orElse("").toString());
            dto.setExerciseBookId(Optional.ofNullable(a.get("id")).orElse("").toString());
            dto.setGrade(Optional.ofNullable(a.get("grade")).orElse("").toString());
            dto.setSemester(Integer.parseInt(a.get("semester").toString()));
            dto.setCourseName(Optional.ofNullable(a.get("subject")).orElse("").toString());
            dto.setVersionName(Optional.ofNullable(a.get("version")).orElse("").toString());
            dto.setBookStatus(Integer.parseInt(a.get("bookStatus").toString())==0?1:2);
            dto.setCheckTime(a.containsKey("checkTime")?new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(a.get("checkTime")):"无");
            int bookType=Integer.parseInt(a.get("bookType").toString());
            if(1==bookType){
                dto.setHalfBook("整本");
            }else if(1==bookType){
                dto.setHalfBook("上半本");
            }else {
                dto.setHalfBook("下半本");
            }

            checkList.add(dto);
        });
       Map<String,Object> map= libManagerMapper.findCheckTeacherDetails(request.getTeacherId(),request.getMaxCreateTime());
       int uncheckCount=0;
       int checkCount=0;
       if(null!=map){
            uncheckCount=Integer.parseInt(map.get("uncheckCount").toString());
            checkCount=Integer.parseInt(map.get("checkCount").toString());
       }
        data.put("pageNo",request.getPageNo());
        data.put("pageSize",request.getPageSize());
        data.put("pages",page.getPages());
        data.put("total",page.getTotal());
        data.put("uncheckCount",uncheckCount);
        data.put("checkCount",checkCount);
        data.put("list",checkList);
       return responseEntity.success(data,"成功");
   }

  @Override
    public  List<CheckTeacherDetailDto> findCheckTeacherList(CheckTeacherDetailsRequest request){
      com.baomidou.mybatisplus.extension.plugins.pagination.Page page = new com.baomidou.mybatisplus.extension.plugins.pagination.Page(request.getPageNo(), request.getPageSize());
      List<Map<String,Object>> list=libManagerMapper.findCheckTeacherDetailsList(request.getTeacherId(),request.getMaxCreateTime(),page);
      List<CheckTeacherDetailDto> checkList=new ArrayList<>();
      list.forEach(a->{
          CheckTeacherDetailDto dto=new CheckTeacherDetailDto();
          dto.setBookId(Optional.ofNullable(a.get("bookId")).orElse("").toString());
          dto.setBookName(Optional.ofNullable(a.get("bookName")).orElse("").toString());
          dto.setExerciseBookId(Optional.ofNullable(a.get("id")).orElse("").toString());
          dto.setGrade(Optional.ofNullable(a.get("grade")).orElse("").toString());
          dto.setSemester(Integer.parseInt(a.get("semester").toString()));
          dto.setCourseName(Optional.ofNullable(a.get("subject")).orElse("").toString());
          dto.setVersionName(Optional.ofNullable(a.get("version")).orElse("").toString());
          dto.setBookStatus(Integer.parseInt(a.get("bookStatus").toString())==0?1:2);
          dto.setCheckTime(a.containsKey("checkTime")?new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(a.get("checkTime")):"无");
          int bookType=Integer.parseInt(a.get("bookType").toString());
          if(1==bookType){
              dto.setHalfBook("整本");
          }else if(1==bookType){
              dto.setHalfBook("上半本");
          }else {
              dto.setHalfBook("下半本");
          }

          checkList.add(dto);
      });
     return checkList;
  }
    @Override
    public ResponseEntity allotExerciseDealTeacher(AllotExerciseTeacherRequest req) {
        ResponseEntity responseEntity = new ResponseEntity();
        if(CollectionUtils.isNotEmpty(req.getExerciseBookIdList())) {
            List<KmtExerciseBook> exerciseBooks = kmtExerciseMapper.findAllExerciseBookPage(req.getExerciseBookIdList(), 0, 500);
            for (ExerciseTeacherClassRequest teacherClassRequest : req.getTeacherList()) {
                TbLibManager manager = managerService.findByUserIdAndType(teacherClassRequest.getTeacherId(), 17);
                if (manager == null) {
                    return responseEntity.failure("该老师没有权限");
                }
                //保存分配记录
                this.saveKmtExerciseTeacherRecord(teacherClassRequest, req.getExerciseBookIdList(), manager.getName());
                //更新练习册表老师id
                this.updateTeacherIdByType(teacherClassRequest.getTeacherId(), teacherClassRequest.getType(), exerciseBooks);
            }
            kmtExerciseBookService.save(exerciseBooks);
            //异步更新练习册题目表老师id
            ThreadPool.getInstance().addTask(new UpdateExerciseQuestionThreadTask(req.getTeacherList(), req.getExerciseBookIdList(), kmtExerciseQuestionService));
        }
        return responseEntity.success();
    }

    /**
     * 更新练习册加工老师
     * @param teacherId
     * @param type
     * @param exerciseBooks
     */
    private void updateTeacherIdByType (String teacherId, int type, List<KmtExerciseBook> exerciseBooks){
       if (CollectionUtils.isNotEmpty(exerciseBooks)){
           for (KmtExerciseBook exerciseBook : exerciseBooks){
               switch (type) {
                   case 1:
                       exerciseBook.setHandleUserId(teacherId);
                       break;
                   case 2:
                       exerciseBook.setAuditingUserId(teacherId);
                       break;
                   case 3:
                       exerciseBook.setAnalysisUserId(teacherId);
                       break;
                   case 4:
                       exerciseBook.setAnalysisAuditerId(teacherId);
                       break;
                   default:
                       break;
               }
           }
       }
    }

    /**
     * 保存分配记录
     * @param req
     */
    private void saveKmtExerciseTeacherRecord (ExerciseTeacherClassRequest req, List<String> exercisebookIds, String teacherName){
        Date now = new Date();
        List<KmtExerciseBookTeacherRecord> teacherRecords = kmtExerciseMapper.findExerciseTeacherByExerciseBookIdsAndAuthType (exercisebookIds, req.getType());
        if (CollectionUtils.isNotEmpty(teacherRecords)){
            for (KmtExerciseBookTeacherRecord record : teacherRecords){
                if (record.getLastFlag() == 1){
                    record.setLastFlag(0);
                    kmtExerciseTeacherRecordService.save(record);
                }
            }
        }

        for (String exerciseBookId : exercisebookIds){
            KmtExerciseBookTeacherRecord teacherRecord = new KmtExerciseBookTeacherRecord();
            teacherRecord.setCreateTime(now);
            teacherRecord.setAuthorityType(req.getType());
            teacherRecord.setExerciseBookId(exerciseBookId);
            teacherRecord.setTeacherId(req.getTeacherId());
            teacherRecord.setTeacherName(teacherName);
            teacherRecord.setLastFlag(1);
            kmtExerciseTeacherRecordService.save(teacherRecord);
        }
    }

    @Override
    public ResponseEntity exerciseTeacherSalary(ExerciseTeacherSalaryReq req) {
        //查询老师分配的最新记录，记录结薪时间
        ResponseEntity responseEntity = new ResponseEntity();
        KmtExerciseBookTeacherRecord teacherRecord = kmtExerciseTeacherRecordService.findByExerciseBookIdAndAuthorityType(req.getExerciseBookId(), req.getType());
        Date now = new Date();
        if (teacherRecord != null){
            teacherRecord.setSalaryGiven(1);
            teacherRecord.setSalaryGivenTime(new Date());
            kmtExerciseTeacherRecordService.save(teacherRecord);
        } else{
            TbLibManager manager = managerService.findByUserIdAndType(req.getTeacherId(), 17);
            teacherRecord = new KmtExerciseBookTeacherRecord();
            teacherRecord.setTeacherId(req.getTeacherId());
            teacherRecord.setCreateTime(now);
            if (manager != null){
                teacherRecord.setTeacherName(manager.getName());
            }
            teacherRecord.setExerciseBookId(req.getExerciseBookId());
            teacherRecord.setAuthorityType(req.getType());
            teacherRecord.setSalaryGiven(1);
            teacherRecord.setSalaryGivenTime(new Date());
            kmtExerciseTeacherRecordService.save(teacherRecord);
        }

        // 异步刷新已分配练习册导出数据
        ThreadPool.getInstance().addTask(new SyncRefreshExerciseBookDistributionCountTask(Collections.singletonList(req.getExerciseBookId()), 3));

        return responseEntity.success();
    }

    @Override
    public List<ExportDistributionExerciseBookDTO> findExportDistributionExerciseBookList(ExportDistributionExerciseBookListReq req) {
        return kmtExerciseMapper.findExportDistributionExerciseBookList(req, Integer.MAX_VALUE);
    }

    @Override
    public ResponseEntity CountOrgRate(String subject){
        ResponseEntity responseEntity=new ResponseEntity();
        //将统计数据的所有旧记录清楚
        com.baomidou.mybatisplus.extension.plugins.pagination.Page page;
        kmtExerciseLibPriorityService.deleteOrgCountBySubject(subject);
        page = new com.baomidou.mybatisplus.extension.plugins.pagination.Page(1, Integer.MAX_VALUE);
        List<Map<String,Object>> list=kmtExerciseMapper.findAllLib(page,subject);
        if(CollectionUtils.isNotEmpty(list)){
            list.forEach(it->{
                List<KmtExerciseBookLibDto>list1=kmtExerciseMapper.findAllExerciseBook(it.get("libId").toString(),subject);
                int totalCount=(int)list1.stream().filter(a->!Objects.equals("未购买",a.getProgress())).count();
                int recogeCount=(int)list1.stream().filter(a->Objects.equals("已发布",a.getProgress())).count();
                int unrecogeCount=(int)list1.stream().filter(a->!Objects.equals("未购买",a.getProgress())&&!Objects.equals("已发布",a.getProgress())).count();
                int unPurchaseCount=(int)list1.stream().filter(a->Objects.equals("未购买",a.getProgress())).count();
                KmtExerciseLibPriority kmtExerciseLibPriority=new KmtExerciseLibPriority();
                kmtExerciseLibPriority.setLibId(Optional.ofNullable(it.get("libId")).orElse("").toString());
                kmtExerciseLibPriority.setSubject(subject);
                kmtExerciseLibPriority.setRecogeNum(recogeCount);
                kmtExerciseLibPriority.setTotalNum(totalCount);
                kmtExerciseLibPriority.setUnrecogeNum(unrecogeCount);
                kmtExerciseLibPriority.setUnpurchaNum(unPurchaseCount);
                String chineseRecogeRate="0.00%";
                if(0!=totalCount){
                    chineseRecogeRate=new BigDecimal(recogeCount).multiply(new BigDecimal(100)).divide(new BigDecimal(totalCount),2,BigDecimal.ROUND_HALF_UP) +"%";
                }
                kmtExerciseLibPriority.setRecogeRate(chineseRecogeRate);
                kmtExerciseLibPriorityService.save(kmtExerciseLibPriority);
            });

        }

        return responseEntity.success("成功");
    }

    @Override
    public int refreshExerciseBookDistributionCount(List<String> selectedExerciseBookIdList, int triggerType) {
        int offset = 0;
        int pageSize = 500;
        int count = 0;
        List<KmtExerciseBook> kmtExerciseBookList;
        List<KmtExerciseBookDistributionCount> kmtExerciseBookDistributionCountList = new ArrayList<>(pageSize);

        do {
            kmtExerciseBookList = kmtExerciseMapper.findAllExerciseBookPage(selectedExerciseBookIdList, offset, pageSize);

            if (Objects.equals(1, triggerType)) {
                // 分配练习册触发
                this.refreshKmtExerciseBookDistributionCountByAllot(kmtExerciseBookList, kmtExerciseBookDistributionCountList);
            } else if (Objects.equals(2, triggerType)) {
                // 各加工身份提交触发
                this.refreshKmtExerciseBookDistributionCountByHandleSubmit(kmtExerciseBookList, kmtExerciseBookDistributionCountList);
            } else if (Objects.equals(3, triggerType)) {
                // 结薪触发
                this.refreshKmtExerciseBookDistributionCountByPayOff(kmtExerciseBookList, kmtExerciseBookDistributionCountList);
            } else if (Objects.equals(4, triggerType)) {
                // 题目报错触发
                this.refreshKmtExerciseBookDistributionCountByQuestionError(kmtExerciseBookList, kmtExerciseBookDistributionCountList);
            }

            if (CollectionUtils.isNotEmpty(kmtExerciseBookDistributionCountList)) {
                pagingHibernateJdbcDao.batchUpdate(kmtExerciseBookDistributionCountList);
                count += kmtExerciseBookDistributionCountList.size();
                kmtExerciseBookDistributionCountList.clear();
            }

            offset += pageSize;
        } while (kmtExerciseBookList.size() >= pageSize);

        return count;
    }

    /**
     * 练习册题目报错触发刷新
     *
     * @param kmtExerciseBookList 练习册list
     * @param kmtExerciseBookDistributionCountList 练习册已分配导出数据list
     */
    private void refreshKmtExerciseBookDistributionCountByQuestionError(List<KmtExerciseBook> kmtExerciseBookList,
                                                                        List<KmtExerciseBookDistributionCount> kmtExerciseBookDistributionCountList) {
        if (CollectionUtils.isNotEmpty(kmtExerciseBookList)) {
            String exerciseBookId;
            KmtExerciseBookDistributionCount kmtExerciseBookDistributionCount;
            Date now = new Date();
            for (KmtExerciseBook kmtExerciseBook : kmtExerciseBookList) {
                exerciseBookId = kmtExerciseBook.getId();
                kmtExerciseBookDistributionCount =
                        kmtExerciseMapper.findKmtExerciseBookDistributionCountByExerciseBookId(exerciseBookId);
                if (kmtExerciseBookDistributionCount != null) {
                    this.setKmtExerciseBookAccuracy(exerciseBookId, kmtExerciseBookDistributionCount);

                    kmtExerciseBookDistributionCount.setUpdateTime(now);

                    kmtExerciseBookDistributionCountList.add(kmtExerciseBookDistributionCount);
                }
            }
        }
    }

    /**
     * 各加工身份结薪触发刷新
     *
     * @param kmtExerciseBookList 练习册list
     * @param kmtExerciseBookDistributionCountList 练习册已分配导出数据list
     */
    private void refreshKmtExerciseBookDistributionCountByPayOff(List<KmtExerciseBook> kmtExerciseBookList,
                                                                 List<KmtExerciseBookDistributionCount> kmtExerciseBookDistributionCountList) {
        if (CollectionUtils.isNotEmpty(kmtExerciseBookList)) {
            String exerciseBookId;
            KmtExerciseBookDistributionCount kmtExerciseBookDistributionCount;
            Date now = new Date();
            for (KmtExerciseBook kmtExerciseBook : kmtExerciseBookList) {
                exerciseBookId = kmtExerciseBook.getId();
                kmtExerciseBookDistributionCount =
                        kmtExerciseMapper.findKmtExerciseBookDistributionCountByExerciseBookId(exerciseBookId);
                if (kmtExerciseBookDistributionCount != null) {
                    this.setKmtExerciseBookHandleUsers(exerciseBookId, kmtExerciseBookDistributionCount);

                    kmtExerciseBookDistributionCount.setUpdateTime(now);

                    kmtExerciseBookDistributionCountList.add(kmtExerciseBookDistributionCount);
                }
            }
        }
    }

    /**
     * 各加工身份提交触发刷新
     *
     * @param kmtExerciseBookList 练习册list
     * @param kmtExerciseBookDistributionCountList 练习册已分配导出数据list
     */
    private void refreshKmtExerciseBookDistributionCountByHandleSubmit(List<KmtExerciseBook> kmtExerciseBookList,
                                                                       List<KmtExerciseBookDistributionCount> kmtExerciseBookDistributionCountList) {
        if (CollectionUtils.isNotEmpty(kmtExerciseBookList)) {
            String exerciseBookId;
            KmtExerciseBookDistributionCount kmtExerciseBookDistributionCount;
            Date now = new Date();
            for (KmtExerciseBook kmtExerciseBook : kmtExerciseBookList) {
                exerciseBookId = kmtExerciseBook.getId();
                kmtExerciseBookDistributionCount =
                        kmtExerciseMapper.findKmtExerciseBookDistributionCountByExerciseBookId(exerciseBookId);
                if (kmtExerciseBookDistributionCount != null) {
                    this.setKmtExerciseBookStatus(kmtExerciseBookDistributionCount, kmtExerciseBook);
                    this.setKmtExerciseBookLastSubmitTime(exerciseBookId, kmtExerciseBookDistributionCount);

                    kmtExerciseBookDistributionCount.setUpdateTime(now);

                    kmtExerciseBookDistributionCountList.add(kmtExerciseBookDistributionCount);
                }
            }
        }
    }

    /**
     * 练习册分配各加工身份触发刷新
     *
     * @param kmtExerciseBookList 练习册list
     * @param kmtExerciseBookDistributionCountList 练习册已分配导出数据list
     */
    private void refreshKmtExerciseBookDistributionCountByAllot(List<KmtExerciseBook> kmtExerciseBookList,
                                                                List<KmtExerciseBookDistributionCount> kmtExerciseBookDistributionCountList) {
        if (CollectionUtils.isNotEmpty(kmtExerciseBookList)) {
            String exerciseBookId;
            KmtExerciseBookDistributionCount kmtExerciseBookDistributionCount;
            Date now = new Date();
            long begin = System.currentTimeMillis();
            for (KmtExerciseBook kmtExerciseBook : kmtExerciseBookList) {
                // 刷新锁的过期时间，避免锁过期
                if (System.currentTimeMillis() - begin > 5000) {
                    tokenManager.refreshExpireTime("exercise_book_distribution_count_lock", 60);
                    begin = System.currentTimeMillis();
                }

                // 四个身份都已分配才需要生成导出数据
                if (StringUtils.isNotBlank(kmtExerciseBook.getHandleUserId()) &&
                        StringUtils.isNotBlank(kmtExerciseBook.getAuditingUserId()) &&
                        StringUtils.isNotBlank(kmtExerciseBook.getAnalysisUserId()) &&
                        StringUtils.isNotBlank(kmtExerciseBook.getAnalysisAuditerId())) {
                    exerciseBookId = kmtExerciseBook.getId();
                    kmtExerciseBookDistributionCount =
                            kmtExerciseMapper.findKmtExerciseBookDistributionCountByExerciseBookId(exerciseBookId);
                    if (kmtExerciseBookDistributionCount == null) {
                        // 不存在就创建
                        kmtExerciseBookDistributionCount = new KmtExerciseBookDistributionCount();
                        kmtExerciseBookDistributionCount.setHandlerAccuracy(100);
                        kmtExerciseBookDistributionCount.setHandleAuditUserAccuracy(100);
                        kmtExerciseBookDistributionCount.setAnalyserAccuracy(100);
                        kmtExerciseBookDistributionCount.setCreateTime(now);

                        this.setKmtExerciseBookBaseInfo(kmtExerciseBookDistributionCount, kmtExerciseBook);

                        this.setKmtExerciseBookStatus(kmtExerciseBookDistributionCount, kmtExerciseBook);

                        this.setKmtExerciseBookUnitCourse(exerciseBookId, kmtExerciseBookDistributionCount);

                        this.setKmtExerciseBookLastSubmitTime(exerciseBookId, kmtExerciseBookDistributionCount);

                        this.setKmtExerciseBookAccuracy(exerciseBookId, kmtExerciseBookDistributionCount);
                    }

                    this.setKmtExerciseBookHandleUsers(exerciseBookId, kmtExerciseBookDistributionCount);

                    kmtExerciseBookDistributionCount.setUpdateTime(now);

                    kmtExerciseBookDistributionCountList.add(kmtExerciseBookDistributionCount);
                }
            }
        }
    }

    /**
     * 设置练习册各加工身份正确率
     *
     * @param kmtExerciseBookDistributionCount 练习册已分配导出数据
     * @param exerciseBookId 练习册
     */
    private void setKmtExerciseBookAccuracy(String exerciseBookId,
                                            KmtExerciseBookDistributionCount kmtExerciseBookDistributionCount) {
        List<Map<String, Integer>> accuracyMapList = kmtExerciseMapper.findAccuracy(exerciseBookId);
        if (CollectionUtils.isNotEmpty(accuracyMapList)) {
            int type;
            for (Map<String, Integer> accuracyMap : accuracyMapList) {
                type = Optional.ofNullable(accuracyMap.get("type")).orElse(0);
                if (Objects.equals(1, type)) {
                    kmtExerciseBookDistributionCount.setHandlerAccuracy(Optional.ofNullable(accuracyMap.get("accuracy")).orElse(10000));
                } else if (Objects.equals(2, type)) {
                    kmtExerciseBookDistributionCount.setHandleAuditUserAccuracy(Optional.ofNullable(accuracyMap.get("accuracy")).orElse(10000));
                } else if (Objects.equals(3, type)) {
                    kmtExerciseBookDistributionCount.setAnalyserAccuracy(Optional.ofNullable(accuracyMap.get("accuracy")).orElse(10000));
                }
            }
        }
    }

    /**
     * 设置练习册各加工身份最新提交时间
     *
     * @param kmtExerciseBookDistributionCount 练习册已分配导出数据
     * @param exerciseBookId 练习册
     */
    private void setKmtExerciseBookLastSubmitTime(String exerciseBookId,
                                                  KmtExerciseBookDistributionCount kmtExerciseBookDistributionCount) {
        Map<String, Date> lastSubmitTimeMap = kmtExerciseMapper.findLastSubmitTime(exerciseBookId);
        if (lastSubmitTimeMap != null) {
            kmtExerciseBookDistributionCount.setHandlerLastSubmitTime(lastSubmitTimeMap.get("handlerLastSubmitTime"));
            kmtExerciseBookDistributionCount.setHandleAuditUserLastSubmitTime(lastSubmitTimeMap.get("handleAuditUserLastSubmitTime"));
            kmtExerciseBookDistributionCount.setAnalyserLastSubmitTime(lastSubmitTimeMap.get("analyserLastSubmitTime"));
            kmtExerciseBookDistributionCount.setAnalysisAuditUserLastSubmitTime(lastSubmitTimeMap.get("analysisAuditUserLastSubmitTime"));
        }
    }

    /**
     * 设置练习册各加工身份信息
     *
     * @param kmtExerciseBookDistributionCount 练习册已分配导出数据
     * @param exerciseBookId 练习册
     */
    private void setKmtExerciseBookHandleUsers(String exerciseBookId,
                                               KmtExerciseBookDistributionCount kmtExerciseBookDistributionCount) {
        List<KmtExerciseBookTeacherRecord> kmtExerciseBookTeacherRecordList = kmtExerciseTeacherRecordService.findByExerciseBookId(exerciseBookId);
        if (CollectionUtils.isNotEmpty(kmtExerciseBookTeacherRecordList)) {
            for (KmtExerciseBookTeacherRecord kmtExerciseBookTeacherRecord : kmtExerciseBookTeacherRecordList) {
                if (Objects.equals(1, kmtExerciseBookTeacherRecord.getAuthorityType())) {
                    kmtExerciseBookDistributionCount.setHandlerName(kmtExerciseBookTeacherRecord.getTeacherName());
                    kmtExerciseBookDistributionCount.setHandlerSalaryGiven(kmtExerciseBookTeacherRecord.getSalaryGiven());
                    kmtExerciseBookDistributionCount.setHandlerSalaryGivenTime(kmtExerciseBookTeacherRecord.getSalaryGivenTime());
                }
                if (Objects.equals(2, kmtExerciseBookTeacherRecord.getAuthorityType())) {
                    kmtExerciseBookDistributionCount.setHandleAuditUserName(kmtExerciseBookTeacherRecord.getTeacherName());
                    kmtExerciseBookDistributionCount.setHandleAuditUserSalaryGiven(kmtExerciseBookTeacherRecord.getSalaryGiven());
                    kmtExerciseBookDistributionCount.setHandleAuditUserSalaryGivenTime(kmtExerciseBookTeacherRecord.getSalaryGivenTime());
                }
                if (Objects.equals(3, kmtExerciseBookTeacherRecord.getAuthorityType())) {
                    kmtExerciseBookDistributionCount.setAnalyserName(kmtExerciseBookTeacherRecord.getTeacherName());
                    kmtExerciseBookDistributionCount.setAnalyserSalaryGiven(kmtExerciseBookTeacherRecord.getSalaryGiven());
                    kmtExerciseBookDistributionCount.setAnalyserSalaryGivenTime(kmtExerciseBookTeacherRecord.getSalaryGivenTime());
                }
                if (Objects.equals(4, kmtExerciseBookTeacherRecord.getAuthorityType())) {
                    kmtExerciseBookDistributionCount.setAnalysisAuditUserName(kmtExerciseBookTeacherRecord.getTeacherName());
                    kmtExerciseBookDistributionCount.setAnalysisAuditUserSalaryGiven(kmtExerciseBookTeacherRecord.getSalaryGiven());
                    kmtExerciseBookDistributionCount.setAnalysisAuditUserSalaryGivenTime(kmtExerciseBookTeacherRecord.getSalaryGivenTime());
                }
            }
        }
    }

    /**
     * 设置练习册单元课时
     *
     * @param kmtExerciseBookDistributionCount 练习册已分配导出数据
     * @param exerciseBookId 练习册id
     */
    private void setKmtExerciseBookUnitCourse(String exerciseBookId,
                                              KmtExerciseBookDistributionCount kmtExerciseBookDistributionCount) {
        Map<String, Long> unitAndCourseCountMap = kmtExerciseMapper.countUnitAndCourse(exerciseBookId);
        if (unitAndCourseCountMap != null) {
            kmtExerciseBookDistributionCount.setUnitCount(Math.toIntExact(Optional.ofNullable(unitAndCourseCountMap.get("unitCount")).orElse(0L)));
            kmtExerciseBookDistributionCount.setCourseCount(Math.toIntExact(Optional.ofNullable(unitAndCourseCountMap.get("courseCount")).orElse(0L)));
        }
    }

    /**
     * 设置练习册加工状态
     *
     * @param kmtExerciseBookDistributionCount 练习册已分配导出数据
     * @param kmtExerciseBook 练习册
     */
    private void setKmtExerciseBookStatus(KmtExerciseBookDistributionCount kmtExerciseBookDistributionCount,
                                          KmtExerciseBook kmtExerciseBook) {
        if (Objects.equals(kmtExerciseBook.getHadHandle(), 0)) {
            kmtExerciseBookDistributionCount.setBookStatus(ExportExerciseBookStatusEnum.Processing.getCode());
        } else if (Objects.equals(kmtExerciseBook.getHadAuditing(), 0)) {
            kmtExerciseBookDistributionCount.setBookStatus(ExportExerciseBookStatusEnum.Auditing.getCode());
        } else if (Objects.equals(kmtExerciseBook.getAnalysisHandled(), 0)) {
            kmtExerciseBookDistributionCount.setBookStatus(ExportExerciseBookStatusEnum.AnalysisProcessing.getCode());
        } else if (Objects.equals(kmtExerciseBook.getAnalysisAudited(), 0)) {
            kmtExerciseBookDistributionCount.setBookStatus(ExportExerciseBookStatusEnum.AnalysisAuditing.getCode());
        } else {
            kmtExerciseBookDistributionCount.setBookStatus(ExportExerciseBookStatusEnum.Published.getCode());
        }
    }

    /**
     * 设置练习册基本信息
     *
     * @param kmtExerciseBookDistributionCount 练习册已分配导出数据
     * @param kmtExerciseBook 练习册
     */
    private void setKmtExerciseBookBaseInfo(KmtExerciseBookDistributionCount kmtExerciseBookDistributionCount,
                                            KmtExerciseBook kmtExerciseBook) {
        kmtExerciseBookDistributionCount.setExerciseBookId(kmtExerciseBook.getId());
        kmtExerciseBookDistributionCount.setImportDate(kmtExerciseBook.getCreateTime());
        kmtExerciseBookDistributionCount.setBookName(kmtExerciseBook.getBookName());
        kmtExerciseBookDistributionCount.setSubject(kmtExerciseBook.getCourseName());
        kmtExerciseBookDistributionCount.setGrade(kmtExerciseBook.getGrade());
        kmtExerciseBookDistributionCount.setVersion(kmtExerciseBook.getVersion());
        kmtExerciseBookDistributionCount.setSemester(kmtExerciseBook.getSemester());
        kmtExerciseBookDistributionCount.setBookType(kmtExerciseBook.getBookType());
    }

    @Override
    public  void updateOrgRateCount(){
        String [] str=new String[]{"语文","数学","英语"};
         for(String subject:str){
                com.baomidou.mybatisplus.extension.plugins.pagination.Page page=new com.baomidou.mybatisplus.extension.plugins.pagination.Page(1, 999999);
                List<ExerciseBookAndLibExportDto> list0=new ArrayList<>();
                List<Map<String,Object>> list=kmtExerciseMapper.findAllDistinctLibBySubject(page,subject);
                if(CollectionUtils.isNotEmpty(list)){
                    list.forEach(it->{
                        TbLibJoin tbLibJoin=libJoinService.getById(it.get("lib_id").toString());
                        Merchant merchant=kmtExerciseMapper.findSignService(it.get("lib_id").toString());
                        String leagueLet=tbLibJoin.getLeagueLat();
                        String leagueLng=tbLibJoin.getLeagueLng();
                        Map addressMap = MapUtils.regeoByAmapApi(Double.valueOf(leagueLng), Double.valueOf(leagueLet));
                        String leagueName=tbLibJoin.getLeagueName();
                        String address=addressMap.get("address").toString();
                        int signService=merchant.getSignService();
                        List<KmtExerciseBookLibDto>list1=kmtExerciseMapper.findAllExerciseBook(it.get("lib_id").toString(),subject);
                        ExerciseBookAndLibExportDto exerciseBookAndLibExportDto=new ExerciseBookAndLibExportDto();
                        Map<String,Object> map=new HashMap<>();
                        Map<String,List<KmtExerciseBookLibDto>> map1=list1.stream().collect(Collectors.groupingBy(p->p.getExerciseName()+"_"+p.getVersion()+"_"+p.getSemester()+"_"+p.getPriority()));
                        List<KmtExerciseLibExportDto> exportList=    map1.keySet().stream().map(key->{
                            String [] u=key.split("_");
                            String exerciseName=u[0];
                            String version=u[1];
                            String semester=u[2];
                            String priority=u[3];
                            if(Objects.equals(priority,"null")){
                                priority="";
                            }
                            KmtExerciseLibExportDto kmt=new KmtExerciseLibExportDto();
                            kmt.setExerciseName(exerciseName);
                            kmt.setVersion(version);
                            kmt.setSemester(semester);
                            kmt.setPriority(priority);
                            List<KmtExerciseBookLibDto> exerciseBookLibDtos=map1.get(key);
                            kmt=this.getKmtList(exerciseBookLibDtos,exerciseName,version,semester,priority);
                            return kmt;
                        }).collect(Collectors.toList());
                        //通过libId和科目获取机构识别信息
                        long totalCount=list1.stream().filter(a->!Objects.equals("未购买",a.getProgress())).count();
                        long recogeCount=list1.stream().filter(a->Objects.equals("已发布",a.getProgress())).count();
                        long unrecogeCount=list1.stream().filter(a->!Objects.equals("未购买",a.getProgress())&&!Objects.equals("已发布",a.getProgress())).count();
                        long unPurchaseCount=list1.stream().filter(a->Objects.equals("未购买",a.getProgress())).count();
                        String chineseRecogeRate="0.00%";
                        if(0!=totalCount){
                            chineseRecogeRate=new BigDecimal(recogeCount).multiply(new BigDecimal(100)).divide(new BigDecimal(totalCount),2,BigDecimal.ROUND_HALF_UP) +"%";
                        }
                        exerciseBookAndLibExportDto.setLibName(leagueName);
                        exerciseBookAndLibExportDto.setLibArea(address);
                        exerciseBookAndLibExportDto.setSignService(signService);
                        exerciseBookAndLibExportDto.setTotalCount(totalCount);
                        exerciseBookAndLibExportDto.setRecogeCount(recogeCount);
                        exerciseBookAndLibExportDto.setUnrecogeCount(unrecogeCount);
                        exerciseBookAndLibExportDto.setUnPurchaseCount(unPurchaseCount);
                        exerciseBookAndLibExportDto.setChineseRecogeRate(chineseRecogeRate);
                        exerciseBookAndLibExportDto.setLibExportDtoList(exportList);
                        list0.add(exerciseBookAndLibExportDto);
                    });
                    if("语文".equals(subject)&&CollectionUtils.isNotEmpty(list0)){
                      String   key="yuwen"+DateUtil.format_yyyyMMdd(new Date());
                      if(redisUtil.exists(key)){
                          redisUtil.del(key);
                      }
                        redisUtil.set(key,JSON.toJSONString(list0),60*60*24);
                    }
                    if("数学".equals(subject)&&CollectionUtils.isNotEmpty(list0)){
                        String   key="shuxue"+DateUtil.format_yyyyMMdd(new Date());
                        if(redisUtil.exists(key)){
                            redisUtil.del(key);
                        }
                        redisUtil.set(key,JSON.toJSONString(list0),60*60*24);
                    }
                    if("英语".equals(subject)&&CollectionUtils.isNotEmpty(list0)){
                        String   key="yingyu"+DateUtil.format_yyyyMMdd(new Date());
                        if(redisUtil.exists(key)){
                            redisUtil.del(key);
                        }
                        redisUtil.set(key,JSON.toJSONString(list0),60*60*24);
                    }



                }
            }


        }



}