一、准备工作:
1.去gitee上引入pom坐标
https://gitee.com/binary/weixin-java-tools
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-miniapp</artifactId>
<version>4.6.0</version>
</dependency>
2.根据配置配置service
@Configuration
public class WxConfig {
@Autowired
private WxProperties properties;
@Bean
public WxMaConfig wxMaConfig() {
WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl();
config.setAppid(properties.getAppid());
config.setSecret(properties.getSecret());
return config;
}
@Bean
public WxMaService wxMaService(WxMaConfig maConfig) {
WxMaService service = new WxMaServiceImpl();
service.setWxMaConfig(maConfig);
return service;
}
}
3.获取微信二维码(包含绑定和登录)
public ResultVo createUnlimitWxaCode(WxLoginDTO wxLoginDTO) {
// sendPost方法的额外参数
Map<String, Object> extraParam = new HashMap<String, Object>();
// 小程序码宽度
String accessToken = null;
try {
accessToken = wxMaService.getAccessToken();
} catch (WxErrorException e) {
throw new ApiException("获取二维码失败,请稍后再试");
}
if (accessToken == null) {
return new ResultVo("access_token为空!");
}
// 获取小程序码的接口头部 拼接完整的URl
String url = properties.getUrl() + "?access_token=" + accessToken;
JSONObject paramJSON = new JSONObject();
Map<String, Object> requestParam = new HashMap<String, Object>();
// 扫码后需要跳转的页面
if (Objects.equals(wxLoginDTO.getScene().substring(0, 1), "b")) {
requestParam.put("page", properties.getPage());
}
if (!Objects.equals(active,"pro")) {
requestParam.put("env_version", "trial");
requestParam.put("check_path", false);
}
String scene = wxLoginDTO.getScene();
// 携带的参数
requestParam.put("scene", scene);
// 小程序码的宽度
requestParam.put("width", 200);
log.info("绑定小程序小程序码scene:{}", scene);
// sendPost额外参数 判断用户是发起获取小程序码还是其他的连接
extraParam.put("type", "getQrCode");
// 发起连接
String base64String = this.sendPost(url, requestParam, extraParam);
return new ResultVo(base64String);
}
4.利用code获取openid
public ResultVo getOpenId(WxLoginDTO wxLoginDTO) {
try {
WxMaJscode2SessionResult sessionInfo = wxMaService.getUserService().getSessionInfo(wxLoginDTO.getCode());
if (sessionInfo != null) {
return new ResultVo(200, "获取成功", sessionInfo.getOpenid());
}
return new ResultVo(400, "获取失败");
} catch (WxErrorException e) {
throw new ApiException("微信二维码获取失败,请稍后再试");
}
}
5.绑定用户
public ResultVo bindWxUser(WxLoginDTO wxLoginDTO) {
try {
String customerCode = wxLoginDTO.getScene().substring(1);
User user = userMapper.selectBy(customerCode);
if (ObjectUtil.isEmpty(user)) {
return new ResultVo(400, "未检测到用户信息");
}
User userByOpenId = userMapper.selectByOpenId(wxLoginDTO.getOpenid());
if (ObjectUtil.isNotEmpty(userByOpenId)) {
return new ResultVo(400, "您的微信已被其他账号绑定");
}
user.setOpenid(wxLoginDTO.getOpenid());
user.setIsBindWeChat("1");
userMapper.updateByPrimaryKeySelective(user);
return new ResultVo(200, "绑定成功");
} catch (Exception e) {
return new ResultVo(400, "绑定失败,请稍后再试");
}
}
6.前端轮询访问状态
public ResultVo getWxaCodeStatus(WxLoginDTO wxLoginDTO) {
String key = "wxaScene:" + wxLoginDTO.getScene();
String status = redisUtil.getCacheObject(key);
try {
if (Objects.equals(WxScanStatusEnum.LOGIN.state(), status)) {
key = "wxaScene:" + wxLoginDTO.getScene() + "_" + WxScanStatusEnum.LOGIN.state();
String openid = redisUtil.getCacheObject(key);
//根据openid查询用户记录
User user = userMapper.selectByOpenId(openid);
//根据openid未得到用户记录
if (user == null) {
return new ResultVo(400, "请登录后前往【个人中心-安全中心】,绑定关联微信");
}
Map<String, Object> map = userService.getLoginMap(user);
return new ResultVo(200, "登陆成功", map);
}
} catch (Exception e) {
throw new ApiException("登陆失败!请稍后再试");
}
return new ResultVo(200, "获取成功", status);
}
7.后台根据前端设置状态
public ResultVo setWxaCodeStatus(WxLoginDTO wxLoginDTO) {
if (StringUtils.isBlank(wxLoginDTO.getScanStatus())) {
return new ResultVo(400, "参数为空");
}
if (Objects.equals(wxLoginDTO.getScanStatus(), WxScanStatusEnum.LOGIN.state()) && StringUtils.isBlank(wxLoginDTO.getOpenid())) {
return new ResultVo(200);
}
String key = "wxaScene:" + wxLoginDTO.getScene();
if (Objects.equals(wxLoginDTO.getScanStatus(), WxScanStatusEnum.LOGIN.state())) {
User userByOpenId = userMapper.selectByOpenId(wxLoginDTO.getOpenid());
if (ObjectUtil.isEmpty(userByOpenId)) {
return new ResultVo(400, "请登录后前往【个人中心-安全中心】,绑定关联微信");
}
redisUtil.setCacheObject(key, wxLoginDTO.getScanStatus(), 300, TimeUnit.SECONDS);
redisUtil.setCacheObject(key + "_" + wxLoginDTO.getScanStatus(), wxLoginDTO.getOpenid(), 300, TimeUnit.SECONDS);
} else {
redisUtil.setCacheObject(key, wxLoginDTO.getScanStatus(), 300, TimeUnit.SECONDS);
}
return new ResultVo(200);
}