package com.qmth.sop.server.api;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.gson.reflect.TypeToken;
import com.qmth.boot.api.annotation.Aac;
import com.qmth.boot.api.constant.ApiConstant;
import com.qmth.boot.api.exception.ApiException;
import com.qmth.boot.core.cache.service.CacheService;
import com.qmth.sop.common.annotation.OperationLog;
import com.qmth.sop.business.bean.dto.*;
import com.qmth.sop.business.bean.params.LoginParam;
import com.qmth.sop.business.bean.result.*;
import com.qmth.sop.business.cache.CommonCacheService;
import com.qmth.sop.business.entity.*;
import com.qmth.sop.business.service.*;
import com.qmth.sop.business.util.ImportExportUtil;
import com.qmth.sop.common.contant.SystemConstant;
import com.qmth.sop.common.enums.*;
import com.qmth.sop.common.util.*;
import io.swagger.annotations.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.io.InputStream;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 * 系统公用 前端控制器
 * </p>
 *
 * @author wangliang
 * @since 2023-07-17
 */
@Api(tags = "系统公用Controller")
@RestController
@RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + SystemConstant.PREFIX_URL_COMMON)
public class SysController {
    private final static Logger log = LoggerFactory.getLogger(SysController.class);

    @Resource
    SysUserService sysUserService;

    @Resource
    CommonCacheService commonCacheService;

    @Resource
    BasicAttachmentService basicAttachmentService;

    @Resource
    ImportExportUtil importExportUtil;

    @Resource
    TBTaskService tbTaskService;

    @Resource
    SysUserRoleService sysUserRoleService;

    @Resource
    BasicVerifyCodeService basicVerifyCodeService;

    @Resource
    SysOrgService sysOrgService;

    @Resource
    SysRoleService sysRoleService;

    @Resource
    CacheService cacheService;

    @Resource
    TBServiceService tbServiceService;

    @Resource
    FileStoreUtil fileStoreUtil;

    @Resource
    TBUserArchivesService tbUserArchivesService;

    @Resource
    SysConfigService sysConfigService;

    @Resource
    SysLogService sysLogService;

