package com.xhkjedu.sapi.service.system;

import com.xhkjedu.sapi.mapper.cloud.CloudMapper;
import com.xhkjedu.sapi.mapper.gradeclass.*;
import com.xhkjedu.sapi.mapper.system.*;
import com.xhkjedu.sapi.model.cloud.TCloud;
import com.xhkjedu.sapi.model.gradeclass.*;
import com.xhkjedu.sapi.model.system.*;
import com.xhkjedu.sapi.utils.ApiUtil;
import com.xhkjedu.sapi.vo.analyze.SchoolParams;
import com.xhkjedu.utils.MD5;
import com.xhkjedu.utils.N_Utils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

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

/**
 * @author ywx
 * @classname TSchoolService
 * @description 
 * @date 2020/6/2 15:07
 **/
@Service
@Slf4j
public class SchoolService {
    @Resource
    private SchoolMapper schoolMapper;
    @Resource
    private ModuledefaultService moduledefaultService;
    @Resource
    private ModuleService moduleService;
    @Resource
    private ClassMapper classMapper;
    @Resource
    private ClassStudentMapper classStudentMapper;
    @Resource
    private ClassTeacherMapper classTeacherMapper;
    @Resource
    private GroupMapper groupMapper;
    @Resource
    private GroupStudentMapper groupStudentMapper;
    @Resource
    private UserMapper userMapper;
    @Resource
    private RoleMapper roleMapper;
    @Resource
    private RoleModuleMapper roleModuleMapper;
    @Resource
    private UserRoleMapper userRoleMapper;
    @Resource
    private SchoolFriendMapper schoolFriendMapper;
    @Resource
    private CloudMapper cloudMapper;
    @Resource
    private SchoolUpgradeMapper schoolUpgradeMapper;
    @Resource
    private SchoolUpgradeHistoryMapper schoolUpgradeHistoryMapper;

    //添加
    @Transactional(rollbackFor = Exception.class)
    public Integer save(TSchool model) throws Exception {
        //添加学校信息
        model.setSchoolstate(1);
        model.setCreatetime(N_Utils.getSecondTimestamp());
        Integer schoolid;
        try {
            schoolMapper.insertUseGeneratedKeys(model);
            schoolid = model.getId();

            //添加管理员信息
            Integer userid = saveUser(model, schoolid);

            //添加角色信息
            Integer roleid = saveRole(schoolid, userid);

            //添加用户角色
            saveUserRole(userid, roleid);

            //添加模块信息
            List<TRoleModule> roleModules = new ArrayList<>();
            List<TModule> moduleList = new ArrayList<>();
            List<TModule> modules = moduledefaultService.listModulesTree(null, null,null,2);//给学校网页复制模块
            for (TModule module : modules) {
                saveModuleSetRoleModule(schoolid, userid, roleid, roleModules, moduleList, module);
            }
            moduleService.batchSave(moduleList);//批量保存模块信息

            //添加角色模块
            roleModuleMapper.insertList(roleModules);
        } catch (DuplicateKeyException e) {
            log.error("添加学校失败:" + e.getMessage());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            throw new RuntimeException("该管理员账号已存在");
        } catch (Exception e) {
            log.error("添加学校失败:" + e.getMessage());
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            throw new RuntimeException("添加学校失败");
        }

        return schoolid;
    }

    /**
     * 添加用户角色
     * @Param [userid, roleid]
     * @Author ywx
     * @Date 2020/7/2 11:52
     **/
    private void saveUserRole(Integer userid, Integer roleid) {
        TUserRole userRole = new TUserRole();
        userRole.setUserid(userid);
        userRole.setRoleid(roleid);
        userRole.setCreateid(userid);
        userRole.setCreatetime(N_Utils.getSecondTimestamp());
        userRoleMapper.insertUseGeneratedKeys(userRole);
    }

    /**
     * 添加角色信息
     * @Param [schoolid, userid]
     * @Author ywx
     * @Date 2020/7/2 11:51
     * @return java.lang.Integer
     **/
    private Integer saveRole(Integer schoolid, Integer userid) {
        TRole role = new TRole();
        role.setRolename("管理员");
        role.setComm("拥有高权限");
        role.setCreateid(userid);
        role.setCreatetime(N_Utils.getSecondTimestamp());
        role.setSchoolid(schoolid);
        role.setRoletype(0);
        roleMapper.insertUseGeneratedKeys(role);
        return role.getId();
    }

