package com.zd.system.controller;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.zd.common.core.constant.Constants;
import com.zd.common.core.constant.HttpStatus;
import com.zd.common.core.constant.SecurityConstants;
import com.zd.common.core.domain.per.PerFun;
import com.zd.common.core.domain.per.PerPrefix;
import com.zd.common.core.exception.ServiceException;
import com.zd.common.core.utils.file.ImageUtils;
import com.zd.common.security.utils.DictUtils;
import com.zd.system.api.RemoteDeptService;
import com.zd.system.api.RemoteFileService;
import com.zd.system.api.chemical.RemoteStockService;
import com.zd.system.api.domain.*;
import com.zd.system.api.laboratory.RemoteSubQueryService;
import com.zd.system.api.model.SimpleUserVO;
import com.zd.system.domain.SysLogoConfig;
import com.zd.system.domain.SysPost;
import com.zd.system.service.*;
import io.swagger.annotations.*;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import com.zd.common.core.constant.UserConstants;
import com.zd.common.core.domain.R;
import com.zd.common.core.utils.SecurityUtils;
import com.zd.common.core.utils.StringUtils;
import com.zd.common.core.utils.poi.ExcelUtil;
import com.zd.common.core.web.controller.BaseController;
import com.zd.common.core.web.domain.AjaxResult;
import com.zd.common.core.web.page.TableDataInfo;
import com.zd.common.log.annotation.Log;
import com.zd.common.log.enums.BusinessType;
import com.zd.common.security.annotation.InnerAuth;
import com.zd.common.security.annotation.PreAuthorize;
import com.zd.system.api.model.LoginUser;

import static com.zd.common.core.constant.Constants.CODE_EXPIRATION;

/**
 * 用户信息
 *
 * @author zd
 */
@RestController
@RequestMapping("/user")
@Api(tags = "用户管理")
public class SysUserController extends BaseController {
    @Autowired
    private ISysUserService userService;

    @Autowired
    private ISysRoleService roleService;

    @Autowired
    private ISysPostService postService;

    @Autowired
    private ISysPermissionService permissionService;

    @Autowired
    private ISysConfigService configService;

    @Autowired
    private RemoteSubQueryService subQueryService;
    @Autowired
    private ISysPermitMenuService sysPermitMenuService;
    @Autowired
    private RemoteFileService remoteFileService;
    @Autowired
    private ISysLogoConfigService sysLogoConfigService;
    @Autowired
    private ISysDeptService deptService;

    @Resource
    private RedisTemplate<String, String> redisTemplate;

    @Resource
    private RemoteStockService stockService;


    /**
     * 获取用户列表 "system:user:list"
     */
    @PreAuthorize(hasPermi = PerPrefix.SYSTEM_USER + PerFun.LIST)
    @ApiOperation("查询用户列表")
    @GetMapping("/list")
    public TableDataInfo list(SysUser user) {
        startPage();
        List<SysUser> list = userService.selectUserList(user);
        return getDataTable(list);
    }


    /**
     * 获取用户列表
     */
    @ApiOperation("查询用户列表")
    @GetMapping("/getNotAuthList")
    public TableDataInfo getNotAuthList(SysUser user) {
        startPage();
        List<SysUser> list = userService.selectUserList(user);
        return getDataTable(list);
    }

    /**
     * 根据电话号码查询用户信息
     */
    @ApiOperation("根据电话号码查询用户信息")
    @RequestMapping("/getUserByPhone/{phone}")
    public R<SysUser> getUserByPhone(@PathVariable("phone") String phone) {
        SysUser sysUser = null;
        if (StringUtils.isNotEmpty(phone)) {
            Long userId = userService.selectUserIdByPhone(phone).getUserId();
            sysUser = userService.selectUserById(userId);
        }
        return R.ok(sysUser);
    }

