AuthController.java 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. package com.zd.auth.controller;
  2. import cn.hutool.core.util.RandomUtil;
  3. import com.zd.auth.form.LoginBody;
  4. import com.zd.auth.form.RegisterBody;
  5. import com.zd.auth.service.SysLoginService;
  6. import com.zd.chemical.api.fegin.RemoteStockService;
  7. import com.zd.common.core.exception.ParamException;
  8. import com.zd.common.core.exception.ServiceException;
  9. import com.zd.common.core.redis.RedisService;
  10. import com.zd.common.core.security.TokenService;
  11. import com.zd.common.core.utils.DESUtils;
  12. import com.zd.common.core.utils.IdUtils;
  13. import com.zd.common.core.utils.StringUtils;
  14. import com.zd.model.constant.*;
  15. import com.zd.model.domain.AjaxResult;
  16. import com.zd.model.domain.R;
  17. import com.zd.model.domain.ResultData;
  18. import com.zd.model.entity.LoginModel;
  19. import com.zd.model.entity.LoginUser;
  20. import com.zd.model.entity.SysUser;
  21. import com.zd.system.api.bo.SysLoginBo;
  22. import com.zd.system.api.feign.RemoteUserService;
  23. import io.swagger.annotations.ApiOperation;
  24. import org.slf4j.Logger;
  25. import org.slf4j.LoggerFactory;
  26. import org.springframework.beans.factory.annotation.Autowired;
  27. import org.springframework.data.redis.core.RedisTemplate;
  28. import org.springframework.web.bind.annotation.*;
  29. import org.springframework.web.multipart.MultipartFile;
  30. import javax.annotation.Resource;
  31. import javax.servlet.http.HttpServletRequest;
  32. import java.util.List;
  33. import java.util.Map;
  34. import java.util.concurrent.TimeUnit;
  35. import static com.zd.model.constant.BaseConstants.CODE_EXPIRATION;
  36. /***
  37. * <p>认证接口</p>
  38. *
  39. * @author linft
  40. * @date 6/21/2023
  41. * @version 3.0
  42. */
  43. @RestController
  44. public class AuthController {
  45. private final Logger logger = LoggerFactory.getLogger(AuthController.class);
  46. @Autowired
  47. private TokenService tokenService;
  48. @Autowired
  49. private SysLoginService sysLoginService;
  50. @Autowired
  51. private RemoteUserService remoteUserService;
  52. @Autowired
  53. private RemoteStockService stockService;
  54. @Resource
  55. private RedisTemplate<String, String> redisTemplate;
  56. @Autowired
  57. private RedisService redisService;
  58. @PostMapping("/login")
  59. public R login(@RequestBody LoginBody form) {
  60. // 用户登录
  61. String authType = form.getAuthType() == null ? BaseConstants.GRANT_TYPE_PASSWORD : form.getAuthType();
  62. LoginModel loginModel = new LoginModel();
  63. SysLoginBo loginBo = new SysLoginBo();
  64. loginBo.setAccount(form.getUsername());
  65. loginBo.setGrantType(authType);
  66. if (BaseConstants.GRANT_TYPE_PASSWORD.equals(authType)) {
  67. //校验参数
  68. if (StringUtils.isEmpty(form.getUsername()) || StringUtils.isEmpty(form.getPassword())) {
  69. throw new ParamException("账号信息不能为空");
  70. } else if (form.getUsername().length() < UserConstants.USERNAME_MIN_LENGTH
  71. || form.getUsername().length() > UserConstants.USERNAME_MAX_LENGTH
  72. || form.getPassword().length() < UserConstants.PASSWORD_MIN_LENGTH
  73. || form.getPassword().length() > UserConstants.PASSWORD_MAX_LENGTH) {
  74. throw new ParamException("账号参数有误");
  75. } else {
  76. loginBo.setPassword(form.getPassword());
  77. loginBo.setLoginType(UserConstants.USER_LOGIN_PC);
  78. R<LoginModel> r = remoteUserService.userLogin(loginBo);
  79. if (r.getCode() == HttpStatus.SUCCESS && r.getData() != null) {
  80. loginModel = r.getData();
  81. } else if (r.getCode() == HttpStatus.ERROR){
  82. return R.fail(r.getMsg());
  83. }
  84. }
  85. } else if (BaseConstants.GRANT_TYPE_MOBILE.equals(authType)) {
  86. //手机号
  87. String key = BaseConstants.DEFAULT_CODE_KEY + BaseConstants.GRANT_TYPE_MOBILE + "@" + form.getUsername();
  88. String code = redisTemplate.opsForValue().get(key);
  89. if (form.getPassword().equals(code)) {
  90. R<LoginModel> r = remoteUserService.phoneAccount(loginBo);
  91. if (r.getCode() == HttpStatus.SUCCESS && r.getData() != null) {
  92. loginModel = r.getData();
  93. } else if (r.getCode() == HttpStatus.ERROR){
  94. return R.fail(r.getMsg());
  95. }
  96. }
  97. }
  98. loginModel.setLoginType(UserConstants.USER_LOGIN_PC);
  99. Map<String, Object> data = tokenService.createToken(loginModel);
  100. //这里判断输入的密码,是否和默认配置密码一样,如果一样,需要提示跳转设置密码
  101. AjaxResult resultPassword = remoteUserService.getConfigKey("sys.user.initPassword");
  102. if ((resultPassword.get("code") + "").equals("200")) {
  103. String defaultPassword = (String) resultPassword.get("msg");
  104. if (defaultPassword != null && defaultPassword.equals(form.getPassword())) {
  105. data.put("reset_password", true);
  106. } else {
  107. data.put("reset_password", false);
  108. }
  109. }
  110. // 区分大屏用户
  111. // 查询大屏链接
  112. AjaxResult result = remoteUserService.getRouters(loginModel.getUserId());
  113. try {
  114. List<Map<String, Object>> routers = (List<Map<String, Object>>) result.get("data");
  115. Map<String, Object> dataMenu = routers.stream().filter(
  116. a -> "https://www.sxitdlc.com".equals(a.get("path") + "")).findFirst().orElse(null);
  117. if (dataMenu != null) {
  118. String tokenKey = "login_screen:";
  119. Integer type;
  120. if (loginModel.isAdmin()) {
  121. type = 1;
  122. } else {
  123. result = remoteUserService.selectAuthUserPower(loginModel.getUserId());
  124. Map<String, Object> map = (Map<String, Object>) result.get("data");
  125. type = Integer.parseInt(map.get("type") + "");
  126. }
  127. if (type == null) {
  128. // 没有大屏权限
  129. type = 3;
  130. data.put("screen_token", "");
  131. } else if (redisService.hasKey(tokenKey + loginModel.getUserId())) {
  132. String token = redisService.getCacheObject(tokenKey + loginModel.getUserId());
  133. commLogin(loginModel, token);
  134. data.put("screen_token", token);
  135. } else {
  136. String token = IdUtils.fastUUID();
  137. commLogin(loginModel, token);
  138. redisService.setCacheObject(tokenKey + loginModel.getUserId(), token, 180L, TimeUnit.DAYS);
  139. // 获取大屏TOKEN
  140. data.put("screen_token", token);
  141. }
  142. data.put("screen_type", type);
  143. } else {
  144. // 没有大屏权限
  145. data.put("screen_type", 3);
  146. data.put("screen_token", "");
  147. }
  148. } catch (Exception e) {
  149. // 没有大屏权限
  150. data.put("screen_type", 3);
  151. data.put("screen_token", "");
  152. }
  153. // 获取登录token
  154. return R.ok(data);
  155. }
  156. //公共登录方法
  157. private void commLogin(LoginModel model, String token) {
  158. model.setToken(token);
  159. redisService.setCacheObject(CacheConstants.LOGIN_TOKEN_KEY + token, model, BaseConstants.TOKEN_EXPIRE, TimeUnit.SECONDS);
  160. }
  161. /**
  162. * 一体机登录
  163. * 小程序登录也在用
  164. */
  165. @PostMapping("/one/login")
  166. public R oneLogin(@RequestBody LoginBody form) {
  167. // 用户登录
  168. SysLoginBo loginBo = new SysLoginBo();
  169. loginBo.setAccount(form.getUsername());
  170. loginBo.setPassword(form.getPassword());
  171. loginBo.setGrantType(BaseConstants.GRANT_TYPE_PASSWORD);
  172. loginBo.setLoginType(UserConstants.USER_LOGIN_WX);
  173. R<LoginModel> r = remoteUserService.userLogin(loginBo);
  174. if (r.getCode() != HttpStatus.SUCCESS || r.getData() == null) {
  175. return R.fail(r.getMsg());
  176. }
  177. LoginModel model = r.getData();
  178. model.setLoginType(UserConstants.USER_LOGIN_WX);
  179. // 获取登录token
  180. return R.ok(tokenService.createProgramToken(model));
  181. }
  182. /***
  183. * 手持机账号、密码 登录
  184. * @param form
  185. * @return
  186. */
  187. @PostMapping("/pda/pwdLogin")
  188. public R padLogin(@RequestBody LoginBody form) {
  189. // 用户登录
  190. SysLoginBo loginBo = new SysLoginBo();
  191. loginBo.setAccount(form.getUsername());
  192. loginBo.setPassword(form.getPassword());
  193. loginBo.setGrantType(BaseConstants.GRANT_TYPE_PASSWORD);
  194. R<LoginModel> r = remoteUserService.userLogin(loginBo);
  195. if (r.getCode() != HttpStatus.SUCCESS || r.getData() == null) {
  196. return R.fail(r.getMsg());
  197. }
  198. LoginModel model = r.getData();
  199. model.setLoginType(UserConstants.HANDSET_LOGIN_AIO);
  200. // 获取登录token
  201. return R.ok(tokenService.createProgramToken(model));
  202. }
  203. /**
  204. * 发送验证码
  205. */
  206. @PostMapping("/send/code")
  207. public R send(@RequestBody LoginBody form) {
  208. String username = form.getUsername();
  209. R<LoginUser> userR = remoteUserService.getUserInfo(username, SecurityConstants.INNER);
  210. if (userR.getCode() != HttpStatus.SUCCESS || userR.getData() == null) {
  211. throw new ServiceException("用户不存在", 530);
  212. }
  213. String key = BaseConstants.DEFAULT_CODE_KEY + BaseConstants.GRANT_TYPE_MOBILE + "@" + username;
  214. String code = RandomUtil.randomNumbers(6);
  215. redisTemplate.opsForValue().set(key, code, CODE_EXPIRATION, TimeUnit.MINUTES);
  216. logger.info("========================>{}<=========================", code);
  217. String countKey = BaseConstants.DEFAULT_CODE_KEY + "@" + username + "_COUNT";
  218. String count = redisTemplate.opsForValue().get(countKey);
  219. if (StringUtils.isEmpty(count)) {
  220. redisTemplate.opsForValue().set(countKey, "1", 60, TimeUnit.MINUTES);
  221. } else {
  222. if (count != null) {
  223. int i = Integer.parseInt(count);
  224. if (i >= 5) {
  225. throw new ServiceException("验证码发送超过限制,请一小时后再试", 530);
  226. }
  227. i++;
  228. redisTemplate.opsForValue().set(countKey, i + "", 60, TimeUnit.MINUTES);
  229. }
  230. }
  231. return stockService.sendSydSms(code, 2, null, form.getUsername());
  232. }
  233. /**
  234. * 学习一体机 用户端登录
  235. * 接口修改为分两步操作,1 刷卡获取人员信息和token , 2 人脸验证之后再调用一次实现真实登录
  236. * type : 1 和 2
  237. */
  238. @PostMapping("/learn/login")
  239. public R learnLogin(HttpServletRequest request, @RequestBody Map<String, Object> params) {
  240. int type = org.apache.commons.lang3.StringUtils.isNotBlank((String) params.get("type")) ? Integer.parseInt((String) params.get("type")) : 1;
  241. String machineCode = params.get("machineCode") == null ? "" : (String) params.get("machineCode");
  242. // 用户登录
  243. String username = (String) params.get("userName");
  244. int aioType = params.get("aioType") == null ? UserConstants.USER_LOGIN_AIO : Integer.parseInt(params.get("aioType") + "");
  245. logger.error("学习机登录,加密前:" + username + ",设备编码:" + machineCode +"设备类型:"+aioType);
  246. if (UserConstants.USER_LOGIN_HXP == aioType) {
  247. //终端传参数据有问题,暂临时后端处理
  248. //通过des生成对称加密卡号
  249. logger.error("化学品补0:" + DESUtils.completeMissing(username));
  250. username = DESUtils.encrypt(DESUtils.completeMissing(username));
  251. logger.error("化学品加密后:" + username);
  252. } else {
  253. username =DESUtils.encrypt(username+"");
  254. logger.error("学习机登录,加密后:" + username);
  255. }
  256. R<SysUser> user = remoteUserService.getUserInfoByCardNum(username, SecurityConstants.INNER);
  257. if (R.FAIL == user.getCode()) {
  258. throw new ServiceException(user.getMsg());
  259. }
  260. if (StringUtils.isNull(user.getData())) {
  261. return R.fail("账号信息不存在");
  262. }
  263. SysLoginBo loginBo = new SysLoginBo();
  264. loginBo.setAccount(user.getData().getUserName());
  265. loginBo.setLoginType(aioType);
  266. R<LoginModel> r = remoteUserService.userLoginByNoPassword(loginBo);
  267. if (r.getCode() != R.SUCCESS) {
  268. return R.fail(r.getMsg());
  269. }
  270. if (r.getData() != null) {
  271. LoginModel userInfo = r.getData();
  272. userInfo.setLoginType(aioType);
  273. userInfo.setMachineCode(machineCode);
  274. Map<String, Object> map = null;
  275. if (type == 1) {
  276. // 获取登录token
  277. map = tokenService.createToken(userInfo);
  278. } else if (type == 2) {
  279. // 资源删除
  280. LoginModel loginUser = tokenService.getLoginUser(request);
  281. if (StringUtils.isNotNull(loginUser)) {
  282. // 删除用户缓存记录
  283. tokenService.delLoginUser(loginUser.getToken());
  284. }
  285. map = tokenService.createToken(userInfo);
  286. if (UserConstants.USER_LOGIN_HXP == aioType) {
  287. map.put("positionName", userInfo.getPositionName());
  288. map.put("cabinetLock", userInfo.isCabinetLock());
  289. map.put("airBottle", userInfo.isAirBottle());
  290. } else if (UserConstants.USER_LOGIN_AIO == aioType) {
  291. if (redisService.hasKey(CacheConstants.LEARN_USER_KEY + userInfo.getUserId())) {
  292. LoginModel userCache = redisService.getCacheObject(CacheConstants.LEARN_USER_KEY + userInfo.getUserId());
  293. if(StringUtils.isNull(params.get("isLogin")) || "0".equals(params.get("isLogin"))){
  294. if (machineCode.equals(userCache.getMachineCode())) {
  295. return R.fail(4466,"您已在设备登录,是否重新登录!");
  296. }else{
  297. return R.fail("签到失败,不能重复签到!");
  298. }
  299. }
  300. }
  301. // 记录学习一体机用户登录状态
  302. redisService.setCacheObject(CacheConstants.LEARN_USER_KEY + userInfo.getUserId(), userInfo, BaseConstants.TOKEN_EXPIRE * 60, TimeUnit.SECONDS);
  303. }
  304. }
  305. return R.ok(map);
  306. } else {
  307. return R.fail("账号信息不存在");
  308. }
  309. }
  310. /**
  311. * 手持机 用户端登录
  312. * 接口操作,1刷卡验证之后调用实现真实登录
  313. */
  314. @PostMapping("/handset/login")
  315. public R handsetLogin(@RequestBody Map<String, Object> params) {
  316. // 用户登录
  317. String username = (String) params.get("userName");
  318. logger.error("手持机登录,加密前:" + username);
  319. //通过des生成对称加密卡号
  320. username = DESUtils.encrypt(username);
  321. logger.error("手持机登录,加密后:" + username);
  322. int aioType = UserConstants.HANDSET_LOGIN_AIO;
  323. R<SysUser> user = remoteUserService.getUserInfoByCardNum(username, SecurityConstants.INNER);
  324. if (R.FAIL == user.getCode()) {
  325. throw new ServiceException(user.getMsg());
  326. }
  327. if (StringUtils.isNull(user.getData())) {
  328. return R.fail("账号信息不存在");
  329. }
  330. SysLoginBo loginBo = new SysLoginBo();
  331. loginBo.setAccount(user.getData().getUserName());
  332. loginBo.setLoginType(aioType);
  333. R<LoginModel> r = remoteUserService.userLoginByNoPassword(loginBo);
  334. if (r.getCode() != R.SUCCESS) {
  335. return R.fail(r.getMsg());
  336. }
  337. if (r.getData() != null) {
  338. LoginModel userInfo = r.getData();
  339. userInfo.setLoginType(aioType);
  340. // 获取登录token
  341. Map<String, Object> map = tokenService.createToken(userInfo);
  342. return R.ok(map);
  343. } else {
  344. return R.fail("账号信息不存在");
  345. }
  346. }
  347. /**
  348. * 学习一体机 用户退出登录
  349. */
  350. @PostMapping("/learn/loginOut")
  351. public R learnLoginOut(HttpServletRequest request) {
  352. LoginModel loginUser = tokenService.getLoginUser(request);
  353. if (StringUtils.isNotNull(loginUser)) {
  354. // 删除用户缓存记录
  355. tokenService.delLoginUser(loginUser.getToken());
  356. // 删除一体机登录状态
  357. redisService.deleteObject(CacheConstants.LEARN_USER_KEY + loginUser.getUserId());
  358. }
  359. return R.ok();
  360. }
  361. @DeleteMapping("logout")
  362. public R logout(HttpServletRequest request) {
  363. LoginModel loginUser = tokenService.getLoginUser(request);
  364. if (StringUtils.isNotNull(loginUser)) {
  365. // 删除用户缓存记录
  366. tokenService.delLoginUser(loginUser.getToken());
  367. }
  368. return R.ok();
  369. }
  370. @PostMapping("refresh")
  371. public R refresh(HttpServletRequest request) {
  372. LoginModel loginUser = tokenService.getLoginUser(request);
  373. if (StringUtils.isNotNull(loginUser)) {
  374. // 刷新令牌有效期
  375. tokenService.refreshToken(loginUser);
  376. return R.ok();
  377. }
  378. return R.ok();
  379. }
  380. @PostMapping("register")
  381. public R register(@RequestBody RegisterBody registerBody) {
  382. // 用户注册
  383. sysLoginService.register(registerBody.getUsername(), registerBody.getPassword());
  384. return R.ok();
  385. }
  386. @ApiOperation(value = "手持机人脸登录")
  387. @PostMapping("/facePda")
  388. public R face(@RequestParam("file") MultipartFile file) {
  389. //调用人脸对比获取用户信息
  390. ResultData<LoginModel> result = remoteUserService.pdaCompare(file);
  391. if (result.getCode().equals(HttpStatus.SUCCESS)) {
  392. LoginModel model = result.getData();
  393. Map<String, Object> data = tokenService.createToken(model);
  394. return R.ok(data);
  395. }
  396. return R.fail(result.getMsg());
  397. }
  398. }