    /**
     * 添加管理员信息
     * @Param [model, schoolid]
     * @Author ywx
     * @Date 2020/7/2 11:49
     * @return java.lang.Integer
     **/
    private Integer saveUser(TSchool model, Integer schoolid) {
        TUser user = new TUser();
        user.setLoginname(model.getLoginname());
        user.setUsername("管理员");
        user.setUsersex(1);
        MD5 m = new MD5();
        String loginpwd = m.getMD5ofStr(m.getMD5ofStr(m.getMD5ofStr("123456")));
        user.setLoginpwd(loginpwd);
        user.setUsertype(0);
        user.setUserstate(1);
        user.setErrornum(0);
        user.setCreateid(model.getCreateid());
        user.setCreatetime(N_Utils.getSecondTimestamp());
        user.setSchoolid(schoolid);
        userMapper.insertUseGeneratedKeys(user);
        return user.getId();
    }

    /**
     * 保存子模块信息并设置角色模块信息
     *
     * @Param [schoolid, userid, roleid, roleModules, module]
     * @Author ywx
     * @Date 2020/7/2 11:47
     **/
    private void saveModuleSetRoleModule(Integer schoolid, Integer userid, Integer roleid, List<TRoleModule> roleModules, List<TModule> moduleList, TModule module) {
        module.setCreateid(userid);
        module.setCreatetime(N_Utils.getSecondTimestamp());
        module.setSchoolid(schoolid);
        module.setDefaultid(module.getModuleid());
        String moduleid = ApiUtil.getId();
        module.setModuleid(moduleid);
        moduleList.add(module);
        saveModuleChild(schoolid, userid, module, roleModules, moduleList, roleid);

        if (module.getBelong() == 1) {
            //角色模块信息
            TRoleModule roleModule = new TRoleModule();
            roleModule.setRoleid(roleid);
            roleModule.setModuleid(moduleid);
            roleModule.setCreateid(userid);
            roleModule.setCreatetime(N_Utils.getSecondTimestamp());
            roleModule.setSchoolid(schoolid);
            roleModule.setBelongcode(module.getBelongcode());
            roleModules.add(roleModule);
        }
    }

    /**
     * 保存子模块信息
     *
     * @Param [schoolid, userid, module, roleModules, roleid]
     * @Author ywx
     * @Date 2020/7/2 11:46
     **/
    private void saveModuleChild(Integer schoolid, Integer userid, TModule module, List<TRoleModule> roleModules, List<TModule> moduleList, Integer roleid) {
        String moduleid = module.getModuleid();
        List<TModule> modulechilds = module.getModulechilds();
        if (N_Utils.isListNotEmpty(modulechilds)) {
            for (TModule modulechild : modulechilds) {
                modulechild.setModulepid(moduleid);
                saveModuleSetRoleModule(schoolid, userid, roleid, roleModules, moduleList, modulechild);
            }
        }
    }

    //删除
    public Integer deleteById(Integer schoolid) {
        //删除系统学校
        return schoolMapper.deleteById(schoolid);
    }

    //修改
    @Transactional(rollbackFor = Exception.class)
    public Integer update(TSchool model) {
        Integer schoolbindmac = model.getSchoolbindmac();
        TSchool school = finById(model.getSchoolid());
        if (schoolbindmac != null && !schoolbindmac.equals(school.getSchoolbindmac())) {
            userMapper.delBindmac(model.getSchoolid());//删除学生绑定信息
        }
        return schoolMapper.updateById(model);
    }

    //获取列表
    public List <Map<String,Object>> findAll() {
        return schoolMapper.findAll();
    }

