package com.qmth.distributed.print.api;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.qmth.boot.api.annotation.Aac;
import com.qmth.boot.api.annotation.BOOL;
import com.qmth.boot.api.constant.ApiConstant;
import com.qmth.boot.api.exception.ApiException;
import com.qmth.distributed.print.business.bean.params.LoginParam;
import com.qmth.distributed.print.business.bean.result.DictionaryResult;
import com.qmth.distributed.print.business.bean.result.EditResult;
import com.qmth.distributed.print.business.entity.ExamPrintPlan;
import com.qmth.distributed.print.business.entity.TBSyncTask;
import com.qmth.distributed.print.business.entity.TeachClazz;
import com.qmth.distributed.print.business.enums.DictionaryEnum;
import com.qmth.distributed.print.business.enums.LoginTypeEnum;
import com.qmth.distributed.print.business.service.*;
import com.qmth.distributed.print.business.util.PdfUtil;
import com.qmth.teachcloud.common.base.BaseEntity;
import com.qmth.teachcloud.common.bean.auth.AuthBean;
import com.qmth.teachcloud.common.bean.result.LoginResult;
import com.qmth.teachcloud.common.bean.result.UserLoginCheckResult;
import com.qmth.teachcloud.common.config.DictionaryConfig;
import com.qmth.teachcloud.common.contant.SystemConstant;
import com.qmth.teachcloud.common.entity.*;
import com.qmth.teachcloud.common.enums.*;
import com.qmth.teachcloud.common.enums.userPush.SpecialPrivilegeEnum;
import com.qmth.teachcloud.common.service.*;
import com.qmth.teachcloud.common.util.FileUtil;
import com.qmth.teachcloud.common.util.Result;
import com.qmth.teachcloud.common.util.ResultUtil;
import com.qmth.teachcloud.common.util.ServletUtil;
import io.swagger.annotations.*;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.entity.ContentType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Date: 2021/3/30.
 */
@Api(tags = "系统Controller")
@RestController
@RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + "/${prefix.url.common}")
public class SysController {
    private final static Logger log = LoggerFactory.getLogger(SysController.class);

    @Resource
    SysUserService sysUserService;

    @Resource
    BasicVerifyCodeService basicVerifyCodeService;

    @Resource
    DictionaryConfig dictionaryConfig;

    @Resource
    CommonCacheService commonCacheService;

    @Resource
    PrintCommonService printCommonService;

    @Resource
    TBTaskService tbTaskService;

    @Resource
    BasicAttachmentService basicAttachmentService;

    @Resource
    SysUserRoleService sysUserRoleService;

    @Resource
    TeachcloudCommonService teachcloudCommonService;

    @Resource
    SysOrgService sysOrgService;

    @Resource
    BasicMajorService basicMajorService;

    @Resource
    BasicClazzService basicClazzService;

    @Resource
    TeachClazzService teachClazzService;

    @Resource
    TeachCourseService teachCourseService;

    @Resource
    BasicStudentService basicStudentService;

    @Resource
    BasicSemesterService basicSemesterService;

    @Resource
    ExamPrintPlanService examPrintPlanService;

    @Resource
    TBSyncTaskService tbSyncTaskService;

    @Resource
    BasicCampusService basicCampusService;

    @Resource
    BasicExamService basicExamService;