    /**
     * 获取用户-下拉列表（只展示名字和ID以及部门信息，不分页） "system:user:list"
     */
//    @PreAuthorize(hasPermi = PerPrefix.SYSTEM_USER+ PerFun.LIST)
    @GetMapping("/selectlist")
    public List<SelectUserVO> selectlist(String nickName) {
        if (StrUtil.isBlank(nickName)) return Collections.EMPTY_LIST;
        SysUser user = new SysUser();
        user.setNickName(nickName);
        List<SysUser> list = userService.selectUserList(user);
        List<SelectUserVO> collect = null;
        //转化
        collect = Optional.ofNullable(list)
                .orElse(new ArrayList<>(0))
                .stream()
                .map(a -> {
                    SelectUserVO selectUserVO = new SelectUserVO();
                    selectUserVO.setUserId(a.getUserId());
                    selectUserVO.setUserName(a.getUserName());
                    selectUserVO.setNickName(a.getNickName());
                    if (a.getDept() != null) {
                        selectUserVO.setDeptId(a.getDept().getDeptId());
                        selectUserVO.setDeptName(a.getDept().getDeptName());
                    }
                    return selectUserVO;

                }).collect(Collectors.toList());
        return collect;
    }

    /**
     * 获取老师用户-下拉列表（只展示名字和ID以及部门信息，不分页） "system:user:list"
     */
//    @PreAuthorize(hasPermi = PerPrefix.SYSTEM_USER+ PerFun.LIST)
    @GetMapping("/selectTeacherList")
    public List<SelectUserVO> selectTeacherList(String nickName) {
        if (StrUtil.isBlank(nickName)) return Collections.EMPTY_LIST;
        SysUser user = new SysUser();
        user.setNickName(nickName);
        user.setUserType("11");
        List<SysUser> list = userService.selectUserList(user);
        List<SelectUserVO> collect = null;
        //转化
        collect = Optional.ofNullable(list)
                .orElse(new ArrayList<>(0))
                .stream()
                .map(a -> {
                    SelectUserVO selectUserVO = new SelectUserVO();
                    selectUserVO.setUserId(a.getUserId());
                    selectUserVO.setUserName(a.getUserName());
                    selectUserVO.setNickName(a.getNickName());
                    if (a.getDept() != null) {
                        selectUserVO.setDeptId(a.getDept().getDeptId());
                        selectUserVO.setDeptName(a.getDept().getDeptName());
                    }
                    return selectUserVO;

                }).collect(Collectors.toList());
        return collect;
    }

    //"system:user:export"
    @Log(title = "用户管理", businessType = BusinessType.EXPORT)
    @PreAuthorize(hasPermi = PerPrefix.SYSTEM_USER + PerFun.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, SysUser user) throws IOException {
        List<SysUser> list = userService.selectUserList(user);
        ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
        util.exportExcel(response, list, "用户数据");
    }

    //"system:user:import"
    @Log(title = "用户管理", businessType = BusinessType.IMPORT)
    @PreAuthorize(hasPermi = PerPrefix.SYSTEM_USER + PerFun.IMPORT)
    @PostMapping("/importData")
    public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception {
        ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
        List<SysUser> userList = util.importExcel(file.getInputStream());
        String operName = SecurityUtils.getUsername();
        String message = userService.importUser(userList, updateSupport, operName);
        return AjaxResult.success(message);
    }

    @PostMapping("/importTemplate")
    public void importTemplate(HttpServletResponse response) throws IOException {
        ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
        util.importTemplateExcel(response, "用户数据");
    }