    public Map<String,Object> checkSchoolUpgrade(Integer schoolid) throws Exception{
        HashMap<String,Object> rtnMap = new HashMap<>();
        TCloud cloud = cloudMapper.getCloudUpTime();
        boolean isup = ApiUtil.compareCurrDateTime(cloud.getStarttime(), cloud.getStoptime());

        //获取当前学校的学年
        int year = schoolMapper.getYearById(schoolid);

        rtnMap.put("isup",isup);
        rtnMap.put("year",year);
        rtnMap.put("starttime",cloud.getStarttime());
        rtnMap.put("stoptime",cloud.getStoptime());
        return rtnMap;
    }

    /**
     * 学年升级
     * @Param [schoolid, year]
     * @Author ywx
     * @Date 2020/6/12 13:50
     **/
    @Transactional(rollbackFor = Exception.class)
    public List<TSchoolUpgradeHistory> upgrade(Integer schoolid, Integer year, Integer createid) throws Exception {
        checkUpTime();

        int timestamp = N_Utils.getSecondTimestamp();
        TSchoolUpgrade su = new TSchoolUpgrade();
        su.setSchoolid(schoolid);
        su.setUptype(1);
        su.setOldyear(year);
        su.setNewyear(year + 1);
        su.setUptime(timestamp);
        su.setUpuserid(createid);
        int classyxznum;//应升级行政班数量
        int classsxznum;//实际升级行政班数量
        int classyxnnum;//应升级虚拟班数量
        int classsxnnum;//实际升级虚拟班数量
        int stuyupnum;//应升级学生数量
        int stusupnum;//实际升级学生数量
        int gradeid;//学年升级id
        List<TSchoolUpgradeHistory> histories = new ArrayList<>();
        List<String> grades = new ArrayList<>();
        try {
            //不需要升级，需要标识毕业的班级，学生
            List<TClass> biyeclass = classMapper.listClassBiyeBySchoolId(schoolid, year, 1);
            List<String> xzList = biyeclass.stream().filter(c -> c.getClasstype().equals(1))
                                           .map(c -> c.getClassid().toString()).collect(Collectors.toList());
            String xzClassIds = String.join(",", xzList);
            List<Integer> bystudents = new ArrayList<>();
            if (N_Utils.isNotEmpty(xzClassIds)) {
                bystudents = classMapper.listStudentIdByClassIds(xzClassIds);//要毕业的学生列表
            }

            List<TClass> classes = classMapper.listClassBySchoolId(schoolid, year);//要升级的班级列表
            if (N_Utils.isListNotEmpty(classes)) {
                List<String> classids = classes.stream().filter(c -> c.getClasstype().equals(1)).map(c -> c.getClassid().toString()).collect(Collectors.toList());
                String classIds = String.join(",", classids);
                List<TClassStudent> cStudents = classMapper.listStudentByClassIds(classIds);//要升级的学生列表
                List<TClassTeacher> cTeachers = classMapper.listTeacherByClassIds(classIds);//要升级的教师列表
                List<TGroup> groups = classMapper.listGroupByClassIds(classIds);//要升级的全体分组列表
                String groupIds = groups.stream().map(g -> g.getGroupid().toString()).collect(Collectors.joining(","));
                List<TGroupStudent> gStudents = classMapper.listStudentByGroupIds(groupIds);//要升级的学生列表
                Map<Integer, List<TClass>> gcollect = classes.stream().collect(Collectors.groupingBy(TClass::getGradeid));
                for (Map.Entry<Integer, List<TClass>> entry : gcollect.entrySet()) {
                    gradeid = entry.getKey();
                    try {
                        List<TClass> classList = entry.getValue();
                        List<TClass> xzbList = classList.stream().filter(c -> c.getClasstype().equals(1)).collect(Collectors.toList());
                        List<TClass> xnbList = classList.stream().filter(c -> c.getClasstype().equals(2)).collect(Collectors.toList());
                        if (N_Utils.isListNotEmpty(xzbList)) {
                            String cIds = xzbList.stream().map(c -> c.getClassid().toString()).collect(Collectors.joining(","));
                            List<TClassStudent> studentList = cStudents.stream().filter(cs -> cIds.contains(String.valueOf(cs.getClassid()))).collect(Collectors.toList());
                            List<TClassTeacher> teacherList = cTeachers.stream().filter(cs -> cIds.contains(String.valueOf(cs.getClassid()))).collect(Collectors.toList());
                            List<TGroup> gList = groups.stream().filter(cs -> cIds.contains(String.valueOf(cs.getClassid()))).collect(Collectors.toList());
                            List<TGroupStudent> gsList = gStudents.stream().filter(cs -> cIds.contains(String.valueOf(cs.getClassid()))).collect(Collectors.toList());
                            List<Integer> list = saveClass(timestamp, xzbList, studentList, teacherList, gList, gsList);
                            classyxznum = xzbList.size();
                            classsxznum = list.get(0);
                            stuyupnum = studentList.size();
                            stusupnum = list.get(1);
                        } else {
                            classyxznum = 0;
                            classsxznum = 0;
                            stuyupnum = 0;
                            stusupnum = 0;
                        }
                        if (N_Utils.isListNotEmpty(xnbList)) {
                            classIds = classes.stream().filter(c -> c.getClasstype().equals(2)).map(c -> c.getClassid().toString()).collect(Collectors.joining(","));
                            cStudents = classMapper.listStudentByClassIds(classIds);//要升级的学生列表
                            cTeachers = classMapper.listTeacherByClassIds(classIds);//要升级的教师列表
                            groups = classMapper.listGroupByClassIds(classIds);//要升级的全体分组列表
                            groupIds = groups.stream().map(g -> g.getGroupid().toString()).collect(Collectors.joining(","));
                            gStudents = classMapper.listStudentByGroupIds(groupIds);//要升级的学生列表
                            String cIds = xnbList.stream().map(c -> c.getClassid().toString()).collect(Collectors.joining(","));
                            List<TClassStudent> studentList = new ArrayList<>();
                            for (TClassStudent cs : cStudents) {
                                if (cIds.contains(cs.getClassid().toString()) && !bystudents.contains(cs.getStudentid())) {
                                    studentList.add(cs);
                                }
                            }
                            List<TClassTeacher> teacherList = cTeachers.stream().filter(cs -> cIds.contains(String.valueOf(cs.getClassid()))).collect(Collectors.toList());
                            List<TGroup> gList = groups.stream().filter(cs -> cIds.contains(String.valueOf(cs.getClassid()))).collect(Collectors.toList());
                            List<TGroupStudent> gsList = gStudents.stream().filter(cs -> cIds.contains(String.valueOf(cs.getClassid()))).collect(Collectors.toList());
                            List<Integer> list = saveClass(timestamp, xnbList, studentList, teacherList, gList, gsList);
                            classyxnnum = xnbList.size();
                            classsxnnum = list.get(0);
                        } else {
                            classyxnnum = 0;
                            classsxnnum = 0;
                        }
                        setSchoolUpHistory(classyxznum, classsxznum, classyxnnum, classsxnnum, stuyupnum, stusupnum, gradeid, histories);
                    } catch (Exception e) {
                        grades.add(N_Utils.getGradeName(gradeid));
                    }
                }
            }


            if (N_Utils.isListNotEmpty(biyeclass)) {
                gradeid = biyeclass.get(0).getGradeid();
                try {
                    List<String> xnList = biyeclass.stream().filter(c -> c.getClasstype().equals(2))
                                                   .map(c -> c.getClassid().toString()).collect(Collectors.toList());
                    String xnClassIds = String.join(",", xnList);
                    if (N_Utils.isNotEmpty(xzClassIds)) {
                        classyxznum = xzList.size();
                        classsxznum = classMapper.updateClassState(3, xzClassIds);//修改班级状态
                    } else {
                        classyxznum = 0;
                        classsxznum = 0;
                    }
                    if (N_Utils.isNotEmpty(xnClassIds)) {
                        classyxnnum = xnList.size();
                        classsxnnum = classMapper.updateClassState(3, xnClassIds);//修改班级状态
                    } else {
                        classyxnnum = 0;
                        classsxnnum = 0;
                    }
                    if (N_Utils.isListNotEmpty(bystudents)) {
                        stuyupnum = bystudents.size();
                        stusupnum = userMapper.batchUpdateState(bystudents, 3);//修改学生状态为已毕业状态
                    } else {
                        stuyupnum = 0;
                        stusupnum = 0;
                    }
                    setSchoolUpHistory(classyxznum, classsxznum, classyxnnum, classsxnnum, stuyupnum, stusupnum, gradeid, histories);
                } catch (Exception e) {
                    grades.add(N_Utils.getGradeName(gradeid));
                }
            }
            if (N_Utils.isListNotEmpty(grades)) {
                String upcomm = String.join("、", grades)
                        + "由于数据有问题，导致升级失败，请联系运维人员进行处理！";
                throw new Exception(upcomm);
            }

            schoolMapper.upgrade(schoolid);//学校年份升级
            su.setUpresult(1);
        } catch (Exception e) {
            String message = e.getMessage();
            log.error("学年升级失败：" + message);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            su.setUpresult(2);
            su.setUpcomm(message);
            throw new RuntimeException(message);
        } finally {
            schoolUpgradeMapper.insertUseGeneratedKeys(su);
            if (N_Utils.isListNotEmpty(histories)) {
                Integer suId = su.getId();
                histories.forEach(h -> {
                    h.setSchoolid(schoolid);
                    h.setSuid(suId);
                });
                schoolUpgradeHistoryMapper.insertList(histories);
            }
        }
        return histories;
    }

