diff --git a/pom.xml b/pom.xml
index 9629c9a35..e9cf38661 100644
--- a/pom.xml
+++ b/pom.xml
@@ -272,6 +272,17 @@
${lock4j.version}
+
+
+ tech.powerjob
+ powerjob-worker-spring-boot-starter
+ ${powerjob.version}
+
+
+ tech.powerjob
+ powerjob-official-processors
+ ${powerjob.version}
+
com.alibaba
@@ -330,18 +341,6 @@
${revision}
-
-
- tech.powerjob
- powerjob-worker-spring-boot-starter
- ${powerjob.version}
-
-
- tech.powerjob
- powerjob-official-processors
- ${powerjob.version}
-
-
diff --git a/ruoyi-admin/src/main/java/org/dromara/web/controller/AuthController.java b/ruoyi-admin/src/main/java/org/dromara/web/controller/AuthController.java
index ff7c3b1dc..c45473474 100644
--- a/ruoyi-admin/src/main/java/org/dromara/web/controller/AuthController.java
+++ b/ruoyi-admin/src/main/java/org/dromara/web/controller/AuthController.java
@@ -1,12 +1,13 @@
package org.dromara.web.controller;
import cn.dev33.satoken.annotation.SaIgnore;
-import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
+import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.request.AuthRequest;
@@ -87,7 +88,7 @@ public class AuthController {
}
/**
- * 第三方登录请求
+ * 认证授权
*
* @param source 登录来源
* @return 结果
@@ -98,43 +99,49 @@ public class AuthController {
if (ObjectUtil.isNull(obj)) {
return R.fail(source + "平台账号暂不支持");
}
- AuthRequest authRequest = SocialUtils.getAuthRequest(source, socialProperties);
+ AuthRequest authRequest = SocialUtils.getAuthRequest(source,
+ obj.getClientId(),
+ obj.getClientSecret(),
+ obj.getRedirectUri());
String authorizeUrl = authRequest.authorize(AuthStateUtils.createState());
return R.ok(authorizeUrl);
}
/**
* 第三方登录回调业务处理
- * 绑定授权
- * @param loginBody
+ *
+ * @param source 登录来源
+ * @param callback 授权响应实体
* @return 结果
*/
@SuppressWarnings("unchecked")
- @PostMapping("/social-login")
- public R socialLogin(@RequestBody LoginBody loginBody) {
- // 授权类型和客户端id
- String clientId = loginBody.getClientId();
- String grantType = loginBody.getGrantType();
+ @GetMapping("/social-login")
+ public R socialLogin(String source,
+ String loginType,
+ String tenantId,
+ String clientId,
+ String grantType,
+ AuthCallback callback) {
+ SocialLoginConfigProperties obj = socialProperties.getType().get(source);
+ if (ObjectUtil.isNull(obj)) {
+ return R.fail(source + "平台账号暂不支持");
+ }
SysClient client = clientService.queryByClientId(clientId);
// 查询不到 client 或 client 内不包含 grantType
if (ObjectUtil.isNull(client) || !StringUtils.contains(client.getGrantType(), grantType)) {
log.info("客户端id: {} 认证类型:{} 异常!.", clientId, grantType);
return R.fail(MessageUtils.message("auth.grant.type.error"));
}
- // 校验租户
- loginService.checkTenant(loginBody.getTenantId());
- //判断用户登录状态,如果已经登录那么就默认为注册,如果没有登录那么默认登录
- if (!StpUtil.isLogin()) {
- return R.ok(IAuthStrategy.login(loginBody, client));
- }else {
- // 获取第三方登录信息
- AuthResponse response = SocialUtils.loginAuth(loginBody, socialProperties);
- AuthUser authUserData = response.getData();
- // 判断授权响应是否成功
- if (!response.ok()) {
- return R.fail(response.getMsg());
- }
- return loginService.sociaRegister(authUserData);
+ AuthRequest authRequest = SocialUtils.getAuthRequest(source,
+ obj.getClientId(),
+ obj.getClientSecret(),
+ obj.getRedirectUri());
+ AuthResponse response = authRequest.login(callback);
+ //判断loginType是否为login,如果是login则为登录,否则为绑定
+ if (StrUtil.equals(loginType, "login")) {
+ return loginService.socialLogin(tenantId , response);
+ } else {
+ return loginService.sociaRegister(response);
}
}
diff --git a/ruoyi-admin/src/main/java/org/dromara/web/service/SysLoginService.java b/ruoyi-admin/src/main/java/org/dromara/web/service/SysLoginService.java
index 84fedeab4..e56c267e6 100644
--- a/ruoyi-admin/src/main/java/org/dromara/web/service/SysLoginService.java
+++ b/ruoyi-admin/src/main/java/org/dromara/web/service/SysLoginService.java
@@ -1,12 +1,15 @@
package org.dromara.web.service;
import cn.dev33.satoken.exception.NotLoginException;
+import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
+import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthUser;
import org.dromara.common.core.constant.Constants;
import org.dromara.common.core.constant.GlobalConstants;
@@ -14,14 +17,12 @@ import org.dromara.common.core.constant.TenantConstants;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.domain.dto.RoleDTO;
import org.dromara.common.core.domain.model.LoginUser;
+import org.dromara.common.core.enums.DeviceType;
import org.dromara.common.core.enums.LoginType;
import org.dromara.common.core.enums.TenantStatus;
import org.dromara.common.core.enums.UserStatus;
import org.dromara.common.core.exception.user.UserException;
-import org.dromara.common.core.utils.DateUtils;
-import org.dromara.common.core.utils.MessageUtils;
-import org.dromara.common.core.utils.ServletUtils;
-import org.dromara.common.core.utils.SpringUtils;
+import org.dromara.common.core.utils.*;
import org.dromara.common.log.event.LogininforEvent;
import org.dromara.common.redis.utils.RedisUtils;
import org.dromara.common.satoken.utils.LoginHelper;
@@ -29,13 +30,13 @@ import org.dromara.common.tenant.exception.TenantException;
import org.dromara.common.tenant.helper.TenantHelper;
import org.dromara.system.domain.SysUser;
import org.dromara.system.domain.bo.SysSocialBo;
+import org.dromara.system.domain.vo.SysSocialVo;
import org.dromara.system.domain.vo.SysTenantVo;
import org.dromara.system.domain.vo.SysUserVo;
import org.dromara.system.mapper.SysUserMapper;
import org.dromara.system.service.ISysPermissionService;
import org.dromara.system.service.ISysSocialService;
import org.dromara.system.service.ISysTenantService;
-import org.dromara.web.domain.vo.LoginVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
@@ -69,22 +70,80 @@ public class SysLoginService {
/**
- * 绑定第三方用户
- * @param authUserData 授权响应实体
+ * 社交登录
+ *
+ * @param tenantId 租户id
+ * @param authUser 授权响应实体
* @return 统一响应实体
*/
- public R sociaRegister(AuthUser authUserData ){
+ public R socialLogin(String tenantId, AuthResponse authUser) {
+ // 判断授权响应是否成功
+ if (!authUser.ok()) {
+ return R.fail("对不起,授权信息验证不通过,请退出重试!");
+ }
+ AuthUser authUserData = authUser.getData();
+ SysSocialVo social = sysSocialService.selectByAuthId(authUserData.getSource() + authUserData.getUuid());
+ //验证授权表里面的租户id是否包含当前租户id
+ if (ObjectUtil.isNotNull(social) && StrUtil.isNotBlank(social.getTenantId())
+ && !social.getTenantId().contains(tenantId)) {
+ return R.fail("对不起,你没有权限登录当前租户!");
+ }
+ if (ObjectUtil.isNotNull(social)) {
+ SysUser user = userMapper.selectOne(new LambdaQueryWrapper()
+ .eq(SysUser::getUserId, social.getUserId()));
+ // 执行登录
+ return loginAndRecord(user.getTenantId(), user.getUserName());
+ } else {
+ return R.fail("你还没有绑定第三方账号,绑定后才可以登录!");
+ }
+ }
+
+
+ /**
+ * 绑定第三方用户
+ * @param authUser 授权响应实体
+ * @return 统一响应实体
+ */
+ public R sociaRegister(AuthResponse authUser){
+ if (!authUser.ok()) {
+ return R.fail("对不起,授权信息验证不通过,请退出重试!");
+ }
+ // 判断是否已登录
+ if (!StpUtil.isLogin()) {
+ return R.fail("授权失败,登录状态异常!");
+ }
+ AuthUser authUserData = authUser.getData();
SysSocialBo bo = new SysSocialBo();
bo.setUserId(LoginHelper.getUserId());
bo.setAuthId(authUserData.getSource() + authUserData.getUuid());
- bo.setOpenId(authUserData.getUuid());
+ bo.setSource(authUserData.getSource());
bo.setUserName(authUserData.getUsername());
- BeanUtils.copyProperties(authUserData, bo);
+ bo.setNickName(authUserData.getNickname());
+ bo.setAvatar(authUserData.getAvatar());
+ bo.setOpenId(authUserData.getUuid());
BeanUtils.copyProperties(authUserData.getToken(), bo);
- sysSocialService.insertByBo(bo);
- return R.ok();
+
+ return sysSocialService.insertByBo(bo) ? R.ok("绑定成功!"):R.fail("绑定失败!");
}
+ /**
+ * 执行登录和记录登录信息操作
+ *
+ * @param tenantId 租户ID
+ * @param userName 用户名
+ * @return 统一响应实体
+ */
+ private R loginAndRecord(String tenantId, String userName) {
+ checkTenant(tenantId);
+ SysUserVo user = loadUserByUsername(tenantId, userName);
+ SaLoginModel model = new SaLoginModel();
+ model.setDevice(DeviceType.PC.getDevice());
+ // 生成token
+ LoginHelper.login(buildLoginUser(user), model);
+ recordLogininfor(user.getTenantId(), userName, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
+ recordLoginInfo(user.getUserId());
+ return R.ok( "登录成功", StpUtil.getTokenValue());
+ }
/**
* 退出登录
@@ -120,6 +179,25 @@ public class SysLoginService {
SpringUtils.context().publishEvent(logininforEvent);
}
+
+ private SysUserVo loadUserByUsername(String tenantId, String username) {
+ SysUser user = userMapper.selectOne(new LambdaQueryWrapper()
+ .select(SysUser::getUserName, SysUser::getStatus)
+ .eq(TenantHelper.isEnable(), SysUser::getTenantId, tenantId)
+ .eq(SysUser::getUserName, username));
+ if (ObjectUtil.isNull(user)) {
+ log.info("登录用户:{} 不存在.", username);
+ throw new UserException("user.not.exists", username);
+ } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
+ log.info("登录用户:{} 已被停用.", username);
+ throw new UserException("user.blocked", username);
+ }
+ if (TenantHelper.isEnable()) {
+ return userMapper.selectTenantUserByUserName(username, tenantId);
+ }
+ return userMapper.selectUserByUserName(username);
+ }
+
/**
* 构建登录用户
*/
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/LoginBody.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/LoginBody.java
index cdff7738b..d399778c7 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/LoginBody.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/LoginBody.java
@@ -3,7 +3,10 @@ package org.dromara.common.core.domain.model;
import jakarta.validation.constraints.Email;
import org.dromara.common.core.constant.UserConstants;
import lombok.Data;
-import org.dromara.common.core.validate.auth.*;
+import org.dromara.common.core.validate.auth.EmailGroup;
+import org.dromara.common.core.validate.auth.PasswordGroup;
+import org.dromara.common.core.validate.auth.SmsGroup;
+import org.dromara.common.core.validate.auth.WechatGroup;
import org.hibernate.validator.constraints.Length;
import jakarta.validation.constraints.NotBlank;
@@ -103,18 +106,6 @@ public class LoginBody {
/**
* 第三方登录平台
*/
- @NotBlank(message = "{social.source.not.blank}" , groups = {SocialGroup.class})
private String source;
- /**
- * 第三方登录code
- */
- @NotBlank(message = "{social.code.not.blank}" , groups = {SocialGroup.class})
- private String socialCode;
-
- /**
- * 第三方登录socialState
- */
- @NotBlank(message = "{social.state.not.blank}" , groups = {SocialGroup.class})
- private String socialState;
}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysUserBo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysUserBo.java
index 374bfbf96..011254ead 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysUserBo.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysUserBo.java
@@ -1,11 +1,5 @@
package org.dromara.system.domain.bo;
-import org.dromara.common.core.constant.UserConstants;
-import org.dromara.common.core.xss.Xss;
-import org.dromara.common.mybatis.core.domain.BaseEntity;
-import org.dromara.common.sensitive.annotation.Sensitive;
-import org.dromara.common.sensitive.core.SensitiveStrategy;
-import org.dromara.system.domain.SysUser;
import io.github.linpeilie.annotations.AutoMapper;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
@@ -13,8 +7,10 @@ import jakarta.validation.constraints.Size;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
-
-import java.util.Date;
+import org.dromara.common.core.constant.UserConstants;
+import org.dromara.common.core.xss.Xss;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.system.domain.SysUser;
/**
* 用户信息业务对象 sys_user
@@ -50,6 +46,7 @@ public class SysUserBo extends BaseEntity {
* 用户昵称
*/
@Xss(message = "用户昵称不能包含脚本字符")
+ @NotBlank(message = "用户昵称不能为空")
@Size(min = 0, max = 30, message = "用户昵称长度不能超过{max}个字符")
private String nickName;
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysDeptService.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysDeptService.java
index 1d3277995..b20938187 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysDeptService.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysDeptService.java
@@ -1,7 +1,6 @@
package org.dromara.system.service;
import cn.hutool.core.lang.tree.Tree;
-import org.dromara.system.domain.SysDept;
import org.dromara.system.domain.bo.SysDeptBo;
import org.dromara.system.domain.vo.SysDeptVo;
@@ -35,7 +34,7 @@ public interface ISysDeptService {
* @param depts 部门列表
* @return 下拉树结构列表
*/
- List> buildDeptTreeSelect(List depts);
+ List> buildDeptTreeSelect(List depts);
/**
* 根据角色ID查询部门树信息
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDeptServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDeptServiceImpl.java
index 36680e392..874f634b8 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDeptServiceImpl.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDeptServiceImpl.java
@@ -70,7 +70,7 @@ public class SysDeptServiceImpl implements ISysDeptService, DeptService {
@Override
public List> selectDeptTreeList(SysDeptBo bo) {
LambdaQueryWrapper lqw = buildQueryWrapper(bo);
- List depts = baseMapper.selectList(lqw);
+ List depts = baseMapper.selectDeptList(lqw);
return buildDeptTreeSelect(depts);
}
@@ -93,7 +93,7 @@ public class SysDeptServiceImpl implements ISysDeptService, DeptService {
* @return 下拉树结构列表
*/
@Override
- public List> buildDeptTreeSelect(List depts) {
+ public List> buildDeptTreeSelect(List depts) {
if (CollUtil.isEmpty(depts)) {
return CollUtil.newArrayList();
}