    /**
     * 登录
     *
     * @param login
     * @return
     */
    @ApiOperation(value = "登录")
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "用户信息", response = LoginResult.class)})
    @Aac(auth = BOOL.FALSE)
    public Result login(@ApiParam(value = "用户信息", required = true) @Valid @RequestBody LoginParam login, BindingResult bindingResult) throws NoSuchAlgorithmException {
        if (bindingResult.hasErrors()) {
            return ResultUtil.error(bindingResult.getAllErrors().get(0).getDefaultMessage());
        }

        BasicSchool basicSchool = null;
        if (!login.getSchoolCode().equalsIgnoreCase(SystemConstant.ADMIN_CODE)) {
            basicSchool = commonCacheService.schoolCache(login.getSchoolCode());
            if (Objects.isNull(basicSchool)) {
                throw ExceptionResultEnum.SCHOOL_NO_DATA.exception();
            }
            if (Objects.nonNull(basicSchool.getEnable()) && !basicSchool.getEnable()) {
                throw ExceptionResultEnum.SCHOOL_ENABLE.exception();
            }
        }
        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
        if (Objects.nonNull(basicSchool)) {
            wrapper.lambda().eq(SysUser::getSchoolId, basicSchool.getId());
        }
        // 账号密码登录
        List<SysUser> userList = null;
        if (LoginTypeEnum.ACCOUNT.name().equals(login.getType())) {
            String loginName = login.getLoginName();
            String password = login.getPassword();
            // 非空校验
            if (StringUtils.isBlank(loginName)) {
                throw ExceptionResultEnum.ERROR.exception("用户名不能为空");
            }
            if (StringUtils.isBlank(password)) {
                throw ExceptionResultEnum.ERROR.exception("密码不能为空");
            }
            wrapper.lambda().and(w -> w.eq(SysUser::getLoginName, loginName).or().eq(SysUser::getCode, loginName));
            userList = sysUserService.list(wrapper);

            //用户不存在
            if (userList == null || userList.isEmpty()) {
                throw ExceptionResultEnum.ERROR.exception("用户不存在");
            }
            if (userList.size() > 1) {
                throw ExceptionResultEnum.ERROR.exception("查出多个用户");
            }

            SysUser sysUser = userList.get(0);
            if (!sysUser.getEnable()) {
                throw ExceptionResultEnum.ERROR.exception("用户被禁用");
            }

            if (!password.equals(userList.get(0).getPassword())) {
                throw ExceptionResultEnum.ERROR.exception("密码错误");
            }
        } else if (LoginTypeEnum.PHONE.name().equals(login.getType())) {
            String mobileNumber = login.getMobileNumber();
            String code = login.getCode();
            // 非空校验
            if (StringUtils.isBlank(mobileNumber)) {
                throw ExceptionResultEnum.ERROR.exception("手机号不能为空");
            }
            if (StringUtils.isBlank(code)) {
                throw ExceptionResultEnum.ERROR.exception("验证码不能为空");
            }
            wrapper.lambda().eq(SysUser::getMobileNumber, mobileNumber);
            userList = sysUserService.list(wrapper);

            //用户不存在
            if (userList == null || userList.isEmpty()) {
                throw ExceptionResultEnum.ERROR.exception("用户不存在");
            }
            if (userList.size() > 1) {
                throw ExceptionResultEnum.ERROR.exception("查出多个用户");
            }
            SysUser sysUser = userList.get(0);
            // 校验验证码
            sysUserService.checkSmsCode(sysUser.getId(), sysUser.getMobileNumber(), code);

            // 如果不是共用验证码再过期
            if (!dictionaryConfig.smsDomain().getSmsNormalCode().equals(login.getCode())) {
                sysUserService.expiredVerifyCode(sysUser.getId(), sysUser.getMobileNumber());
            }
        } else {
            throw ExceptionResultEnum.ERROR.exception("登录参数错误");
        }

        if (login.getSchoolCode().equalsIgnoreCase(SystemConstant.ADMIN_CODE)) {
            userList.forEach(o -> {
                AuthBean authBean = teachcloudCommonService.getUserAuth(o.getId());
                if (Objects.nonNull(authBean) && Objects.nonNull(authBean.getRoleList()) && authBean.getRoleList().size() > 0) {
                    if (Objects.nonNull(authBean.getSchool())) {
                        throw ExceptionResultEnum.ERROR.exception("用户无法通过当前页面登录");
                    }
                }
            });
        }
        SysUser sysUser = userList.get(0);
        LoginResult loginResult = teachcloudCommonService.login(login.getPassword(), sysUser, AppSourceEnum.SYSTEM);

        return ResultUtil.ok(loginResult);
    }

    /**
     * 登出
     *
     * @return
     */
    @ApiOperation(value = "登出")
    @RequestMapping(value = "/logout", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "返回信息", response = EditResult.class)})
    public Result logout() throws NoSuchAlgorithmException {
        SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
        teachcloudCommonService.removeUserInfo(sysUser.getId(), false);
        return ResultUtil.ok();
    }

    /**
     * 发送验证码
     *
     * @param loginParam
     * @return
     */
    @ApiOperation(value = "发送验证码")
    @RequestMapping(value = "/get_verify_code", method = RequestMethod.POST)
    @Aac(auth = BOOL.FALSE)
    public Result getVerifyCode(@RequestBody LoginParam loginParam) {
        String mobileNumber = loginParam.getMobileNumber();
        if (StringUtils.isBlank(mobileNumber)) {
            throw ExceptionResultEnum.ERROR.exception("手机号不能为空");
        }
        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(loginParam.getSchoolCode())) {
            BasicSchool basicSchool = commonCacheService.schoolCache(loginParam.getSchoolCode());
            if (Objects.nonNull(basicSchool)) {
                wrapper.lambda().eq(SysUser::getSchoolId, basicSchool.getId());
            }
        }
        wrapper.lambda().eq(SysUser::getMobileNumber, mobileNumber);
        List<SysUser> userList = sysUserService.list(wrapper);

        //用户不存在
        if (userList == null || userList.isEmpty()) {
            throw ExceptionResultEnum.ERROR.exception("手机号不存在");
        }
        if (userList.size() > 1) {
            throw ExceptionResultEnum.ERROR.exception("手机号绑定了多个用户");
        }
        SysUser sysUser = userList.get(0);

        if (!sysUser.getEnable()) {
            throw ExceptionResultEnum.ERROR.exception("手机号被禁用");
        }

        if (SystemConstant.strNotNull(mobileNumber)) {
            basicVerifyCodeService.sendVeirfyCode(mobileNumber, sysUser);
        }
        int pwdCount = sysUser.getPwdCount();
        List<SysRole> sysRoleList = sysUserRoleService.listRoleByUserId(sysUser.getId());
        if (sysRoleList.stream().map(SysRole::getType).collect(Collectors.toSet()).contains(RoleTypeEnum.ADMIN)) {
            mobileNumber = sysUser.getLoginName() + "（特权用户）";
            pwdCount = 1;
        }
        UserLoginCheckResult userLoginCheckResult = new UserLoginCheckResult(sysUser.getId(), mobileNumber, pwdCount);
        return ResultUtil.ok(userLoginCheckResult, "");
    }


    /**
     * 发送验证码（绑定手机号）
     *
     * @param loginParam
     * @return
     */
    @ApiOperation(value = "发送验证码（绑定手机号）")
    @RequestMapping(value = "/get_verify_code_for_bind", method = RequestMethod.POST)
    @Aac(auth = BOOL.FALSE)
    public Result getVerifyCodeForBind(@RequestBody LoginParam loginParam) {
        String loginName = loginParam.getLoginName();
        String password = loginParam.getPassword();
        String schoolCode = loginParam.getSchoolCode();
        String mobileNumber = loginParam.getMobileNumber();

        if (StringUtils.isBlank(schoolCode)) {
            throw ExceptionResultEnum.ERROR.exception("学校代码不能为空");
        }
        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
        BasicSchool basicSchool = commonCacheService.schoolCache(loginParam.getSchoolCode());
        if (Objects.isNull(basicSchool)) {
            throw ExceptionResultEnum.ERROR.exception("学校不存在");
        }

        if (StringUtils.isBlank(mobileNumber)) {
            throw ExceptionResultEnum.ERROR.exception("手机号不能为空");
        }

        wrapper.lambda().eq(SysUser::getSchoolId, basicSchool.getId())
                .eq(SysUser::getMobileNumber, mobileNumber);
        List<SysUser> userList = sysUserService.list(wrapper);

        if (userList != null && userList.size() > 0) {
            throw ExceptionResultEnum.ERROR.exception("手机号已使用");
        }

        // 根据账号/密码取用户ID
        if (StringUtils.isBlank(loginName)) {
            throw ExceptionResultEnum.ERROR.exception("账号不能为空");
        }
        if (StringUtils.isBlank(password)) {
            throw ExceptionResultEnum.ERROR.exception("密码不能为空");
        }
        QueryWrapper<SysUser> sysUserQueryWrapper = new QueryWrapper<>();
        sysUserQueryWrapper.lambda().eq(SysUser::getSchoolId, basicSchool.getId())
                .and(w -> w.eq(SysUser::getLoginName, loginName).or().eq(SysUser::getCode, loginName))
                .eq(SysUser::getPassword, password);
        SysUser sysUser = sysUserService.getOne(sysUserQueryWrapper);
        if (sysUser == null) {
            throw ExceptionResultEnum.ERROR.exception("用户数据异常");
        }

        // 发送短信验证码
        basicVerifyCodeService.sendVeirfyCode(mobileNumber, sysUser);

        int pwdCount = sysUser.getPwdCount();
        List<SysRole> sysRoleList = sysUserRoleService.listRoleByUserId(sysUser.getId());
        if (sysRoleList.stream().map(SysRole::getType).collect(Collectors.toSet()).contains(RoleTypeEnum.ADMIN)) {
            mobileNumber = sysUser.getLoginName() + "（特权用户）";
            pwdCount = 1;
        }
        UserLoginCheckResult userLoginCheckResult = new UserLoginCheckResult(sysUser.getId(), mobileNumber, pwdCount);
        return ResultUtil.ok(userLoginCheckResult, "");
    }

    @ApiOperation(value = "根据机构代码查询机构信息接口")
    @RequestMapping(value = "/school/query_by_school_code", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "学校信息", response = EditResult.class)})
    @Aac(auth = BOOL.FALSE)
    public Result queryBySchoolCode(@ApiParam(value = "机构code", required = true) @RequestParam String code) {
        if (Objects.nonNull(code) && code.contains("#")) {
            code = code.substring(0, code.indexOf("#"));
        }
        if (!code.equalsIgnoreCase(SystemConstant.ADMIN_CODE)) {
            BasicSchool basicSchool = commonCacheService.schoolCache(code);
            if (Objects.isNull(basicSchool)) {
                throw ExceptionResultEnum.SCHOOL_NO_DATA.exception();
            }
            Map<String, String> map = new HashMap<>();
            map.put(SystemConstant.LOGO, basicSchool.getLogo());
            map.put("name", basicSchool.getName());
            return ResultUtil.ok(map);
        } else {
            Map<String, String> map = new HashMap<>();
            map.put(SystemConstant.LOGO, dictionaryConfig.sysDomain().getAdminLogoUrl());
            map.put("name", null);
            return ResultUtil.ok(map);
        }
    }

    @ApiOperation(value = "文件上传接口")
    @RequestMapping(value = "/file/upload", method = RequestMethod.POST)
    @Transactional
    @ApiResponses({@ApiResponse(code = 200, message = "返回信息", response = EditResult.class)})
    public Result fileUpload(@ApiParam(value = "上传文件", required = true) @RequestParam MultipartFile file,
                             @ApiParam(value = "上传文件类型", required = true) @RequestParam UploadFileEnum type) {
        BasicAttachment basicAttachment = null;
        try {
            basicAttachment = printCommonService.saveAttachment(file, ServletUtil.getRequestMd5(), type);
            if (Objects.isNull(basicAttachment)) {
                throw ExceptionResultEnum.ATTACHMENT_ERROR.exception();
            }
        } catch (Exception e) {
            log.error(SystemConstant.LOG_ERROR, e);
            if (Objects.nonNull(basicAttachment)) {
                basicAttachmentService.deleteAttachment(basicAttachment);
            }
            if (e instanceof ApiException) {
                ResultUtil.error((ApiException) e, e.getMessage());
            } else {
                ResultUtil.error(e.getMessage());
            }
        }
        return ResultUtil.ok(new EditResult(basicAttachment.getId(), teachcloudCommonService.filePreview(basicAttachment.getPath()), basicAttachment.getPages()));
    }

    @ApiOperation(value = "考试试卷文件上传接口")
    @RequestMapping(value = "/file/exam_paper_upload", method = RequestMethod.POST)
    @Transactional
    @ApiResponses({@ApiResponse(code = 200, message = "返回信息", response = EditResult.class)})
    public Result fileExamPaperUpload(@ApiParam(value = "上传文件", required = true) @RequestParam MultipartFile file,
                                      @ApiParam(value = "上传文件类型", required = true) @RequestParam UploadFileEnum type) {
        Map<String, EditResult> resultMap = new HashMap<>();
        BasicAttachment basicOriginalAttachment = null;
        BasicAttachment basicTranslateAttachment = null;
        EditResult original = new EditResult();
        EditResult translate = new EditResult();
        File pdfOriginalFile = null;
        File localTempFile = null;
        try {
            pdfOriginalFile = FileUtil.multipartFileToFile(file);
            PageSizeEnum pageSizeEnum = PdfUtil.getPdfFormat(pdfOriginalFile);
            switch (pageSizeEnum) {
                case A3:
                    basicOriginalAttachment = printCommonService.saveAttachment(file, ServletUtil.getRequestMd5(), type);
                    if (Objects.isNull(basicOriginalAttachment)) {
                        throw ExceptionResultEnum.ATTACHMENT_ERROR.exception();
                    }
                    original.setId(basicOriginalAttachment.getId());
                    original.setUrl(teachcloudCommonService.filePreview(basicOriginalAttachment.getPath()));
                    original.setPages(basicOriginalAttachment.getPages());

                    BeanUtils.copyProperties(original, translate);
                    break;
                case A4:
                    basicOriginalAttachment = printCommonService.saveAttachment(file, ServletUtil.getRequestMd5(), type);
                    if (Objects.isNull(basicOriginalAttachment)) {
                        throw ExceptionResultEnum.ATTACHMENT_ERROR.exception();
                    }
                    original.setId(basicOriginalAttachment.getId());
                    original.setUrl(teachcloudCommonService.filePreview(basicOriginalAttachment.getPath()));
                    original.setPages(basicOriginalAttachment.getPages());

                    String destUrl = SystemConstant.PDF_TEMP_FILES_DIR + File.separator + file.getOriginalFilename();
                    localTempFile = new File(destUrl);
                    OutputStream out = new FileOutputStream(localTempFile);
                    PdfUtil.concatPDFs(new FileInputStream(pdfOriginalFile), out, false);
                    // File转换成MutipartFile
                    FileInputStream inputStream = new FileInputStream(localTempFile);
                    MultipartFile multipartFile = new MockMultipartFile(localTempFile.getName(), localTempFile.getName(), ContentType.APPLICATION_OCTET_STREAM.toString(), inputStream);
                    basicTranslateAttachment = printCommonService.saveAttachment(multipartFile, DigestUtils.md5Hex(multipartFile.getBytes()), type);
                    translate.setId(basicTranslateAttachment.getId());
                    translate.setUrl(teachcloudCommonService.filePreview(basicTranslateAttachment.getPath()));
                    translate.setPages(basicTranslateAttachment.getPages());
                    break;
                default:
                    throw ExceptionResultEnum.ERROR.exception("请上传A4或A3格式的试卷文件");
            }
            resultMap.put("original", original);
            resultMap.put("translate", translate);
        } catch (Exception e) {
            log.error(SystemConstant.LOG_ERROR, e);
            if (Objects.nonNull(basicOriginalAttachment)) {
                basicAttachmentService.deleteAttachment(basicOriginalAttachment);
            }
            if (Objects.nonNull(basicTranslateAttachment)) {
                basicAttachmentService.deleteAttachment(basicTranslateAttachment);
            }
            if (e instanceof ApiException) {
                ResultUtil.error((ApiException) e, e.getMessage());
            } else {
                ResultUtil.error(e.getMessage());
            }
        } finally {
            if (Objects.nonNull(localTempFile) && Objects.nonNull(dictionaryConfig.sysDomain()) && dictionaryConfig.sysDomain().isOss()) {
                FileUtil.deleteFile(localTempFile);
            }
            if (Objects.nonNull(pdfOriginalFile) && Objects.nonNull(dictionaryConfig.sysDomain()) && dictionaryConfig.sysDomain().isOss()) {
                FileUtil.deleteFile(pdfOriginalFile);
            }
        }
        return ResultUtil.ok(resultMap);
    }

    @ApiOperation(value = "文件下载接口")
    @RequestMapping(value = "/file/download", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "返回信息", response = EditResult.class)})
    public Result fileDownload(@ApiParam(value = "任务id", required = true) @RequestParam String id,
                               @ApiParam(value = "下载文件类型", required = true) @RequestParam DownloadFileEnum type) {
        String path = null;
        if (DownloadFileEnum.SYNC_REPORT.equals(type)) {
            TBSyncTask tbSyncTask = tbSyncTaskService.getById(SystemConstant.convertIdToLong(id));
            if (Objects.isNull(tbSyncTask)) {
                throw ExceptionResultEnum.SYNC_TASK_NO_DATA.exception();
            }
            path = tbSyncTask.getReportFilePath();
        } else {
            TBTask tbTask = tbTaskService.getById(Long.parseLong(id));
            if (Objects.isNull(tbTask)) {
                throw ExceptionResultEnum.TASK_NO_DATA.exception();
            }
            switch (type) {
                case IMPORT_FILE:
                    path = tbTask.getImportFilePath();
                    break;
                case TASK_REPORT:
                    path = tbTask.getReportFilePath();
                    break;
                case RESULT:
                    path = tbTask.getResultFilePath();
                    break;
            }
        }
        if (Objects.isNull(path)) {
            throw ExceptionResultEnum.PATH_NO_DATA.exception();
        }
        return ResultUtil.ok(new EditResult(teachcloudCommonService.filePreview(path)));
    }

    @ApiOperation(value = "文件预览接口")
    @RequestMapping(value = "/file/preview", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "返回信息", response = EditResult.class)})
    public Result filePreview(@ApiParam(value = "附件id", required = false, defaultValue = "") @RequestParam(value = "id", required = false, defaultValue = "") String id) {
        if (StringUtils.isBlank(id)) {
            throw ExceptionResultEnum.ERROR.exception("没有附件");
        } else {
            BasicAttachment basicAttachment = basicAttachmentService.getById(Long.parseLong(id));
            return ResultUtil.ok(new EditResult(teachcloudCommonService.filePreview(basicAttachment.getPath())));
        }
    }

    @ApiOperation(value = "查询用户权限")
    @RequestMapping(value = "/get_menu", method = RequestMethod.POST)
    public Result getMenu() {
        return ResultUtil.ok(sysUserRoleService.listByUserId());
    }

    @ApiOperation(value = "获取服务器时间")
    @RequestMapping(value = "/get_system_time", method = RequestMethod.POST)
    @Aac(auth = BOOL.FALSE)
    public Result getSystemTime() {
        return ResultUtil.ok(System.currentTimeMillis());
    }

    @ApiOperation(value = "获取系统编码")
    @RequestMapping(value = "/get_code", method = RequestMethod.POST)