    //学校学年升级年级记录赋值
    private void setSchoolUpHistory(int classyxznum, int classsxznum, int classyxnnum, int classsxnnum
            , int stuyupnum, int stusupnum, int gradeid, List<TSchoolUpgradeHistory> histories) {
        TSchoolUpgradeHistory suh = new TSchoolUpgradeHistory();
        suh.setGradeid(gradeid);
        suh.setClassyxznum(classyxznum);
        suh.setClasssxznum(classsxznum);
        suh.setClassyxnnum(classyxnnum);
        suh.setClasssxnnum(classsxnnum);
        suh.setStuyupnum(stuyupnum);
        suh.setStusupnum(stusupnum);
        histories.add(suh);
    }

    //保存班级信息
    private List<Integer> saveClass(int timestamp, List<TClass> classes, List<TClassStudent> cStudents
            , List<TClassTeacher> cTeachers, List<TGroup> groups, List<TGroupStudent> gStudents) {
        List<TClassStudent> classStudents = new ArrayList<>();//升级后的班级学生
        List<TClassTeacher> classTeachers = new ArrayList<>();//升级后的班级教师
        List<TGroupStudent> groupStudents = new ArrayList<>();//升级后的分组学生
        for (TClass c : classes) {
            //复制班级信息
            c.setYear(c.getYear() + 1);
            c.setGradeid(c.getGradeid() + 1);
            c.setClassstate(1);
            c.setCreatetime(timestamp);
        }
        int classnum = classMapper.insertList(classes);//保存升级后的班级信息
        for (TClass c : classes) {
            //复制班级信息
            Integer oldClassId = c.getClassid();
            Integer classid = c.getId();

            //复制班级学生信息
            boolean rtn = false;
            for (TClassStudent s : cStudents) {
                if (oldClassId.equals(s.getClassid())) {
                    s.setClassid(classid);
                    s.setCreatetime(timestamp);
                    classStudents.add(s);
                    rtn = true;
                } else if (!oldClassId.equals(s.getClassid()) && rtn) {
                    break;
                }
            }

            //复制班级教师信息
            rtn = false;
            for (TClassTeacher t : cTeachers) {
                if (oldClassId.equals(t.getClassid())) {
                    t.setClassid(classid);
                    t.setCreatetime(timestamp);
                    classTeachers.add(t);
                    rtn = true;
                } else if (!oldClassId.equals(t.getClassid()) && rtn) {
                    break;
                }
            }

            for (TGroup g : groups) {
                if (oldClassId.equals(g.getClassid())) {
                    //复制班级分组信息
                    g.setClassid(classid);
                    g.setCreatetime(timestamp);
                    break;
                }
            }
        }
        if (N_Utils.isListNotEmpty(groups)) groupMapper.insertList(groups);//保存升级后的班级分组信息
        for (TGroup g : groups) {
            Integer classid = g.getClassid();
            Integer oldGroupId = g.getGroupid();
            Integer groupid = g.getId();
            //复制分组学生信息
            boolean rtn = false;
            for (TGroupStudent s : gStudents) {
                if (oldGroupId.equals(s.getGroupid())) {
                    s.setClassid(classid);
                    s.setGroupid(groupid);
                    s.setCreatetime(timestamp);
                    groupStudents.add(s);
                    rtn = true;
                } else if (!oldGroupId.equals(s.getGroupid()) && rtn) {
                    break;
                }
            }
        }
        int stunum = 0;
        if (N_Utils.isListNotEmpty(classStudents)) {
            stunum = classStudentMapper.insertList(classStudents);//保存升级后的班级学生信息
        }
        if (N_Utils.isListNotEmpty(classTeachers)) classTeacherMapper.insertList(classTeachers);//保存升级后的班级教师信息
        if (N_Utils.isListNotEmpty(groupStudents)) groupStudentMapper.insertList(groupStudents);//保存升级后的分组学生信息
        List<Integer> list = new ArrayList<>();
        list.add(classnum);
        list.add(stunum);
        return list;
    }

