AuthController.java 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. package com.qxgmat.controller.api;
  2. import com.github.pagehelper.Page;
  3. import com.nuliji.tools.Response;
  4. import com.nuliji.tools.ResponseHelp;
  5. import com.nuliji.tools.Tools;
  6. import com.nuliji.tools.Transform;
  7. import com.nuliji.tools.exception.AuthException;
  8. import com.nuliji.tools.exception.ParameterException;
  9. import com.nuliji.tools.exception.SystemException;
  10. import com.qxgmat.data.constants.enums.ServiceKey;
  11. import com.qxgmat.data.dao.entity.TextbookLibrary;
  12. import com.qxgmat.data.dao.entity.User;
  13. import com.qxgmat.data.dao.entity.UserMessage;
  14. import com.qxgmat.data.dao.entity.UserOrderRecord;
  15. import com.qxgmat.data.relation.entity.UserPreviewPaperRelation;
  16. import com.qxgmat.dto.request.*;
  17. import com.qxgmat.dto.response.MyDto;
  18. import com.qxgmat.help.AiHelp;
  19. import com.qxgmat.help.CaptchaHelp;
  20. import com.qxgmat.help.ShiroHelp;
  21. import com.qxgmat.help.SmsHelp;
  22. import com.qxgmat.service.UsersService;
  23. import com.qxgmat.service.UserServiceService;
  24. import com.qxgmat.service.extend.MessageExtendService;
  25. import com.qxgmat.service.extend.PreviewService;
  26. import com.qxgmat.service.inline.TextbookLibraryService;
  27. import com.qxgmat.service.inline.UserAbnormalService;
  28. import com.qxgmat.service.inline.UserMessageService;
  29. import com.qxgmat.service.inline.UserOrderRecordService;
  30. import io.swagger.annotations.Api;
  31. import io.swagger.annotations.ApiOperation;
  32. import org.springframework.beans.factory.annotation.Autowired;
  33. import org.springframework.http.MediaType;
  34. import org.springframework.validation.annotation.Validated;
  35. import org.springframework.web.bind.annotation.*;
  36. import javax.servlet.http.HttpServletRequest;
  37. import javax.servlet.http.HttpServletResponse;
  38. import javax.servlet.http.HttpSession;
  39. import javax.validation.Validator;
  40. import java.util.Collection;
  41. import java.util.Date;
  42. import java.util.List;
  43. /**
  44. * Created by GaoJie on 2017/10/31.
  45. */
  46. @RestController
  47. @RequestMapping("/api/auth")
  48. @Api(tags = "用户验证", description = "登录注册找回密码", produces = MediaType.APPLICATION_JSON_VALUE)
  49. public class AuthController {
  50. @Autowired
  51. private CaptchaHelp captchaHelp;
  52. @Autowired
  53. private SmsHelp smsHelp;
  54. @Autowired
  55. private AiHelp aiHelp;
  56. @Autowired
  57. private ShiroHelp shiroHelp;
  58. @Autowired
  59. private UsersService usersService;
  60. @Autowired
  61. private UserServiceService userServiceService;
  62. @Autowired
  63. private UserAbnormalService userAbnormalService;
  64. // 初始化用户信息
  65. @Autowired
  66. private TextbookLibraryService textbookLibraryService;
  67. @Autowired
  68. private UserMessageService userMessageService;
  69. @Autowired
  70. private UserOrderRecordService userOrderRecordService;
  71. @Autowired
  72. private PreviewService previewService;
  73. @Autowired
  74. private MessageExtendService messageExtendService;
  75. @RequestMapping(value = "/token", method = RequestMethod.POST)
  76. @ApiOperation(value = "验证token", httpMethod = "POST")
  77. public Response<MyDto> token(@RequestHeader(value = "token", required = false) String token, HttpSession session, HttpServletRequest request) {
  78. User user;
  79. if (token == null || token.isEmpty()){
  80. user = shiroHelp.getLoginUser();
  81. if (user == null) {
  82. throw new AuthException("未登录");
  83. }
  84. }else{
  85. user = usersService.getUserByToken(token);
  86. // 用该token登录
  87. shiroHelp.getSession().login(shiroHelp.user(user.getArea()+":"+user.getMobile(), ""));
  88. }
  89. User entity = usersService.get(user.getId());
  90. MyDto dto = processUser(entity, request);
  91. return ResponseHelp.success(dto);
  92. }
  93. @RequestMapping(value = "/login", method = RequestMethod.POST)
  94. @ApiOperation(value = "登录/注册", httpMethod = "POST")
  95. public Response<MyDto> login(@RequestBody @Validated UserLoginDto userLoginDto, HttpSession session, HttpServletRequest request) {
  96. if (!smsHelp.verifyCode(userLoginDto.getArea(), userLoginDto.getMobile(), userLoginDto.getMobileVerifyCode(), session)) {
  97. throw new ParameterException("手机验证码错误!");
  98. }
  99. if (userLoginDto.getEmail() != null){
  100. User emailUser = usersService.getByEmail(userLoginDto.getEmail());
  101. if (emailUser != null){
  102. throw new ParameterException("该邮箱已绑定其他账号,请更换邮箱地址");
  103. }
  104. }
  105. try {
  106. String ip = Tools.getClientIp(request);
  107. usersService.register(userLoginDto.getArea(), userLoginDto.getMobile(), userLoginDto.getInviteCode(), userLoginDto.getEmail(), null, ip, aiHelp.parseIp(ip));
  108. }catch (ParameterException e){
  109. // 忽略已注册信息
  110. }
  111. shiroHelp.getSession().login(shiroHelp.user(userLoginDto.getArea()+":"+userLoginDto.getMobile(), ""));
  112. User user = shiroHelp.getLoginUser();
  113. User entity = usersService.get(user.getId());
  114. MyDto dto = processUser(entity, request);
  115. return ResponseHelp.success(dto);
  116. }
  117. @RequestMapping(value = "/wechat_pc", method = RequestMethod.GET)
  118. @ApiOperation(value = "直接微信二维码登录", httpMethod = "GET")
  119. public Response<MyDto> directWechatPc(
  120. @RequestParam(required = false, defaultValue = "") String code,
  121. HttpSession session, HttpServletRequest request) {
  122. User user = (User) shiroHelp.getLoginUser();
  123. try{
  124. if (user == null){
  125. // 直接二维码登录
  126. shiroHelp.getSession().login(shiroHelp.oauth(code, "wechat_pc", true));
  127. }else{
  128. // 登录成功绑定二维码
  129. usersService.Oauth(user, code, "wechat_pc", true);
  130. }
  131. }catch (Exception e){
  132. throw new ParameterException("登录失败");
  133. }
  134. User openUser = (User) shiroHelp.getLoginUser();
  135. if (openUser.getId() != null && openUser.getId() > 0){
  136. shiroHelp.getSession().login(shiroHelp.user(openUser.getArea()+":"+openUser.getMobile(), ""));
  137. }
  138. MyDto dto = processUser(openUser, request);
  139. return ResponseHelp.success(dto);
  140. }
  141. // 公众号登录注册:wechat(false) -> wechat(true) -> bind
  142. // pc登录注册:wechat_pc(true) -> bind
  143. // login -> wechat_pc(true)
  144. @RequestMapping(value = "/wechat", method = RequestMethod.GET)
  145. @ApiOperation(value = "直接微信公众号登录", httpMethod = "GET")
  146. public Response<MyDto> directWechat(
  147. @RequestParam(required = false, defaultValue = "") String code,
  148. @RequestParam(required = false, defaultValue = "") boolean userInfo,
  149. HttpSession session, HttpServletRequest request) {
  150. try{
  151. // userInfo:false,尝试登录
  152. // userInfo:true,第一次登录,尝试授权,等待绑定手机号
  153. shiroHelp.getSession().login(shiroHelp.oauth(code, "wechat_native", userInfo));
  154. }catch (Exception e){
  155. throw new ParameterException("登录失败");
  156. }
  157. User openUser = (User) shiroHelp.getLoginUser();
  158. if (openUser.getId() != null && openUser.getId() > 0){
  159. shiroHelp.getSession().login(shiroHelp.user(openUser.getArea()+":"+openUser.getMobile(), ""));
  160. }
  161. MyDto dto = processUser(openUser, request);
  162. return ResponseHelp.success(dto);
  163. }
  164. @RequestMapping(value = "/logout", method = RequestMethod.POST)
  165. @ApiOperation(value = "登出", httpMethod = "POST")
  166. public Response<Boolean> logout(HttpSession session, HttpServletRequest request) {
  167. shiroHelp.logout();
  168. return ResponseHelp.success(true);
  169. }
  170. @RequestMapping(value = "/bind", method = RequestMethod.POST)
  171. @ApiOperation(value = "绑定手机号", notes="第三方登录后可执行", httpMethod = "POST")
  172. public Response<MyDto> bind(@RequestBody @Validated UserValidMobileDto userValidMobileDto, HttpSession session, HttpServletRequest request) {
  173. if (!smsHelp.verifyCode(userValidMobileDto.getArea(), userValidMobileDto.getMobile(), userValidMobileDto.getMobileVerifyCode(), session)) {
  174. throw new ParameterException("验证码有误,请重新获取!");
  175. }
  176. User openUser = (User) shiroHelp.getLoginUser();
  177. if(openUser == null)
  178. throw new SystemException("第三方登录错误");
  179. if(openUser.getMobile() != null && openUser.getMobile().length() > 0)
  180. throw new SystemException("手机号已绑定");
  181. if (userValidMobileDto.getEmail() != null){
  182. User emailUser = usersService.getByEmail(userValidMobileDto.getEmail());
  183. if (emailUser != null){
  184. throw new ParameterException("该邮箱已绑定其他账号,请更换邮箱地址");
  185. }
  186. }
  187. try{
  188. // 创建新的账号,设定手机号,绑定第三方登录
  189. String ip = Tools.getClientIp(request);
  190. User user = usersService.register(userValidMobileDto.getArea(), userValidMobileDto.getMobile(), userValidMobileDto.getInviteCode(), userValidMobileDto.getEmail(), openUser, ip, aiHelp.parseIp(ip));
  191. }catch (ParameterException e){
  192. throw new ParameterException("该手机号绑定其他账号,请更换手机号码!");
  193. }
  194. shiroHelp.getSession().login(shiroHelp.user(userValidMobileDto.getArea()+":"+userValidMobileDto.getMobile(), ""));
  195. User user = shiroHelp.getLoginUser();
  196. User entity = usersService.get(user.getId());
  197. MyDto dto = processUser(entity, request);
  198. return ResponseHelp.success(dto);
  199. }
  200. @RequestMapping(value = "/valid/invite_code", method = RequestMethod.GET)
  201. @ApiOperation(value = "验证邀请码", notes="查询邀请码对应账号", httpMethod = "GET")
  202. public Response<String> validInviteCode(
  203. @RequestParam(required = true) String inviteCode
  204. ){
  205. User user = usersService.getByInviteCode(inviteCode);
  206. if(user == null){
  207. return ResponseHelp.success(null);
  208. }else{
  209. return ResponseHelp.success(user.getNickname());
  210. }
  211. }
  212. @RequestMapping(value = "/valid/mobile", method = RequestMethod.GET)
  213. @ApiOperation(value = "验证手机号", notes="查询手机对应账号", httpMethod = "GET")
  214. public Response<Boolean> validMobile(
  215. @RequestParam(required = true) String area,
  216. @RequestParam(required = true) String mobile
  217. ){
  218. User user = usersService.getByMobile(area, mobile);
  219. if(user != null){
  220. return ResponseHelp.success(false);
  221. }
  222. return ResponseHelp.success(true);
  223. }
  224. @RequestMapping(value = "/valid/email", method = RequestMethod.GET)
  225. @ApiOperation(value = "验证手机号", notes="查询手机对应账号", httpMethod = "GET")
  226. public Response<Boolean> validEmail(
  227. @RequestParam(required = true) String email
  228. ){
  229. User user = usersService.getByEmail(email);
  230. if(user != null){
  231. return ResponseHelp.success(false);
  232. }
  233. return ResponseHelp.success(true);
  234. }
  235. @RequestMapping(value = "/valid/wechat", method = RequestMethod.GET)
  236. @ApiOperation(value = "验证手机号是否绑定微信", notes="查询手机对应账号", httpMethod = "GET")
  237. public Response<Boolean> validWechat(
  238. @RequestParam(required = true) String area,
  239. @RequestParam(required = true) String mobile
  240. ){
  241. User user = usersService.getByMobile(area, mobile);
  242. if (user != null && user.getWechatUnionid() != null && !user.getWechatUnionid().equals("")){
  243. return ResponseHelp.success(false);
  244. }
  245. return ResponseHelp.success(true);
  246. }
  247. private MyDto processUser(User user, HttpServletRequest request){
  248. MyDto dto = Transform.convert(user, MyDto.class);
  249. if (user.getId() == null || user.getId() == 0) return dto;
  250. String ip = Tools.getClientIp(request);
  251. User entity = User.builder().id(user.getId()).build();
  252. entity.setLatestLoginTime(new Date());
  253. if (!user.getRegisterIp().equals(ip) && !user.getLatestLoginIp().equals(ip)){
  254. entity.setLatestLoginIp(ip);
  255. // 登录异常处理
  256. if(!aiHelp.compareIp(user.getRegisterIp(), ip)){
  257. String[] info = aiHelp.parseIp(ip);
  258. userAbnormalService.push(user.getId(), ip, info);
  259. }
  260. }
  261. // 更新登录信息
  262. usersService.edit(entity);
  263. if (!user.getMobile().isEmpty()){
  264. dto.setBindMobile(true);
  265. }
  266. if (!user.getWechatUnionid().isEmpty()){
  267. dto.setBindWechat(true);
  268. }
  269. if (user.getRealStatus() > 0){
  270. dto.setBindReal(true);
  271. }
  272. if(!user.getPrepareStatus().isEmpty()){
  273. dto.setBindPrepare(true);
  274. }
  275. // vip
  276. dto.setVip(userServiceService.timeService(user.getId(), ServiceKey.VIP));
  277. // 最新机经
  278. if (userServiceService.hasService(user.getId(), ServiceKey.TEXTBOOK)){
  279. TextbookLibrary latest = textbookLibraryService.getLatest();
  280. dto.setTextbook(latest.getUpdateTime());
  281. }
  282. // 未读消息
  283. Page<UserMessage> messageList = userMessageService.list(1, 4, user.getId(), null, 0);
  284. dto.setMessageNumber((int)messageList.getTotal());
  285. messageExtendService.refreshMessage(messageList);
  286. dto.setMessages(messageList);
  287. // 未完成作业
  288. List<UserOrderRecord> recordList = userOrderRecordService.listWithCourse(1, 1000, null, null, true, false, null, null);
  289. Collection recordIds = Transform.getIds(recordList, UserOrderRecord.class, "id");
  290. List<UserPreviewPaperRelation> relationList = previewService.listByRecordId(user.getId(), recordIds, 2);
  291. dto.setPreviewNumber(relationList.size());
  292. return dto;
  293. }
  294. }