    /**
     * 获取当前用户信息
     *
     * @param loginType 区分小程序端登录/PC 端登录  1 PC ，2 小程序
     */
    @InnerAuth
    @GetMapping(value = {"/info/{username}", "/info/{username}/{loginType}"})
    public R<LoginUser> info(@PathVariable("username") String username,
                             @PathVariable(value = "loginType", required = false) Integer loginType) {
        SysUser sysUser = userService.selectUserByUserName(username);
        if (StringUtils.isNull(sysUser)) {
            return R.fail(503, "用户名或密码错误");
        }

        LoginUser sysUserVo = new LoginUser();
        if (loginType != null && UserConstants.USER_LOGIN_HXP == loginType) {
            List<SysLogoConfig> list = sysLogoConfigService.selectSysLogoConfigList(new SysLogoConfig());
            if (list.size() > 0 && list.get(0) != null) {
                if (sysUser.getUserType().equals(list.get(0).getUserType()) && "-1".equals(list.get(0).getUserType())) {
                    return R.fail("登录失败，没有使用权限！");
                }
                // TODO 校验是否有柜锁权限
                Optional.ofNullable(list.get(0).getSmartLock()).ifPresent(a -> {
                    sysUserVo.setCabinetLock(a != null && a == 1 ? true : false);
                });
                Optional.ofNullable(list.get(0).getAirBottle()).ifPresent(a -> {
                    sysUserVo.setAirBottle(a != null && a == 1 ? true : false);
                });

            }
        }

        sysUserVo.setSysUser(sysUser);

//        if(loginType != null && loginType == UserConstants.USER_LOGIN_PC){
        // 权限集合
        Set<String> permissions = permissionService.getMenuPermission(sysUser);
        sysUserVo.setPermissions(permissions);

        sysUser.setPermits(sysPermitMenuService.selectPerMitByUserId(sysUser));

        // 角色集合
        //Set<String> roles = permissionService.getRolePermission(sysUser.getUserId());
        //sysUserVo.setRoles(roles);
//        }else {
//            sysUser.setPermits(ListUtil.empty());
//        }
        return R.ok(sysUserVo);
    }

    /**
     * 获取当前用户信息
     */
    @InnerAuth
    @GetMapping("/info/id/{id}")
    public R<SysUser> info(@PathVariable("id") Long id) {
        SysUser sysUser = userService.selectUserById(id);
        return R.ok(sysUser);
    }

    /**
     * 根据用户ids获取电话
     *
     * @return 结果
     */
    @GetMapping("/phone/{ids}")
    public R<List<String>> getPhoneByUserIDS(@PathVariable("ids") Long... ids) {
        return R.ok(userService.queryPhoneByIds(ids));
    }

    /**
     * 获取当前用户Simple信息
     */
    @InnerAuth
    @GetMapping("/my/info/Simple")
    public R<SimpleUserVO> myInfoSimple() {
        SysUser sysUser = userService.selectUserById(SecurityUtils.getUserId());
        if (sysUser != null) {
            SimpleUserVO simpleUserVO = new SimpleUserVO();
            simpleUserVO.setUserName(sysUser.getNickName());
            simpleUserVO.setDeptName(Optional.ofNullable(sysUser.getDept())
                    .map(a -> a.getDeptName())
                    .orElse(StrUtil.EMPTY));
            simpleUserVO.setAvatar(sysUser.getAvatar());
            //判断职称
            //如果用户类型为00
            if ("00".equals(sysUser.getUserType())) {
                simpleUserVO.setProfessional("管理员");
            }
            if (UserConstants.USER_TYPE_STUDENT.equals(sysUser.getUserType())) {
                simpleUserVO.setProfessional("学生");
            } else {
                String professional = Optional.ofNullable(sysUser.getPosition())
                        .map(a -> DictUtils.getDictCacheLable("professional", a))
                        .orElse(StrUtil.EMPTY);
                simpleUserVO.setProfessional(professional);
                //设置管理实验室数量
                //设置预警数量
                R<Map<String, Object>> mapR = subQueryService.querySubCListVO();
                simpleUserVO.setCount(mapR.getData());
            }
            return R.ok(simpleUserVO);
        }
        return R.ok();
    }

    /**
     * 获取当前用户信息
     */
    @InnerAuth
    @GetMapping("/info/username/{username}")
    public R<SysUser> infoByUserNae(@PathVariable("username") String username) {
        SysUser sysUser = userService.selectUserByUserName(username);
        return R.ok(sysUser);
    }

    /**
     * 获取当前用户信息
     */
    @InnerAuth
    @GetMapping("/info/cardnum/{cardnum}")
    public R<SysUser> infoByUserCardnum(@PathVariable("cardnum") String cardnum) {
        SysUser sysUser = userService.selectUserByCardNum(cardnum);
        return R.ok(sysUser);
    }