    /**
     * 学年降级
     * @Param [schoolid, year]
     * @Author ywx
     * @Date 2020/6/16 13:51
     **/
    @Transactional(rollbackFor = Exception.class)
    public List<TSchoolUpgradeHistory> downgrade(Integer schoolid, Integer year, Integer createid) throws Exception {
        checkUpTime();

        int timestamp = N_Utils.getSecondTimestamp();
        TSchoolUpgrade su = new TSchoolUpgrade();
        su.setSchoolid(schoolid);
        su.setUptype(2);
        su.setOldyear(year);
        su.setNewyear(year - 1);
        su.setUptime(timestamp);
        su.setUpuserid(createid);
        int classyxznum = 0;//应升级行政班数量
        int classsxznum = 0;//实际升级行政班数量
        int classyxnnum = 0;//应升级虚拟班数量
        int classsxnnum = 0;//实际升级虚拟班数量
        int stuyupnum = 0;//应升级学生数量
        int stusupnum = 0;//实际升级学生数量
        int gradeid = 0;//学年升级id
        List<TSchoolUpgradeHistory> histories = new ArrayList<>();
        try {
            //之前已毕业的班级进行恢复
            List<TClass> biyeclass = classMapper.listClassBiyeBySchoolId(schoolid, year - 1, 3);

            if (N_Utils.isListNotEmpty(biyeclass)) {
                gradeid = biyeclass.get(0).getGradeid();
                try {
                    List<String> xzList = biyeclass.stream().filter(c -> c.getClasstype().equals(1))
                                                   .map(c -> c.getClassid().toString()).collect(Collectors.toList());
                    classyxznum = xzList.size();
                    List<String> xnList = biyeclass.stream().filter(c -> c.getClasstype().equals(2))
                                                   .map(c -> c.getClassid().toString()).collect(Collectors.toList());
                    classyxnnum = xnList.size();
                    String xzClassIds = String.join(",", xzList);
                    String xnClassIds = String.join(",", xnList);
                    List<Integer> bystudents = null;
                    if (N_Utils.isNotEmpty(xzClassIds)) {
                        bystudents = classMapper.listStudentIdByClassIds(xzClassIds);//要毕业的学生列表
                        stuyupnum = bystudents.size();
                    }

                    if(N_Utils.isNotEmpty(xzClassIds)) classsxznum = classMapper.updateClassState(1, xzClassIds);//修改班级状态
                    if(N_Utils.isNotEmpty(xnClassIds)) classsxnnum = classMapper.updateClassState(1, xnClassIds);//修改班级状态
                    if (N_Utils.isListNotEmpty(bystudents)) {
                        stusupnum = userMapper.batchUpdateState(bystudents, 1);//修改学生状态
                    }
                } catch (Exception e) {
                    String upcomm = N_Utils.getGradeName(gradeid)
                            + "由于数据有问题，导致升级失败，请联系运维人员进行处理！";
                    throw new Exception(upcomm);
                }
            }
            schoolMapper.downgrade(schoolid, year);
            su.setUpresult(1);
        } catch (Exception e) {
            String message = e.getMessage();
            log.error("学年降级失败：" + message);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            su.setUpresult(2);
            su.setUpcomm(message);
            throw new RuntimeException(message);
        } finally {
            schoolUpgradeMapper.insertUseGeneratedKeys(su);
            TSchoolUpgradeHistory suh = new TSchoolUpgradeHistory();
            suh.setSchoolid(schoolid);
            suh.setSuid(su.getId());
            suh.setGradeid(gradeid);
            suh.setClassyxznum(classyxznum);
            suh.setClasssxznum(classsxznum);
            suh.setClassyxnnum(classyxnnum);
            suh.setClasssxnnum(classsxnnum);
            suh.setStuyupnum(stuyupnum);
            suh.setStusupnum(stusupnum);
            schoolUpgradeHistoryMapper.insertSelective(suh);
            histories.add(suh);
        }
        return histories;
    }

