diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/config/WxProperties.java b/ruoyi-admin/src/main/java/com/ruoyi/web/config/WxProperties.java new file mode 100644 index 00000000..638269cc --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/config/WxProperties.java @@ -0,0 +1,119 @@ +package com.ruoyi.web.config; + + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/* +* 微信配置属性 +* */ + +@Component +@ConfigurationProperties(prefix = "wx") +public class WxProperties { + /** + * 微信小程序/公众号 appId + */ + private String appId; + + /** + * 微信小程序/公众号 appSecret + */ + private String appSecret; + + /** + * 微信授权回调地址 + */ + private String redirectUri; + + /** + * 微信接口调用凭证有效期(单位:秒) + */ + private Long accessTokenExpireTime = 7200L; + + /** + * 微信网页授权作用域 + * snsapi_base: 静默授权,只能获取openid + * snsapi_userinfo: 手动授权,可获取用户基本信息 + */ + private String scope = "snsapi_userinfo"; + + /** + * 微信API接口地址 + */ + private String apiUrl = "https://api.weixin.qq.com"; + + + + + + + + public String getAppId() { + return appId; + } + + public void setAppId(String appId) { + this.appId = appId; + } + + public String getAppSecret() { + return appSecret; + } + + public void setAppSecret(String appSecret) { + this.appSecret = appSecret; + } + + public String getRedirectUri() { + return redirectUri; + } + + + /** + * 获取微信授权URL + * @param state 状态参数 + * @return 授权URL + */ + public String getAuthorizationUrl(String state) { + return String.format( + "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s#wechat_redirect", + appId, + redirectUri, + scope, + state + ); + } + + /** + * 获取access_token接口地址 + * @return 接口地址 + */ + public String getAccessTokenUrl() { + return apiUrl + "/sns/oauth2/access_token"; + } + + /** + * 获取用户信息接口地址 + * @return 接口地址 + */ + public String getUserInfoUrl() { + return apiUrl + "/sns/userinfo"; + } + + /** + * 校验access_token是否有效接口地址 + * @return 接口地址 + */ + public String getCheckAccessTokenUrl() { + return apiUrl + "/sns/auth"; + } + + /** + * 刷新access_token接口地址 + * @return 接口地址 + */ + public String getRefreshTokenUrl() { + return apiUrl + "/sns/oauth2/refresh_token"; + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/wxController/WxAuthController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/wxController/WxAuthController.java new file mode 100644 index 00000000..ca3d9b7e --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/wxController/WxAuthController.java @@ -0,0 +1,128 @@ +package com.ruoyi.web.controller.wxController; + +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.system.domain.SysSignIn; +import com.ruoyi.system.domain.dto.WxLoginDTO; +import com.ruoyi.system.domain.dto.WxLoginTDTO; +import com.ruoyi.system.domain.dto.WxUserDTO; +import com.ruoyi.system.domain.dto.XmLoginDto; +import com.ruoyi.system.service.ISysSignInService; +import com.ruoyi.system.service.ISysUserService; +import com.ruoyi.system.service.WxAuthService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.*; +import com.ruoyi.common.core.redis.RedisCache; + +@RestController +@RequestMapping("/api/wx/auth") +public class WxAuthController { + + @Autowired + private WxAuthService wxAuthService; + + @Autowired + private RedisCache redisCache; + + @Autowired + private ISysUserService sysUserService; + + @Autowired + private ISysSignInService sysSignInService; + + @PostMapping("/login") + public AjaxResult login(@RequestBody WxLoginDTO loginDTO) { + +// WxLoginDTO loginDTO = new WxLoginDTO(); +// loginDTO.setCode(code); + try { + WxLoginTDTO wxLoginTDTO = wxAuthService.login(loginDTO); + + if(wxLoginTDTO == null){ + return AjaxResult.error("登录失败"); + } + + AjaxResult ajax = AjaxResult.success("登录成功"); + ajax.put("phone", wxLoginTDTO.getPhone()); + ajax.put("calculateNumber", wxLoginTDTO.getCalculateNumber()); + ajax.put("nickname", wxLoginTDTO.getNickname()); + ajax.put("avatar", wxLoginTDTO.getAvatar()); + ajax.put(Constants.TOKEN, wxLoginTDTO.getToken()); + + return ajax; + } catch (Exception e) { + + System.out.println("微信登录失败: "+e.getMessage()); + return AjaxResult.error("登录失败"); + } + } + + + /* + * 绑定手机号+将微信账号和手机号绑定 + * */ + @Transactional + @PostMapping("/bind") + public AjaxResult bind(@RequestBody XmLoginDto xmLoginDto) { + // 绑定手机号 + System.out.println("登录者手机"+xmLoginDto.getPhone()); + + //---------------------------20241206 测试时先注释掉短信验证------------------------------------ + //---获取手机验证码------ + String sms = redisCache.getCacheObject("SMSCODE:" + xmLoginDto.getPhone()); + System.out.println("SMSCODE:" + xmLoginDto.getPhone()); + System.out.println("验证码"+sms); + if (!sms.equals(xmLoginDto.getSmsCode())) { + return AjaxResult.error("短信验证码错误"); + } + //-------------------------------end 验证码---------------------------------------------- + + // 以前用户名应该是手机号 + SysUser sysUser = sysUserService.selectUserByUserName(xmLoginDto.getPhone()); + + SysSignIn sysSignInApp = sysSignInService.selectSysSignInByUId(sysUser.getUserId()); + + // 当前用户的微信账号id + Long userId = SecurityUtils.getUserId(); + + // 微信用户账号 + SysUser sysUserWx = sysUserService.selectUserById(userId); + + // 若存在手机号说明该微信账号已经绑定过手机号. + if(!sysUserWx.getPhonenumber().isEmpty()){ + System.out.println("用户手机号: "+ sysUserWx.getPhonenumber()); + return AjaxResult.error("该账号已绑定, 请不要重复绑定手机号"); + } + + //更新账号手机号信息 + sysUserWx.setPhonenumber(xmLoginDto.getPhone()); + + int infoUser = sysUserService.updateUser(sysUserWx); + + if(infoUser == 0){ + return AjaxResult.error("绑定失败, 请联系管理员"); + } + + + // 查询当前微信账号的签到信息---绑定信息 + SysSignIn sysSignInWx = sysSignInService.selectSysSignInByUId(userId); + + sysSignInWx.setVipStartTime(sysSignInApp.getVipStartTime()); + sysSignInWx.setVipStopTime(sysSignInApp.getVipStopTime()); + sysSignInWx.setCalculateNumber(Math.max(10L, sysSignInApp.getCalculateNumber())); + + + //更新微信用户账号信息 + int infoSign = sysSignInService.updateSysSignIn(sysSignInWx); + + if (infoSign == 0) { + return AjaxResult.error("绑定失败"); + } + return AjaxResult.success("绑定成功"); + + //------------------------------绑定用户信息---------------------------------------------- + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/wxController/WxAuthServiceImpl.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/wxController/WxAuthServiceImpl.java new file mode 100644 index 00000000..e1d137fd --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/wxController/WxAuthServiceImpl.java @@ -0,0 +1,269 @@ +package com.ruoyi.web.controller.wxController; + + +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.framework.web.service.SysLoginService; +import com.ruoyi.system.domain.SysSignIn; +import com.ruoyi.system.domain.dto.WxAccessDto; +import com.ruoyi.system.domain.dto.WxLoginTDTO; +import com.ruoyi.system.service.ISysSignInService; +import com.ruoyi.system.service.ISysUserService; +import com.ruoyi.web.config.WxProperties; +import com.ruoyi.system.domain.WxUser; +import com.ruoyi.system.domain.dto.WxLoginDTO; +import com.ruoyi.system.domain.dto.WxUserDTO; +import com.ruoyi.system.service.WxAuthService; + +import com.ruoyi.web.utils.WxUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; + +@Service +public class WxAuthServiceImpl implements WxAuthService { + @Autowired + private WxProperties wxProperties; + +// @Autowired +// private WxUserMapper wxUserMapper; +// +// @Autowired +// private WxLoginLogMapper loginLogMapper; + +// @Autowired +// private RedisCache redisCache; + + @Autowired + private WxUtils wxUtils; + + @Autowired + private ISysUserService sysUserService; + + @Autowired + ISysSignInService sysSignInService; + + @Autowired + private SysLoginService loginService; + +// @Override +// @Transactional(rollbackFor = Exception.class) + public WxLoginTDTO login(WxLoginDTO loginDTO) { + +// System.out.println("loginDTO.getCode()"+loginDTO.getCode()); + + // 1. 获取微信用户信息 + String code = loginDTO.getCode(); +// 得到用户 openId 和 accessToken----------------本地测试先注释掉--------------------------- + WxAccessDto wxAccessDto = wxUtils.getAccessToken(code); + +// //-------------20241206 本地测试------------------------- +// WxAccessDto wxAccessDto = new WxAccessDto(); +// // 采用数据库中已有的用户 +// wxAccessDto.setOpenId("oz6eUwMrW4vqVi5wfmAMRDFAYIgw"); +// //-----------20241206 本地测试结束---------------------- + + if(wxAccessDto != null) { + + //判断数据库中是否存在这个openId,------用户是否已注册 + SysUser user = sysUserService.selectUserByUserName(wxAccessDto.getOpenId()); + + if(user==null){ + System.out.println("用户不存在, 注册新用户"); + + // 获取用户信息 + WxUser wxUserInfo = wxUtils.getWxUserInfo(wxAccessDto); + + // 获取微信用户信息失败 + if(wxUserInfo == null){ + System.out.println("获取用户信息失败"); + return null; + } + + WxUserDTO userDTO = new WxUserDTO(); + + userDTO.setNickname(wxUserInfo.getNickname()); + userDTO.setAvatarUrl(wxUserInfo.getAvatarUrl()); + + + // 新用户注册 + SysUser newSysUser = new SysUser(); + // 用 openid代替用户名 + newSysUser.setUserName(wxAccessDto.getOpenId()); + newSysUser.setNickName(wxUserInfo.getNickname()); + newSysUser.setPhonenumber(null); + + newSysUser.setPassword(SecurityUtils.encryptPassword(wxAccessDto.getOpenId())); + +// System.out.println("getAvatarUrl:"+wxUserInfo.getAvatarUrl()+"len: "+wxUserInfo.getAvatarUrl().length()); + newSysUser.setAvatar(wxUserInfo.getAvatarUrl()); + sysUserService.insertUser(newSysUser); + + // 获取新用户 id + SysUser newSysUser1 = sysUserService.selectUserByUserName(wxAccessDto.getOpenId()); + + Long userId = newSysUser1.getUserId(); + SysSignIn sysSignIn = new SysSignIn(); + sysSignIn.setUid(userId); + sysSignIn.setSignInDays(0L); + //初始默认6次 + sysSignIn.setStatus(1L); + sysSignIn.setCalculateNumber(10L); + + DateFormat dateFormat1 = new SimpleDateFormat("yyyy-MM-dd"); + Date myDate1 = null; + try { + myDate1 = dateFormat1.parse("2009-06-01"); + } + catch (Exception e) { + e.printStackTrace(); + } + sysSignIn.setSignUpdateTime(myDate1); + //TODO 设置为普通香民 增加返回连续上香天数 测算时间 + sysSignInService.insertSysSignIn(sysSignIn); + String token = loginService.wxLogin(wxAccessDto.getOpenId(), wxAccessDto.getOpenId()); + + WxLoginTDTO wxLoginTDTO = new WxLoginTDTO(); + wxLoginTDTO.setToken(token); + wxLoginTDTO.setPhone(wxAccessDto.getOpenId()); + wxLoginTDTO.setCalculateNumber(10L); + + wxLoginTDTO.setAvatar(wxUserInfo.getAvatarUrl()); + wxLoginTDTO.setNickname(wxUserInfo.getNickname()); + + return wxLoginTDTO; + + + + } + + // 不是新用户 + else{ + String token = loginService.wxLogin(wxAccessDto.getOpenId(), wxAccessDto.getOpenId()); + + // TODO 增加返回连续上香天数 测算时间 + SysSignIn sysSignIn = sysSignInService.selectSysSignInByUId(user.getUserId()); + + sysSignInService.loginVerificationInformation(sysSignIn); + + WxLoginTDTO wxLoginTDTO = new WxLoginTDTO(); + wxLoginTDTO.setToken(token); + wxLoginTDTO.setPhone(wxAccessDto.getOpenId()); + wxLoginTDTO.setCalculateNumber(sysSignIn.getCalculateNumber()); + + wxLoginTDTO.setAvatar(user.getAvatar()); + wxLoginTDTO.setNickname(user.getNickName()); + + return wxLoginTDTO; + + + } + + } + else{ + return null; + } + +// // 2. 检查用户是否存在 +// WxUser existUser = wxUserMapper.selectByOpenId(wxUserInfo.getOpenid()); +// +// WxUser wxUser; +// if (existUser == null) { +// // 3. 新用户注册 +// wxUser = wxUserInfo; +// wxUser.setCreateTime(LocalDateTime.now()); +// wxUser.setIsDeleted(false); +// wxUserMapper.insert(wxUser); +// } else { +// // 4. 更新已有用户信息 +// wxUser = existUser; +// wxUser.setNickname(wxUserInfo.getNickname()); +// wxUser.setAvatarUrl(wxUserInfo.getAvatarUrl()); +// wxUser.setGender(wxUserInfo.getGender()); +// wxUser.setCountry(wxUserInfo.getCountry()); +// wxUser.setProvince(wxUserInfo.getProvince()); +// wxUser.setCity(wxUserInfo.getCity()); +// wxUser.setLoginIp(IpUtils.getIpAddr()); +// wxUser.setLoginDate(LocalDateTime.now()); +// wxUserMapper.updateById(wxUser); +// } + +// // 5. 生成Token +// String token = wxUtils.generateToken(wxUser); + +// // 6. 缓存用户信息 +// String userKey = String.format("wx:user:%s", wxUser.getOpenid()); +// redisCache.setCacheObject(userKey, wxUser, 24, TimeUnit.HOURS); +// +// // 7. 记录登录日志 +// WxLoginLog loginLog = new WxLoginLog(); +// loginLog.setUserId(wxUser.getId()); +// loginLog.setOpenid(wxUser.getOpenid()); +// loginLog.setLoginIp(IpUtils.getIpAddr()); +// loginLog.setLoginLocation(IpUtils.getRealAddressByIP(IpUtils.getIpAddr())); +// loginLog.setStatus(0); // 登录成功 +// loginLog.setMsg("登录成功"); +// loginLogMapper.insert(loginLog); + + // 8. 返回用户信息 + + + } + + @Override + public WxUserDTO refreshToken(String refreshToken) { + // 1. 验证刷新token, 这是用户后台登录token +// Long userId = wxUtils.validateRefreshToken(refreshToken); +// if (userId == null) { +// throw new IllegalArgumentException("无效的刷新令牌"); +// } + +// // 2. 获取用户信息 +// WxUser wxUser = wxUserMapper.selectById(userId); +// if (wxUser == null || wxUser.getIsDeleted()) { +// throw new IllegalArgumentException("用户不存在"); +// } +// +// // 3. 生成新token +// String newToken = wxUtils.generateToken(wxUser); +// +// // 4. 返回用户信息 +// return new WxUserDTO( +// wxUser.getId(), +// wxUser.getNickname(), +// wxUser.getAvatarUrl(), +// newToken +// ); +// WxUserDTO userDTO = new WxUserDTO(); +// userDTO.setUserId(userId); + + return null; + } + + @Override + public void logout(Long userId) { +// // 1. 清除Redis中的用户信息 +// WxUser wxUser = wxUserMapper.selectById(userId); +// if (wxUser != null) { +// String userKey = String.format("wx:user:%s", wxUser.getOpenid()); +// redisCache.deleteObject(userKey); +// } +// +// // 2. 清除token +// String tokenKey = String.format("wx:token:%d", userId); +// redisCache.deleteObject(tokenKey); +// +// // 3. 记录登出日志 +// WxLoginLog loginLog = new WxLoginLog(); +// loginLog.setUserId(userId); +// loginLog.setOpenid(wxUser != null ? wxUser.getOpenid() : null); +// loginLog.setLoginIp(IpUtils.getIpAddr()); +// loginLog.setLoginLocation(IpUtils.getRealAddressByIP(IpUtils.getIpAddr())); +// loginLog.setStatus(0); +// loginLog.setMsg("退出登录"); +// loginLogMapper.insert(loginLog); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xmComtroller/PayController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xmComtroller/PayController.java index 3457ac0c..fa17d419 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xmComtroller/PayController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xmComtroller/PayController.java @@ -89,8 +89,11 @@ public class PayController extends BaseController { String mchOrderNo = "M" + UUID.randomUUID().toString().replaceAll("-", ""); redisCache.setCacheObject(mchOrderNo, sysUser.getUserId() + "_" + predictCount, 1, TimeUnit.DAYS); // log.info("缓存订单和用户关系: mchOrderNo=" + mchOrderNo + ", userId=" + userId); + // 支付方式 WX_APP--微信app String wayCode = "QR_CASHIER"; +// String wayCode = "WX_NATIVE"; + Byte divisionMode = 0; // 前端明确了支付参数的类型 payDataType @@ -120,6 +123,8 @@ public class PayController extends BaseController { //设置扩展参数 JSONObject extParams = new JSONObject(); + +// 返回图片二维码url----------解除注释就是不返回支付地址,而是返回支付二维码 if (StringUtils.isNotEmpty(payDataType)) { extParams.put("payDataType", payDataType.trim()); } @@ -132,11 +137,20 @@ public class PayController extends BaseController { APPKEY); PayOrderCreateResponse payOrderCreateResponse = jeepayClient.execute(request); -// System.out.println(payOrderCreateResponse.toString()); + + + System.out.println(payOrderCreateResponse.toString()); PayResponseVo payResponseVo = JSONObject.parseObject(payOrderCreateResponse.toString(), PayResponseVo.class); String url = payResponseVo.getData().getPayData(); //设置Access-Control-Expose-Headers避免前端调用获取Content-Disposition出现Refused to get unsafe header异常 + String payDateType = payResponseVo.getData().getPayDataType(); + + System.out.println("payDateType:" + payDateType); + + + System.out.println("url:" + url); + response.addHeader("Access-Control-Expose-Headers", "Content-Disposition"); response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("img.jpg", "UTF-8")); diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/utils/GsonUtils.java b/ruoyi-admin/src/main/java/com/ruoyi/web/utils/GsonUtils.java new file mode 100644 index 00000000..4631e0a7 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/utils/GsonUtils.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2017 Baidu, Inc. All Rights Reserved. + */ +package com.ruoyi.web.utils; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonParseException; + +import java.lang.reflect.Type; + +/** + * Json工具类. + */ +public class GsonUtils { + private static Gson gson = new GsonBuilder().create(); + + public static String toJson(Object value) { + return gson.toJson(value); + } + + public static T fromJson(String json, Class classOfT) throws JsonParseException { + return gson.fromJson(json, classOfT); + } + + public static T fromJson(String json, Type typeOfT) throws JsonParseException { + return (T) gson.fromJson(json, typeOfT); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/utils/WxUtils.java b/ruoyi-admin/src/main/java/com/ruoyi/web/utils/WxUtils.java new file mode 100644 index 00000000..ac60ae12 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/utils/WxUtils.java @@ -0,0 +1,238 @@ +package com.ruoyi.web.utils; + + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.ruoyi.common.core.redis.RedisCache; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.system.domain.dto.WxAccessDto; +import com.ruoyi.web.config.WxProperties; +import com.ruoyi.system.domain.WxUser; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +@Component +public class WxUtils { + + private final ObjectMapper objectMapper; + + @Autowired + private WxProperties wxProperties; + + @Autowired + private RedisCache redisCache; + +// @Autowired + private RestTemplate restTemplate; + + // JWT密钥 + private static final String JWT_SECRET = "your-jwt-secret-key"; + + // Token过期时间(7天) + private static final long EXPIRE_TIME = 7 * 24 * 60 * 60 * 1000; + + // 刷新Token过期时间(30天) + private static final long REFRESH_EXPIRE_TIME = 30 * 24 * 60 * 60 * 1000; + + public WxUtils() { + this.objectMapper = new ObjectMapper(); + } + + + + + + /** + * 获取微信access_token + * + * @param code 微信授权码 + * @return access_token + */ + public WxAccessDto getAccessToken(String code) { + + System.out.println("code: " + code); + System.out.println("AppId: " + wxProperties.getAppId()); + System.out.println("AppSecret: " + wxProperties.getAppSecret()); + String url = String.format( + "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code", + wxProperties.getAppId(), + wxProperties.getAppSecret(), + code + ); + + System.out.println("url: " + url); + + String accessToken = null; + + try{ + URL obj = new URL(url); + HttpURLConnection con = (HttpURLConnection) obj.openConnection(); + con.setRequestMethod("GET"); // 设置请求方法为 GET + + // 获取响应代码 + int responseCode = con.getResponseCode(); + + if (responseCode == 200) { + // 读取返回的内容 + BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); + String inputLine; + StringBuilder response = new StringBuilder(); + + while ((inputLine = in.readLine()) != null) { + response.append(inputLine); + } + in.close(); + +// System.out.println("Response : " + response); + /* + *正常返回结果示例: + * { + "access_token":"ACCESS_TOKEN", + "expires_in":7200, + "refresh_token":"REFRESH_TOKEN", + "openid":"OPENID", + "scope":"SCOPE", + "is_snapshotuser": 1, + "unionid": "UNIONID" + } + * */ + /* + * 错误返回结果示例: + * {"errcode":40029,"errmsg":"invalid code"} + * */ + + //---------------------正常通过微信获取 oepnid和access_token------------------------------------------------------- + Map result = GsonUtils.fromJson(response.toString(), HashMap.class); + if(result.containsKey("errcode")){ + System.out.println("获取微信用户AccessToken失败: " + result.get("errmsg")); + return null; + } + + System.out.println("result: " + result); + + WxAccessDto wxAccessDto = new WxAccessDto(); + wxAccessDto.setAccessToken(result.get("access_token").toString()); + wxAccessDto.setOpenId(result.get("openid").toString()); + //---------------------------------------------------- + +// //--------------------------测试用----------------------------- +// +// WxAccessDto wxAccessDto = new WxAccessDto(); +// wxAccessDto.setAccessToken("86_m2-jHoRUFSF5UrrGosJvZHFxl_1UZH0Am-Di8xavbZ7DDYEp_2G-s2OiB6t2QJeQlaudaMsx7BEgv7ci_DdcELzsSDtsaRvQHEwNEEynr-8"); +// wxAccessDto.setOpenId("oz6eUwMrW4vqVi5wfmAMRDFAYIgw"); +// //------------------------------------------------------------ + + return wxAccessDto; + + } + + }catch (Exception e) { + e.printStackTrace(); // 处理异常 + } + + + return null; + } + + + + /** + * 获取微信用户信息 + * + * access_token 和 open_id + * @return 微信用户信息 + */ + public WxUser getWxUserInfo(WxAccessDto wxAccessDto) { + String url = String.format( + "https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN", + wxAccessDto.getAccessToken(), + wxAccessDto.getOpenId() + ); + + try { + + URL obj = new URL(url); + HttpURLConnection con = (HttpURLConnection) obj.openConnection(); + con.setRequestMethod("GET"); // 设置请求方法为 GET + + // 获取响应代码 + int responseCode = con.getResponseCode(); + + if (responseCode == 200) { + // 读取返回的内容 + BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); + String inputLine; + StringBuilder response = new StringBuilder(); + + while ((inputLine = in.readLine()) != null) { + response.append(inputLine); + } + in.close(); + +// System.out.println("Response : " + response); + /* + *正常返回结果示例: + * "openid": "OPENID", + "nickname": NICKNAME, + "sex": 1, + "province":"PROVINCE", + "city":"CITY", + "country":"COUNTRY", + "headimgurl":"https://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46", + "privilege":[ "PRIVILEGE1" "PRIVILEGE2" ], + "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL" + * */ + /* + * 错误返回结果示例: + * {"errcode":40003,"errmsg":" invalid openid "} + * */ + + Map result = GsonUtils.fromJson(response.toString(), HashMap.class); + + System.out.println("user info result: " + result); + + + if(result.containsKey("errcode")){ + + System.out.println("获取微信用户信息失败: " + result.get("errcode")); + return null; + } + + + WxUser wxUser = new WxUser(); + wxUser.setOpenid((String) result.get("openid")); + wxUser.setUnionid((String) result.get("unionid")); + wxUser.setNickname((String) result.get("nickname")); + wxUser.setAvatarUrl((String) result.get("headimgurl")); + wxUser.setGender( (Double)result.get("sex")); + wxUser.setCountry((String) result.get("country")); + wxUser.setProvince((String) result.get("province")); + wxUser.setCity((String) result.get("city")); + + return wxUser; + } + } catch (Exception e) { + + e.printStackTrace(); // 处理异常 + return null; + } + + return null; + } + + +} diff --git a/ruoyi-admin/src/main/resources/a.key b/ruoyi-admin/src/main/resources/a.key new file mode 100644 index 00000000..197327da --- /dev/null +++ b/ruoyi-admin/src/main/resources/a.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEAt/6LrJc/VDDnRYIRigLzm2aKIXsYIk2m3oyMBRA/baWj+x80 +2UrmqIT4ARJR79fuVi375p0Xd4qutxXStQZllf3f/vISza8hsO4QM5cdUn8WM7LN +Mp12Yp/fFqjdizFlitzAh1Am6q56vAvB84K1MEBpNtjjA9sldXRUk4CNZVpw0FsX +CAoSBS72RrFSEJDy8LLsmWbHio18E0W5bVGnXg4TBnx8fpnHbRs2P77ajQLP2XxR +bm/SG4RxHtPnnMi80jBA2JRgNi5CdLSOub4xIMljN1x3sNIHq4ki3SM+mbcQ9hvK +KyTIEiWfDebmZcThb52bFxJr9iJmVdRut0H79QIDAQABAoIBAC2wZdq7zBwJ8MQP +4m8VAI0sT0y1Fm8ePTuyRurS+A0wPqITQ7pZoSFjs3oApJwcULDRxmWjyLoElBIe +ty4AoqU2X7MdRZIR1RnsY9WLxto/eLHpyo6xDz66WFl2IV15LK/o1V5EhwVrwkqD +2OuxH3EV7YqTHPxOJOUfuAjQuUvbV5kS1HMI4hiJg8xy2acy2mjumVWMHv/5c+WD +NVK3F+hDDV3+TUhMOOWCx5P2lKOLoZaHCmkjypnpv98B8eTcynxwwcDMjXOAG62J +5TeN3e+0/pi9MexNpN7D9zF8qycZmrwOGAMk7tL85u+cn+qi5hBHokX+CIrCF1/d +R8S1/oECgYEA4pr50IFwRKU++QpWQzWC1nXl4V+70aJls5wSZdvSgEI9mu9pZ2nH +pWcHpfXvUY9iXfHSbTfj3YcrO87g+AUEukfizXxHS0wWCw9XqaTEVoBnfl4Y13ag +FL36aukSQuDwmlj15/6uuJCfFfWgm2VvUN5+PH9Feky1SLQgwpCOiuUCgYEAz9yO +5tq1B6ZqrsWkbIvkBbSENPjVtTCKYnQBanEd1VnfSw177CwcJHNQnNxy720vGpDq +Rx/UGZ0u/Z0wba0+LyIFPnsw85CQGLoQLjTcUecXtB6TlwRfK/XxymX1SY98eBkP +i4KOQTdIBfTTHu+NddZ3xFAghy9AmJUzkXDTy9ECgYAKpk3nRq4IC9wRyDKVpgYo +HhJXrTAeggtVjZgvwUz7SiGrDmVdvtLrKxRo8E32/04YLC0/hMjouFmHzgk0nsfC +GW7HSXfwSfsfOfFcv6mahx5WCgYQ2jpbvzHtpFZ/XiLwng2wgX+knOddGNYbd4Dr +xAkavsB9Ju2+JPkFK9YHIQKBgDjOx4NSLH2NvsRLIbfEt6nTfvpXM1jUjk1/9M8Z +YRTo/fyuD7spBvvzRAnKueKzjVcOWejcSwRBEBGh/xVKbp9FBffghS1byfXoC/oE +2l3L8Y95d86jFDuYeN9e5B2ZiGPuPXBcWvJ54EY4deaTg6670XmmiG1Jvba1uCU8 +l7WxAoGAe03SSuu1gQ05j2jZEKoX16gtWs3u0o2F4K4hTkXhZcqnUNm9km2K9jUH +gQWbK/feZD6VCH1dWSAQdoHszpjII7B+tjhYscGS3nXxuiCIuZhdUp7VkbmjDd2C +4L/j0lu7av2LxD/YXsIKxc4DfNAUemtTgyIr/+GG1L5YQcaA1pY= +-----END RSA PRIVATE KEY----- diff --git a/ruoyi-admin/src/main/resources/a.pem b/ruoyi-admin/src/main/resources/a.pem new file mode 100644 index 00000000..53f98605 --- /dev/null +++ b/ruoyi-admin/src/main/resources/a.pem @@ -0,0 +1,103 @@ +-----BEGIN CERTIFICATE----- +MIIF8DCCBFigAwIBAgIRAMuauUTxfaK74LOvin0+n7IwDQYJKoZIhvcNAQEMBQAw +WTELMAkGA1UEBhMCQ04xJTAjBgNVBAoTHFRydXN0QXNpYSBUZWNobm9sb2dpZXMs +IEluYy4xIzAhBgNVBAMTGlRydXN0QXNpYSBSU0EgRFYgVExTIENBIEczMB4XDTI0 +MTEyOTAwMDAwMFoXDTI1MDIyNzIzNTk1OVowGzEZMBcGA1UEAxMQY2VzdWFuLmRv +bmkubGluazCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf+i6yXP1Qw +50WCEYoC85tmiiF7GCJNpt6MjAUQP22lo/sfNNlK5qiE+AESUe/X7lYt++adF3eK +rrcV0rUGZZX93/7yEs2vIbDuEDOXHVJ/FjOyzTKddmKf3xao3YsxZYrcwIdQJuqu +erwLwfOCtTBAaTbY4wPbJXV0VJOAjWVacNBbFwgKEgUu9kaxUhCQ8vCy7Jlmx4qN +fBNFuW1Rp14OEwZ8fH6Zx20bNj++2o0Cz9l8UW5v0huEcR7T55zIvNIwQNiUYDYu +QnS0jrm+MSDJYzdcd7DSB6uJIt0jPpm3EPYbyiskyBIlnw3m5mXE4W+dmxcSa/Yi +ZlXUbrdB+/UCAwEAAaOCAm8wggJrMB8GA1UdIwQYMBaAFMjzxQkbM6JfphKrkNYA +tlz8jRwGMB0GA1UdDgQWBBQ0DUsKMag0j/nsUNwJUWYlX+3ybzAOBgNVHQ8BAf8E +BAMCBaAwDAYDVR0TAQH/BAIwADAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUH +AwIwSQYDVR0gBEIwQDA0BgsrBgEEAbIxAQICMTAlMCMGCCsGAQUFBwIBFhdodHRw +czovL3NlY3RpZ28uY29tL0NQUzAIBgZngQwBAgEwfQYIKwYBBQUHAQEEcTBvMEIG +CCsGAQUFBzAChjZodHRwOi8vY3J0LnRydXN0LXByb3ZpZGVyLmNuL1RydXN0QXNp +YVJTQURWVExTQ0FHMy5jcnQwKQYIKwYBBQUHMAGGHWh0dHA6Ly9vY3NwLnRydXN0 +LXByb3ZpZGVyLmNuMIIBAwYKKwYBBAHWeQIEAgSB9ASB8QDvAHUAzxFW7tUufK/z +h1vZaS6b6RpxZ0qwF+ysAdJbd87MOwgAAAGTdfRgLgAABAMARjBEAiAlmD/kFjgx +LnjDVV/ylMFhdC6DJnzBqp/yd9t2gfqn2AIgGB3QtP39rIqfElt+aqWN7mWb5s49 +7ov1vsAynyn1eLoAdgDM+w9qhXEJZf6Vm1PO6bJ8IumFXA2XjbapflTA/kwNsAAA +AZN19F/xAAAEAwBHMEUCIQDHsacrPWCJdb7p0YI2gIn4tyV+k1bZEDOEOmuo5FCT +lQIgC4rgETwe0QUwkOLWcuPMHx8p1FY8vuJkx9b9m7FuKfcwGwYDVR0RBBQwEoIQ +Y2VzdWFuLmRvbmkubGluazANBgkqhkiG9w0BAQwFAAOCAYEAQxa6hAE4liwObQUZ +zs4GWRil2QIrAvSJWZuQT4OrCkwxbYBtHERXQ1oSu+W+btNj7dpaTsQO2gXE0nPc +IKAH2AKREVSIbHMsMFfgQPw4Kq9qDGFl1xYH62BTAsBwBuKXp+v9soncPhURnlYY +1bFDU9Whq1R5gwC5k30uSfsHrirx1Yq2NVUKTi0LOupeAJtqnam9UFz1P6E5cv1j +jmf28/dsZM/CaESocNvsVSGQaF6GO4fN+daW3/OypznZwtXCYouMCjzwe0G9pKRK +C+buEnUdOzhWoTwifhh/CnF+kGqtkgIlVUJ8K+/jiClRGXam7lh6PT//Xhcva6wv +ciOE26i2vCYKSSB9/v0wB+vp4+S3eLmb1UtYD/c0NMf74VgYKMY2oSh60rN4K/1U +TMB3cdYGWtOjFDz7F2+mcjLvMOwA6EEjGmjgSoqgHzeGCADvKSY0pSPTVyW/juVZ +j7vqRIipTvcyWfC2ZpZPw+PaJECQGTOE6P6Wec8KWyYasZ5E +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIGXzCCBEegAwIBAgIRAOvYVZsFNC3ItSadAqqNGkYwDQYJKoZIhvcNAQEMBQAw +gYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpOZXcgSmVyc2V5MRQwEgYDVQQHEwtK +ZXJzZXkgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMS4wLAYD +VQQDEyVVU0VSVHJ1c3QgUlNBIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTIy +MDQyMDAwMDAwMFoXDTMyMDQxOTIzNTk1OVowWTELMAkGA1UEBhMCQ04xJTAjBgNV +BAoTHFRydXN0QXNpYSBUZWNobm9sb2dpZXMsIEluYy4xIzAhBgNVBAMTGlRydXN0 +QXNpYSBSU0EgRFYgVExTIENBIEczMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIB +igKCAYEAlo59CPBfarkCDfu3YxrBAHpyrAq1CCLh+BDcQEst60QsuqDzCXi2dk3h +YdUa7x30jts/u0XrZiJnuJGGNJ+Cs8bE6722JQYjw1h0f8r+pjwPY7XSx1dXHmUE +519eCKQJ6BQsaDWUOZBdTv85yPdmZsSXvjI2BFlro6LWAt/HGcsGIheQDI/HHrEA +ityeHQciMZi7XhkysIHdkPz4wugkz9+c1S8rgnhvfPY+vFL10tfx5vbmojK+jFlr +Ohc1qqi5cruOAPvoCmHJgNUmdZSki0BjLb16o6HlCjwApVo2S2lAUJM4QGA6n/Xg +WbasDqmdXC8gvYrJrBoHlaSUPbOoxg8eGKVbBdq+SfOIr4TgLF0fQqLQZJ5CuxEl +GFqXOzu76JUOdJjfsaATcawQrIFiH5O2+u4li1HALK8dhqjxXauQPapRvdjb8SKt +uUm5ARusBjuYW7Wt4i52AT7MA8D6AGFNffhSFo7RUATAnB7kd2ES47tF/u+zF814 +3JNS0PSfAgMBAAGjggFwMIIBbDAfBgNVHSMEGDAWgBRTeb9aqitKz1SA4dibwJ3y +sgNmyzAdBgNVHQ4EFgQUyPPFCRszol+mEquQ1gC2XPyNHAYwDgYDVR0PAQH/BAQD +AgGGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsG +AQUFBwMCMCIGA1UdIAQbMBkwDQYLKwYBBAGyMQECAjEwCAYGZ4EMAQIBMFAGA1Ud +HwRJMEcwRaBDoEGGP2h0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VU0VSVHJ1c3RS +U0FDZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDBxBggrBgEFBQcBAQRlMGMwOgYI +KwYBBQUHMAKGLmh0dHA6Ly9jcnQudXNlcnRydXN0LmNvbS9VU0VSVHJ1c3RSU0FB +QUFDQS5jcnQwJQYIKwYBBQUHMAGGGWh0dHA6Ly9vY3NwLnVzZXJ0cnVzdC5jb20w +DQYJKoZIhvcNAQEMBQADggIBAEExffbJa/WKif1WdT4WVgcq3tfPdBiFJhbSajJX +6QVHNdYf+hztDgDu3HOq8gtLJMQ8Lg2wXlfe3pJiGtgKNQcvaUyTsJnNC6/Zf85T +qMlt6sc/KNVdby05nooimNg1ZQBLV5NJHn+LstvZwAd+przzpJIjgkLSInGdnE+V +UO93P2YodaI8UgkhmDIPgYjeIvr6G7wcwU2XsaVv5jza50JrNapPtLPt62uVAyQv +Eb5jK9ZB6OTxRnNToj1zY+sh3NQF3dMrp/j90LpA2ErmXV7mHeSB8I0+B+R46pM6 +2zmi76cXGTpVE9rAc91BclyS6efqf9Mj9w4Fj8xJBWlz8VVI8TV0GnWABN6wA7Iv +XJtzXOJr00ZOyUdwTsePApeMRoac0l3mBZdnK6cGmVNqqZ6/Lf1Wp5IJyjNx4Oc2 ++0jg0R+wYGtZLgeGeuUYILRpDn4LwHdbqEVxK99ched75yZnXOvQFMt+tI5rhFtw +hdpZDBCF4GsItyMeEoegYXlAdJUSKL5BRii2Hir693G2MvJHD7/GvSXfpmV8pvpJ ++DBqQPuXzJ/4ruMEg016Q6gegf612Bxm92U+/kzzQz5WTRHkbk31MMPCxNYSrL2V +DGzvni/C/kVt4+Oc5wAulG04gtwM3UpOfh3uNtuKrna/boJ8gq1YggCv5YLJYGyX +L0X+ +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFgTCCBGmgAwIBAgIQOXJEOvkit1HX02wQ3TE1lTANBgkqhkiG9w0BAQwFADB7 +MQswCQYDVQQGEwJHQjEbMBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYD +VQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UE +AwwYQUFBIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTE5MDMxMjAwMDAwMFoXDTI4 +MTIzMTIzNTk1OVowgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpOZXcgSmVyc2V5 +MRQwEgYDVQQHEwtKZXJzZXkgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBO +ZXR3b3JrMS4wLAYDVQQDEyVVU0VSVHJ1c3QgUlNBIENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAgBJlFzYOw9sI +s9CsVw127c0n00ytUINh4qogTQktZAnczomfzD2p7PbPwdzx07HWezcoEStH2jnG +vDoZtF+mvX2do2NCtnbyqTsrkfjib9DsFiCQCT7i6HTJGLSR1GJk23+jBvGIGGqQ +Ijy8/hPwhxR79uQfjtTkUcYRZ0YIUcuGFFQ/vDP+fmyc/xadGL1RjjWmp2bIcmfb +IWax1Jt4A8BQOujM8Ny8nkz+rwWWNR9XWrf/zvk9tyy29lTdyOcSOk2uTIq3XJq0 +tyA9yn8iNK5+O2hmAUTnAU5GU5szYPeUvlM3kHND8zLDU+/bqv50TmnHa4xgk97E +xwzf4TKuzJM7UXiVZ4vuPVb+DNBpDxsP8yUmazNt925H+nND5X4OpWaxKXwyhGNV +icQNwZNUMBkTrNN9N6frXTpsNVzbQdcS2qlJC9/YgIoJk2KOtWbPJYjNhLixP6Q5 +D9kCnusSTJV882sFqV4Wg8y4Z+LoE53MW4LTTLPtW//e5XOsIzstAL81VXQJSdhJ +WBp/kjbmUZIO8yZ9HE0XvMnsQybQv0FfQKlERPSZ51eHnlAfV1SoPv10Yy+xUGUJ +5lhCLkMaTLTwJUdZ+gQek9QmRkpQgbLevni3/GcV4clXhB4PY9bpYrrWX1Uu6lzG +KAgEJTm4Diup8kyXHAc/DVL17e8vgg8CAwEAAaOB8jCB7zAfBgNVHSMEGDAWgBSg +EQojPpbxB+zirynvgqV/0DCktDAdBgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rID +ZsswDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wEQYDVR0gBAowCDAG +BgRVHSAAMEMGA1UdHwQ8MDowOKA2oDSGMmh0dHA6Ly9jcmwuY29tb2RvY2EuY29t +L0FBQUNlcnRpZmljYXRlU2VydmljZXMuY3JsMDQGCCsGAQUFBwEBBCgwJjAkBggr +BgEFBQcwAYYYaHR0cDovL29jc3AuY29tb2RvY2EuY29tMA0GCSqGSIb3DQEBDAUA +A4IBAQAYh1HcdCE9nIrgJ7cz0C7M7PDmy14R3iJvm3WOnnL+5Nb+qh+cli3vA0p+ +rvSNb3I8QzvAP+u431yqqcau8vzY7qN7Q/aGNnwU4M309z/+3ri0ivCRlv79Q2R+ +/czSAaF9ffgZGclCKxO/WIu6pKJmBHaIkU4MiRTOok3JMrO66BQavHHxW/BBC5gA +CiIDEOUMsfnNkjcZ7Tvx5Dq2+UUTJnWvu6rvP3t3O9LEApE9GQDTF1w52z97GA1F +zZOFli9d31kWTz9RvdVFGD/tSo7oBmF0Ixa1DVBzJ0RHfxBdiSprhTEUxOipakyA +vGp4z7h/jnZymQyd/teRCBaho1+V +-----END CERTIFICATE----- diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java index 1f15c44d..31328045 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java @@ -112,7 +112,8 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter .authorizeRequests() // 对于登录login 注册register 验证码captchaImage 允许匿名访问 // ,"/calculate/**""/calculate/**", - .antMatchers("/pay/**","/api/**","/login", "/register", "/captchaImage","/wxPay/result/**").permitAll() + .antMatchers("/pay/**","/api/**","/login", "/register", "/captchaImage","/wxPay/result/**", + "/api/wx/auth/**").permitAll() // 静态资源,可匿名访问 .antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll() .antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll() diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java index abbebf58..95a5da41 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java @@ -100,6 +100,41 @@ public class SysLoginService return tokenService.createToken(loginUser); } + public String wxLogin(String username, String password){ + // 用户验证 + Authentication authentication = null; + try + { + UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password); + AuthenticationContextHolder.setContext(authenticationToken); + // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername + authentication = authenticationManager.authenticate(authenticationToken); + } + catch (Exception e) + { + if (e instanceof BadCredentialsException) + { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match"))); + throw new UserPasswordNotMatchException(); + } + else + { + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage())); + throw new ServiceException(e.getMessage()); + } + } + finally + { + AuthenticationContextHolder.clearContext(); + } + AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"))); + LoginUser loginUser = (LoginUser) authentication.getPrincipal(); + recordLoginInfo(loginUser.getUserId()); + // 生成token + return tokenService.createToken(loginUser); + + } + /** * 校验验证码 * diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/WxUser.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/WxUser.java new file mode 100644 index 00000000..273975cb --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/WxUser.java @@ -0,0 +1,138 @@ +package com.ruoyi.system.domain; + +import java.time.LocalDateTime; + +public class WxUser { + + private Long id; + private String openid; + + private String unionid; + private String nickname; + private String avatarUrl; + private Double gender; + private String country; + private String province; + private String city; + private Boolean isDeleted; + private String loginIp; + private LocalDateTime loginDate; + private LocalDateTime createTime; + private LocalDateTime updateTime; + private String remark; + + public Long getId() { + return id; + } + public void setId(Long id) { + this.id = id; + } + public String getOpenid() { + return openid; + } + public void setOpenid(String openid) { + this.openid = openid; + } + public String getUnionid() { + return unionid; + } + public void setUnionid(String unionid) { + this.unionid = unionid; + } + + public String getNickname() { + return nickname; + } + + public void setNickname(String nickname) { + this.nickname = nickname; + } + + public String getAvatarUrl() { + return avatarUrl; + } + + public void setAvatarUrl(String avatarUrl) { + this.avatarUrl = avatarUrl; + } + + public Double getGender() { + return gender; + } + + public void setGender(Double gender) { + this.gender = gender; + } + + public String getCountry() { + return country; + } + + public void setCountry(String country) { + this.country = country; + } + + public String getProvince() { + return province; + } + + public void setProvince(String province) { + this.province = province; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public Boolean getIsDeleted() { + return isDeleted; + } + + public void setIsDeleted(Boolean isDeleted) { + this.isDeleted = isDeleted; + } + + public String getLoginIp() { + return loginIp; + } + + public void setLoginIp(String loginIp) { + this.loginIp = loginIp; + } + + public LocalDateTime getLoginDate() { + return loginDate; + } + + public void setLoginDate(LocalDateTime loginDate) { + this.loginDate = loginDate; + } + + public LocalDateTime getCreateTime() { + return createTime; + } + + public void setCreateTime(LocalDateTime createTime) { + this.createTime = createTime; + } + + public LocalDateTime getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(LocalDateTime updateTime) { + this.updateTime = updateTime; + } + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/WxAccessDto.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/WxAccessDto.java new file mode 100644 index 00000000..1f72b1a5 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/WxAccessDto.java @@ -0,0 +1,23 @@ +package com.ruoyi.system.domain.dto; + +public class WxAccessDto { + + private String accessToken; + private String openId; + + public String getAccessToken() { + return accessToken; + } + + public void setAccessToken(String accessToken) { + this.accessToken = accessToken; + } + + public String getOpenId() { + return openId; + } + + public void setOpenId(String openId) { + this.openId = openId; + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/WxLoginDTO.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/WxLoginDTO.java new file mode 100644 index 00000000..71b2b0ad --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/WxLoginDTO.java @@ -0,0 +1,25 @@ +package com.ruoyi.system.domain.dto; + +import java.util.Objects; + +public class WxLoginDTO +{ + private String code; + private String state; + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/WxLoginTDTO.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/WxLoginTDTO.java new file mode 100644 index 00000000..8168efc6 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/WxLoginTDTO.java @@ -0,0 +1,54 @@ +package com.ruoyi.system.domain.dto; + +/* +* 返回登录信息的dto +* */ +public class WxLoginTDTO { + private String phone; + private String token; + private String avatar; + private String nickname; + private Long calculateNumber; + + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + + public Long getCalculateNumber() { + return calculateNumber; + } + + public void setCalculateNumber(Long calculateNumber) { + this.calculateNumber = calculateNumber; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public String getNickname() { + return nickname; + } + + public void setNickname(String nickname) { + this.nickname = nickname; + } + +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/WxUserDTO.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/WxUserDTO.java new file mode 100644 index 00000000..126e69cf --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/dto/WxUserDTO.java @@ -0,0 +1,40 @@ +package com.ruoyi.system.domain.dto; + +public class WxUserDTO { + + private Long userId; + private String nickname; + private String avatarUrl; + private String token; + + public Long getUserId() { + return userId; + } + + public void setUserId(Long userId) { + this.userId = userId; + } + + public String getNickname() { + return nickname; + } + + public void setNickname(String nickname) { + this.nickname = nickname; + } + + public String getAvatarUrl() { + return avatarUrl; + } + + public void setAvatarUrl(String avatarUrl) { + this.avatarUrl = avatarUrl; + } + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/WxAuthService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/WxAuthService.java new file mode 100644 index 00000000..948e94e0 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/WxAuthService.java @@ -0,0 +1,33 @@ +package com.ruoyi.system.service; + +import com.ruoyi.system.domain.dto.WxLoginDTO; +import com.ruoyi.system.domain.dto.WxLoginTDTO; +import com.ruoyi.system.domain.dto.WxUserDTO; + +public interface WxAuthService { + + /** + * 微信登录 + * + * @param loginDTO 登录参数 + * @return 用户信息 + */ +// String WxLoginTDTO(WxLoginDTO loginDTO); + + /** + * 刷新token + * + * @param refreshToken 刷新token + * @return 新的用户信息 + */ + WxUserDTO refreshToken(String refreshToken); + + /** + * 退出登录 + * + * @param userId 用户ID + */ + void logout(Long userId); + + public WxLoginTDTO login(WxLoginDTO loginDTO); +}