Commit a5825c86 by 郑云飞

小程序静默登录获取openid

小程序获取手机号
parent 85f00e2f
......@@ -8,6 +8,7 @@ import com.yongqi.common.core.domain.entity.SysUser;
import com.yongqi.common.core.domain.model.LoginBody;
import com.yongqi.common.core.domain.model.LoginUser;
import com.yongqi.common.core.domain.model.SmsLoginBody;
import com.yongqi.common.core.domain.model.XcxLoginUser;
import com.yongqi.common.helper.LoginHelper;
import com.yongqi.system.domain.vo.RouterVo;
import com.yongqi.system.service.ISysMenuService;
......@@ -73,7 +74,7 @@ public class SysLoginController {
}
/**
* 小程序登录(示例)
* 小程序登录(静态登录)
*
* @param xcxCode 小程序code
* @return 结果
......@@ -84,6 +85,23 @@ public class SysLoginController {
Map<String, Object> ajax = new HashMap<>();
// 生成令牌
String token = loginService.xcxLogin(xcxCode);
ajax.put("openId", token);
return R.ok(ajax);
}
/**
* 小程序登录(手机号登录)
*
* @param xcxCode 小程序code
* @return 结果
*/
@SaIgnore
@PostMapping("/xcxPhoneLogin")
public R<Map<String, Object>> xcxPhoneLogin(@NotBlank(message = "{xcx.code.not.blank}") String xcxCode
, @NotBlank(message = "{xcx.code.not.blank}") String openId) {
Map<String, Object> ajax = new HashMap<>();
// 生成令牌
String token = loginService.xcxPhoneLogin(xcxCode, openId);
ajax.put(Constants.TOKEN, token);
return R.ok(ajax);
}
......
......@@ -169,13 +169,13 @@ sms:
sdkAppId:
wx:
# pay:
# appId: wx312fb4fecd3ee803 #微信公众号或者小程序等的appid
# mchId: #微信支付商户号
# mchKey: #微信支付商户密钥
# subAppId: #服务商模式下的子商户公众账号ID
# subMchId: #服务商模式下的子商户号
# keyPath: # p12证书的位置,可以指定绝对路径,也可以指定类路径(以classpath:开头)
pay:
appId: wx312fb4fecd3ee803 #微信公众号或者小程序等的appid
mchId: 1640607392 #微信支付商户号
mchKey: fdfgg56hdfgh52sdf35dfgscfg84wsed #微信支付商户密钥
subAppId: #服务商模式下的子商户公众账号ID
subMchId: #服务商模式下的子商户号
keyPath: C:\\ProgramData\\certKey\xinrenli\\apiclient_cert.p12 # p12证书的位置,可以指定绝对路径,也可以指定类路径(以classpath:开头)
# mp:
# useRedis: false
# redisConfig:
......
......@@ -137,7 +137,12 @@ security:
# actuator 监控配置
- /actuator
- /actuator/**
- /**
# 登录
- /login
- /captchaImage
- /smsLogin
- /xcxLogin
- /xcxPhoneLogin
# MyBatisPlus配置
# https://baomidou.com/config/
......
//package com.yongqi.common.core.config;
//
//import com.github.binarywang.wxpay.config.WxPayConfig;
//import com.github.binarywang.wxpay.service.WxPayService;
//import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
//import lombok.AllArgsConstructor;
//import org.apache.commons.lang3.StringUtils;
//import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
//import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
//import org.springframework.boot.context.properties.EnableConfigurationProperties;
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration;
//
///**
// * @author Binary Wang
// */
//@Configuration
//@ConditionalOnClass(WxPayService.class)
//@EnableConfigurationProperties(WxPayProperties.class)
//@AllArgsConstructor
//public class WxPayConfiguration {
// private WxPayProperties properties;
//
// @Bean
// @ConditionalOnMissingBean
// public WxPayService wxService() {
// WxPayConfig payConfig = new WxPayConfig();
// payConfig.setAppId(StringUtils.trimToNull(this.properties.getAppId()));
// payConfig.setMchId(StringUtils.trimToNull(this.properties.getMchId()));
// payConfig.setMchKey(StringUtils.trimToNull(this.properties.getMchKey()));
// payConfig.setSubAppId(StringUtils.trimToNull(this.properties.getSubAppId()));
// payConfig.setSubMchId(StringUtils.trimToNull(this.properties.getSubMchId()));
// payConfig.setKeyPath(StringUtils.trimToNull(this.properties.getKeyPath()));
//
// // 可以指定是否使用沙箱环境
// payConfig.setUseSandboxEnv(false);
//
// WxPayService wxPayService = new WxPayServiceImpl();
// wxPayService.setConfig(payConfig);
// return wxPayService;
// }
//
//}
package com.yongqi.common.core.config;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author Binary Wang
*/
@Configuration
@ConditionalOnClass(WxPayService.class)
@EnableConfigurationProperties(WxPayProperties.class)
@AllArgsConstructor
public class WxPayConfiguration {
private WxPayProperties properties;
@Bean
@ConditionalOnMissingBean
public WxPayService wxService() {
WxPayConfig payConfig = new WxPayConfig();
payConfig.setAppId(StringUtils.trimToNull(this.properties.getAppId()));
payConfig.setMchId(StringUtils.trimToNull(this.properties.getMchId()));
payConfig.setMchKey(StringUtils.trimToNull(this.properties.getMchKey()));
payConfig.setSubAppId(StringUtils.trimToNull(this.properties.getSubAppId()));
payConfig.setSubMchId(StringUtils.trimToNull(this.properties.getSubMchId()));
payConfig.setKeyPath(StringUtils.trimToNull(this.properties.getKeyPath()));
// 可以指定是否使用沙箱环境
payConfig.setUseSandboxEnv(false);
WxPayService wxPayService = new WxPayServiceImpl();
wxPayService.setConfig(payConfig);
return wxPayService;
}
}
//package com.yongqi.common.core.config;
//
//import lombok.Data;
//import org.springframework.boot.context.properties.ConfigurationProperties;
//
///**
// * wxpay pay properties.
// *
// * @author Binary Wang
// */
//@Data
//@ConfigurationProperties(prefix = "wx.pay")
//public class WxPayProperties {
// /**
// * 设置微信公众号或者小程序等的appid
// */
// private String appId;
//
// /**
// * 微信支付商户号
// */
// private String mchId;
//
// /**
// * 微信支付商户密钥
// */
// private String mchKey;
//
// /**
// * 服务商模式下的子商户公众账号ID,普通模式请不要配置,请在配置文件中将对应项删除
// */
// private String subAppId;
//
// /**
// * 服务商模式下的子商户号,普通模式请不要配置,最好是请在配置文件中将对应项删除
// */
// private String subMchId;
//
// /**
// * apiclient_cert.p12文件的绝对路径,或者如果放在项目中,请以classpath:开头指定
// */
// private String keyPath;
//
//}
package com.yongqi.common.core.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* wxpay pay properties.
*
* @author Binary Wang
*/
@Data
@ConfigurationProperties(prefix = "wx.pay")
public class WxPayProperties {
/**
* 设置微信公众号或者小程序等的appid
*/
private String appId;
/**
* 微信支付商户号
*/
private String mchId;
/**
* 微信支付商户密钥
*/
private String mchKey;
/**
* 服务商模式下的子商户公众账号ID,普通模式请不要配置,请在配置文件中将对应项删除
*/
private String subAppId;
/**
* 服务商模式下的子商户号,普通模式请不要配置,最好是请在配置文件中将对应项删除
*/
private String subMchId;
/**
* apiclient_cert.p12文件的绝对路径,或者如果放在项目中,请以classpath:开头指定
*/
private String keyPath;
}
......@@ -35,6 +35,11 @@
<artifactId>yongqi-sms</artifactId>
</dependency>
<dependency>
<groupId>com.yongqi</groupId>
<artifactId>yongqi-xinrenli</artifactId>
</dependency>
</dependencies>
</project>
package com.yongqi.system.service;
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.secure.BCrypt;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yongqi.common.constant.CacheConstants;
import com.yongqi.common.constant.Constants;
import com.yongqi.common.core.domain.event.LogininforEvent;
......@@ -27,12 +31,18 @@ import com.yongqi.common.utils.StringUtils;
import com.yongqi.common.utils.redis.RedisUtils;
import com.yongqi.common.utils.spring.SpringUtils;
import com.yongqi.system.mapper.SysUserMapper;
import com.yongqi.xinrenli.domain.DbWxUser;
import com.yongqi.xinrenli.enums.DeleteStatusEnum;
import com.yongqi.xinrenli.mapper.DbWxUserMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import java.rmi.ServerException;
import java.time.Duration;
import java.util.List;
import java.util.function.Supplier;
......@@ -56,6 +66,10 @@ public class SysLoginService {
@Value("${user.password.lockTime}")
private Integer lockTime;
@Autowired
private WxMaService wxMaService;
@Autowired
private DbWxUserMapper wxUserMapper;
/**
* 登录验证
......@@ -105,20 +119,48 @@ public class SysLoginService {
// xcxCode 为 小程序调用 wx.login 授权后获取
// todo 以下自行实现
// 校验 appid + appsrcret + xcxCode 调用登录凭证校验接口 获取 session_key 与 openid
String openid = "";
SysUser user = loadUserByOpenid(openid);
WxMaJscode2SessionResult sessionInfo = null;
try {
sessionInfo = wxMaService.getUserService().getSessionInfo(xcxCode);
} catch (WxErrorException e) {
log.error("获取微信openid失败:{}",e.getMessage());
e.printStackTrace();
}
if (sessionInfo == null) {
throw new RuntimeException("获取微信信息失败");
}
DbWxUser user = loadUserByOpenid(sessionInfo, null);
return user.getOpenId();
}
public String xcxPhoneLogin(String xcxCode, String openId) {
// xcxCode 为 小程序调用 wx.login 授权后获取
// todo 以下自行实现
// 校验 appid + appsrcret + xcxCode 调用登录凭证校验接口 获取 session_key 与 openid
WxMaPhoneNumberInfo newPhoneNoInfo = null;
try {
newPhoneNoInfo = wxMaService.getUserService().getNewPhoneNoInfo(xcxCode);
} catch (WxErrorException e) {
log.error("获取微信openid失败:{}",e.getMessage());
e.printStackTrace();
}
if (newPhoneNoInfo == null) {
throw new RuntimeException("获取微信信息失败");
}
WxMaJscode2SessionResult sessionInfo = new WxMaJscode2SessionResult();
sessionInfo.setOpenid(openId);
DbWxUser user = loadUserByOpenid(sessionInfo, newPhoneNoInfo.getPhoneNumber());
// 此处可根据登录用户的数据不同 自行创建 loginUser
XcxLoginUser loginUser = new XcxLoginUser();
loginUser.setUserId(user.getUserId());
loginUser.setUsername(user.getUserName());
loginUser.setUserType(user.getUserType());
loginUser.setOpenid(openid);
loginUser.setUserId(user.getId());
loginUser.setUsername(user.getNickname());
loginUser.setUserType(DeviceType.XCX.getDevice());
loginUser.setOpenid(sessionInfo.getOpenid());
// 生成token
LoginHelper.loginByDevice(loginUser, DeviceType.XCX);
recordLogininfor(user.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
recordLoginInfo(user.getUserId(), user.getUserName());
recordLogininfor(user.getNickname(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
recordLoginInfo(user.getId(), user.getNickname());
return StpUtil.getTokenValue();
}
......@@ -212,16 +254,23 @@ public class SysLoginService {
return userMapper.selectUserByPhonenumber(phonenumber);
}
private SysUser loadUserByOpenid(String openid) {
private DbWxUser loadUserByOpenid(WxMaJscode2SessionResult sessionInfo, String phone) {
// 使用 openid 查询绑定用户 如未绑定用户 则根据业务自行处理 例如 创建默认用户
// todo 自行实现 userService.selectUserByOpenid(openid);
SysUser user = new SysUser();
DbWxUser user = wxUserMapper.selectOne(Wrappers.<DbWxUser>lambdaQuery().eq(DbWxUser::getOpenId, sessionInfo.getOpenid()));
if (ObjectUtil.isNull(user)) {
log.info("登录用户:{} 不存在.", openid);
// todo 用户不存在 业务逻辑自行实现
} else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
log.info("登录用户:{} 已被停用.", openid);
// todo 用户已被停用 业务逻辑自行实现
log.info("登录用户:{} 不存在.", sessionInfo.getOpenid());
user = new DbWxUser();
user.setOpenId(sessionInfo.getOpenid());
user.setSessionKey(sessionInfo.getSessionKey());
user.setUnionId(sessionInfo.getUnionid());
wxUserMapper.insert(user);
} else if (DeleteStatusEnum.DELETED.getCode().equals(user.getDeleteFlag())) {
log.info("登录用户:{} 已被停用.", sessionInfo.getOpenid());
throw new RuntimeException("当前用户已停用,请联系管理员");
} else if (StringUtils.isNotEmpty(phone) && StringUtils.isNotEmpty(user.getMobile())) {
user.setMobile(phone);
user.setAuthMobile(phone);
wxUserMapper.updateById(user);
}
return user;
}
......
......@@ -28,10 +28,6 @@ public class DbWxUser {
*/
private String openId;
/**
* 是否是团长:1:是,2:否
*/
private Integer headOrNot;
/**
* 用户昵称
*/
private String nickname;
......@@ -68,14 +64,6 @@ public class DbWxUser {
*/
private String authMobile;
/**
* 商场编码
*/
private String mallCode;
/**
* 会员卡号
*/
private String userCode;
/**
*
*/
private String sessionKey;
......@@ -92,21 +80,13 @@ public class DbWxUser {
*/
private String wechatOriginalId;
/**
* 下单次数
*/
private Long orderNum;
/**
* 累计消费
*/
private BigDecimal cumulativeConsumption;
/**
* 最近消费时间
* 创建时间
*/
private Date lastConsumptionTime;
private Date createTime;
/**
* 创建人Code
* 创建人
*/
private String createCode;
private String createBy;
/**
* 更新时间
*/
......
......@@ -62,7 +62,7 @@ public class DbWxUserServiceImpl implements IDbWxUserService {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<DbWxUser> lqw = Wrappers.lambdaQuery();
lqw.eq(StringUtils.isNotBlank(bo.getOpenId()), DbWxUser::getOpenId, bo.getOpenId());
lqw.eq(bo.getHeadOrNot() != null, DbWxUser::getHeadOrNot, bo.getHeadOrNot());
lqw.like(StringUtils.isNotBlank(bo.getNickname()), DbWxUser::getNickname, bo.getNickname());
lqw.eq(bo.getSex() != null, DbWxUser::getSex, bo.getSex());
lqw.eq(StringUtils.isNotBlank(bo.getProvince()), DbWxUser::getProvince, bo.getProvince());
......@@ -72,16 +72,10 @@ public class DbWxUserServiceImpl implements IDbWxUserService {
lqw.eq(StringUtils.isNotBlank(bo.getUnionId()), DbWxUser::getUnionId, bo.getUnionId());
lqw.eq(StringUtils.isNotBlank(bo.getMobile()), DbWxUser::getMobile, bo.getMobile());
lqw.eq(StringUtils.isNotBlank(bo.getAuthMobile()), DbWxUser::getAuthMobile, bo.getAuthMobile());
lqw.eq(StringUtils.isNotBlank(bo.getMallCode()), DbWxUser::getMallCode, bo.getMallCode());
lqw.eq(StringUtils.isNotBlank(bo.getUserCode()), DbWxUser::getUserCode, bo.getUserCode());
lqw.eq(StringUtils.isNotBlank(bo.getSessionKey()), DbWxUser::getSessionKey, bo.getSessionKey());
lqw.eq(bo.getWechatSubscribe() != null, DbWxUser::getWechatSubscribe, bo.getWechatSubscribe());
lqw.eq(bo.getCancelSubscribe() != null, DbWxUser::getCancelSubscribe, bo.getCancelSubscribe());
lqw.eq(StringUtils.isNotBlank(bo.getWechatOriginalId()), DbWxUser::getWechatOriginalId, bo.getWechatOriginalId());
lqw.eq(bo.getOrderNum() != null, DbWxUser::getOrderNum, bo.getOrderNum());
lqw.eq(bo.getCumulativeConsumption() != null, DbWxUser::getCumulativeConsumption, bo.getCumulativeConsumption());
lqw.eq(bo.getLastConsumptionTime() != null, DbWxUser::getLastConsumptionTime, bo.getLastConsumptionTime());
lqw.eq(StringUtils.isNotBlank(bo.getCreateCode()), DbWxUser::getCreateCode, bo.getCreateCode());
lqw.eq(bo.getModifyTime() != null, DbWxUser::getModifyTime, bo.getModifyTime());
lqw.eq(StringUtils.isNotBlank(bo.getModifyBy()), DbWxUser::getModifyBy, bo.getModifyBy());
lqw.eq(StringUtils.isNotBlank(bo.getModifyCode()), DbWxUser::getModifyCode, bo.getModifyCode());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment