package com.zd.auth.controller; import cn.hutool.core.util.RandomUtil; import com.zd.auth.form.LoginBody; import com.zd.auth.form.RegisterBody; import com.zd.auth.service.SysLoginService; import com.zd.chemical.api.fegin.RemoteStockService; import com.zd.common.core.exception.ServiceException; import com.zd.common.core.redis.RedisService; import com.zd.common.core.security.TokenService; import com.zd.common.core.utils.DESUtils; import com.zd.common.core.utils.IdUtils; import com.zd.common.core.utils.StringUtils; import com.zd.model.constant.*; import com.zd.model.domain.AjaxResult; import com.zd.model.domain.R; import com.zd.model.entity.LoginUser; import com.zd.model.entity.SysUser; import com.zd.system.api.feign.RemoteUserService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.concurrent.TimeUnit; import static com.zd.model.constant.BaseConstants.CODE_EXPIRATION; /** * token 控制 * * @author zd */ @RestController public class TokenController { private final Logger logger = LoggerFactory.getLogger(TokenController.class); @Autowired private TokenService tokenService; @Autowired private SysLoginService sysLoginService; @Autowired private RemoteUserService remoteUserService; @Autowired private RedisService redisService; @Autowired private RemoteStockService stockService; @Resource private RedisTemplate redisTemplate; @PostMapping("login") public R login(@RequestBody LoginBody form) { // 用户登录 String authType = form.getAuthType() == null ? BaseConstants.GRANT_TYPE_PASSWORD : form.getAuthType(); LoginUser userInfo; if (Objects.equals(authType, BaseConstants.GRANT_TYPE_MOBILE)) { String key = BaseConstants.DEFAULT_CODE_KEY + BaseConstants.GRANT_TYPE_MOBILE + "@" + form.getUsername(); String code = redisTemplate.opsForValue().get(key); if (form.getPassword().equals(code)) { R userR = remoteUserService.getUserInfo(form.getUsername(), SecurityConstants.INNER); if (userR.getCode() == HttpStatus.SUCCESS && userR.getData() != null) { userInfo = userR.getData(); } else { throw new ServiceException("服务未知异常,请稍后重试"); } } else { throw new ServiceException("验证码不正确", 503); } } else { userInfo = sysLoginService.login(form.getUsername(), UserConstants.USER_LOGIN_PC, form.getPassword()); } userInfo.setLoginType(UserConstants.USER_LOGIN_PC); Map data = tokenService.createToken(userInfo); //这里判断输入的密码,是否和默认配置密码一样,如果一样,需要提示跳转设置密码 AjaxResult resultPassword = remoteUserService.getConfigKey("sys.user.initPassword"); if ((resultPassword.get("code") + "").equals("200")) { String defaultPassword = (String) resultPassword.get("msg"); if (defaultPassword != null && defaultPassword.equals(form.getPassword())) { data.put("reset_password", true); } else { data.put("reset_password", false); } } // 区分大屏用户 // 查询大屏链接 AjaxResult result = remoteUserService.getRouters(userInfo.getUserid()); try { List> routers = (List>) result.get("data"); Map dataMenu = routers.stream().filter( a -> "https://www.sxitdlc.com".equals(a.get("path") + "")).findFirst().orElse(null); if (dataMenu != null) { String tokenKey = "login_screen:"; Integer type; if (userInfo.getSysUser().isAdmin()) { type = 1; } else { result = remoteUserService.selectAuthUserPower(userInfo.getUserid()); Map map = (Map) result.get("data"); type = Integer.parseInt(map.get("type") + ""); } if (type == null) { // 没有大屏权限 type = 3; data.put("screen_token", ""); } else if (redisService.hasKey(tokenKey + userInfo.getUserid())) { String token = redisService.getCacheObject(tokenKey + userInfo.getUserid()); commLogin(userInfo, token); data.put("screen_token", token); } else { String token = IdUtils.fastUUID(); commLogin(userInfo, token); redisService.setCacheObject(tokenKey + userInfo.getUserid(), token); // 获取大屏TOKEN data.put("screen_token", token); } data.put("screen_type", type); } else { // 没有大屏权限 data.put("screen_type", 3); data.put("screen_token", ""); } } catch (Exception e) { // 没有大屏权限 data.put("screen_type", 3); data.put("screen_token", ""); } // 获取登录token return R.ok(data); } //公共登录方法 private void commLogin(LoginUser userInfo, String token) { LoginUser loginUser = new LoginUser(); BeanUtils.copyProperties(userInfo, loginUser); loginUser.setToken(token); redisService.setCacheObject(CacheConstants.LOGIN_TOKEN_KEY + token, loginUser); } /** * 一体机登录 * 小程序登录也在用 */ @PostMapping("/one/login") public R oneLogin(@RequestBody LoginBody form) { // 用户登录 LoginUser userInfo = sysLoginService.login(form.getUsername(), UserConstants.USER_LOGIN_WX, form.getPassword()); userInfo.setLoginType(UserConstants.USER_LOGIN_WX); // 获取登录token return R.ok(tokenService.createProgramToken(userInfo)); } /** * 发送验证码 */ @PostMapping("/send/code") public R send(@RequestBody LoginBody form) { String username = form.getUsername(); R userR = remoteUserService.getUserInfo(username, SecurityConstants.INNER); if (userR.getCode() != HttpStatus.SUCCESS || userR.getData() == null) { throw new ServiceException("用户不存在", 530); } String key = BaseConstants.DEFAULT_CODE_KEY + BaseConstants.GRANT_TYPE_MOBILE + "@" + username; String code = RandomUtil.randomNumbers(6); redisTemplate.opsForValue().set(key, code, CODE_EXPIRATION, TimeUnit.MINUTES); logger.info("========================>{}<=========================", code); String countKey = BaseConstants.DEFAULT_CODE_KEY + "@" + username + "_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, form.getUsername()); } /** * 学习一体机 用户端登录 * 接口修改为分两步操作,1 刷卡获取人员信息和token , 2 人脸验证之后再调用一次实现真实登录 * type : 1 和 2 */ @PostMapping("/learn/login") public R learnLogin(HttpServletRequest request, @RequestBody Map params) { int type = org.apache.commons.lang3.StringUtils.isNotBlank((String) params.get("type")) ? Integer.parseInt((String) params.get("type")) : 1; String machineCode = params.get("machineCode") == null ? "" : (String) params.get("machineCode"); // 用户登录 String username = (String) params.get("userName"); int aioType = params.get("aioType") == null ? UserConstants.USER_LOGIN_AIO : Integer.parseInt(params.get("aioType") + ""); logger.error("学习机登录,加密前:" + username + ",设备编码:" + machineCode); if (UserConstants.USER_LOGIN_HXP == aioType) { // TODO 终端传参数据有问题,暂临时后端处理 //通过des生成对称加密卡号 logger.error("化学品登录,加密前:" + username); username =DESUtils.encrypt(username+""); logger.error("化学品登录,加密后:" + username); // username = username.replaceAll("%00", "") // .replaceAll("%02", "") // .replaceAll("%03", "") // .replaceAll("%0A", "") // .replaceAll("%0D", "") // .trim(); } else { // 查询用户信息 // if (StringUtils.isNumeric(username)) { // username = Long.toHexString(Long.parseLong(username)).toUpperCase(); username =DESUtils.encrypt(username+""); logger.error("学习机登录,加密后:" + username); // } else { // logger.error("通过卡号未找到用户"); // return R.fail("无效卡号或未绑定用户,请联系管理员!"); // } } R user = remoteUserService.getUserInfoByCardNum(username, SecurityConstants.INNER); if (R.FAIL == user.getCode()) { throw new ServiceException(user.getMsg()); } if (StringUtils.isNull(user.getData())) { return R.fail("账号信息不存在"); } R userResult = remoteUserService.getUserInfo(user.getData().getUserName(), aioType, SecurityConstants.INNER); if (R.FAIL == userResult.getCode() || 503 == userResult.getCode()) { return R.fail(userResult.getMsg()); } if (userResult.getData() != null) { LoginUser userInfo = userResult.getData(); userInfo.setLoginType(aioType); userInfo.setMachineCode(machineCode); if (userInfo.getSysUser() == null) { return R.fail("账号信息不存在"); } Map map = null; if (type == 1) { // 获取登录token map = tokenService.createToken(userInfo); } else if (type == 2) { // 资源删除 LoginUser loginUser = tokenService.getLoginUser(request); if (StringUtils.isNotNull(loginUser)) { // 删除用户缓存记录 tokenService.delLoginUser(loginUser.getToken()); } map = tokenService.createToken(userInfo); if (UserConstants.USER_LOGIN_HXP == aioType) { map.put("positionName", userInfo.getSysUser().getPositionName()); map.put("cabinetLock", userInfo.isCabinetLock()); map.put("airBottle", userInfo.isAirBottle()); } else if (UserConstants.USER_LOGIN_AIO == aioType) { if (redisService.hasKey(CacheConstants.LEARN_USER_KEY + userInfo.getSysUser().getUserId())) { LoginUser userCache = redisService.getCacheObject(CacheConstants.LEARN_USER_KEY + userInfo.getSysUser().getUserId()); if (!machineCode.equals(userCache.getMachineCode())) { return R.fail("签到失败,不能重复签到!"); } } // 记录学习一体机用户登录状态 redisService.setCacheObject(CacheConstants.LEARN_USER_KEY + userInfo.getSysUser().getUserId(), userInfo, BaseConstants.TOKEN_EXPIRE * 60, TimeUnit.SECONDS); } } return R.ok(map); } else { return R.fail("账号信息不存在"); } } /** * 学习一体机 用户退出登录 */ @PostMapping("/learn/loginOut") public R learnLoginOut(HttpServletRequest request) { LoginUser loginUser = tokenService.getLoginUser(request); if (StringUtils.isNotNull(loginUser)) { SysUser user = loginUser.getSysUser(); // 删除用户缓存记录 tokenService.delLoginUser(loginUser.getToken()); // 记录用户退出日志 sysLoginService.logout(user); // 删除一体机登录状态 redisService.deleteObject(CacheConstants.LEARN_USER_KEY + loginUser.getUserid()); } return R.ok(); } @DeleteMapping("logout") public R logout(HttpServletRequest request) { LoginUser loginUser = tokenService.getLoginUser(request); if (StringUtils.isNotNull(loginUser)) { SysUser user = loginUser.getSysUser(); // 删除用户缓存记录 tokenService.delLoginUser(loginUser.getToken()); // 记录用户退出日志 sysLoginService.logout(user); } return R.ok(); } @PostMapping("refresh") public R refresh(HttpServletRequest request) { LoginUser loginUser = tokenService.getLoginUser(request); if (StringUtils.isNotNull(loginUser)) { // 刷新令牌有效期 tokenService.refreshToken(loginUser); return R.ok(); } return R.ok(); } @PostMapping("register") public R register(@RequestBody RegisterBody registerBody) { // 用户注册 sysLoginService.register(registerBody.getUsername(), registerBody.getPassword()); return R.ok(); } }