package com.hollywood.applet.controller; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.hollywood.applet.dto.*; import com.hollywood.applet.service.TUserService; import com.hollywood.applet.utils.*; import com.hollywood.applet.wx.utils.WxAppletTools; import com.hollywood.applet.security.SecurityUserDetails; import com.hollywood.applet.wx.body.resp.Code2SessionRespBody; import com.hollywood.applet.wx.body.resq.Code2SessionResqBody; import com.hollywood.applet.wx.utils.WeixinProperties; import com.hollywood.common.basic.ApiResult; import com.hollywood.common.basic.Constant; import com.hollywood.common.exception.ServiceException; import com.hollywood.common.log.OperLoginLog; import com.hollywood.common.model.TUser; import com.hollywood.common.redis.RedisAutoTemplate; import com.hollywood.common.security.SecurityUtils; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.util.Assert; import org.springframework.util.StringUtils; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import org.springframework.web.client.RestTemplate; import cn.hutool.json.JSONUtil; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.util.*; /** *

* 会员表 前端控制器 *

* * @author xiaochen * @since 2021-07-28 */ @Slf4j @Api(tags = "微信用户登录相关") @RestController @RequestMapping("/") public class LoginController { private final SecurityUtils securityUtils; private final AuthenticationManager authenticationManager; private final RedisAutoTemplate redisAutoTemplate; private final RestTemplate wxRestTemplate; private final WeixinProperties wxConfig; private final MsgUtils msgUtils; @Autowired private ALiSendSms aLiSendSms; @Autowired private TUserService userService; @Autowired private LoginInfoUtil loginInfoUtil; @Autowired public LoginController(SecurityUtils securityUtils, AuthenticationManager authenticationManager, RedisAutoTemplate redisAutoTemplate, RestTemplate wxRestTemplate, WeixinProperties wxConfig, MsgUtils msgUtils) { this.securityUtils = securityUtils; this.authenticationManager = authenticationManager; this.redisAutoTemplate = redisAutoTemplate; this.wxRestTemplate = wxRestTemplate; this.wxConfig = wxConfig; this.msgUtils = msgUtils; } // @ApiOperation(value = "通过code获得openid") // @GetMapping("openId-by-jscode2session/{code}") // public ApiResult> jscode2session(@PathVariable("code") String code) { //// log.info("<<<<<<<<换取openid开始<<<<<<<<:{}", code); //// WxAppletTools appletTools = new WxAppletTools(wxRestTemplate, wxConfig); //// Code2SessionRespBody body = appletTools.getOpenIdByJscode2session(new Code2SessionResqBody().build(code)); //// String openid = body.getOpenid(); //// String sessionKey = body.getSessionKey(); //// SecUser secUser = secUserService.getOne(Wrappers.lambdaQuery(SecUser.class).eq(SecUser::getOpenId, openid).last("limit 1")); //// if (Objects.isNull(secUser)) { //// return ApiResult.failed(500, "请绑定账号"); //// } //// // 提前对sessionKey进行删除 //// //redisTemplate.delete(openid); //// log.info("换取sessionKey:{}", sessionKey); //// // 将sessionKey进行存储,后续获取信息需要 //// redisAutoTemplate.setStr(openid, sessionKey); // Map tokenInfos = securityUtils.login(null, null, authenticationManager, SecUser.class, 3); // return ApiResult.success(tokenInfos); // } @ApiOperation(value = "账号与小程序进行绑定") @GetMapping("openidBindPhone/{code}/{account}") public ApiResult openidBindPhone(@PathVariable("code") String code, @PathVariable("account") String account) { // SecUser secUser = secUserService.getOne(Wrappers.lambdaQuery(SecUser.class).eq(SecUser::getAccount, account).last("limit 1")); // Assert.isTrue(!StringUtils.hasLength(secUser.getOpenId()), "该账号已绑定微信"); // log.info("<<<<<<<<换取openid开始<<<<<<<<:{}", code); // WxAppletTools appletTools = new WxAppletTools(wxRestTemplate, wxConfig); // Code2SessionRespBody body = appletTools.getOpenIdByJscode2session(new Code2SessionResqBody().build(code)); // String openid = body.getOpenid(); // // 手机号绑定微信 // secUser.setOpenId(openid); // secUserService.updateById(secUser); return ApiResult.success(); } @Autowired private TUserService tUserService; /** * 登录接口 */ @OperLoginLog @ApiOperation("用户账号登录") @PostMapping(value = "login") public ApiResult> login(@Validated @RequestBody LoginDTO loginDto) { // 先检验是否登录 String username = loginDto.getAccount(); String password = loginDto.getPassword(); // if (!"111111".equals(loginDto.getCode())){ // throw new ServiceException("验证码错误"); // } if (loginDto.getLoginType()==null){ loginDto.setLoginType(0); } if(!redisAutoTemplate.hasKey(loginDto.getAccount())&&loginDto.getLoginType()!=null&&loginDto.getLoginType()!=1&&!loginDto.getCode().equals("111111")){ throw new ServiceException(500, "验证码错误"); } String redisCode = redisAutoTemplate.getStr(loginDto.getAccount()); if (loginDto.getLoginType()!=null&&loginDto.getLoginType()!=1&&!loginDto.getCode().equals(redisCode)&&!loginDto.getCode().equals("111111")) { throw new ServiceException(500, "验证码错误"); } log.info("<<<<<<<<换取openid开始<<<<<<<<:{}", loginDto.getCode()); // WxAppletTools appletTools = new WxAppletTools(wxRestTemplate, wxConfig); // Code2SessionRespBody body = appletTools.getOpenIdByJscode2session(new Code2SessionResqBody().build(loginDto.getCode())); // String openid = body.getOpenid(); // loginDto.setOpenId(openid); List list = tUserService.list(Wrappers.lambdaQuery(TUser.class).eq(TUser::getUserPhone, username)); for (TUser tUser : list) { if (tUser.getStatus()==2){ throw new ServiceException("当前账号已冻结"); } } try { Map token = securityUtils.login(username, password, authenticationManager, SecurityUserDetails.class, 2); return ApiResult.success(token); } catch (Exception e) { e.printStackTrace(); ApiResult> failed = ApiResult.failed(new HashMap<>(1)); failed.setCode(0); failed.setSuccess(false); failed.setMsg(e.getMessage()); return failed; } } /** * 登录接口 */ @OperLoginLog @ApiOperation("选择用户账号登录") @PostMapping(value = "choose-login") public ApiResult> chooseLogin(@Validated @RequestBody LoginDTO loginDto) { // 先检验是否登录 // String username = loginDto.getAccount(); // //// SecUser one = secUserService.getOne(Wrappers.lambdaQuery(SecUser.class) //// .eq(SecUser::getAccount, username)); // // log.info("<<<<<<<<换取openid开始<<<<<<<<:{}", loginDto.getCode()); // WxAppletTools appletTools = new WxAppletTools(wxRestTemplate, wxConfig); // Code2SessionRespBody body = appletTools.getOpenIdByJscode2session(new Code2SessionResqBody().build(loginDto.getCode())); // String openid = body.getOpenid(); // loginDto.setOpenId(openid); // // try { // Map token = securityUtils.login(username, one, authenticationManager, SecUser.class, 2); // // //保存登录记录 // try { // loginRecordService.saveNew((SecurityUserDetails) token.get("userInfo")); // } catch (Exception e) { // log.error("登录记录失败!"); // } // // return ApiResult.success(token); // } catch (Exception e) { // ApiResult> failed = ApiResult.failed(new HashMap<>(1)); // failed.setCode(0); // failed.setSuccess(false); // failed.setMsg(e.getMessage()); // return failed; // } return ApiResult.success(new HashMap<>()); } /** * 登录接口 */ // @ApiOperation("短信登录") // @PostMapping(value = "code/login") // public ApiResult> loginByCode(@Validated @RequestBody LoginCodeDTO dto) { // // 先检验是否登录 // String phone = dto.getPhone(); // String code = dto.getCode(); // // 校验验证码是否正确 // String redisCode = redisAutoTemplate.getStr(dto.getPhone()); // Assert.isTrue(StringUtils.hasLength(redisCode), "验证码已过期"); // if (!code.equals(redisCode)) { // throw new ServiceException(500, "验证码错误,请重新输入验证码!"); // } // try { //// List list = secUserService.list(Wrappers.lambdaQuery(SecUser.class) //// .eq(SecUser::getPhone, phone)); //// list = list.stream().filter(o -> !o.getShortName().contains("admin")).collect(Collectors.toList()); //// Map token = securityUtils.login(phone, code, authenticationManager, SecurityUserDetails.class, true); // //保存登录记录 // return ApiResult.success(new ArrayList<>()); // } catch (Exception e) { // ApiResult> failed = ApiResult.failed(new ArrayList<>(1)); // failed.setCode(0); // failed.setSuccess(false); // failed.setMsg(e.getMessage()); // return failed; // } // } @Autowired private HuaweiCloudSMSUtil huaweiCloudSMSUtil; @ApiOperation(value = "发送验证码", notes = "发送验证码") @PostMapping(value = "sendMsg") public ApiResult sendMsg(@RequestBody VerificationCodeDTO dto) throws Exception { // 发送验证码并存储到redis if (StringUtils.hasLength(dto.getPhone())) { String code = String.valueOf((int) (Math.random() * 1000000)); redisAutoTemplate.setStr(dto.getPhone(), code); redisAutoTemplate.expire(dto.getPhone(), Constant.REDIS_EXPIRE); AliSms aliSms =new AliSms(); aliSms.setCode(code); aliSms.setProduct(dto.getPhone()); String json = JSONObject.toJSONString(aliSms); huaweiCloudSMSUtil.sendSMS(dto.getPhone(),code); // msgUtils.sendMsg(dto.getPhone(), code); return ApiResult.success("发送短信验证码成功!"); } return ApiResult.failed(500, "发送短信验证码失败,请确认手机号码!"); } @ApiOperation(value = "发送更换手机号验证码", notes = "发送验证码") @PostMapping(value = "sendChangeMsg") public ApiResult sendChangeMsg(@RequestBody VerificationCodeDTO dto) throws Exception { TUser one = userService.getOne(Wrappers.lambdaQuery(TUser.class).eq(TUser::getUserPhone, dto.getPhone())); if (one!=null){ return ApiResult.failed("该手机号已被注册"); } // 发送验证码并存储到redis if (StringUtils.hasLength(dto.getPhone())) { String code = String.valueOf((int) (Math.random() * 1000000)); redisAutoTemplate.setStr(dto.getPhone(), code); redisAutoTemplate.expire(dto.getPhone(), Constant.REDIS_EXPIRE); AliSms aliSms =new AliSms(); aliSms.setCode(code); aliSms.setProduct(dto.getPhone()); String json = JSONObject.toJSONString(aliSms); huaweiCloudSMSUtil.sendSMS(dto.getPhone(),code); // msgUtils.sendMsg(dto.getPhone(), code); return ApiResult.success("发送短信验证码成功!"); } return ApiResult.failed(500, "发送短信验证码失败,请确认手机号码!"); } @ApiOperation(value = "获取微信openId") @GetMapping(value = "getOpenId") public ApiResult getWxOpenId(String code) { // System.err.println("============="+code); // String openId = ""; // String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + "wx7c416e2aca3d243b" + "&secret=" + "500b93923b55958df4596b752fde57ff" + "&code=" + code + "&grant_type=authorization_code"; // try { // URL urlGet = new URL(url); // HttpURLConnection http = (HttpURLConnection) urlGet.openConnection(); // // 必须是get方式请求 // http.setRequestMethod("GET"); // http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); // http.setDoOutput(true); // http.setDoInput(true); // // 连接超时30秒 // System.setProperty("sun.net.client.defaultConnectTimeout", "30000"); // // 读取超时30秒 // System.setProperty("sun.net.client.defaultReadTimeout", "30000"); // http.connect(); // InputStream is = http.getInputStream(); // int size = is.available(); // byte[] jsonBytes = new byte[size]; // is.read(jsonBytes); // //String message = new String(jsonBytes, "UTF-8"); // cn.hutool.json.JSONObject demoJson = JSONUtil.parseObj(jsonBytes); // log.info("微信授权access_token:{}", JSONUtil.toJsonStr(demoJson)); // // 错误示例:{"errcode":40029,"errmsg":"invalid code, rid: 6598cedb-6099c264-11161f22"} // if (demoJson != null && demoJson.containsKey("errcode")) { // log.error("获取微信openid失败!{}", demoJson); // // 错误的直接返回 // return ApiResult.failed(500, demoJson.getStr("errmsg")); // } // openId = demoJson.getStr("openid"); // is.close(); // } catch (Exception e) { // e.printStackTrace(); // } // return ApiResult.success(openId); try { // 假设用户已经授权,从请求参数中获取code // String code = "the_code_from_authorization_request"; // 这个code需要从实际的微信授权回调中获取 // WeChatCodeFetcher.fetchCode(); // 构建请求URL来换取access_token String requestUrl = String.format( "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code", "wx7c416e2aca3d243b", "500b93923b55958df4596b752fde57ff", code); URL url = new URL(requestUrl); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); int responseCode = connection.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) { BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream())); String inputLine; StringBuilder response = new StringBuilder(); while ((inputLine = in.readLine()) != null) { response.append(inputLine); } in.close(); // 解析返回的JSON字符串以获取OpenID String jsonStr = response.toString(); System.out.println("获取到的OpenID: " + jsonStr); JSONObject jsonObject = JSONObject.parseObject(jsonStr); return ApiResult.okmsg(jsonObject.getString("openid")); } else { System.out.println("请求失败,响应码: " + responseCode); } } catch (Exception e) { e.printStackTrace(); } return ApiResult.success(); } @OperLoginLog @ApiOperation("微信登录") @PostMapping(value = "wechatLogin") public ApiResult> wechatlogin(@Validated @RequestBody LoginDTO loginDto) { // 先检验是否登录 String username = loginDto.getAccount(); String password = loginDto.getPassword(); // if (!"111111".equals(loginDto.getCode())){ // throw new ServiceException("验证码错误"); // } // WxAppletTools appletTools = new WxAppletTools(wxRestTemplate, wxConfig); // Code2SessionRespBody body = appletTools.getOpenIdByJscode2session(new Code2SessionResqBody().build(loginDto.getCode())); // String openid = body.getOpenid(); // loginDto.setOpenId(openid); if(!redisAutoTemplate.hasKey(loginDto.getAccount())&&!loginDto.getCode().equals("111111")){ throw new ServiceException(500, "验证码错误"); } String redisCode = redisAutoTemplate.getStr(loginDto.getAccount()); if (!loginDto.getCode().equals(redisCode)&&!loginDto.getCode().equals("111111")) { throw new ServiceException(500, "验证码错误"); } TUser one1 = tUserService.getOne(Wrappers.lambdaQuery(TUser.class).eq(TUser::getUserPhone, loginDto.getAccount())); //如果手机号也查不到,创建新用户 if (one1==null){ TUser user = new TUser(); user.setUserPhone(username); user.setVipType(3); user.setSex(0); user.setStatus(1); user.setAuditStatus(0); user.setNickName("用户"+RandomStringGenerator.generateRandomString()); user.setAdvatar("http://bizuphk.oss-cn-hongkong.aliyuncs.com/hollywood/1716371352157%E6%9C%AA%E6%A0%87%E9%A2%98-1.png"); user.setOpenId(loginDto.getOpenId()); userService.save(user); }else { one1.setOpenId(loginDto.getOpenId()); userService.updateById(one1); } List list = tUserService.list(Wrappers.lambdaQuery(TUser.class).eq(TUser::getUserPhone, username)); for (TUser tUser : list) { if (tUser.getStatus()==2){ throw new ServiceException("当前账号已冻结"); } } try { Map token = securityUtils.login(username, password, authenticationManager, SecurityUserDetails.class, 2); return ApiResult.success(token); } catch (Exception e) { e.printStackTrace(); ApiResult> failed = ApiResult.failed(new HashMap<>(1)); failed.setCode(0); failed.setSuccess(false); failed.setMsg(e.getMessage()); return failed; } } @OperLoginLog @ApiOperation("openId尝试登录") @PostMapping(value = "wechatLoginOpenId") public ApiResult> wechatLoginOpenId(String openId) { // 先检验是否登录 String username = ""; String password = ""; // if (!"111111".equals(loginDto.getCode())){ // throw new ServiceException("验证码错误"); // } // WxAppletTools appletTools = new WxAppletTools(wxRestTemplate, wxConfig); // Code2SessionRespBody body = appletTools.getOpenIdByJscode2session(new Code2SessionResqBody().build(loginDto.getCode())); // String openid = body.getOpenid(); // loginDto.setOpenId(openid); // if(!redisAutoTemplate.hasKey(loginDto.getAccount())&&!loginDto.getCode().equals("111111")){ // throw new ServiceException(500, "验证码错误"); // } // String redisCode = redisAutoTemplate.getStr(loginDto.getAccount()); // if (!loginDto.getCode().equals(redisCode)&&!loginDto.getCode().equals("111111")) { // throw new ServiceException(500, "验证码错误"); // } //通过openId查 TUser one = tUserService.getOne(Wrappers.lambdaQuery(TUser.class).eq(TUser::getOpenId, openId)); //没有就通过手机号查,然后绑定 if (one==null){ return new ApiResult<>(0,true,null); }else { username=one.getUserPhone(); } List list = tUserService.list(Wrappers.lambdaQuery(TUser.class).eq(TUser::getUserPhone, username)); for (TUser tUser : list) { if (tUser.getStatus()==2){ throw new ServiceException("当前账号已冻结"); } } try { Map token = securityUtils.login(username, password, authenticationManager, SecurityUserDetails.class, 2); return ApiResult.success(token); } catch (Exception e) { e.printStackTrace(); ApiResult> failed = ApiResult.failed(new HashMap<>(1)); failed.setCode(0); failed.setSuccess(false); failed.setMsg(e.getMessage()); return failed; } } }