    @ApiOperation(value = "登录")
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "用户信息", response = LoginResult.class)})
    @Aac(auth = 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());
        }
        SysUser sysUser = null;
        List<SysUser> sysUserList = null;
        if (login.getType() == LoginTypeEnum.ACCOUNT) {//账号登录
            // 非空校验
            Optional.ofNullable(login.getLoginName()).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("手机号/账号不能为空"));
            Optional.ofNullable(login.getPassword()).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("密码不能为空"));
            sysUserList = sysUserService.list(new QueryWrapper<SysUser>().lambda().eq(SysUser::getLoginName, login.getLoginName()).or().eq(SysUser::getMobileNumber, login.getLoginName()));
            if (CollectionUtils.isEmpty(sysUserList)) {
                throw ExceptionResultEnum.ERROR.exception("对不起，您不是系统用户，无法进行登录！");
            }
            if (sysUserList.size() > 1) {
                throw ExceptionResultEnum.ERROR.exception("查出多个用户");
            }
            sysUser = sysUserList.get(0);

            if (!sysUser.getEnable()) {
                throw ExceptionResultEnum.ERROR.exception("该用户已禁用");
            }
            if (!Objects.equals(sysUser.getPassword(), login.getPassword())) {
                throw ExceptionResultEnum.ERROR.exception("用户名或密码错误");
            }
        } else {//验证码模式
            Optional.ofNullable(login.getMobileNumber()).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("手机号不能为空"));
            Optional.ofNullable(login.getCode()).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("验证码不能为空"));

            SysConfig sysConfig = commonCacheService.addSysConfigCache(SystemConstant.SMS_NORMAL_CODE);
            Optional.ofNullable(sysConfig).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("未配置万能短信验证码"));

            sysUserList = sysUserService.list(new QueryWrapper<SysUser>().lambda().eq(SysUser::getMobileNumber, login.getMobileNumber()));
            if (CollectionUtils.isEmpty(sysUserList)) {
                throw ExceptionResultEnum.ERROR.exception("对不起，您不是系统用户，无法进行登录！");
            }
            if (sysUserList.size() > 1) {
                throw ExceptionResultEnum.ERROR.exception("查出多个用户");
            }
            sysUser = sysUserList.get(0);
            if (!sysUser.getEnable()) {
                throw ExceptionResultEnum.ERROR.exception("该用户已禁用");
            }
            // 校验验证码
            sysUserService.checkSmsCode(sysUser.getId(), sysUser.getMobileNumber(), login.getCode());

            if (!Objects.equals(sysConfig.getConfigValue().trim(), login.getCode().trim())) {
                sysUserService.expiredVerifyCode(sysUser.getId(), sysUser.getMobileNumber());
            }
        }
        if (Objects.nonNull(sysUser.getSource()) && sysUser.getSource() == UserSourceEnum.ARCHIVES) {//如果是档案用户，需校验是否在认证有效期内
            UserArchivesResult userArchivesResult = tbUserArchivesService.findUserArchivesByArchivesIdORUserId(null, sysUser.getId());
            Optional.ofNullable(userArchivesResult).orElseThrow(() -> ExceptionResultEnum.USER_ARCHIVES_NO_DATA.exception());
            if (Objects.isNull(userArchivesResult.getAuthenticationValidTime()) || System.currentTimeMillis() >= userArchivesResult.getAuthenticationValidTime().longValue()) {
                throw ExceptionResultEnum.ERROR.exception("该档案用户认证状态已失效");
            }
            if (!userArchivesResult.getEnable()) {
                throw ExceptionResultEnum.ERROR.exception("该档案用户已禁用");
            }
        }
        LoginResult result = sysUserService.login(login.getPassword(), sysUser, AppSourceEnum.SYSTEM);
        try {
            sysLogService.saveLogWithNoAuth(sysUser.getId(), "用户登录", LogTypeEnum.LOGIN);
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return ResultUtil.ok(result);
    }

    @ApiOperation(value = "登出")
    @RequestMapping(value = "/logout", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "返回信息", response = Object.class)})
    @OperationLog(detail = "用户登出（注销）", logType = LogTypeEnum.LOGOUT)
    public Result logout() throws NoSuchAlgorithmException {
        SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
        return ResultUtil.ok(sysUserService.removeUserInfo(sysUser.getId(), false));
    }

    @ApiOperation(value = "文件上传接口")
    @RequestMapping(value = "/file/upload", method = RequestMethod.POST)
    @Transactional
    @ApiResponses({@ApiResponse(code = 200, message = "返回信息", response = AttachmentResult.class)})
    @OperationLog(logType = LogTypeEnum.UN_KNOW)
    public Result fileUpload(@ApiParam(value = "上传文件", required = true) @RequestParam MultipartFile file,
                             @ApiParam(value = "上传文件类型", required = true) @RequestParam UploadFileEnum type,
                             @ApiParam(value = "小程序签名key") @RequestParam(required = false) String key) throws Exception {
        BasicAttachment basicAttachment = null;
        try {
            basicAttachment = basicAttachmentService.saveAttachment(file, type, key);
        } catch (Exception e) {
            log.error(SystemConstant.LOG_ERROR, e);
            basicAttachmentService.deleteAttachment(basicAttachment);
            if (e instanceof ApiException) {
                ResultUtil.error((ApiException) e, ((ApiException) e).getCode(), e.getMessage());
            } else {
                ResultUtil.error(e.getMessage());
            }
        }
        JSONObject jsonObject = JSONObject.parseObject(basicAttachment.getPath());
        String filePath = (String) jsonObject.get(SystemConstant.PATH);
        return ResultUtil.ok(new AttachmentResult(basicAttachment.getId(), basicAttachmentService.filePreview(basicAttachment.getPath()), filePath, key));
    }

    @ApiOperation(value = "下载导入模板")
    @RequestMapping(value = "/download_import_template", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "返回信息", response = Object.class)})
    @OperationLog(logType = LogTypeEnum.EXPORT)
    public void downloadImportTemplate(@ApiParam(value = "模版类型", required = true) @RequestParam ImportTemplateEnum type) throws IOException {
        List<ImportTemplateEnum> templateEnums = Stream.of(ImportTemplateEnum.values()).map(m -> m).collect(Collectors.toList());
        if (!templateEnums.contains(type)) {
            throw ExceptionResultEnum.ERROR.exception("不支持的模板类型");
        }
        InputStream inputStream = this.getClass().getResourceAsStream("/" + SystemConstant.STATIC + "/" + type.getTemplateName());
        // 导出
        importExportUtil.outputFile(inputStream, type.getFileName());
    }

    @ApiOperation(value = "文件下载接口")
    @RequestMapping(value = "/file/download", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "返回信息", response = EditResult.class)})
    @OperationLog(logType = LogTypeEnum.UN_KNOW)
    public Result fileDownload(@ApiParam(value = "任务id", required = true) @RequestParam Long taskId,
                               @ApiParam(value = "下载文件类型", required = true) @RequestParam DownloadFileEnum type) throws Exception {
        TBTask tbTask = tbTaskService.getById(taskId);
        Optional.ofNullable(tbTask).orElseThrow(() -> ExceptionResultEnum.TASK_NO_DATA.exception());
        String path = null, content = null;
        switch (type) {
            case IMPORT_FILE:
                path = tbTask.getImportFilePath();
                break;
            case REPORT_FILE:
                path = tbTask.getReportFilePath();
                JSONObject jsonObject = JSONObject.parseObject(path);
                UploadFileEnum uploadFileEnum = Enum.valueOf(UploadFileEnum.class, (String) jsonObject.get(SystemConstant.UPLOAD_TYPE));
                String filePath = (String) jsonObject.get(SystemConstant.PATH);
                HttpServletResponse response = ServletUtil.getResponse();
                byte[] bytes = fileStoreUtil.ossDownload(filePath, uploadFileEnum.getFssType());
                content = new String(bytes, sysConfigService.findByConfigKey(SystemConstant.SYS_CONFIG_KEY_CHARSETS).getConfigValue());
//                response.setContentType("text/html; charset=utf-8");
//                response.getWriter().print(string);
                break;
            case EXPORT_FILE:
                path = tbTask.getResultFilePath();
                break;
            default:
                break;
        }
        Optional.ofNullable(path).orElseThrow(() -> ExceptionResultEnum.PATH_NO_DATA.exception());
        return ResultUtil.ok(new EditResult(basicAttachmentService.filePreview(path), content));
    }

    @ApiOperation(value = "小程序签名预览接口")
    @RequestMapping(value = "/file/preview/app", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "返回信息", response = EditResult.class)})
    @OperationLog(logType = LogTypeEnum.PREVIEW)
    public Result filePreviewApp(@ApiParam(value = "小程序签名key", required = true) @RequestParam String key) throws Exception {
        List<BasicAttachment> basicAttachmentList = basicAttachmentService.filePreviewApp(key);
        if (CollectionUtils.isEmpty(basicAttachmentList)) {
            throw ExceptionResultEnum.ATTACHMENT_NO_DATA.exception();
        }
        List<EditResult> editResultList = new ArrayList<>(basicAttachmentList.size());
        for (BasicAttachment b : basicAttachmentList) {
            editResultList.add(new EditResult(b.getId(), basicAttachmentService.filePreview(b.getPath()), key));
        }
        return ResultUtil.ok(editResultList);
    }

    @ApiOperation(value = "小程序文件上传接口")
    @RequestMapping(value = "/file/upload/app", method = RequestMethod.POST)
    @Transactional
    @ApiResponses({@ApiResponse(code = 200, message = "返回信息", response = AttachmentResult.class)})
    @Aac(auth = false)
    public Result fileUploadApp(@ApiParam(value = "上传文件", required = true) @RequestParam MultipartFile file,
                                @ApiParam(value = "上传文件类型", required = true) @RequestParam UploadFileEnum type,
                                @ApiParam(value = "小程序签名key") @RequestParam(required = false) String key) throws Exception {
        BasicAttachment basicAttachment = null;
        try {
            basicAttachment = basicAttachmentService.saveAttachmentNoAuth(file, type, key);
        } catch (Exception e) {
            log.error(SystemConstant.LOG_ERROR, e);
            basicAttachmentService.deleteAttachment(basicAttachment);
            if (e instanceof ApiException) {
                ResultUtil.error((ApiException) e, ((ApiException) e).getCode(), e.getMessage());
            } else {
                ResultUtil.error(e.getMessage());
            }
        }
        JSONObject jsonObject = JSONObject.parseObject(basicAttachment.getPath());
        String filePath = (String) jsonObject.get(SystemConstant.PATH);
        return ResultUtil.ok(new AttachmentResult(basicAttachment.getId(), basicAttachmentService.filePreview(basicAttachment.getPath()), filePath, key));
    }


    @ApiOperation(value = "文件预览接口")
    @RequestMapping(value = "/file/preview", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "返回信息", response = EditResult.class)})
    @OperationLog(logType = LogTypeEnum.PREVIEW)
    public Result filePreview(@ApiParam(value = "附件id数组", required = true) @RequestBody List<Long> ids) throws Exception {
        if (CollectionUtils.isEmpty(ids)) {
            throw ExceptionResultEnum.PARAMS_ERROR.exception("附件id数组不能为空");
        }
        List<EditResult> editResultList = new ArrayList<>(ids.size());
        for (Long l : ids) {
            editResultList.add(new EditResult(l, basicAttachmentService.filePreview(l)));
        }
        return ResultUtil.ok(editResultList);
    }

    @ApiOperation(value = "发送验证码")
    @RequestMapping(value = "/get_verify_code", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "返回信息", response = Object.class)})
    @Aac(auth = false)
    public Result getVerifyCode(@RequestBody LoginParam login) {
        Optional.ofNullable(login.getMobileNumber()).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("手机号不能为空"));
        List<SysUser> userList = sysUserService.list(new QueryWrapper<SysUser>().lambda().eq(SysUser::getMobileNumber, login.getMobileNumber()));

        if (!login.getMobileNumber().matches(SystemConstant.REGULAR_EXPRESSION_OF_PHONE)) {
            throw ExceptionResultEnum.ERROR.exception("手机号[" + login.getMobileNumber() + "]不符合输入规范");
        }

        //用户不存在
        if (CollectionUtils.isEmpty(userList)) {
            throw ExceptionResultEnum.ERROR.exception("手机号不存在");
        }
        if (userList.size() > 1) {
            throw ExceptionResultEnum.ERROR.exception("手机号绑定了多个用户");
        }

        SysUser sysUser = userList.get(0);
        if (!sysUser.getEnable()) {
            throw ExceptionResultEnum.ERROR.exception("手机号被禁用");
        }
        return ResultUtil.ok(basicVerifyCodeService.sendVeirfyCode(login.getMobileNumber(), sysUser));
    }

    @ApiOperation(value = "查询用户权限")
    @RequestMapping(value = "/get_menu", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "返回信息", response = MenuResult.class)})
    public Result getMenu() {
        return ResultUtil.ok(sysUserRoleService.listByUserId());
    }

    @ApiOperation(value = "获取服务器时间")
    @RequestMapping(value = "/get_system_time", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "返回信息", response = Object.class)})
    @Aac(auth = false)
    public Result getSystemTime() {
        return ResultUtil.ok(System.currentTimeMillis());
    }

    @ApiOperation(value = "获取机构下所有用户")
    @RequestMapping(value = "/get_org_user_list", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "返回信息", response = OrgDto.class)})
    public Result getOrgUserList() {
        return ResultUtil.ok(sysOrgService.listOrgTree(true));
    }

    @ApiOperation(value = "获取所有角色")
    @RequestMapping(value = "/get_role_list", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "返回信息", response = RoleDto.class)})
    public Result getRoleList() {
        return ResultUtil.ok(sysRoleService.listRolesByUserId(null));
    }

    @ApiOperation(value = "获取所有用户")
    @RequestMapping(value = "/get_user_list", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "返回信息", response = UserDto.class)})
    public Result getUserList() {
        IPage<UserDto> userDtoIPage = sysUserService.query(new Page<>(SystemConstant.PAGE_NUMBER_MIN, SystemConstant.PAGE_SIZE_MAX_SELECT), null, null, null, null);
        return ResultUtil.ok(userDtoIPage.getRecords());
    }

    @ApiOperation(value = "获取所有用户（动态表单用）")
    @RequestMapping(value = "/get_user_list/form_widget", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "返回信息", response = FormWidgetDto.class)})
    public Result getUserListFormWidget(@ApiParam(value = "用户来源", required = true) @RequestParam UserSourceEnum userSource) {
        return ResultUtil.ok(sysUserService.queryUser(userSource));
    }

    @ApiOperation(value = "根据角色类型获取所有用户")
    @RequestMapping(value = "/get_user_list_by_role_type", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "返回信息", response = UserDto.class)})
    public Result getUserListByRoleType(@ApiParam(value = "角色类型", required = true) @RequestParam RoleTypeEnum roleTypeEnum) {
        return ResultUtil.ok(sysUserRoleService.userListByRoleType(Arrays.asList(roleTypeEnum)));
    }

    @ApiOperation(value = "获取所有机构")
    @RequestMapping(value = "/get_org_list", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "返回信息", response = UserDto.class)})
    public Result getOrgList() {
        List<SysOrg> sysOrgList = sysOrgService.list();
        List<OrgDtoNotTree> orgDtoNotTreeList = GsonUtil.fromJson(GsonUtil.toJson(sysOrgList), new TypeToken<List<OrgDtoNotTree>>() {
        }.getType());
        return ResultUtil.ok(orgDtoNotTreeList);
    }

    @ApiOperation(value = "忘记密码")
    @RequestMapping(value = "/forget_password", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "返回信息", response = Object.class)})
    @Aac(auth = false)
    @Transactional
    public Result forgetPassword(@RequestBody LoginParam login) throws NoSuchAlgorithmException {
        Optional.ofNullable(login.getMobileNumber()).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("手机号不能为空"));
        Optional.ofNullable(login.getCode()).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("验证码不能为空"));
        Optional.ofNullable(login.getPassword()).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("密码不能为空"));

        SysConfig sysConfig = commonCacheService.addSysConfigCache(SystemConstant.SMS_NORMAL_CODE);
        Optional.ofNullable(sysConfig).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("未配置万能短信验证码"));

        List<SysUser> sysUserList = sysUserService.list(new QueryWrapper<SysUser>().lambda().eq(SysUser::getMobileNumber, login.getMobileNumber()));
        if (CollectionUtils.isEmpty(sysUserList)) {
            throw ExceptionResultEnum.ERROR.exception("用户不存在");
        }
        if (sysUserList.size() > 1) {
            throw ExceptionResultEnum.ERROR.exception("查出多个用户");
        }
        SysUser sysUser = sysUserList.get(0);

        // 校验验证码
        sysUserService.checkSmsCode(sysUser.getId(), sysUser.getMobileNumber(), login.getCode());

        if (!Objects.equals(sysConfig.getConfigValue().trim(), login.getCode().trim())) {
            sysUserService.expiredVerifyCode(sysUser.getId(), sysUser.getMobileNumber());
        }

        if (!Objects.equals(sysUser.getPassword(), login.getPassword())) {
            boolean success = sysUserService.update(new UpdateWrapper<SysUser>().lambda().eq(SysUser::getId, sysUser.getId())
                    .set(SysUser::getPassword, login.getPassword())
                    .set(SysUser::getUpdateTime, System.currentTimeMillis()));
            if (success) {
                commonCacheService.updateUserCache(sysUser.getId());
                //修改密码后，需要踢下线重新登录
                sysUserService.removeUserInfo(sysUser.getId(), true);
            }
            return ResultUtil.ok(success);
        } else {
            return ResultUtil.ok(true);
        }
    }

    @ApiOperation(value = "修改密码")
    @RequestMapping(value = "/update_password", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "返回信息", response = Object.class)})
    @OperationLog(logType = LogTypeEnum.UPDATE)
    public Result updatePassword(@RequestBody SysUser sysUser) throws NoSuchAlgorithmException {
        return ResultUtil.ok(sysUserService.updatePassword(sysUser));
    }

    @ApiOperation(value = "清除缓存")
    @RequestMapping(value = "/cache_clear", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "返回信息", response = Object.class)})
    public Result cacheClear(@ApiParam(value = "缓存值") @RequestParam(required = false) String endpoint,
                             @ApiParam(value = "缓存key") @RequestParam(required = false) String key) {
        if (Objects.nonNull(endpoint) && Objects.nonNull(key)) {
            cacheService.evict(endpoint, key);
        } else if (Objects.nonNull(endpoint)) {
            cacheService.clear(endpoint);
        } else {
            cacheService.clear(SystemConstant.USER_ACCOUNT_CACHE);
            cacheService.clear(SystemConstant.SYS_CONFIG_CACHE);
            cacheService.clear(SystemConstant.USER_OAUTH_CACHE);
            cacheService.clear(SystemConstant.ORG_CACHE);
            cacheService.clear(SystemConstant.PRIVILEGE_URL_CACHE);
            cacheService.clear(SystemConstant.ROLE_PRIVILEGE_CACHE);
            cacheService.clear(SystemConstant.USER_ROLE_PRIVILEGE_CACHE);
            cacheService.clear(SystemConstant.FORM_WIDGET_CACHE);
            cacheService.clear(SystemConstant.TABLE_PROP_CACHE);
            cacheService.clear(SystemConstant.ROLE_CACHE);
            cacheService.clear(SystemConstant.USER_MENU_CACHE);
            cacheService.clear(SystemConstant.SCHOOL_CACHE);
            cacheService.clear(SystemConstant.SCHOOL_CODE_CACHE);
        }
        return ResultUtil.ok(true);
    }

    @ApiOperation(value = "查询枚举")
    @RequestMapping(value = "/query_enum", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "返回信息", response = Object.class)})
    public Result queryEnum(@ApiParam(value = "枚举类型", required = true) @RequestParam EnumList enumList) throws ClassNotFoundException {
        Map<Enum, String> map = new LinkedHashMap<>();
        switch (enumList) {
            case QUALITY_PROBLEM_TYPE_ENUM://问题类型枚举
                QualityProblemTypeEnum[] qualityProblemTypeEnums = QualityProblemTypeEnum.values();
                for (QualityProblemTypeEnum qualityProblemTypeEnum : qualityProblemTypeEnums) {
                    map.put(qualityProblemTypeEnum, qualityProblemTypeEnum.getTitle());
                }
                break;
            case IN_OUT_TYPE_ENUM://签到类型枚举
                InOutTypeEnum[] inOutTypeEnums = InOutTypeEnum.values();
                for (InOutTypeEnum inOutTypeEnum : inOutTypeEnums) {
                    map.put(inOutTypeEnum, inOutTypeEnum.getTitle());
                }
                break;
            case QUALITY_PROBLEM_REASON_ENUM://问题原因枚举
                QualityProblemReasonEnum[] qualityProblemReasonEnums = QualityProblemReasonEnum.values();
                for (QualityProblemReasonEnum qualityProblemReasonEnum : qualityProblemReasonEnums) {
                    map.put(qualityProblemReasonEnum, qualityProblemReasonEnum.getTitle());
                }
                break;
            case IN_FLUENCE_DEGREE_ENUM://问题影响度枚举
                InfluenceDegreeEnum[] influenceDegreeEnums = InfluenceDegreeEnum.values();
                for (InfluenceDegreeEnum influenceDegreeEnum : influenceDegreeEnums) {
                    map.put(influenceDegreeEnum, influenceDegreeEnum.name());
                }
                break;
            case FLOW_TYPE_ENUM://流程类型枚举
                TFCustomTypeEnum[] tfCustomTypeEnums = TFCustomTypeEnum.values();
                for (TFCustomTypeEnum tfCustomTypeEnum : tfCustomTypeEnums) {
                    map.put(tfCustomTypeEnum, tfCustomTypeEnum.getTitle());
                }
                break;
            case FLOW_STATUS_ENUM://流程状态枚举
                FlowStatusEnum[] flowStatusEnums = FlowStatusEnum.values();
                for (FlowStatusEnum flowStatusEnum : flowStatusEnums) {
                    map.put(flowStatusEnum, flowStatusEnum.getTitle());
                }
                break;
            case FLOW_APPROVE_OPERATION_ENUM://流程审批操作枚举
                FlowApproveOperationEnum[] flowApproveOperationEnums = FlowApproveOperationEnum.values();
                for (FlowApproveOperationEnum flowApproveOperationEnum : flowApproveOperationEnums) {
                    map.put(flowApproveOperationEnum, flowApproveOperationEnum.getTitle());
                }
                break;
            case FLOW_TASK_TYPE_ENUM://流程待办任务类型枚举
                FlowTaskTypeEnum[] flowTaskTypeEnums = FlowTaskTypeEnum.values();
                for (FlowTaskTypeEnum flowTaskTypeEnum : flowTaskTypeEnums) {
                    map.put(flowTaskTypeEnum, flowTaskTypeEnum.getTitle());
                }
                break;
            case ROLE_TYPE_ENUM://角色类型枚举
                RoleTypeEnum[] roleTypeEnums = RoleTypeEnum.values();
                for (RoleTypeEnum roleTypeEnum : roleTypeEnums) {
                    map.put(roleTypeEnum, roleTypeEnum.getTitle());
                }
                break;
            case MESSAGE_TYPE_ENUM://消息类型枚举
                MessageTypeEnum[] messageTypeEnums = MessageTypeEnum.values();
                for (MessageTypeEnum messageTypeEnum : messageTypeEnums) {
                    map.put(messageTypeEnum, messageTypeEnum.getTitle());
                }
                break;
            case GENDER_ENUM://性别
                GenderEnum[] genderEnums = GenderEnum.values();
                for (GenderEnum genderEnum : genderEnums) {
                    map.put(genderEnum, genderEnum.getTitle());
                }
                break;
            case EDUCATION_ENUM://学历
                EducationEnum[] educationEnums = EducationEnum.values();
                for (EducationEnum educationEnum : educationEnums) {
                    map.put(educationEnum, educationEnum.getTitle());
                }
                break;
            case SEQUENCE_ENUM://用户档案编号枚举
                SequenceEnum[] sequenceEnums = SequenceEnum.values();
                for (SequenceEnum sequenceEnum : sequenceEnums) {
                    map.put(sequenceEnum, sequenceEnum.getTitle());
                }
                break;
            case DING_EXCEPTION_APPROVE_ENUM://考勤异常审核枚举
                DingExceptionApproveEnum[] dingExceptionApproveEnums = DingExceptionApproveEnum.values();
                for (DingExceptionApproveEnum dingExceptionApproveEnum : dingExceptionApproveEnums) {
                    map.put(dingExceptionApproveEnum, dingExceptionApproveEnum.getTitle());
                }
                break;
            case DEVICE_USAGE_TYPE_ENUM://设备用户类型
                DeviceUsageTypeEnum[] deviceUsageTypeEnums = DeviceUsageTypeEnum.values();
                for (DeviceUsageTypeEnum deviceUsageTypeEnum : deviceUsageTypeEnums) {
                    map.put(deviceUsageTypeEnum, deviceUsageTypeEnum.getTitle());
                }
                break;
            case DEVICE_STATUS_ENUM://设备状态类型
                DeviceStatusEnum[] deviceStatusEnums = DeviceStatusEnum.values();
                for (DeviceStatusEnum deviceStatusEnum : deviceStatusEnums) {
                    map.put(deviceStatusEnum, deviceStatusEnum.getTitle());
                }
                break;
            case WARN_TYPE_ENUM://预警类型
                WarnTypeEnum[] warnTypeEnums = WarnTypeEnum.values();
                for (WarnTypeEnum warnTypeEnum : warnTypeEnums) {
                    map.put(warnTypeEnum, warnTypeEnum.getTitle());
                }
                break;
            case DELAY_WARN_TYPE_ENUM://变更类型
                DelayWarnTypeEnum[] delayWarnTypeEnums = DelayWarnTypeEnum.values();
                for (DelayWarnTypeEnum delayWarnTypeEnum : delayWarnTypeEnums) {
                    map.put(delayWarnTypeEnum, delayWarnTypeEnum.getTitle());
                }
                break;
            case PRODUCT_TYPE_ENUM://客户/产品类型
                ProductTypeEnum[] productTypeEnums = ProductTypeEnum.values();
                for (ProductTypeEnum productTypeEnum : productTypeEnums) {
                    map.put(productTypeEnum, productTypeEnum.getTitle());
                }
                break;
            case PROJECT_EXCHANGE_FLOW_STATUS_ENUM://项目计划变更流程状态类型
                ProjectExchangeFlowStatusEnum[] projectExchangeFlowStatusEnums = ProjectExchangeFlowStatusEnum.values();
                for (ProjectExchangeFlowStatusEnum projectExchangeFlowStatusEnum : projectExchangeFlowStatusEnums) {
                    map.put(projectExchangeFlowStatusEnum, projectExchangeFlowStatusEnum.getTitle());
                }
                break;
            case PROJECT_EXCHANGE_APPROVE_ENUM://项目计划变更流程审核类型
                ProjectExchangeApproveEnum[] projectExchangeApproveEnums = ProjectExchangeApproveEnum.values();
                for (ProjectExchangeApproveEnum projectExchangeApproveEnum : projectExchangeApproveEnums) {
                    map.put(projectExchangeApproveEnum, projectExchangeApproveEnum.getTitle());
                }
                break;
            case PROCESS_LIMITED_ENUM://处理时限枚举类型
                ProcessLimitedEnum[] processLimitedEnums = ProcessLimitedEnum.values();
                for (ProcessLimitedEnum processLimitedEnum : processLimitedEnums) {
                    map.put(processLimitedEnum, processLimitedEnum.getTitle());
                }
                break;
            case TASK_TYPE_ENUM://任务枚举类型
                TaskTypeEnum[] taskTypeEnums = TaskTypeEnum.values();
                for (TaskTypeEnum taskTypeEnum : taskTypeEnums) {
                    map.put(taskTypeEnum, taskTypeEnum.getTitle());
                }
                break;
            default:
                break;
        }
        return ResultUtil.ok(map);
    }

    @ApiOperation(value = "公共接口-查询服务单元列表")
    @RequestMapping(value = "/query_service_unit", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "查询成功", response = TBService.class)})
    public Result queryServiceUnit(@ApiParam(value = "业务类型") @RequestParam(required = false) ProductTypeEnum type,
                                   @ApiParam(value = "服务状态") @RequestParam(required = false) List<ServiceStatusEnum> statusList,
                                   @ApiParam(value = "服务单元名称") @RequestParam(required = false) String name) {
        SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
        DataPermissionDto dpr = sysUserService.buildUserDataPermission(requestUser.getId());
        return ResultUtil.ok(tbServiceService.queryServiceUnit(type, statusList, name, dpr));
    }
}
