diff --git a/ruoyi-admin/src/test/java/com/fjp/lc/test/service/WechatTest.java b/ruoyi-admin/src/test/java/com/fjp/lc/test/service/WechatTest.java
new file mode 100644
index 0000000..a8ebdf0
--- /dev/null
+++ b/ruoyi-admin/src/test/java/com/fjp/lc/test/service/WechatTest.java
@@ -0,0 +1,25 @@
+package com.fjp.lc.test.service;
+
+import com.cyl.h5.pojo.vo.form.WechatLoginForm;
+import com.cyl.ums.service.MemberWechatService;
+import com.ruoyi.RuoYiApplication;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = RuoYiApplication.class)
+@ActiveProfiles("dev")
+public class WechatTest {
+ @Autowired
+ private MemberWechatService memberWechatService;
+ @Test
+ public void testAuth() {
+ WechatLoginForm f = new WechatLoginForm();
+ f.setCode("081zPgHa1FbRQE0wGIIa1lgb1C1zPgHi");
+ memberWechatService.login(f);
+ }
+}
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 27b4237..2198fba 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
@@ -31,6 +31,8 @@ import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
+import java.util.Arrays;
+import java.util.Collections;
import java.util.Date;
import java.util.List;
@@ -209,13 +211,13 @@ public class SysLoginService {
userService.registerUser(user);
// 赋予角色
- SysRole vipRole = sysRoleService.selectRoleByKey("vip");
+ SysRole role = sysRoleService.selectRoleByKey("common");
// 增加用户的权限,绑定角色
- sysRoleService.insertAuthUsers(vipRole.getRoleId(), new Long[]{user.getUserId()});
+ sysRoleService.insertAuthUsers(role.getRoleId(), new Long[]{user.getUserId()});
AsyncManager.me().execute(AsyncFactory.recordLogininfor(body.getLogin(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.register.success")));
recordLoginInfo(user);
-
+ user.setRoles(Collections.singletonList(role));
return user;
}
diff --git a/ruoyi-mall/pom.xml b/ruoyi-mall/pom.xml
index 38db63a..08a3b55 100644
--- a/ruoyi-mall/pom.xml
+++ b/ruoyi-mall/pom.xml
@@ -77,5 +77,9 @@
+
+ com.ruoyi
+ ruoyi-framework
+
diff --git a/ruoyi-mall/src/main/java/com/cyl/external/ExternalException.java b/ruoyi-mall/src/main/java/com/cyl/external/ExternalException.java
new file mode 100644
index 0000000..885a864
--- /dev/null
+++ b/ruoyi-mall/src/main/java/com/cyl/external/ExternalException.java
@@ -0,0 +1,13 @@
+package com.cyl.external;
+
+import lombok.Data;
+
+@Data
+public class ExternalException extends RuntimeException {
+ private String code;
+
+ public ExternalException(String code, String message) {
+ super(message);
+ this.code = code;
+ }
+}
diff --git a/ruoyi-mall/src/main/java/com/cyl/external/WechatUtil.java b/ruoyi-mall/src/main/java/com/cyl/external/WechatUtil.java
index da76b32..c6a1cdc 100644
--- a/ruoyi-mall/src/main/java/com/cyl/external/WechatUtil.java
+++ b/ruoyi-mall/src/main/java/com/cyl/external/WechatUtil.java
@@ -1,10 +1,29 @@
package com.cyl.external;
+import cn.hutool.http.HttpUtil;
+import com.alibaba.fastjson.JSON;
+import com.cyl.external.resp.AccessTokenResp;
+import com.cyl.external.resp.BaseResp;
+import com.cyl.external.resp.UserInfoResp;
+import com.ruoyi.common.exception.base.BaseException;
import org.apache.commons.codec.digest.DigestUtils;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.stereotype.Component;
import java.util.Arrays;
+@Component
+@ConfigurationProperties(prefix = "wechat")
public class WechatUtil {
+ private static String appId;
+ private static String secret;
+ public void setAppId(String appId) {
+ WechatUtil.appId = appId;
+ }
+ public void setSecret(String secret) {
+ WechatUtil.secret = secret;
+ }
public static boolean validParam(String signature, String... arr) {
Arrays.sort(arr);
StringBuilder sb = new StringBuilder();
@@ -18,4 +37,26 @@ public class WechatUtil {
return signature.equals(DigestUtils.sha1Hex(sb.toString()));
}
+ private static final String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
+ private static final String USER_INFO_URL = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";
+ public static AccessTokenResp getAccessToken(String code) {
+ String url = ACCESS_TOKEN_URL.replace("APPID", appId).replace("SECRET", secret).replace("CODE", code);
+ String res = HttpUtil.get(url);
+ AccessTokenResp resp = JSON.parseObject(res, AccessTokenResp.class);
+ validResp(resp);
+ return resp;
+ }
+
+ public static UserInfoResp getUserInfo(String accessToken, String openid) {
+ String url = USER_INFO_URL.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openid);
+ String res = HttpUtil.get(url);
+ UserInfoResp resp = JSON.parseObject(res, UserInfoResp.class);
+ validResp(resp);
+ return resp;
+ }
+ public static void validResp(BaseResp resp) {
+ if (resp.getErrcode() != null) {
+ throw new ExternalException(resp.getErrcode() + "", resp.getErrmsg());
+ }
+ }
}
diff --git a/ruoyi-mall/src/main/java/com/cyl/external/resp/AccessTokenResp.java b/ruoyi-mall/src/main/java/com/cyl/external/resp/AccessTokenResp.java
new file mode 100644
index 0000000..9f8589f
--- /dev/null
+++ b/ruoyi-mall/src/main/java/com/cyl/external/resp/AccessTokenResp.java
@@ -0,0 +1,19 @@
+package com.cyl.external.resp;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import lombok.Data;
+
+@Data
+public class AccessTokenResp extends BaseResp {
+ @JSONField(name = "access_token")
+ private String accessToken;
+ @JSONField(name = "expires_in")
+ private Integer expiresIn;
+ @JSONField(name = "refresh_token")
+ private String refreshToken;
+ private String openid;
+ private String scope;
+ @JSONField(name = "is_snapshotuser")
+ private Integer snapshotuser;
+ private String unionid;
+}
diff --git a/ruoyi-mall/src/main/java/com/cyl/external/resp/BaseResp.java b/ruoyi-mall/src/main/java/com/cyl/external/resp/BaseResp.java
new file mode 100644
index 0000000..751df98
--- /dev/null
+++ b/ruoyi-mall/src/main/java/com/cyl/external/resp/BaseResp.java
@@ -0,0 +1,9 @@
+package com.cyl.external.resp;
+
+import lombok.Data;
+
+@Data
+public class BaseResp {
+ private Integer errcode;
+ private String errmsg;
+}
diff --git a/ruoyi-mall/src/main/java/com/cyl/external/resp/UserInfoResp.java b/ruoyi-mall/src/main/java/com/cyl/external/resp/UserInfoResp.java
new file mode 100644
index 0000000..929e321
--- /dev/null
+++ b/ruoyi-mall/src/main/java/com/cyl/external/resp/UserInfoResp.java
@@ -0,0 +1,14 @@
+package com.cyl.external.resp;
+
+import lombok.Data;
+
+@Data
+public class UserInfoResp extends BaseResp {
+ private String openid;
+ private String nickname;
+ private Integer sex;
+ private String province;
+ private String city;
+ private String country;
+ private String headimgurl;
+}
diff --git a/ruoyi-mall/src/main/java/com/cyl/h5/controller/WechatController.java b/ruoyi-mall/src/main/java/com/cyl/h5/controller/WechatController.java
index 3e1e38f..3827466 100644
--- a/ruoyi-mall/src/main/java/com/cyl/h5/controller/WechatController.java
+++ b/ruoyi-mall/src/main/java/com/cyl/h5/controller/WechatController.java
@@ -1,9 +1,11 @@
package com.cyl.h5.controller;
import com.cyl.external.WechatUtil;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import com.cyl.h5.pojo.vo.form.WechatLoginForm;
+import com.cyl.ums.service.MemberWechatService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
@@ -13,6 +15,8 @@ import javax.servlet.http.HttpServletRequest;
@RestController
@RequestMapping("")
public class WechatController {
+ @Autowired
+ private MemberWechatService memberWechatService;
/**
* 微信公众号服务器认证
* @return
@@ -32,9 +36,8 @@ public class WechatController {
* 微信公众号服务器认证
* @return
*/
- @GetMapping("/no-auth/wechat/h5-login")
- public String h5Login(HttpServletRequest request) {
- // TODO
- return "err";
+ @PostMapping("/no-auth/wechat/h5-login")
+ public ResponseEntity h5Login(@RequestBody WechatLoginForm form) {
+ return ResponseEntity.ok(memberWechatService.login(form));
}
}
diff --git a/ruoyi-mall/src/main/java/com/cyl/h5/pojo/vo/form/WechatLoginForm.java b/ruoyi-mall/src/main/java/com/cyl/h5/pojo/vo/form/WechatLoginForm.java
new file mode 100644
index 0000000..531d01c
--- /dev/null
+++ b/ruoyi-mall/src/main/java/com/cyl/h5/pojo/vo/form/WechatLoginForm.java
@@ -0,0 +1,9 @@
+package com.cyl.h5.pojo.vo.form;
+
+import lombok.Data;
+
+@Data
+public class WechatLoginForm {
+ private String code;
+ private String state;
+}
diff --git a/ruoyi-mall/src/main/java/com/cyl/ums/convert/MemberWechatConvert.java b/ruoyi-mall/src/main/java/com/cyl/ums/convert/MemberWechatConvert.java
index f34840e..a33ccfd 100644
--- a/ruoyi-mall/src/main/java/com/cyl/ums/convert/MemberWechatConvert.java
+++ b/ruoyi-mall/src/main/java/com/cyl/ums/convert/MemberWechatConvert.java
@@ -1,5 +1,7 @@
package com.cyl.ums.convert;
+import com.cyl.external.resp.AccessTokenResp;
+import com.cyl.external.resp.UserInfoResp;
import org.mapstruct.Mapper;
import com.cyl.ums.domain.MemberWechat;
import com.cyl.ums.pojo.vo.MemberWechatVO;
@@ -13,4 +15,6 @@ import java.util.List;
public interface MemberWechatConvert {
List dos2vos(List list);
+
+ MemberWechat info2do(AccessTokenResp info);
}
diff --git a/ruoyi-mall/src/main/java/com/cyl/ums/service/MemberWechatService.java b/ruoyi-mall/src/main/java/com/cyl/ums/service/MemberWechatService.java
index 062d27b..b6d7289 100644
--- a/ruoyi-mall/src/main/java/com/cyl/ums/service/MemberWechatService.java
+++ b/ruoyi-mall/src/main/java/com/cyl/ums/service/MemberWechatService.java
@@ -1,11 +1,31 @@
package com.cyl.ums.service;
import java.time.LocalDateTime;
+import java.time.temporal.ChronoUnit;
import java.util.Arrays;
import java.util.List;
import java.time.LocalDateTime;
+import java.util.concurrent.TimeUnit;
+
+import cn.hutool.core.util.IdUtil;
+import cn.hutool.core.util.RandomUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.cyl.external.WechatUtil;
+import com.cyl.external.resp.AccessTokenResp;
+import com.cyl.external.resp.UserInfoResp;
+import com.cyl.h5.pojo.vo.form.WechatLoginForm;
+import com.cyl.ums.convert.MemberWechatConvert;
import com.github.pagehelper.PageHelper;
+import com.ruoyi.common.core.domain.entity.SysUser;
+import com.ruoyi.common.core.domain.model.ExtraUserBody;
+import com.ruoyi.framework.web.service.SysLoginService;
+import com.ruoyi.system.mapper.SysUserMapper;
+import com.ruoyi.system.service.ISysUserService;
+import lombok.extern.java.Log;
+import lombok.extern.log4j.Log4j;
+import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.apache.commons.lang3.StringUtils;
@@ -20,10 +40,19 @@ import com.cyl.ums.pojo.query.MemberWechatQuery;
*
* @author zcc
*/
+@Slf4j
@Service
public class MemberWechatService {
@Autowired
private MemberWechatMapper memberWechatMapper;
+ @Autowired
+ private MemberWechatConvert memberWechatConvert;
+ @Autowired
+ private SysUserMapper sysUserMapper;
+ @Autowired
+ private ISysUserService userService;
+ @Autowired
+ private SysLoginService loginService;
/**
* 查询用户微信信息
@@ -132,4 +161,51 @@ public class MemberWechatService {
public int deleteById(Long id) {
return memberWechatMapper.deleteById(id);
}
+
+ public String login(WechatLoginForm form) {
+ // 1. code -> token
+ AccessTokenResp tokenResp = WechatUtil.getAccessToken(form.getCode());
+ // 2. token -> user_info
+ UserInfoResp info = null;
+ try {
+ info = WechatUtil.getUserInfo(tokenResp.getAccessToken(), tokenResp.getOpenid());
+ } catch (Exception e) {
+ log.error("form: {}", form.getCode(), e);
+ }
+ // 3. 查找用户是否存在, 若没有则创建
+ LambdaQueryWrapper qw = new LambdaQueryWrapper<>();
+ qw.eq(MemberWechat::getOpenid, tokenResp.getOpenid());
+ MemberWechat m = memberWechatMapper.selectOne(qw);
+ SysUser u;
+ if (m != null) {
+ SysUser update = new SysUser();
+ if (info != null) {
+ if (StrUtil.isNotEmpty(info.getNickname())) {
+ update.setNickName(info.getNickname());
+ }
+ if (info.getSex() != null) {
+ update.setSex(info.getSex() + "");
+ }
+ if (StrUtil.isNotEmpty(info.getHeadimgurl())) {
+ update.setAvatar(info.getHeadimgurl());
+ }
+ sysUserMapper.updateUser(update);
+ }
+ u = sysUserMapper.selectUserById(m.getMemberId());
+ } else {
+ ExtraUserBody body = ExtraUserBody.builder()
+ .nickname(info == null ? "" : info.getNickname())
+ .avatar(info == null ? "" : info.getHeadimgurl())
+ .login(RandomUtil.randomNumbers(9))
+ .sex(info == null ? null : info.getSex())
+ .build();
+ u = loginService.initVipUser(body);
+ MemberWechat w = memberWechatConvert.info2do(tokenResp);
+ w.setMemberId(u.getUserId());
+ w.setExpireTime(LocalDateTime.now().plus(tokenResp.getExpiresIn(), ChronoUnit.SECONDS));
+ memberWechatMapper.insert(w);
+ }
+ // 4. 生成token
+ return loginService.createToken(u);
+ }
}