    /**
     * 注册用户信息
     */
    @InnerAuth
    @PostMapping("/register")
    public R<Boolean> register(@RequestBody SysUser sysUser) {
        String username = sysUser.getUserName();
        if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(username))) {
            return R.fail("保存用户'" + username + "'失败，注册账号已存在");
        }
        return R.ok(userService.registerUser(sysUser));
    }

    /**
     * 获取用户信息
     *
     * @return 用户信息
     */
    @GetMapping("getInfo")
    public AjaxResult getInfo() {
        Long userId = SecurityUtils.getUserId();
        SysUser sysUser = userService.selectUserById(userId);
        // 角色集合
        //Set<String> roles = permissionService.getRolePermission(userId);
        // 权限集合
        Set<String> permissions = permissionService.getMenuPermission(sysUser);
        AjaxResult ajax = AjaxResult.success();
        ajax.put("user", sysUser);
        //ajax.put("roles", roles);
        ajax.put("permissions", permissions);
        return ajax;
    }

    /**
     * 根据用户编号获取详细信息 "system:user:query"
     */
    @PreAuthorize(hasPermi = PerPrefix.SYSTEM_USER + PerFun.QUERY)
    @GetMapping(value = {"/", "/{userId}"})
    public AjaxResult getInfo(@PathVariable(value = "userId", required = false) Long userId) {
        AjaxResult ajax = AjaxResult.success();
        List<SysRole> roles = roleService.selectRoleAll();
        ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
        ajax.put("posts", postService.selectPostAll(new SysPost()));
        if (StringUtils.isNotNull(userId)) {
            ajax.put(AjaxResult.DATA_TAG, userService.selectUserById(userId));
            ajax.put("postIds", postService.selectPostListByUserId(userId));
            ajax.put("roleIds", roleService.selectRoleListByUserId(userId));
        }
        return ajax;
    }

    /**
     * 新增用户 "system:user:add"
     */
    @PreAuthorize(hasPermi = PerPrefix.SYSTEM_USER + PerFun.ADD)
    @Log(title = "用户管理", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@Validated @RequestBody SysUser user) {
        if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(user.getUserName()))) {
            return AjaxResult.error("新增用户'" + user.getUserName() + "'失败，登录账号已存在");
        } else if (StringUtils.isNotEmpty(user.getPhonenumber())
                && UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user))) {
            return AjaxResult.error("新增用户'" + user.getUserName() + "'失败，手机号码已存在");
        } else if (StringUtils.isNotEmpty(user.getEmail())
                && UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user))) {
            return AjaxResult.error("新增用户'" + user.getUserName() + "'失败，邮箱账号已存在");
        }
        user.setCreateBy(SecurityUtils.getUsername());
        user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
        return toAjax(userService.insertUser(user));
    }

    /**
     * 修改用户 "system:user:edit"
     */
    @PreAuthorize(hasPermi = PerPrefix.SYSTEM_USER + PerFun.EDIT)
    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@Validated @RequestBody SysUser user) {
        userService.checkUserAllowed(user);
        if (StringUtils.isNotEmpty(user.getPhonenumber())
                && UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user))) {
            return AjaxResult.error("修改用户'" + user.getUserName() + "'失败，手机号码已存在");
        } else if (StringUtils.isNotEmpty(user.getEmail())
                && UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user))) {
            return AjaxResult.error("修改用户'" + user.getUserName() + "'失败，邮箱账号已存在");
        }
        user.setUpdateBy(SecurityUtils.getUsername());
        return toAjax(userService.updateUser(user));
    }


    /**
     * 用户自己修改手机号
     */
    @Log(title = "用户自己修改手机号", businessType = BusinessType.UPDATE)
    @PutMapping("/change/phone")
    public AjaxResult changePhone(SysUser user, String code) {
        if (StringUtils.isNotEmpty(user.getPhonenumber())
                && UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user))) {
            return AjaxResult.error("修改用户'" + SecurityUtils.getUsername() + "'失败，手机号码已存在");
        }
        user.setUpdateBy(SecurityUtils.getUsername());
        user.setUserId(SecurityUtils.getUserId());
        return toAjax(userService.updateUser(user));
    }

    /**
     * 删除用户
     */
    @PreAuthorize(hasPermi = "system:user:remove")
    @Log(title = "用户管理", businessType = BusinessType.DELETE)
    @DeleteMapping("/{userIds}")
    public AjaxResult remove(@PathVariable Long[] userIds) {
        if (ArrayUtils.contains(userIds, SecurityUtils.getUserId())) {
            return AjaxResult.error("当前用户不能删除");
        }
        return toAjax(userService.deleteUserByIds(userIds));
    }

    /**
     * 重置密码 "system:user:edit"
     */
    @PreAuthorize(hasPermi = PerPrefix.SYSTEM_USER + PerFun.EDIT)
    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
    @PutMapping("/resetPwd")
    public AjaxResult resetPwd(@RequestBody SysUser user) {
        userService.checkUserAllowed(user);
        user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
        user.setUpdateBy(SecurityUtils.getUsername());
        return toAjax(userService.resetPwd(user));
    }

    /**
     * 状态修改 "system:user:edit"
     */
    @PreAuthorize(hasPermi = PerPrefix.SYSTEM_USER + PerFun.EDIT)
    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
    @PutMapping("/changeStatus")
    public AjaxResult changeStatus(@RequestBody SysUser user) {
        userService.checkUserAllowed(user);
        user.setUpdateBy(SecurityUtils.getUsername());
        return toAjax(userService.updateUserStatus(user));
    }

    /**
     * 根据用户编号获取授权角色 "system:user:query"
     */
    @PreAuthorize(hasPermi = PerPrefix.SYSTEM_USER + PerFun.QUERY)
    @GetMapping("/authRole/{userId}")
    public AjaxResult authRole(@PathVariable("userId") Long userId) {
        AjaxResult ajax = AjaxResult.success();
        SysUser user = userService.selectUserById(userId);
        List<SysRole> roles = roleService.selectRolesByUserId(userId);
        ajax.put("user", user);
        ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
        return ajax;
    }

    /**
     * 用户授权角色 "system:user:edit"
     */
    @PreAuthorize(hasPermi = PerPrefix.SYSTEM_USER + PerFun.EDIT)
    @Log(title = "用户管理", businessType = BusinessType.GRANT)
    @PutMapping("/authRole")
    public AjaxResult insertAuthRole(Long userId, Long[] roleIds) {
        userService.insertUserAuth(userId, roleIds);
        return success();
    }

    /**
     * 获取所有可用户IDS
     *
     * @return 结果
     */
    @InnerAuth
    @GetMapping("/all")
    public AjaxResult userALLIDS() {
        Long userId = SecurityUtils.getUserId();
        SysUser user = new SysUser();
        user.setDelFlag(Constants.NORMAL);
        user.setStatus(Constants.NORMAL);
        List<SysUser> sysUsers = userService.selectUserList(user);
        List<Long> collect = sysUsers.stream().map(a -> a.getUserId()).collect(Collectors.toList());
        return AjaxResult.success(collect);

    }

    /**
     * 获取指定院系用户IDS
     *
     * @param deptId
     * @return 结果
     */
    @InnerAuth
    @GetMapping("/dept/{deptId}")
    public AjaxResult userDeptIDS(@PathVariable("deptId") Long... deptId) {

        List<SysUser> sysUsers = userService.selectUserListByDeptIds(deptId);
        List<Long> collect = sysUsers.stream().map(a -> a.getUserId()).collect(Collectors.toList());
        return AjaxResult.success(collect);

    }

    /**
     * 根据用户名查询
     *
     * @param nickName
     * @return
     */
    @GetMapping("/selectUserListByName")
    public List<SysUser> selectUserListByName(String nickName, String userType) {
        if (StrUtil.isBlank(nickName)) return Collections.EMPTY_LIST;
        SysUser user = new SysUser();
        user.setUserType(StrUtil.isBlank(userType) ? "11" : userType);//用户身份 11教职工 22学生
        user.setNickName(nickName);
        startPage();
        List<SysUser> list = userService.selectUserListByName(user);
        return list;
    }


    /**
     * 根据用户名查询不在白名单的用户
     *
     * @param nickName
     * @return
     */
    @GetMapping("/selectUserListByNotWhite")
    public List<SysUser> selectUserListByNotWhite(String nickName) {
        if (StrUtil.isBlank(nickName)) return Collections.EMPTY_LIST;
        SysUser user = new SysUser();
        //当前登录用户所属院校部门集合
        List<Long> deptIds = userService.getLogingUserDeptids();
        user.setDeptIds(deptIds);
        user.setUserType("11");//用户身份 11教职工 22学生
        user.setNickName(nickName);
        List<SysUser> list = userService.selectUserListByNotWhite(user);
        return list;
    }

    /**
     * 获取职位下的人员
     *
     * @param user
     * @return
     */
    @GetMapping("/positionByList")
    public TableDataInfo positionByList(SysUser user) {
        startPage();
//        user.setUserType("11");//教职工
        List<SysUser> list = userService.selectUserList(user);
        return getDataTable(list);
    }

    /**
     * 获取没有关联职位的人员
     *
     * @param user
     * @return
     */
    @GetMapping("/noJoinPositionByList")
    public TableDataInfo noJoinPositionByList(SysUser user) {
        startPage();
        List<SysUser> list = userService.noJoinPositionByList(user);
        return getDataTable(list);
    }


    /**
     * 给用户绑定职位
     */
    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
    @PutMapping("/bingUserByPosition")
    public AjaxResult bingUserByPosition(SysUser user) {
        user.setUpdateBy(SecurityUtils.getUsername());
        user.setUpdateTime(new Date());
        return toAjax(userService.bingUserByPosition(user));
    }

    /**
     * 解除用户绑定职位
     */
    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
    @PutMapping("/relieveUserByPosition")
    public AjaxResult relieveUserByPosition(SysUser user) {
        user.setUpdateBy(SecurityUtils.getUsername());
        user.setUpdateTime(new Date());
        return toAjax(userService.relieveUserByPosition(user));
    }

    /**
     * 电子签名抠图生成图片
     *
     * @return base64 图片
     */
    @PostMapping("/genSign")
    @ApiOperation("电子签名抠图生成图片")
    public R<String> getPsPictureSign(@RequestParam("file") MultipartFile file) {
        try {
            return R.ok(ImageUtils.transparent(file.getInputStream(), 152));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return R.fail("生成失败！");
    }

    @PostMapping("/updateSignature")
    @ApiOperation("修改用户电子签名")
    public R updateSignature(@ApiParam("签名图片") @RequestParam("file") MultipartFile file) {

        //保存
        R<SysFile> fileResult = remoteFileService.upload(file);
        if (StringUtils.isNull(fileResult) || StringUtils.isNull(fileResult.getData())) {
            return R.fail("文件服务异常，请联系管理员");
        }
        String url = fileResult.getData().getUrl();
        SysUser user = new SysUser();
        user.setUserId(SecurityUtils.getUserId());
        user.setSignature(url);
        userService.update(user);
        return R.ok();
    }

    /**
     * 查询用户是否已经上传签名
     */
    @PostMapping("/querySignature")
    public R querySignature() {
        SysUser user = userService.selectUserById(SecurityUtils.getUserId());
        Map<String, Object> map = new HashMap<>();
        map.put("isUpload", StringUtils.isNotBlank(user.getSignature()) ? true : false);
        map.put("signature", user.getSignature());
        return R.ok(map);
    }


    /**
     * 获取安全负责人用户列表
     */
    @ApiOperation("获取安全负责人用户列表")
    @GetMapping("/getSafeUserList")
    public AjaxResult getSafeUserList(SysUser user) {
        List<SysUser> list = userService.getSafeUserList(user);
        return AjaxResult.success(list);
    }

    /**
     * 获取当前登录用户所属学校以及下级部门id集合
     */
    @ApiOperation("获取当前登录用户所属学校以及下级部门id集合")
    @GetMapping("/getLogingUserDeptids")
    public AjaxResult getLogingUserDeptids() {
        List<Long> collect = userService.getLogingUserDeptids();
        return AjaxResult.success(collect);

    }

    /***
     * 获取当前登录用户所属学校的deptid
     * @return
     */
    @ApiOperation("获取当前登录用户所属学校的deptid")
    @GetMapping("/getLoginUserSchoolDeptid")
    public Long getLoginUserSchoolDeptid() {
        //获取当前登录用户信息
        Long userId = SecurityUtils.getUserId();
        SysUser sysUser = userService.selectUserById(userId);
        SysDept sysDept = deptService.selectDeptById(sysUser.getDept().getDeptId());
        Long deptId = "0".equals(sysDept.getAncestors()) == true ? sysDept.getDeptId() : Long.valueOf(sysDept.getAncestors().split(",")[1]);
        return deptId;
    }

    /**
     * 发送验证码
     * @param phone 手机号码
     * @return 验证码
     */
    @ApiOperation("发送验证码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "phone",required = true,value = "手机号")
    })
    @PostMapping("/send/code")
    public R<?> send(@RequestParam String phone) {
        String key = Constants.DEFAULT_CODE_KEY + Constants.UPDATE_TYPE_MOBILE + "@" + phone;
        String code = RandomUtil.randomNumbers(6);
        redisTemplate.opsForValue().set(key, code, CODE_EXPIRATION, TimeUnit.MINUTES);
        logger.info("========================>{}<=========================", code);
        String countKey=Constants.DEFAULT_CODE_KEY + "@" + phone+"_COUNT";
        String count = redisTemplate.opsForValue().get(countKey);
        if (StringUtils.isEmpty(count)){
            redisTemplate.opsForValue().set(countKey,"1",60,TimeUnit.MINUTES);
        }else {
            if (count!=null){
                int i=Integer.parseInt(count);
                if (i>=5){
                    throw new ServiceException("验证码发送超过限制，请一小时后再试",530);
                }
                i++;
                redisTemplate.opsForValue().set(countKey,i+"",60,TimeUnit.MINUTES);
            }
        }
        return stockService.sendSydSms(code, 2, null, phone);
    }

    /**
     * 验证码校验
     * @param phone 手机号
     * @param code 验证码
     * @return 校对结果
     */
    @ApiOperation("验证码校验")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "phone",required = true,value = "手机号"),
            @ApiImplicitParam(name = "code",required = true,value = "验证码")
    })
    @GetMapping("/check/code")
    public R<?> checkCode(@RequestParam("phone") String phone, @RequestParam("code") String code) {
        return R.ok(check(phone, code));
    }

    /**
     * 用户修改手机号
     * @param oldPhone 原手机号
     * @param newPhone 新手机号
     * @param code 验证码
     * @return  AjaxResult
     */
    @ApiOperation("修改手机号")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "oldPhone",required = true,value = "原手机号"),
            @ApiImplicitParam(name = "newPhone",required = true,value = "新手机号"),
            @ApiImplicitParam(name = "code",required = true,value = "验证码")
    })
    @Log(title = "用户修改手机号", businessType = BusinessType.UPDATE)
    @PutMapping("/update/phone")
    public AjaxResult updatePhone(@RequestParam("oldPhone") String oldPhone,@RequestParam("newPhone") String newPhone,@RequestParam("code") String code) {
        if (StringUtils.isEmpty(oldPhone) || StringUtils.isEmpty(newPhone)){
            throw new ServiceException("原密码或新密码不能为空");
        }

        SysUser user = userService.selectUserIdByPhone(oldPhone);
        if(user==null){
            throw new ServiceException("用户查询失败");
        }
        user.setPhonenumber(newPhone);
        if (StringUtils.isNotEmpty(user.getPhonenumber())
                && UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user))) {
            return AjaxResult.error("修改用户'" + SecurityUtils.getUsername() + "'失败，手机号码已存在");
        }
        Boolean check = check(newPhone, code);
        if (Boolean.TRUE.equals(check)){
            user.setUpdateBy(SecurityUtils.getUsername());
            user.setUserId(SecurityUtils.getUserId());
            return toAjax(userService.updateUser(user));
        }
        throw new ServiceException("验证码不正确，请重新输入");
    }

    private Boolean check(String phone, String code) {
        if (StringUtils.isEmpty(phone)) {
            throw new ServiceException("请输入手机号");
        }
        if (StringUtils.isEmpty(code)) {
            throw new ServiceException("请输入验证码");
        }
        String key = Constants.DEFAULT_CODE_KEY + Constants.UPDATE_TYPE_MOBILE + "@" + phone;

        String temp = redisTemplate.opsForValue().get(key);
        if (temp == null) {
            throw new ServiceException("验证码已过期");
        }
        logger.info("========================>{}:{}<=========================", code, temp);
        return temp.equals(code);
    }
}