    private void checkUpTime() throws Exception {
        //获取区域限制学年升级时间
        TCloud cloud = cloudMapper.getCloudUpTime();
        if (N_Utils.isEmpty(cloud.getStarttime())) throw new Exception("未设置升级时间，请联系区管理员");

        if (!ApiUtil.compareCurrDateTime(cloud.getStarttime(), cloud.getStoptime())) {
            throw new Exception("不在学年升级时间范围，禁止升级");
        }
    }

    /**
     * 获取学校详情
     * @Param [schoolid]
     * @Author ywx
     * @Date 2020/9/21 16:12
     * @return com.xhkjedu.model.gradeclass.TSchool
     **/
    public TSchool finById(Integer schoolid) {
        return schoolMapper.selectByPrimaryKey(schoolid);
    }

    //学校选择列表
    public List<Map<String,Object>> listForSel(String schoolname) {
        return schoolMapper.listForSel(schoolname);
    }

    //根据学校名称查找学校数量
    public Integer countBySchoolName(String schoolname) {
        return schoolMapper.countBySchoolName(schoolname);
    }

    //获取学校当前年份
    public Integer getYearById(Integer schoolid) {
        return schoolMapper.getYearById(schoolid);
    }

    //获取准考证号长度限制
    public Integer getLimiteNoLen(Integer schoolid) {
        return schoolMapper.getLimiteNoLen(schoolid);
    }

