小程序登录相关
This commit is contained in:
@@ -54,7 +54,7 @@ public class SaTokenConfigure implements WebMvcConfigurer {
|
||||
// 重置根路径,防止satoken切割根路径导致匹配不到路径
|
||||
ApplicationInfo.routePrefix = "";
|
||||
|
||||
SaRouter.match("/user/**")
|
||||
SaRouter.match("/user/**").notMatch("/user/login")
|
||||
.check(r -> StpKit.USER.checkLogin())
|
||||
.setHit(true)
|
||||
// .match("/**")
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.czg.account.dto.auth;
|
||||
|
||||
import com.czg.account.entity.UserInfo;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author Administrator
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@Data
|
||||
public class LoginTokenDTO {
|
||||
private String token;
|
||||
private UserInfo userInfo;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.czg.account.dto.auth;
|
||||
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author Administrator
|
||||
*/
|
||||
@Data
|
||||
public class UserAuthorizationLoginDTO {
|
||||
/**
|
||||
* 登录类型
|
||||
*/
|
||||
@NotEmpty(message = "登录类型")
|
||||
private String source;
|
||||
/**
|
||||
* 登录code
|
||||
*/
|
||||
@NotEmpty(message = "登录code")
|
||||
private String code;
|
||||
/**
|
||||
* 登录返回的data
|
||||
*/
|
||||
private String rawData;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.czg.account.dto.auth;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author Administrator
|
||||
*/
|
||||
@Data
|
||||
public class WechatRawDataDTO {
|
||||
private String nickName;
|
||||
private Integer gender;
|
||||
private String language;
|
||||
private String city;
|
||||
private String province;
|
||||
private String country;
|
||||
private String avatarUrl;
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
package com.czg.account.entity;
|
||||
|
||||
import com.mybatisflex.annotation.Column;
|
||||
import com.mybatisflex.annotation.Id;
|
||||
import com.mybatisflex.annotation.KeyType;
|
||||
import com.mybatisflex.annotation.Table;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 实体类。
|
||||
*
|
||||
* @author Administrator
|
||||
* @since 2025-02-11
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Table("tb_user_info")
|
||||
public class UserInfo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
@Id(keyType = KeyType.Auto)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 用户头像
|
||||
*/
|
||||
private String headImg;
|
||||
|
||||
/**
|
||||
* 用户昵称
|
||||
*/
|
||||
private String nickName;
|
||||
|
||||
/**
|
||||
* 电话号码
|
||||
*/
|
||||
private String phone;
|
||||
|
||||
/**
|
||||
* 会员生日
|
||||
*/
|
||||
private String birthDay;
|
||||
|
||||
/**
|
||||
* 0-女 1男
|
||||
*/
|
||||
private Integer sex;
|
||||
|
||||
/**
|
||||
* 微信 openid
|
||||
*/
|
||||
private String wechatOpenId;
|
||||
|
||||
/**
|
||||
* 支付宝 openid
|
||||
*/
|
||||
private String alipayOpenId;
|
||||
|
||||
/**
|
||||
* 1正常
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 最近登录时间
|
||||
*/
|
||||
private LocalDateTime lastLoginTime;
|
||||
|
||||
/**
|
||||
* 登录密码
|
||||
*/
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* 支付密码
|
||||
*/
|
||||
private String payPwd;
|
||||
|
||||
@Column(onInsertValue = "now()")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Column(onInsertValue = "now()", onUpdateValue = "now()")
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.czg.account.service;
|
||||
|
||||
import com.czg.account.dto.auth.LoginTokenDTO;
|
||||
import com.czg.account.dto.auth.UserAuthorizationLoginDTO;
|
||||
|
||||
/**
|
||||
* @author Administrator
|
||||
*/
|
||||
public interface UserAuthorizationService {
|
||||
LoginTokenDTO login(UserAuthorizationLoginDTO userAuthorizationLoginDTO);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.czg.account.service;
|
||||
|
||||
import com.czg.account.entity.UserInfo;
|
||||
import com.mybatisflex.core.service.IService;
|
||||
|
||||
/**
|
||||
* 服务层。
|
||||
*
|
||||
* @author Administrator
|
||||
* @since 2025-02-11
|
||||
*/
|
||||
public interface UserInfoService extends IService<UserInfo> {
|
||||
|
||||
}
|
||||
@@ -13,6 +13,10 @@
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.alipay.sdk</groupId>
|
||||
<artifactId>alipay-sdk-java</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.czg.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 登录类型枚举
|
||||
* @author Administrator
|
||||
*/
|
||||
@Getter
|
||||
public enum UserAuthSourceEnum {
|
||||
WECHAT("微信", "wechat"),
|
||||
ALIPAY("支付宝", "alipay");
|
||||
|
||||
private final String name;
|
||||
private final String value;
|
||||
|
||||
UserAuthSourceEnum(String name, String value) {
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
package com.czg.utils;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.alipay.api.AlipayClient;
|
||||
import com.alipay.api.AlipayConfig;
|
||||
import com.alipay.api.DefaultAlipayClient;
|
||||
import com.alipay.api.internal.util.AlipayEncrypt;
|
||||
import com.alipay.api.request.AlipaySystemOauthTokenRequest;
|
||||
import com.alipay.api.response.AlipaySystemOauthTokenResponse;
|
||||
import com.czg.exception.CzgException;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 支付宝通用SDK工具类
|
||||
*
|
||||
* @author tankaikai
|
||||
* @since 2024-09-23 16:15
|
||||
*/
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class AlipayUtil {
|
||||
|
||||
/**
|
||||
* 网关地址 线上:https://openapi.alipay.com/gateway.do 沙箱:https://openapi.alipaydev.com/gateway.do
|
||||
*/
|
||||
@Value("${alipay.serverUrl}")
|
||||
private String serverUrl;
|
||||
/**
|
||||
* 应用ID
|
||||
*/
|
||||
@Value("${alipay.appId}")
|
||||
private String appId;
|
||||
/**
|
||||
* 应用私钥
|
||||
*/
|
||||
@Value("${alipay.privateKey}")
|
||||
private String privateKey;
|
||||
/**
|
||||
* 支付宝公钥
|
||||
*/
|
||||
@Value("${alipay.alipayPublicKey}")
|
||||
private String alipayPublicKey;
|
||||
/**
|
||||
* 支付宝公钥
|
||||
*/
|
||||
@Value("${alipay.encryptKey}")
|
||||
private String encryptKey;
|
||||
|
||||
/**
|
||||
* 创建支付宝客户端
|
||||
* @return AlipayClient
|
||||
*/
|
||||
@SneakyThrows
|
||||
public AlipayClient createClient() {
|
||||
AlipayConfig alipayConfig = new AlipayConfig();
|
||||
//设置网关地址
|
||||
alipayConfig.setServerUrl(serverUrl);
|
||||
//设置应用ID
|
||||
alipayConfig.setAppId(appId);
|
||||
//设置应用私钥
|
||||
alipayConfig.setPrivateKey(privateKey);
|
||||
//设置支付宝公钥
|
||||
alipayConfig.setAlipayPublicKey(alipayPublicKey);
|
||||
return new DefaultAlipayClient(alipayConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取支付宝用户的openId
|
||||
* @param code 用户信息授权码
|
||||
* @return openId
|
||||
*/
|
||||
public String getOpenId(String code){
|
||||
AlipaySystemOauthTokenRequest req = new AlipaySystemOauthTokenRequest();
|
||||
//SDK已经封装掉了公共参数,这里只需要传入业务参数
|
||||
req.setCode(code);
|
||||
req.setGrantType("authorization_code");
|
||||
//此次只是参数展示,未进行字符串转义,实际情况下请转义
|
||||
//req.setBizContent(" {" + " \"primary_industry_name\":\"IT科技/IT软件与服务\"," + " \"primary_industry_code\":\"10001/20102\"," + " \"secondary_industry_code\":\"10001/20102\"," + " \"secondary_industry_name\":\"IT科技/IT软件与服务\"" + " }");
|
||||
AlipaySystemOauthTokenResponse response;
|
||||
try {
|
||||
response = createClient().execute(req);
|
||||
}catch (Exception e){
|
||||
log.error("获取支付宝用户信息失败", e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
log.info("获取支付宝用户信息成功,返回结果:{}", response.getBody());
|
||||
//调用失败
|
||||
if (!response.isSuccess()) {
|
||||
log.error("获取支付宝用户信息失败,错误码:{},错误信息:{}", response.getSubCode(), response.getSubMsg());
|
||||
throw new RuntimeException(StrUtil.format("获取支付宝用户信息失败,错误码:{},错误信息:{}", response.getSubCode(), response.getSubMsg()));
|
||||
}
|
||||
//调用成功,则处理业务逻辑,为配合支付系统确定沿用支付宝的老标准使用userId
|
||||
return response.getUserId();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package com.czg.utils;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Administrator
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class WechatAuthUtil {
|
||||
|
||||
@Value("${wx.appId}")
|
||||
private String appId;
|
||||
|
||||
@Value("${wx.secrete}")
|
||||
private String secrete;
|
||||
|
||||
static LinkedHashMap<String,String> linkedHashMap=new LinkedHashMap<>();
|
||||
|
||||
static {
|
||||
|
||||
linkedHashMap.put("40001","获取 access_token 时 AppSecret 错误,或者 access_token 无效。请开发者认真比对 AppSecret 的正确性,或查看是否正在为恰当的公众号调用接口");
|
||||
linkedHashMap.put("40003","不合法的 OpenID ,请开发者确认 OpenID (该用户)是否已关注公众号,或是否是其他公众号的 OpenID");
|
||||
linkedHashMap.put("40014","不合法的 access_token ,请开发者认真比对 access_token 的有效性(如是否过期),或查看是否正在为恰当的公众号调用接口");
|
||||
linkedHashMap.put("40037","不合法的 template_id");
|
||||
linkedHashMap.put("43101","用户未订阅消息");
|
||||
linkedHashMap.put("43107","订阅消息能力封禁");
|
||||
linkedHashMap.put("43108","并发下发消息给同一个粉丝");
|
||||
linkedHashMap.put("45168","命中敏感词");
|
||||
linkedHashMap.put("47003","参数错误");
|
||||
|
||||
}
|
||||
|
||||
public String getSessionKeyOrOpenId(String code) {
|
||||
String requestUrl = "https://api.weixin.qq.com/sns/jscode2session";
|
||||
Map<String, Object> requestUrlParam = new HashMap<>();
|
||||
// https://mp.weixin.qq.com/wxopen/devprofile?action=get_profile&token=164113089&lang=zh_CN
|
||||
//小程序appId
|
||||
requestUrlParam.put("appid", appId);
|
||||
//小程序secret
|
||||
requestUrlParam.put("secret", secrete);
|
||||
//小程序端返回的code
|
||||
requestUrlParam.put("js_code", code);
|
||||
//默认参数
|
||||
requestUrlParam.put("grant_type", "authorization_code");
|
||||
//发送post请求读取调用微信接口获取openid用户唯一标识
|
||||
String resp = HttpUtil.post(requestUrl, requestUrlParam);
|
||||
JSONObject jsonObject = JSON.parseObject(resp);
|
||||
log.info("微信获取openid响应报文:{}", resp);
|
||||
String openid = jsonObject.getString("openid");
|
||||
if (StrUtil.isBlank(openid)) {
|
||||
throw new RuntimeException("openId获取失败");
|
||||
}
|
||||
|
||||
return openid;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user