fix: 微信登录,接口修改。
This commit is contained in:
@@ -40,6 +40,7 @@ import com.intc.web.service.SysLoginService;
|
||||
import com.intc.web.service.SysRegisterService;
|
||||
import com.intc.weixin.domain.bo.ReqWxLogin;
|
||||
import com.intc.weixin.service.WxLoginService;
|
||||
import com.intc.weixin.config.WxMaProperties;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -83,6 +84,9 @@ public class AuthController {
|
||||
@Autowired(required = false)
|
||||
private WxLoginService wxLoginService;
|
||||
|
||||
@Autowired(required = false)
|
||||
private WxMaProperties wxMaProperties;
|
||||
|
||||
|
||||
/**
|
||||
* 登录方法
|
||||
@@ -250,14 +254,27 @@ public class AuthController {
|
||||
/**
|
||||
* 微信小程序登录
|
||||
*
|
||||
* @param request 微信登录请求
|
||||
* @param body 微信登录请求JSON字符串
|
||||
* @return 结果
|
||||
*/
|
||||
@ApiEncrypt
|
||||
@PostMapping("/wechat_login")
|
||||
public R<AquUser> wechatLogin(@Validated @RequestBody ReqWxLogin request) {
|
||||
public R<LoginVo> wechatLogin(@RequestBody String body) {
|
||||
try {
|
||||
log.info("收到微信登录请求: clientId={}, tenantId={}", request.getClientId(), request.getTenantId());
|
||||
ReqWxLogin request = JsonUtils.parseObject(body, ReqWxLogin.class);
|
||||
ValidatorUtils.validate(request);
|
||||
|
||||
// 如果未传递 clientId,使用默认配置的 clientId
|
||||
if (StringUtils.isBlank(request.getClientId()) && wxMaProperties != null) {
|
||||
request.setClientId(wxMaProperties.getDefaultClientId());
|
||||
// 更新 body 中的 clientId
|
||||
body = JsonUtils.toJsonString(request);
|
||||
}
|
||||
|
||||
String clientId = request.getClientId();
|
||||
String grantType = "wechat"; // 微信登录的授权类型
|
||||
|
||||
log.info("收到微信登录请求: clientId={}, tenantId={}", clientId, request.getTenantId());
|
||||
|
||||
// 1. 检查服务是否可用
|
||||
if (wxLoginService == null) {
|
||||
@@ -266,43 +283,33 @@ public class AuthController {
|
||||
}
|
||||
|
||||
// 2. 校验客户端
|
||||
SysClientVo client = clientService.queryByClientId(request.getClientId());
|
||||
SysClientVo client = clientService.queryByClientId(clientId);
|
||||
if (ObjectUtil.isNull(client)) {
|
||||
log.error("客户端不存在: clientId={}", request.getClientId());
|
||||
log.error("客户端不存在: clientId={}", clientId);
|
||||
return R.fail(MessageUtils.message("auth.grant.type.error"));
|
||||
}
|
||||
// 校验 client 内是否包含 grantType
|
||||
if (!StringUtils.contains(client.getGrantType(), grantType)) {
|
||||
log.error("客户端不支持该授权类型: clientId={}, grantType={}", clientId, grantType);
|
||||
return R.fail(MessageUtils.message("auth.grant.type.error"));
|
||||
}
|
||||
if (!SystemConstants.NORMAL.equals(client.getStatus())) {
|
||||
log.error("客户端已被禁用: clientId={}, status={}", request.getClientId(), client.getStatus());
|
||||
log.error("客户端已被禁用: clientId={}, status={}", clientId, client.getStatus());
|
||||
return R.fail(MessageUtils.message("auth.grant.type.blocked"));
|
||||
}
|
||||
|
||||
// 3. 校验租户
|
||||
if (StringUtils.isNotBlank(request.getTenantId())) {
|
||||
try {
|
||||
loginService.checkTenant(request.getTenantId());
|
||||
} catch (Exception e) {
|
||||
log.error("租户校验失败: tenantId={}", request.getTenantId(), e);
|
||||
return R.fail("租户校验失败: " + e.getMessage());
|
||||
}
|
||||
loginService.checkTenant(request.getTenantId());
|
||||
}
|
||||
|
||||
// 4. 执行微信登录
|
||||
AquUser aquUser = wxLoginService.loginByWeChat(
|
||||
request.getCode(),
|
||||
request.getJsCode(),
|
||||
request.getTenantId()
|
||||
);
|
||||
// 4. 使用标准的 IAuthStrategy 登录方法
|
||||
LoginVo loginVo = IAuthStrategy.login(body, client, grantType);
|
||||
|
||||
log.info("微信登录成功: userId={}, accessToken={}",
|
||||
loginVo.getUserId(), loginVo.getAccessToken() != null ? "***" : "null");
|
||||
|
||||
if (aquUser == null) {
|
||||
log.error("微信登录失败,未返回用户信息");
|
||||
return R.fail("登录失败,请重试");
|
||||
}
|
||||
|
||||
// 5. 返回用户信息
|
||||
log.info("微信登录成功: userId={}, mobilePhone={}",
|
||||
aquUser.getId(), aquUser.getMobilePhone());
|
||||
|
||||
return R.ok(aquUser);
|
||||
return R.ok(loginVo);
|
||||
|
||||
} catch (ServiceException e) {
|
||||
log.error("微信登录业务异常: {}", e.getMessage(), e);
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
package com.intc.web.service.impl;
|
||||
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.dev33.satoken.stp.parameter.SaLoginParameter;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.intc.common.core.constant.SystemConstants;
|
||||
import com.intc.common.core.domain.model.LoginUser;
|
||||
import com.intc.common.core.exception.ServiceException;
|
||||
import com.intc.common.core.exception.user.UserException;
|
||||
import com.intc.common.core.utils.StringUtils;
|
||||
import com.intc.common.core.utils.ValidatorUtils;
|
||||
import com.intc.common.json.utils.JsonUtils;
|
||||
import com.intc.common.satoken.utils.LoginHelper;
|
||||
import com.intc.common.tenant.helper.TenantHelper;
|
||||
import com.intc.fishery.domain.AquUser;
|
||||
import com.intc.system.domain.SysUser;
|
||||
import com.intc.system.domain.vo.SysClientVo;
|
||||
import com.intc.system.domain.vo.SysUserVo;
|
||||
import com.intc.system.mapper.SysUserMapper;
|
||||
import com.intc.web.domain.vo.LoginVo;
|
||||
import com.intc.web.service.IAuthStrategy;
|
||||
import com.intc.web.service.SysLoginService;
|
||||
import com.intc.weixin.domain.bo.ReqWxLogin;
|
||||
import com.intc.weixin.service.WxLoginService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 微信小程序认证策略
|
||||
*
|
||||
* @author intc
|
||||
*/
|
||||
@Slf4j
|
||||
@Service("wechat" + IAuthStrategy.BASE_NAME)
|
||||
@RequiredArgsConstructor
|
||||
public class WechatAuthStrategy implements IAuthStrategy {
|
||||
|
||||
private final WxLoginService wxLoginService;
|
||||
private final SysLoginService loginService;
|
||||
private final SysUserMapper userMapper;
|
||||
|
||||
@Override
|
||||
public LoginVo login(String body, SysClientVo client) {
|
||||
ReqWxLogin loginBody = JsonUtils.parseObject(body, ReqWxLogin.class);
|
||||
ValidatorUtils.validate(loginBody);
|
||||
|
||||
String tenantId = loginBody.getTenantId();
|
||||
String code = loginBody.getCode();
|
||||
String jsCode = loginBody.getJsCode();
|
||||
|
||||
// 在租户上下文中执行登录
|
||||
AquUser[] aquUserHolder = new AquUser[1]; // 用于保存 AquUser
|
||||
LoginUser loginUser = TenantHelper.dynamic(tenantId, () -> {
|
||||
// 1. 调用微信登录服务获取或创建渔业用户(用于获取手机号和openId)
|
||||
AquUser aquUser = wxLoginService.loginByWeChat(code, jsCode, tenantId);
|
||||
|
||||
if (aquUser == null) {
|
||||
log.error("微信登录失败,未返回用户信息");
|
||||
throw new ServiceException("登录失败,请重试");
|
||||
}
|
||||
|
||||
aquUserHolder[0] = aquUser; // 保存以便后续使用
|
||||
|
||||
log.info("获取微信用户信息成功: aquUserId={}, mobilePhone={}",
|
||||
aquUser.getId(), aquUser.getMobilePhone());
|
||||
|
||||
// 2. 根据手机号查询系统用户
|
||||
String mobilePhone = aquUser.getMobilePhone();
|
||||
if (StringUtils.isBlank(mobilePhone)) {
|
||||
log.error("微信用户手机号为空: aquUserId={}", aquUser.getId());
|
||||
throw new ServiceException("获取手机号失败,请重新授权");
|
||||
}
|
||||
|
||||
SysUserVo sysUser = loadUserByPhone(mobilePhone);
|
||||
|
||||
log.info("找到对应的系统用户: sysUserId={}, userName={}",
|
||||
sysUser.getUserId(), sysUser.getUserName());
|
||||
|
||||
// 3. 使用系统用户构建 LoginUser(包含完整的权限信息)
|
||||
return loginService.buildLoginUser(sysUser);
|
||||
});
|
||||
|
||||
// 3. 设置客户端信息
|
||||
loginUser.setClientKey(client.getClientKey());
|
||||
loginUser.setDeviceType(client.getDeviceType());
|
||||
|
||||
// 4. 配置登录参数
|
||||
SaLoginParameter model = new SaLoginParameter();
|
||||
model.setDeviceType(client.getDeviceType());
|
||||
model.setTimeout(client.getTimeout());
|
||||
model.setActiveTimeout(client.getActiveTimeout());
|
||||
model.setExtra(LoginHelper.CLIENT_KEY, client.getClientId());
|
||||
|
||||
// 5. 执行登录,生成 token
|
||||
LoginHelper.login(loginUser, model);
|
||||
|
||||
// 6. 构建返回对象
|
||||
LoginVo loginVo = new LoginVo();
|
||||
loginVo.setAccessToken(StpUtil.getTokenValue());
|
||||
loginVo.setExpireIn(StpUtil.getTokenTimeout());
|
||||
loginVo.setClientId(client.getClientId());
|
||||
loginVo.setOpenid(aquUserHolder[0].getWxOpenId()); // 从 AquUser 中获取 openId
|
||||
loginVo.setUserId(loginUser.getUserId());
|
||||
loginVo.setUserName(loginUser.getUsername());
|
||||
loginVo.setNickName(loginUser.getNickname());
|
||||
|
||||
return loginVo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据手机号加载系统用户
|
||||
*
|
||||
* @param phone 手机号
|
||||
* @return 系统用户信息
|
||||
*/
|
||||
private SysUserVo loadUserByPhone(String phone) {
|
||||
SysUserVo user = userMapper.selectVoOne(
|
||||
new LambdaQueryWrapper<SysUser>()
|
||||
.eq(SysUser::getPhonenumber, phone)
|
||||
);
|
||||
|
||||
if (ObjectUtil.isNull(user)) {
|
||||
log.error("系统中不存在该手机号的用户: phone={}", phone);
|
||||
throw new UserException("user.not.exists", phone);
|
||||
}
|
||||
|
||||
if (SystemConstants.DISABLE.equals(user.getStatus())) {
|
||||
log.error("用户已被停用: phone={}, userId={}", phone, user.getUserId());
|
||||
throw new UserException("user.blocked", phone);
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
}
|
||||
@@ -39,4 +39,9 @@ public class WxMaProperties {
|
||||
*/
|
||||
private String msgDataFormat;
|
||||
|
||||
/**
|
||||
* 默认客户端ID(小程序登录使用)
|
||||
*/
|
||||
private String defaultClientId = "miniapp-client";
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.intc.weixin.domain.bo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.Data;
|
||||
|
||||
@@ -27,12 +28,12 @@ public class ReqWxLogin implements Serializable {
|
||||
* 登录时获取的jsCode(用于获取openId)
|
||||
*/
|
||||
@NotBlank(message = "jsCode不能为空")
|
||||
@JsonProperty("js_code")
|
||||
private String jsCode;
|
||||
|
||||
/**
|
||||
* 客户端ID
|
||||
*/
|
||||
@NotBlank(message = "客户端ID不能为空")
|
||||
private String clientId;
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user