    //保存学校关联附属学校
    @Transactional(rollbackFor = Exception.class)
    public void saveSchoolFriend(SchoolParams params){
        //先移除学校关联学校
        schoolFriendMapper.deleteBySchoolid(params.getSchoolid());
        List<Integer> schoolids  = params.getSchoolids();

        if(N_Utils.isListNotEmpty(schoolids)){
            List<TSchoolFriend> schoolfriends = new ArrayList<>();

            int timestemp = N_Utils.getSecondTimestamp();
            for(Integer shid : schoolids){
                if(!params.getSchoolid().equals(shid)){
                    TSchoolFriend sf = new TSchoolFriend();
                    sf.setSchoolid(params.getSchoolid());
                    sf.setFschoolid(shid);
                    sf.setCreateid(params.getCreateid());
                    sf.setCreatetime(timestemp);
                    schoolfriends.add(sf);
                }
            }
            if(N_Utils.isListNotEmpty(schoolfriends)){
                schoolFriendMapper.insertList(schoolfriends);
            }
        }
    }

    //获取学校附属学校
    public List<Map<String,Object>> listFSchoolidsBySchoolid(Integer schoolid){
        return schoolFriendMapper.listFSchoolidsBySchoolid(schoolid);
    }

    //获取学校及附属学校班级
    public List<Map<String,Object>> listSchoolAndFriendSchools(Integer schoolid){
        List<Map<String,Object>> rtnlist = new ArrayList<>();
        List<Map<String,Object>> schools = schoolFriendMapper.listSchoolClass(schoolid);
        setSchoolGradeSclass(rtnlist,schools);
        List<Map<String,Object>> fschools = schoolFriendMapper.listFriendSchoolClass(schoolid);
        setFriendSchoolGradeSclass(rtnlist,fschools);
        return rtnlist;
    }