//    @Aac(auth = BOOL.FALSE)
    public Result getCode(@ApiParam(value = "编码类型", required = true) @RequestParam SystemCodeEnum type) {
        SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
        String number = teachcloudCommonService.getSysIncrCode(type, sysUser);
        return ResultUtil.ok((Object) number);
    }

    @ApiOperation(value = "共用接口-查询字典")
    @RequestMapping(value = "/get_dictionary", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "查询成功", response = Result.class)})
    public Result findDictionaryList(@ApiParam(value = "校区id") @RequestParam(required = false) String campusId,
                                     @ApiParam(value = "学期id") @RequestParam(required = false) String semesterId,
                                     @ApiParam(value = "学院id") @RequestParam(required = false) String collegeId,
                                     @ApiParam(value = "专业id") @RequestParam(required = false) String majorId,
                                     @ApiParam(value = "班级id") @RequestParam(required = false) String clazzId,
                                     @ApiParam(value = "学生id") @RequestParam(required = false) String studentId,
                                     @ApiParam(value = "查询字典对象") @RequestParam(required = true) DictionaryEnum dictionaryEnum) {
        Long schoolId = SystemConstant.convertIdToLong(ServletUtil.getRequestHeaderSchoolId().toString());
        List<DictionaryResult> dictionaryResultList = new ArrayList<>();
        switch (dictionaryEnum) {
            case CAMPUS:
                List<BasicCampus> basicCampusList = basicCampusService.list(new QueryWrapper<BasicCampus>().lambda().eq(BasicCampus::getSchoolId, schoolId));
                dictionaryResultList = basicCampusList.stream().map(e -> {
                    DictionaryResult dictionaryResult = new DictionaryResult();
                    dictionaryResult.setName(e.getCampusName());
                    dictionaryResult.setCode(e.getCampusCode());
                    dictionaryResult.setId(e.getId());
                    return dictionaryResult;
                }).collect(Collectors.toList());
                break;
            case SEMESTER:
                List<BasicSemester> basicSemesterList = basicSemesterService.list(new QueryWrapper<BasicSemester>().lambda().eq(BasicSemester::getSchoolId, schoolId).eq(BasicSemester::getEnable, true));
                dictionaryResultList = basicSemesterList.stream().map(e -> {
                    DictionaryResult dictionaryResult = new DictionaryResult();
                    dictionaryResult.setId(e.getId());
                    dictionaryResult.setCode(e.getCode());
                    dictionaryResult.setName(e.getName());
                    return dictionaryResult;
                }).collect(Collectors.toList());
                break;
            case COLLEGE:
                if (Objects.nonNull(semesterId)) {
                    QueryWrapper<BasicExam> basicExamQueryWrapper = new QueryWrapper<>();
                    basicExamQueryWrapper.lambda().eq(BasicExam::getSemesterId, SystemConstant.convertIdToLong(semesterId));
                    List<BasicExam> basicExamList = basicExamService.list(basicExamQueryWrapper);
                    if (Objects.nonNull(basicExamList) && basicExamList.size() > 0) {
                        List<Long> examIdList = basicExamList.stream().map(BaseEntity::getId).collect(Collectors.toList());
                        QueryWrapper<ExamPrintPlan> examPrintPlanQueryWrapper = new QueryWrapper<>();
                        examPrintPlanQueryWrapper.lambda().in(ExamPrintPlan::getExamId, examIdList);
                        List<ExamPrintPlan> examPrintPlanList = examPrintPlanService.list(examPrintPlanQueryWrapper);
                        if (Objects.nonNull(examPrintPlanList) && examPrintPlanList.size() > 0) {
                            Set<Long> orgIdSet = examPrintPlanList.stream().map(ExamPrintPlan::getOrgId).collect(Collectors.toSet());
                            QueryWrapper<SysOrg> sysOrgQueryWrapper = new QueryWrapper<>();
                            sysOrgQueryWrapper.lambda().in(SysOrg::getId, orgIdSet);
                            List<SysOrg> sysOrgList = sysOrgService.list(sysOrgQueryWrapper);
                            List<SysOrg> newSysOrgList = new ArrayList<>(sysOrgList);
                            for (SysOrg s : sysOrgList) {
                                if (s.getType() == OrgTypeEnum.SCHOOL) {
                                    newSysOrgList.addAll(sysOrgService.findByConnectByRootOrgId(s.getId()));
                                } else if (s.getType() == OrgTypeEnum.TEACHING_ROOM || s.getType() == OrgTypeEnum.FACULTY || s.getType() == OrgTypeEnum.PRINTING_HOUSE) {
                                    newSysOrgList.addAll(sysOrgService.findByConnectByParentId(s.getId(), true, false));
                                }
                            }
                            Map<Long, SysOrg> sysOrgMap = new LinkedHashMap<>();
                            for (SysOrg s : newSysOrgList) {
                                if (s.getType() == OrgTypeEnum.COLLEGE) {
                                    sysOrgMap.put(s.getId(), s);
                                }
                            }
                            List<DictionaryResult> finalDictionaryResultList = dictionaryResultList;
                            sysOrgMap.forEach((k, v) -> {
                                DictionaryResult dictionaryResult = new DictionaryResult();
                                dictionaryResult.setId(v.getId());
                                dictionaryResult.setCode(v.getCode());
                                dictionaryResult.setName(v.getName());
                                finalDictionaryResultList.add(dictionaryResult);
                            });
                        }
                    }
                } else {
                    List<SysOrg> sysOrgList = sysOrgService.list(new QueryWrapper<SysOrg>().lambda().eq(SysOrg::getSchoolId, schoolId).eq(SysOrg::getEnable, true));
                    dictionaryResultList = sysOrgList.stream().map(e -> {
                        DictionaryResult dictionaryResult = new DictionaryResult();
                        dictionaryResult.setId(e.getId());
                        dictionaryResult.setCode(e.getCode());
                        dictionaryResult.setName(e.getName());
                        return dictionaryResult;
                    }).collect(Collectors.toList());
                }
                break;
            case MAJOR:
                QueryWrapper<BasicMajor> majorQueryWrapper = new QueryWrapper<>();
                majorQueryWrapper.lambda()
                        .eq(BasicMajor::getSchoolId, schoolId)
                        .eq(BasicMajor::getEnable, true);

                if (SystemConstant.longNotNull(SystemConstant.convertIdToLong(collegeId))) {
                    majorQueryWrapper.lambda().eq(BasicMajor::getBelongOrgId, collegeId);
                }
                List<BasicMajor> basicMajorList = basicMajorService.list(majorQueryWrapper);
                dictionaryResultList = basicMajorList.stream().map(e -> {
                    DictionaryResult dictionaryResult = new DictionaryResult();
                    dictionaryResult.setId(e.getId());
                    dictionaryResult.setCode(e.getCode());
                    dictionaryResult.setName(e.getName());
                    return dictionaryResult;
                }).collect(Collectors.toList());
                break;
            case CLAZZ:
                QueryWrapper<BasicClazz> clazzQueryWrapper = new QueryWrapper<>();
                clazzQueryWrapper.lambda().eq(BasicClazz::getSchoolId, schoolId).eq(BasicClazz::getEnable, true);
                if (SystemConstant.longNotNull(SystemConstant.convertIdToLong(campusId))) {
                    clazzQueryWrapper.lambda().eq(BasicClazz::getCampusId, campusId);
                }
                if (SystemConstant.longNotNull(SystemConstant.convertIdToLong(majorId))) {
                    clazzQueryWrapper.lambda().eq(BasicClazz::getMajorId, majorId);
                }
                // 基础班
                List<BasicClazz> basicClazzList = basicClazzService.list(clazzQueryWrapper);
                List<DictionaryResult> resultBasicClazzList = basicClazzList.stream().map(e -> {
                    DictionaryResult dictionaryResult = new DictionaryResult();
                    dictionaryResult.setId(e.getId());
                    dictionaryResult.setCode(e.getClazzCode());
                    dictionaryResult.setName(e.getClazzName());
                    return dictionaryResult;
                }).collect(Collectors.toList());

                dictionaryResultList.addAll(resultBasicClazzList);
                break;
            case ALL_CLAZZ: //针对归档管理临时处理用
                QueryWrapper<BasicClazz> basicClazzQueryWrapper = new QueryWrapper<>();
                basicClazzQueryWrapper.lambda().eq(BasicClazz::getSchoolId, schoolId).eq(BasicClazz::getEnable, true);
                if (SystemConstant.longNotNull(SystemConstant.convertIdToLong(campusId))) {
                    basicClazzQueryWrapper.lambda().eq(BasicClazz::getCampusId, campusId);
                }
                if (SystemConstant.longNotNull(SystemConstant.convertIdToLong(majorId))) {
                    basicClazzQueryWrapper.lambda().eq(BasicClazz::getMajorId, majorId);
                }
                // 基础班
                List<BasicClazz> bClazzList = basicClazzService.list(basicClazzQueryWrapper);
                List<DictionaryResult> rbClazzList = bClazzList.stream().map(e -> {
                    DictionaryResult dictionaryResult = new DictionaryResult();
                    dictionaryResult.setId(e.getId());
                    dictionaryResult.setCode(e.getClazzCode());
                    dictionaryResult.setName(e.getClazzName());
                    return dictionaryResult;
                }).collect(Collectors.toList());

                dictionaryResultList.addAll(rbClazzList);

                // 教学班
                QueryWrapper<TeachClazz> teachClazzQueryWrapper = new QueryWrapper<>();
                teachClazzQueryWrapper.lambda().in(TeachClazz::getSchoolId, schoolId);
                List<TeachClazz> teachClazzList = teachClazzService.list(teachClazzQueryWrapper);
                List<DictionaryResult> resultTeachClazzList = teachClazzList.stream().map(e -> {
                    DictionaryResult dictionaryResult = new DictionaryResult();
                    dictionaryResult.setId(e.getId());
                    dictionaryResult.setCode(e.getTeachClazzCode());
                    dictionaryResult.setName(e.getTeachClazzName());
                    return dictionaryResult;
                }).collect(Collectors.toList());

                if (resultTeachClazzList.size() > 0) {
                    dictionaryResultList.addAll(resultTeachClazzList);
                }
                break;
            case STUDENT:
                QueryWrapper<BasicStudent> studentQueryWrapper = new QueryWrapper<>();
                studentQueryWrapper.lambda().eq(BasicStudent::getSchoolId, schoolId).eq(BasicStudent::getEnable, true);
                if (SystemConstant.longNotNull(SystemConstant.convertIdToLong(campusId))) {
                    studentQueryWrapper.lambda().eq(BasicStudent::getCampusId, campusId);
                }
                if (SystemConstant.longNotNull(SystemConstant.convertIdToLong(collegeId))) {
                    studentQueryWrapper.lambda().eq(BasicStudent::getBelongOrgId, collegeId);
                }
                if (SystemConstant.longNotNull(SystemConstant.convertIdToLong(majorId))) {
                    studentQueryWrapper.lambda().eq(BasicStudent::getMajorId, majorId);
                }
                if (SystemConstant.longNotNull(SystemConstant.convertIdToLong(clazzId))) {
                    studentQueryWrapper.lambda().eq(BasicStudent::getClazzId, clazzId);
                }
                if (SystemConstant.longNotNull(SystemConstant.convertIdToLong(studentId))) {
                    studentQueryWrapper.lambda().eq(BasicStudent::getId, studentId);
                }
                List<BasicStudent> basicStudentList = basicStudentService.list(studentQueryWrapper);
                dictionaryResultList = basicStudentList.stream().map(e -> {
                    DictionaryResult dictionaryResult = new DictionaryResult();
                    dictionaryResult.setId(e.getId());
                    dictionaryResult.setCode(e.getStudentCode());
                    dictionaryResult.setName(e.getStudentName());
                    return dictionaryResult;
                }).collect(Collectors.toList());
                break;
        }
        return ResultUtil.ok(dictionaryResultList);
    }

    /**
     * 获取用户阅卷角色
     *
     * @return
     */
    @ApiOperation(value = "获取用户阅卷角色")
    @RequestMapping(value = "/get_open_role", method = RequestMethod.POST)
    public Result getOpenRole() {
        SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
        SpecialPrivilegeEnum userSpecialPrivilege = sysUserService.findUserSpecialPrivilegeByUserId(sysUser.getId());
        List<SpecialPrivilegeEnum> list = new ArrayList<>();
        if (!SpecialPrivilegeEnum.UNIDENTIFIED.equals(userSpecialPrivilege)) {
            if (SpecialPrivilegeEnum.COMPOSITE.equals(userSpecialPrivilege)) {
                list.add(SpecialPrivilegeEnum.MARKER);
                list.add(SpecialPrivilegeEnum.SUBJECT_HEADER);
            } else {
                list.add(userSpecialPrivilege);
            }
        }
        return ResultUtil.ok(list);
    }
}