    private void setSchoolGradeSclass(List<Map<String,Object>> rtnlist,List<Map<String,Object>> schools){
        //处理学校
        Map<String,Object> schoolsmap = schools.get(0);
        LinkedHashMap<String,Object> schoolm = new LinkedHashMap<>();
        schoolm.put("schoolid",Integer.parseInt(schoolsmap.get("schoolid").toString()));
        schoolm.put("schoolname",schoolsmap.get("schoolname").toString());

        List<Map<String,Object>> gradelist = new ArrayList<>();
        //根据年级进行分组
        Map<String,List<Map<String,Object>>> grademap =  schools.stream().collect(Collectors.groupingBy(s -> s.get("gradeid").toString(), Collectors.toList()));
        for(Map.Entry<String, List<Map<String,Object>>> entry : grademap.entrySet()){
            LinkedHashMap<String,Object> gmap = new LinkedHashMap<>();
            gmap.put("gradeid",Integer.parseInt(entry.getKey()));
            List<Map<String,Object>> classlist = entry.getValue();
            for(Map<String,Object> cmap : classlist){
                cmap.remove("schoolid");
                cmap.remove("schoolname");
                cmap.remove("gradeid");
            }
            gmap.put("classes",classlist);
            gradelist.add(gmap);
        }
        schoolm.put("grades",gradelist);
        rtnlist.add(schoolm);
    }

    private void setFriendSchoolGradeSclass(List<Map<String,Object>> rtnlist,List<Map<String,Object>> schools){
        Map<String,List<Map<String,Object>>> schoolmap =  schools.stream().collect(Collectors.groupingBy(s -> s.get("schoolid").toString(), Collectors.toList()));
        for(Map.Entry<String, List<Map<String,Object>>> entry : schoolmap.entrySet()){
            Map<String,Object> schoolm = new LinkedHashMap<>();
            schoolm.put("schoolid",Integer.parseInt(entry.getKey()));
            Map<String,Object> schoolm2 = entry.getValue().get(0);
            schoolm.put("schoolname",schoolm2.get("schoolname").toString());
            List<Map<String,Object>> gradelist = entry.getValue();
            List<Map<String,Object>> savegradelist = new ArrayList<>();
            //根据年级进行分组
            Map<String,List<Map<String,Object>>> grademap =  gradelist.stream().collect(Collectors.groupingBy(s -> s.get("gradeid").toString(), Collectors.toList()));
            for(Map.Entry<String, List<Map<String,Object>>> entryg : grademap.entrySet()){
                Map<String,Object> gmap = new LinkedHashMap<>();
                gmap.put("gradeid",Integer.parseInt(entryg.getKey()));
                List<Map<String,Object>> classlist = entryg.getValue();
                for(Map<String,Object> cmap : classlist){
                    cmap.remove("schoolid");
                    cmap.remove("schoolname");
                    cmap.remove("gradeid");
                }
                gmap.put("classes",classlist);
                savegradelist.add(gmap);
            }
            schoolm.put("grades",savegradelist);

            rtnlist.add(schoolm);
        }
    }

    //获取学年列表
    public List<Integer> listYear(Integer schoolid) {
        return schoolMapper.listYear(schoolid);
    }

    //获取区域学年列表
    public List<Integer> listCloudYear() {
        return schoolMapper.listCloudYear();
    }

    //详情
    public Map<String,Object> findById(Integer schoolid) {
        Map<String,Object> map = schoolMapper.findById(schoolid);
        List<Map<String,Object>> friendSchools=schoolMapper.listSchool(schoolid);
        map.put("friendSchools",friendSchools);//伙伴学校列表
        List<Map<String,Object>> joinSchools=schoolMapper.listJoinSchool(schoolid);
        map.put("joinSchools",joinSchools);//加入学校列表
        return map;
    }

    //伙伴学校选择列表
    public List<Map<String,Object>> listFriendForSel(TSchool school) {
        return schoolMapper.listFriendForSel(school);
    }

    //学校升级记录
    public List<Map<String,Object>> listUpgrade(Integer schoolid) {
        return schoolMapper.listUpgrade(schoolid);
    }
}
