其它针对租户功能的修改

This commit is contained in:
dataprince 2024-01-03 17:20:23 +08:00
parent 4946f2f45f
commit 5a1c99cfd5
55 changed files with 803 additions and 463 deletions

View File

@ -37,6 +37,11 @@
<artifactId>postgresql</artifactId> <artifactId>postgresql</artifactId>
</dependency> </dependency>
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common-tenant</artifactId>
</dependency>
<!-- system模块--> <!-- system模块-->
<dependency> <dependency>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>

View File

@ -1,31 +1,38 @@
package com.ruoyi.web.controller; package com.ruoyi.web.controller;
import cn.dev33.satoken.annotation.SaIgnore; import cn.dev33.satoken.annotation.SaIgnore;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import com.mybatisflex.core.query.QueryWrapper; import com.mybatisflex.core.query.QueryWrapper;
import com.ruoyi.common.core.constant.Constants; import com.ruoyi.common.core.constant.UserConstants;
import com.ruoyi.common.core.core.domain.AjaxResult; import com.ruoyi.common.core.core.domain.AjaxResult;
import com.ruoyi.common.core.core.domain.model.LoginUser; import com.ruoyi.common.core.core.domain.model.LoginUser;
import com.ruoyi.common.core.utils.*;
import com.ruoyi.common.encrypt.annotation.ApiEncrypt;
import com.ruoyi.common.json.utils.JsonUtils;
import com.ruoyi.common.security.utils.LoginHelper; import com.ruoyi.common.security.utils.LoginHelper;
import com.ruoyi.system.domain.SysMenu; import com.ruoyi.common.tenant.helper.TenantHelper;
import com.ruoyi.system.domain.SysUser; import com.ruoyi.system.domain.bo.SysTenantBo;
import com.ruoyi.system.domain.vo.SysTenantVo;
import com.ruoyi.system.domain.vo.SysUserVo; import com.ruoyi.system.domain.vo.SysUserVo;
import com.ruoyi.system.service.*; import com.ruoyi.system.service.*;
import com.ruoyi.web.domain.vo.LoginTenantVo;
import com.ruoyi.web.domain.vo.LoginVo; import com.ruoyi.web.domain.vo.LoginVo;
import com.ruoyi.web.domain.vo.TenantListVo;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import com.ruoyi.common.core.core.domain.R; import com.ruoyi.common.core.core.domain.R;
import com.ruoyi.common.core.core.domain.model.LoginBody; import com.ruoyi.common.core.core.domain.model.LoginBody;
import com.ruoyi.common.core.core.domain.model.RegisterBody; import com.ruoyi.common.core.core.domain.model.RegisterBody;
import com.ruoyi.common.core.utils.MessageUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.system.domain.SysClient; import com.ruoyi.system.domain.SysClient;
import com.ruoyi.web.service.IAuthStrategy; import com.ruoyi.web.service.IAuthStrategy;
import com.ruoyi.web.service.SysLoginService; import com.ruoyi.web.service.SysLoginService;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.net.URL;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@ -42,29 +49,27 @@ import static com.ruoyi.system.domain.table.SysClientTableDef.SYS_CLIENT;
@Validated @Validated
@RequiredArgsConstructor @RequiredArgsConstructor
@RestController @RestController
@RequestMapping("/auth")
public class AuthController { public class AuthController {
@Resource @Resource
private final SysLoginService loginService; private SysLoginService loginService;
@Resource @Resource
private final ISysClientService clientService; private ISysClientService clientService;
@Resource @Resource
private final ISysUserService sysUserService; private ISysTenantService tenantService;
@Resource
private final ISysPermissionService permissionService;
@Resource
private ISysMenuService menuService;
/** /**
* 登录方法 * 登录方法
* *
* @param loginBody 登录信息 * @param body 登录信息
* @return 结果 * @return 结果
*/ */
@ApiEncrypt
@PostMapping("/login") @PostMapping("/login")
public R<LoginVo> login(@RequestBody LoginBody loginBody) { public R<LoginVo> login(@RequestBody String body) {
LoginBody loginBody = JsonUtils.parseObject(body, LoginBody.class);
AjaxResult ajax = AjaxResult.success(); ValidatorUtils.validate(loginBody);
// 授权类型和客户端id // 授权类型和客户端id
String clientId = loginBody.getClientId(); String clientId = loginBody.getClientId();
String grantType = loginBody.getGrantType(); String grantType = loginBody.getGrantType();
@ -74,53 +79,14 @@ public class AuthController {
if (ObjectUtil.isNull(client) || !StringUtils.contains(client.getGrantType(), grantType)) { if (ObjectUtil.isNull(client) || !StringUtils.contains(client.getGrantType(), grantType)) {
log.info("客户端id: {} 认证类型:{} 异常!.", clientId, grantType); log.info("客户端id: {} 认证类型:{} 异常!.", clientId, grantType);
return R.fail(MessageUtils.message("auth.grant.type.error")); return R.fail(MessageUtils.message("auth.grant.type.error"));
} else if (!UserConstants.NORMAL.equals(client.getStatus())) {
return R.fail(MessageUtils.message("auth.grant.type.blocked"));
} }
// 校验租户
// TODO:校验租户 loginService.checkTenant(loginBody.getTenantId());
//loginService.checkTenant(loginBody.getTenantId());
// 登录 // 登录
return R.ok(IAuthStrategy.login(loginBody, client)); return R.ok(IAuthStrategy.login(body, client, grantType));
}
/**
* 获取用户信息
*
* @return 用户信息
*/
@GetMapping("/getInfo")
public AjaxResult getInfo() {
LoginUser loginUser = LoginHelper.getLoginUser();
//TODO:多租户 超级管理员 如果重新加载用户信息需清除动态租户
SysUserVo user = sysUserService.selectUserById(loginUser.getUserId());
// 角色集合
Set<String> roles = permissionService.getRolePermission(user.getUserId());
// 权限集合
Set<String> permissions = permissionService.getMenuPermission(user.getUserId());
AjaxResult ajax = AjaxResult.success();
ajax.put("user", user);
ajax.put("roles", roles);
ajax.put("permissions", permissions);
return ajax;
}
/**
* 获取路由信息
*
* @return 路由信息
*/
@GetMapping("/getRouters")
public AjaxResult getRouters()
{
LoginUser loginUser = LoginHelper.getLoginUser();
// 用户信息
SysUserVo user = sysUserService.selectUserById(loginUser.getUserId());
List<SysMenu> menus = menuService.selectMenuTreeByUserId(user.getUserId());
return AjaxResult.success(menuService.buildMenus(menus));
} }
/** /**
@ -135,7 +101,7 @@ public class AuthController {
/** /**
* 用户注册 * 用户注册
*/ */
@PostMapping("LoginHelper.getUserId()") @PostMapping("/register")
public R<Void> register(@Validated @RequestBody RegisterBody user) { public R<Void> register(@Validated @RequestBody RegisterBody user) {
//if (!configService.selectRegisterEnabled(user.getTenantId())) // TODO注册代码 //if (!configService.selectRegisterEnabled(user.getTenantId())) // TODO注册代码
{ {
@ -145,5 +111,32 @@ public class AuthController {
// return R.ok(); // return R.ok();
} }
/**
* 登录页面租户下拉框
*
* @return 租户列表
*/
@GetMapping("/tenant/list")
public R<LoginTenantVo> tenantList(HttpServletRequest request) throws Exception {
List<SysTenantVo> tenantList = tenantService.selectList(new SysTenantBo());
List<TenantListVo> voList = MapstructUtils.convert(tenantList, TenantListVo.class);
// 获取域名
String host;
String referer = request.getHeader("referer");
if (StringUtils.isNotBlank(referer)) {
// 这里从referer中取值是为了本地使用hosts添加虚拟域名方便本地环境调试
host = referer.split("//")[1].split("/")[0];
} else {
host = new URL(request.getRequestURL().toString()).getHost();
}
// 根据域名进行筛选
List<TenantListVo> list = StreamUtils.filter(voList, vo ->
StringUtils.equals(vo.getDomain(), host));
// 返回对象
LoginTenantVo vo = new LoginTenantVo();
vo.setVoList(CollUtil.isNotEmpty(list) ? list : voList);
return R.ok(vo);
}
} }

View File

@ -8,7 +8,6 @@ import cn.hutool.captcha.generator.CodeGenerator;
import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.IdUtil;
import com.ruoyi.common.core.annotation.RateLimiter; import com.ruoyi.common.core.annotation.RateLimiter;
import com.ruoyi.common.core.constant.GlobalConstants; import com.ruoyi.common.core.constant.GlobalConstants;
import com.ruoyi.common.core.core.domain.AjaxResult;
import com.ruoyi.common.core.enums.LimitType; import com.ruoyi.common.core.enums.LimitType;
import com.ruoyi.common.core.utils.StringUtils; import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.reflect.ReflectUtils; import com.ruoyi.common.core.utils.reflect.ReflectUtils;
@ -32,6 +31,7 @@ import com.ruoyi.common.web.config.properties.CaptchaProperties;
* 验证码操作处理 * 验证码操作处理
* *
* @author ruoyi * @author ruoyi
* @author 数据小王子
*/ */
@SaIgnore @SaIgnore
@Slf4j @Slf4j
@ -46,13 +46,13 @@ public class CaptchaController
* 生成验证码 * 生成验证码
*/ */
@RateLimiter(time = 60, count = 10, limitType = LimitType.IP) @RateLimiter(time = 60, count = 10, limitType = LimitType.IP)
@GetMapping("/captchaImage") @GetMapping("/auth/code")
public AjaxResult getCode() { public R<CaptchaVo> getCode() {
CaptchaVo captchaVo = new CaptchaVo(); CaptchaVo captchaVo = new CaptchaVo();
boolean captchaEnabled = captchaProperties.getEnable(); boolean captchaEnabled = captchaProperties.getEnable();
if (!captchaEnabled) { if (!captchaEnabled) {
captchaVo.setCaptchaEnabled(false); captchaVo.setCaptchaEnabled(false);
return AjaxResult.success(captchaVo); return R.ok(captchaVo);
} }
// 保存验证码信息 // 保存验证码信息
String uuid = IdUtil.simpleUUID(); String uuid = IdUtil.simpleUUID();
@ -75,8 +75,6 @@ public class CaptchaController
captchaVo.setUuid(uuid); captchaVo.setUuid(uuid);
captchaVo.setImg(captcha.getImageBase64()); captchaVo.setImg(captcha.getImageBase64());
return AjaxResult.success(captchaVo); return R.ok(captchaVo);
} }
} }

View File

@ -0,0 +1,20 @@
package com.ruoyi.web.domain.vo;
import lombok.Data;
import java.util.List;
/**
* 登录租户对象
*
* @author Michelle.Chung
*/
@Data
public class LoginTenantVo {
/**
* 租户对象列表
*/
private List<TenantListVo> voList;
}

View File

@ -0,0 +1,22 @@
package com.ruoyi.web.domain.vo;
import com.ruoyi.system.domain.vo.SysTenantVo;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
/**
* 租户列表
*
* @author Lion Li
*/
@Data
@AutoMapper(target = SysTenantVo.class)
public class TenantListVo {
private String tenantId;
private String companyName;
private String domain;
}

View File

@ -20,27 +20,19 @@ public interface IAuthStrategy {
/** /**
* 登录 * 登录
*/ */
static LoginVo login(LoginBody loginBody, SysClient client) { static LoginVo login(String body, SysClient client, String grantType) {
// 授权类型和客户端id // 授权类型和客户端id
String clientId = loginBody.getClientId();
String grantType = loginBody.getGrantType();
String beanName = grantType + BASE_NAME; String beanName = grantType + BASE_NAME;
if (!SpringUtils.containsBean(beanName)) { if (!SpringUtils.containsBean(beanName)) {
throw new ServiceException("授权类型不正确!"); throw new ServiceException("授权类型不正确!");
} }
IAuthStrategy instance = SpringUtils.getBean(beanName); IAuthStrategy instance = SpringUtils.getBean(beanName);
instance.validate(loginBody); return instance.login(body,client);
return instance.login(clientId, loginBody, client);
} }
/**
* 参数校验
*/
void validate(LoginBody loginBody);
/** /**
* 登录 * 登录
*/ */
LoginVo login(String clientId, LoginBody loginBody, SysClient client); LoginVo login(String body, SysClient client);
} }

View File

@ -4,20 +4,25 @@ import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import com.mybatisflex.core.tenant.TenantManager;
import com.ruoyi.common.core.constant.*; import com.ruoyi.common.core.constant.*;
import com.ruoyi.common.core.core.domain.dto.RoleDTO; import com.ruoyi.common.core.core.domain.dto.RoleDTO;
import com.ruoyi.common.core.enums.LoginType; import com.ruoyi.common.core.enums.LoginType;
import com.ruoyi.common.core.enums.TenantStatus;
import com.ruoyi.common.core.exception.user.*; import com.ruoyi.common.core.exception.user.*;
import com.ruoyi.common.core.utils.ServletUtils; import com.ruoyi.common.core.utils.ServletUtils;
import com.ruoyi.common.core.utils.SpringUtils; import com.ruoyi.common.core.utils.SpringUtils;
import com.ruoyi.common.log.event.LogininforEvent; import com.ruoyi.common.log.event.LogininforEvent;
import com.ruoyi.common.redis.utils.RedisUtils; import com.ruoyi.common.redis.utils.RedisUtils;
import com.ruoyi.common.security.utils.LoginHelper; import com.ruoyi.common.security.utils.LoginHelper;
import com.ruoyi.common.tenant.exception.TenantException;
import com.ruoyi.common.tenant.helper.TenantHelper; import com.ruoyi.common.tenant.helper.TenantHelper;
import com.ruoyi.system.domain.SysUser; import com.ruoyi.system.domain.SysUser;
import com.ruoyi.system.domain.bo.SysUserBo; import com.ruoyi.system.domain.bo.SysUserBo;
import com.ruoyi.system.domain.vo.SysTenantVo;
import com.ruoyi.system.domain.vo.SysUserVo; import com.ruoyi.system.domain.vo.SysUserVo;
import com.ruoyi.system.service.ISysPermissionService; import com.ruoyi.system.service.ISysPermissionService;
import com.ruoyi.system.service.ISysTenantService;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -30,6 +35,7 @@ import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import java.time.Duration; import java.time.Duration;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.function.Supplier; import java.util.function.Supplier;
@ -37,6 +43,7 @@ import java.util.function.Supplier;
* 登录校验方法 * 登录校验方法
* *
* @author ruoyi * @author ruoyi
* @author 数据小王子
*/ */
@RequiredArgsConstructor @RequiredArgsConstructor
@Slf4j @Slf4j
@ -49,11 +56,15 @@ public class SysLoginService {
@Value("${user.password.lockTime}") @Value("${user.password.lockTime}")
private Integer lockTime; private Integer lockTime;
private final ISysPermissionService permissionService; @Resource
private ISysPermissionService permissionService;
@Resource @Resource
private ISysUserService userService; private ISysUserService userService;
@Resource
private ISysTenantService tenantService;
/** /**
* 登录校验 * 登录校验
*/ */
@ -91,17 +102,28 @@ public class SysLoginService {
/** /**
* 校验租户 * 校验租户
* *
* @param tenantId 租户ID * @param tenantId 租户编号
*/ */
public void checkTenant(String tenantId) { public void checkTenant(Long tenantId) {
if (!TenantHelper.isEnable()) {
return;
}
if (TenantConstants.DEFAULT_TENANT_ID.equals(tenantId)) { if (TenantConstants.DEFAULT_TENANT_ID.equals(tenantId)) {
return; return;
} }
if (ObjectUtil.isNull(tenantId)) {
throw new TenantException("tenant.number.not.blank");
}
SysTenantVo tenant = tenantService.selectById(tenantId);
//TODO:完善heckTenant功能 if (ObjectUtil.isNull(tenant)) {
log.info("登录租户:{} 不存在.", tenantId);
throw new TenantException("tenant.not.exists");
} else if (TenantStatus.DISABLE.getCode().equals(tenant.getStatus())) {
log.info("登录租户:{} 已被停用.", tenantId);
throw new TenantException("tenant.blocked");
} else if (ObjectUtil.isNotNull(tenant.getExpireTime())
&& new Date().after(tenant.getExpireTime())) {
log.info("登录租户:{} 已超过有效期.", tenantId);
throw new TenantException("tenant.expired");
}
} }
/** /**
@ -164,7 +186,7 @@ public class SysLoginService {
if (ObjectUtil.isNull(loginUser)) { if (ObjectUtil.isNull(loginUser)) {
return; return;
} }
if (TenantHelper.isEnable() && LoginHelper.isSuperAdmin()) { if (LoginHelper.isSuperAdmin()) {
// 超级管理员 登出清除动态租户 // 超级管理员 登出清除动态租户
TenantHelper.clearDynamic(); TenantHelper.clearDynamic();
} }

View File

@ -4,6 +4,9 @@ import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import com.ruoyi.common.core.core.domain.AjaxResult; import com.ruoyi.common.core.core.domain.AjaxResult;
import com.ruoyi.common.core.core.domain.model.EmailLoginBody;
import com.ruoyi.common.json.utils.JsonUtils;
import com.ruoyi.common.tenant.helper.TenantHelper;
import com.ruoyi.system.domain.vo.SysUserVo; import com.ruoyi.system.domain.vo.SysUserVo;
import com.ruoyi.system.service.ISysUserService; import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.web.domain.vo.LoginVo; import com.ruoyi.web.domain.vo.LoginVo;
@ -43,18 +46,12 @@ public class EmailAuthStrategy implements IAuthStrategy {
@Resource @Resource
private final SysLoginService loginService; private final SysLoginService loginService;
@Resource @Resource
private ISysUserService userService; private ISysUserService userService;
// private final SysUserMapper userMapper;
@Override @Override
public void validate(LoginBody loginBody) { public LoginVo login(String body, SysClient client) {
ValidatorUtils.validate(loginBody, EmailGroup.class); EmailLoginBody loginBody = JsonUtils.parseObject(body, EmailLoginBody.class);
} ValidatorUtils.validate(loginBody);
@Override
public LoginVo login(String clientId, LoginBody loginBody, SysClient client) {
Long tenantId = loginBody.getTenantId(); Long tenantId = loginBody.getTenantId();
String email = loginBody.getEmail(); String email = loginBody.getEmail();
String emailCode = loginBody.getEmailCode(); String emailCode = loginBody.getEmailCode();
@ -65,25 +62,26 @@ public class EmailAuthStrategy implements IAuthStrategy {
loginService.checkLogin(LoginType.EMAIL, tenantId, user.getUserName(), () -> !validateEmailCode(tenantId, email, emailCode)); loginService.checkLogin(LoginType.EMAIL, tenantId, user.getUserName(), () -> !validateEmailCode(tenantId, email, emailCode));
// 此处可根据登录用户的数据不同 自行创建 loginUser 属性不够用继承扩展就行了 // 此处可根据登录用户的数据不同 自行创建 loginUser 属性不够用继承扩展就行了
LoginUser loginUser = loginService.buildLoginUser(user); LoginUser loginUser = loginService.buildLoginUser(user);
loginUser.setClientKey(client.getClientKey());
loginUser.setDeviceType(client.getDeviceType());
SaLoginModel model = new SaLoginModel(); SaLoginModel model = new SaLoginModel();
model.setDevice(client.getDeviceType()); model.setDevice(client.getDeviceType());
// 自定义分配 不同用户体系 不同 token 授权时间 不设置默认走全局 yml 配置 // 自定义分配 不同用户体系 不同 token 授权时间 不设置默认走全局 yml 配置
// 例如: 后台用户30分钟过期 app用户1天过期 // 例如: 后台用户30分钟过期 app用户1天过期
model.setTimeout(client.getTimeout()); model.setTimeout(client.getTimeout());
model.setActiveTimeout(client.getActiveTimeout()); model.setActiveTimeout(client.getActiveTimeout());
model.setExtra(LoginHelper.CLIENT_KEY, clientId); model.setExtra(LoginHelper.CLIENT_KEY, client.getClientId());
// 生成token // 生成token
LoginHelper.login(loginUser, model); LoginHelper.login(loginUser, model);
loginService.recordLogininfor(loginUser.getTenantId(), user.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")); // loginService.recordLogininfor(loginUser.getTenantId(), user.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
loginService.recordLoginInfo(user.getUserId()); // loginService.recordLoginInfo(user.getUserId());
LoginVo loginVo = new LoginVo(); LoginVo loginVo = new LoginVo();
loginVo.setAccessToken(StpUtil.getTokenValue()); loginVo.setAccessToken(StpUtil.getTokenValue());
loginVo.setExpireIn(StpUtil.getTokenTimeout()); loginVo.setExpireIn(StpUtil.getTokenTimeout());
loginVo.setClientId(clientId); loginVo.setClientId(client.getClientId());
return loginVo; return loginVo;
// return StpUtil.getTokenValue();
} }
/** /**
@ -99,10 +97,7 @@ public class EmailAuthStrategy implements IAuthStrategy {
} }
private SysUserVo loadUserByEmail(Long tenantId, String email) { private SysUserVo loadUserByEmail(Long tenantId, String email) {
// SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>() return TenantHelper.dynamic(tenantId, () -> {
// .select(SysUser::getEmail, SysUser::getStatus)
// .eq(TenantHelper.isEnable(), SysUser::getTenantId, tenantId)
// .eq(SysUser::getEmail, email));
SysUserVo user =userService.selectUserByEmail(email); SysUserVo user =userService.selectUserByEmail(email);
if (ObjectUtil.isNull(user)) { if (ObjectUtil.isNull(user)) {
log.info("登录用户:{} 不存在.", email); log.info("登录用户:{} 不存在.", email);
@ -111,10 +106,9 @@ public class EmailAuthStrategy implements IAuthStrategy {
log.info("登录用户:{} 已被停用.", email); log.info("登录用户:{} 已被停用.", email);
throw new UserException("user.blocked", email); throw new UserException("user.blocked", email);
} }
// if (TenantHelper.isEnable()) {
// return userMapper.selectTenantUserByEmail(email, tenantId);
// }
return user; return user;
});
} }
} }

View File

@ -4,14 +4,15 @@ import cn.dev33.satoken.secure.BCrypt;
import cn.dev33.satoken.stp.SaLoginModel; import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import com.ruoyi.common.core.core.domain.AjaxResult; import com.ruoyi.common.core.core.domain.model.PasswordLoginBody;
import com.ruoyi.common.json.utils.JsonUtils;
import com.ruoyi.common.tenant.helper.TenantHelper;
import com.ruoyi.system.service.ISysUserService; import com.ruoyi.system.service.ISysUserService;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import com.ruoyi.common.core.constant.Constants; import com.ruoyi.common.core.constant.Constants;
import com.ruoyi.common.core.constant.GlobalConstants; import com.ruoyi.common.core.constant.GlobalConstants;
import com.ruoyi.common.core.core.domain.model.LoginBody;
import com.ruoyi.common.core.core.domain.model.LoginUser; import com.ruoyi.common.core.core.domain.model.LoginUser;
import com.ruoyi.common.core.enums.LoginType; import com.ruoyi.common.core.enums.LoginType;
import com.ruoyi.common.core.enums.UserStatus; import com.ruoyi.common.core.enums.UserStatus;
@ -21,14 +22,11 @@ import com.ruoyi.common.core.exception.user.UserException;
import com.ruoyi.common.core.utils.MessageUtils; import com.ruoyi.common.core.utils.MessageUtils;
import com.ruoyi.common.core.utils.StringUtils; import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.ValidatorUtils; import com.ruoyi.common.core.utils.ValidatorUtils;
import com.ruoyi.common.core.validate.auth.PasswordGroup;
import com.ruoyi.common.redis.utils.RedisUtils; import com.ruoyi.common.redis.utils.RedisUtils;
import com.ruoyi.common.security.utils.LoginHelper; import com.ruoyi.common.security.utils.LoginHelper;
import com.ruoyi.common.web.config.properties.CaptchaProperties; import com.ruoyi.common.web.config.properties.CaptchaProperties;
import com.ruoyi.system.domain.SysClient; import com.ruoyi.system.domain.SysClient;
import com.ruoyi.system.domain.SysUser;
import com.ruoyi.system.domain.vo.SysUserVo; import com.ruoyi.system.domain.vo.SysUserVo;
import com.ruoyi.system.mapper.SysUserMapper;
import com.ruoyi.web.domain.vo.LoginVo; import com.ruoyi.web.domain.vo.LoginVo;
import com.ruoyi.web.service.IAuthStrategy; import com.ruoyi.web.service.IAuthStrategy;
import com.ruoyi.web.service.SysLoginService; import com.ruoyi.web.service.SysLoginService;
@ -45,18 +43,15 @@ import org.springframework.stereotype.Service;
public class PasswordAuthStrategy implements IAuthStrategy { public class PasswordAuthStrategy implements IAuthStrategy {
private final CaptchaProperties captchaProperties; private final CaptchaProperties captchaProperties;
private final SysLoginService loginService; @Resource
private SysLoginService loginService;
@Resource @Resource
private ISysUserService userService; private ISysUserService userService;
@Override @Override
public void validate(LoginBody loginBody) { public LoginVo login(String body, SysClient client) {
ValidatorUtils.validate(loginBody, PasswordGroup.class); PasswordLoginBody loginBody = JsonUtils.parseObject(body, PasswordLoginBody.class);
} ValidatorUtils.validate(loginBody);
@Override
public LoginVo login(String clientId, LoginBody loginBody, SysClient client) {
Long tenantId = loginBody.getTenantId(); Long tenantId = loginBody.getTenantId();
String username = loginBody.getUsername(); String username = loginBody.getUsername();
String password = loginBody.getPassword(); String password = loginBody.getPassword();
@ -73,13 +68,15 @@ public class PasswordAuthStrategy implements IAuthStrategy {
loginService.checkLogin(LoginType.PASSWORD, tenantId, username, () -> !BCrypt.checkpw(password, user.getPassword())); loginService.checkLogin(LoginType.PASSWORD, tenantId, username, () -> !BCrypt.checkpw(password, user.getPassword()));
// 此处可根据登录用户的数据不同 自行创建 loginUser // 此处可根据登录用户的数据不同 自行创建 loginUser
LoginUser loginUser = loginService.buildLoginUser(user); LoginUser loginUser = loginService.buildLoginUser(user);
loginUser.setClientKey(client.getClientKey());
loginUser.setDeviceType(client.getDeviceType());
SaLoginModel model = new SaLoginModel(); SaLoginModel model = new SaLoginModel();
model.setDevice(client.getDeviceType()); model.setDevice(client.getDeviceType());
// 自定义分配 不同用户体系 不同 token 授权时间 不设置默认走全局 yml 配置 // 自定义分配 不同用户体系 不同 token 授权时间 不设置默认走全局 yml 配置
// 例如: 后台用户30分钟过期 app用户1天过期 // 例如: 后台用户30分钟过期 app用户1天过期
model.setTimeout(client.getTimeout()); model.setTimeout(client.getTimeout());
model.setActiveTimeout(client.getActiveTimeout()); model.setActiveTimeout(client.getActiveTimeout());
model.setExtra(LoginHelper.CLIENT_KEY, clientId); model.setExtra(LoginHelper.CLIENT_KEY, client.getClientId());
// 生成token // 生成token
LoginHelper.login(loginUser, model); LoginHelper.login(loginUser, model);
@ -89,11 +86,9 @@ public class PasswordAuthStrategy implements IAuthStrategy {
LoginVo loginVo = new LoginVo(); LoginVo loginVo = new LoginVo();
loginVo.setAccessToken(StpUtil.getTokenValue()); loginVo.setAccessToken(StpUtil.getTokenValue());
loginVo.setExpireIn(StpUtil.getTokenTimeout()); loginVo.setExpireIn(StpUtil.getTokenTimeout());
loginVo.setClientId(clientId); loginVo.setClientId(client.getClientId());
return loginVo; return loginVo;
//return StpUtil.getTokenValue();
} }
/** /**
@ -118,8 +113,8 @@ public class PasswordAuthStrategy implements IAuthStrategy {
} }
private SysUserVo loadUserByUsername(Long tenantId, String username) { private SysUserVo loadUserByUsername(Long tenantId, String username) {
//TODO:以后根据tenantId条件过滤查询
SysUserVo user = userService.selectUserByUserName(username); SysUserVo user = userService.selectTenantUserByUserName(username,tenantId);
if (ObjectUtil.isNull(user)) { if (ObjectUtil.isNull(user)) {
log.info("登录用户:{} 不存在.", username); log.info("登录用户:{} 不存在.", username);
throw new UserException("user.not.exists", username); throw new UserException("user.not.exists", username);
@ -127,9 +122,6 @@ public class PasswordAuthStrategy implements IAuthStrategy {
log.info("登录用户:{} 已被停用.", username); log.info("登录用户:{} 已被停用.", username);
throw new UserException("user.blocked", username); throw new UserException("user.blocked", username);
} }
// if (TenantHelper.isEnable()) {
// return userMapper.selectTenantUserByUserName(username, tenantId);
// }
return user; return user;
} }

View File

@ -91,7 +91,7 @@ redisson:
--- # 监控中心客户端配置 --- # 监控中心客户端配置
spring.boot.admin.client: spring.boot.admin.client:
# 增加客户端开关 # 增加客户端开关
enabled: true enabled: false
url: http://localhost:9090/admin url: http://localhost:9090/admin
instance: instance:
service-host-type: IP service-host-type: IP
@ -102,7 +102,7 @@ spring.boot.admin.client:
powerjob: powerjob:
worker: worker:
# 如何开启调度中心请查看文档教程 # 如何开启调度中心请查看文档教程
enabled: true enabled: false
# 需要先在 powerjob 登录页执行应用注册后才能使用 # 需要先在 powerjob 登录页执行应用注册后才能使用
app-name: ruoyi-worker app-name: ruoyi-worker
# 28080 端口 随着主应用端口飘逸 避免集群冲突 # 28080 端口 随着主应用端口飘逸 避免集群冲突

View File

@ -146,7 +146,7 @@ mybatis-flex:
# 默认的逻辑删除字段 # 默认的逻辑删除字段
logic-delete-column: del_flag logic-delete-column: del_flag
# 默认的多租户字段 # 默认的多租户字段
#tenant-column: tenant_id tenant-column: tenant_id
# 默认的乐观锁字段 # 默认的乐观锁字段
version-column: version version-column: version
@ -295,11 +295,6 @@ security:
- /captcha/get - /captcha/get
- /captcha/check - /captcha/check
# 多租户配置
tenant:
# 是否开启
enable: false
--- # Actuator 监控端点的配置项 --- # Actuator 监控端点的配置项
management: management:
endpoints: endpoints:

View File

@ -29,6 +29,7 @@ user.notfound=请重新登录
user.forcelogout=管理员强制退出,请重新登录 user.forcelogout=管理员强制退出,请重新登录
user.unknown.error=未知错误,请重新登录 user.unknown.error=未知错误,请重新登录
auth.grant.type.error=认证权限类型错误 auth.grant.type.error=认证权限类型错误
auth.grant.type.blocked=认证权限类型已禁用
auth.grant.type.not.blank=认证权限类型不能为空 auth.grant.type.not.blank=认证权限类型不能为空
auth.clientid.not.blank=认证客户端id不能为空 auth.clientid.not.blank=认证客户端id不能为空
##文件上传消息 ##文件上传消息
@ -49,7 +50,10 @@ sms.code.retry.limit.exceed=短信验证码输入错误{0}次,帐户锁定{1}
email.code.not.blank=邮箱验证码不能为空 email.code.not.blank=邮箱验证码不能为空
email.code.retry.limit.count=邮箱验证码输入错误{0}次 email.code.retry.limit.count=邮箱验证码输入错误{0}次
email.code.retry.limit.exceed=邮箱验证码输入错误{0}次,帐户锁定{1}分钟 email.code.retry.limit.exceed=邮箱验证码输入错误{0}次,帐户锁定{1}分钟
xcx.code.not.blank=小程序code不能为空 xcx.code.not.blank=小程序[code]不能为空
social.source.not.blank=第三方登录平台[source]不能为空
social.code.not.blank=第三方登录平台[code]不能为空
social.state.not.blank=第三方登录平台[state]不能为空
##租户 ##租户
tenant.number.not.blank=租户编号不能为空 tenant.number.not.blank=租户编号不能为空
tenant.not.exists=对不起, 您的租户不存在,请联系管理员 tenant.not.exists=对不起, 您的租户不存在,请联系管理员

View File

@ -29,6 +29,7 @@ user.notfound=Please login again
user.forcelogout=The administrator is forced to exitplease login again user.forcelogout=The administrator is forced to exitplease login again
user.unknown.error=Unknown error, please login again user.unknown.error=Unknown error, please login again
auth.grant.type.error=Auth grant type error auth.grant.type.error=Auth grant type error
auth.grant.type.blocked=Auth grant type disabled
auth.grant.type.not.blank=Auth grant type cannot be blank auth.grant.type.not.blank=Auth grant type cannot be blank
auth.clientid.not.blank=Auth clientid cannot be blank auth.clientid.not.blank=Auth clientid cannot be blank
##文件上传消息 ##文件上传消息
@ -49,7 +50,10 @@ sms.code.retry.limit.exceed=Sms code input error {0} times, account locked for {
email.code.not.blank=Email code cannot be blank email.code.not.blank=Email code cannot be blank
email.code.retry.limit.count=Email code input error {0} times email.code.retry.limit.count=Email code input error {0} times
email.code.retry.limit.exceed=Email code input error {0} times, account locked for {1} minutes email.code.retry.limit.exceed=Email code input error {0} times, account locked for {1} minutes
xcx.code.not.blank=Mini program code cannot be blank xcx.code.not.blank=Mini program [code] cannot be blank
social.source.not.blank=Social login platform [source] cannot be blank
social.code.not.blank=Social login platform [code] cannot be blank
social.state.not.blank=Social login platform [state] cannot be blank
##租户 ##租户
tenant.number.not.blank=Tenant number cannot be blank tenant.number.not.blank=Tenant number cannot be blank
tenant.not.exists=Sorry, your tenant does not exist. Please contact the administrator tenant.not.exists=Sorry, your tenant does not exist. Please contact the administrator

View File

@ -29,6 +29,7 @@ user.notfound=请重新登录
user.forcelogout=管理员强制退出,请重新登录 user.forcelogout=管理员强制退出,请重新登录
user.unknown.error=未知错误,请重新登录 user.unknown.error=未知错误,请重新登录
auth.grant.type.error=认证权限类型错误 auth.grant.type.error=认证权限类型错误
auth.grant.type.blocked=认证权限类型已禁用
auth.grant.type.not.blank=认证权限类型不能为空 auth.grant.type.not.blank=认证权限类型不能为空
auth.clientid.not.blank=认证客户端id不能为空 auth.clientid.not.blank=认证客户端id不能为空
##文件上传消息 ##文件上传消息
@ -49,7 +50,10 @@ sms.code.retry.limit.exceed=短信验证码输入错误{0}次,帐户锁定{1}
email.code.not.blank=邮箱验证码不能为空 email.code.not.blank=邮箱验证码不能为空
email.code.retry.limit.count=邮箱验证码输入错误{0}次 email.code.retry.limit.count=邮箱验证码输入错误{0}次
email.code.retry.limit.exceed=邮箱验证码输入错误{0}次,帐户锁定{1}分钟 email.code.retry.limit.exceed=邮箱验证码输入错误{0}次,帐户锁定{1}分钟
xcx.code.not.blank=小程序code不能为空 xcx.code.not.blank=小程序[code]不能为空
social.source.not.blank=第三方登录平台[source]不能为空
social.code.not.blank=第三方登录平台[code]不能为空
social.state.not.blank=第三方登录平台[state]不能为空
##租户 ##租户
tenant.number.not.blank=租户编号不能为空 tenant.number.not.blank=租户编号不能为空
tenant.not.exists=对不起, 您的租户不存在,请联系管理员 tenant.not.exists=对不起, 您的租户不存在,请联系管理员

View File

@ -80,68 +80,14 @@ public class Constants
public static final String TOKEN = "token"; public static final String TOKEN = "token";
/** /**
* 令牌前缀 * 顶级部门id
*/ */
public static final String TOKEN_PREFIX = "Bearer "; public static final Long TOP_PARENT_ID = 0L;
/**
* 令牌前缀
*/
public static final String LOGIN_USER_KEY = "login_user_key";
/**
* 用户ID
*/
public static final String JWT_USERID = "userid";
/**
* 用户名称
*/
public static final String JWT_USERNAME = Claims.SUBJECT;
/**
* 用户头像
*/
public static final String JWT_AVATAR = "avatar";
/**
* 创建时间
*/
public static final String JWT_CREATED = "created";
/**
* 用户权限
*/
public static final String JWT_AUTHORITIES = "authorities";
/** /**
* 资源映射路径 前缀 * 资源映射路径 前缀
*/ */
public static final String RESOURCE_PREFIX = "/profile"; public static final String RESOURCE_PREFIX = "/profile";
/**
* RMI 远程方法调用
*/
public static final String LOOKUP_RMI = "rmi:";
/**
* LDAP 远程方法调用
*/
public static final String LOOKUP_LDAP = "ldap:";
/**
* LDAPS 远程方法调用
*/
public static final String LOOKUP_LDAPS = "ldaps:";
/**
* 定时任务白名单配置仅允许访问的包名如其他需要可以自行添加
*/
public static final String[] JOB_WHITELIST_STR = { "com.ruoyi" };
/**
* 定时任务违规的字符
*/
public static final String[] JOB_ERROR_STR = { "java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml",
"org.springframework", "org.apache", "com.ruoyi.common.utils.file", "com.ruoyi.common.config" };
} }

View File

@ -5,44 +5,67 @@ package com.ruoyi.common.core.constant;
* *
* @author ruoyi * @author ruoyi
*/ */
public class GenConstants public class GenConstants {
{ /**
/** 单表(增删改查) */ * 单表增删改查
*/
public static final String TPL_CRUD = "crud"; public static final String TPL_CRUD = "crud";
/** 树表(增删改查) */ /**
* 树表增删改查
*/
public static final String TPL_TREE = "tree"; public static final String TPL_TREE = "tree";
/** 主子表(增删改查) */ /**
* 主子表增删改查
*/
public static final String TPL_SUB = "sub"; public static final String TPL_SUB = "sub";
/** 树编码字段 */ /**
* 树编码字段
*/
public static final String TREE_CODE = "treeCode"; public static final String TREE_CODE = "treeCode";
/** 树父编码字段 */ /**
* 树父编码字段
*/
public static final String TREE_PARENT_CODE = "treeParentCode"; public static final String TREE_PARENT_CODE = "treeParentCode";
/** 树名称字段 */ /**
* 树名称字段
*/
public static final String TREE_NAME = "treeName"; public static final String TREE_NAME = "treeName";
/** 上级菜单ID字段 */ /**
* 上级菜单ID字段
*/
public static final String PARENT_MENU_ID = "parentMenuId"; public static final String PARENT_MENU_ID = "parentMenuId";
/** 上级菜单名称字段 */ /**
* 上级菜单名称字段
*/
public static final String PARENT_MENU_NAME = "parentMenuName"; public static final String PARENT_MENU_NAME = "parentMenuName";
/** 数据库字符串类型 */ /**
public static final String[] COLUMNTYPE_STR = { "char", "varchar", "nvarchar", "varchar2","character","character varying" }; * 数据库字符串类型
*/
public static final String[] COLUMNTYPE_STR = {"char", "varchar", "nvarchar", "enum", "set", "nchar", "nvarchar", "varchar2", "nvarchar2", "character", "character varying"};
/** 数据库文本类型 */ /**
* 数据库文本类型
*/
public static final String[] COLUMNTYPE_TEXT = {"tinytext", "text", "mediumtext", "longtext", "binary", "varbinary", "blob", public static final String[] COLUMNTYPE_TEXT = {"tinytext", "text", "mediumtext", "longtext", "binary", "varbinary", "blob",
"ntext", "image", "bytea"}; "ntext", "image", "bytea"};
/** 数据库时间类型 */ /**
* 数据库时间类型
*/
public static final String[] COLUMNTYPE_TIME = {"datetime", "time", "date", "timestamp", "timestamp without time zone", "year", "interval", public static final String[] COLUMNTYPE_TIME = {"datetime", "time", "date", "timestamp", "timestamp without time zone", "year", "interval",
"smalldatetime", "datetime2", "datetimeoffset"}; "smalldatetime", "datetime2", "datetimeoffset"};
/** 数据库数字类型 */ /**
* 数据库数字类型
*/
public static final String[] COLUMNTYPE_NUMBER = {"tinyint", "smallint", "mediumint", "int", "number", "integer", public static final String[] COLUMNTYPE_NUMBER = {"tinyint", "smallint", "mediumint", "int", "number", "integer",
"bit", "bigint", "float", "double", "decimal", "numeric", "real", "double precision", "bit", "bigint", "float", "double", "decimal", "numeric", "real", "double precision",
"smallserial", "serial", "bigserial", "money", "smallmoney"}; "smallserial", "serial", "bigserial", "money", "smallmoney"};
@ -50,75 +73,120 @@ public class GenConstants
/** /**
* BO对象 不需要添加字段 * BO对象 不需要添加字段
*/ */
public static final String[] COLUMNNAME_NOT_ADD = {"create_by", "create_time", "update_by", "update_time" }; public static final String[] COLUMNNAME_NOT_ADD = {"tenant_id", "version", "del_flag", "create_by", "create_time", "update_by", "update_time"};
/** BO对象 不需要编辑字段 */ /**
public static final String[] COLUMNNAME_NOT_EDIT = { "create_by", "create_time", "update_by", "update_time" }; * BO对象 不需要编辑字段
*/
public static final String[] COLUMNNAME_NOT_EDIT = {"tenant_id", "version", "del_flag", "create_by", "create_time", "update_by", "update_time"};
/** VO对象 不需要显示的列表字段 */ /**
public static final String[] COLUMNNAME_NOT_LIST = { "create_by", "create_time", "update_by", "update_time" }; * VO对象 不需要显示的列表字段
*/
public static final String[] COLUMNNAME_NOT_LIST = {"tenant_id", "version", "del_flag", "create_by", "create_time", "update_by", "update_time"};
/** BO对象 不需要查询字段 */ /**
public static final String[] COLUMNNAME_NOT_QUERY = { "create_by", "create_time", "update_by", * BO对象 不需要查询字段
"update_time", "del_flag", "remark", "version" }; */
public static final String[] COLUMNNAME_NOT_QUERY = {"tenant_id", "version", "del_flag", "create_by", "create_time", "update_by", "update_time", "remark", "id"};
/** Entity基类字段 */ /**
public static final String[] BASE_ENTITY = { "createBy", "createTime", "updateBy", "updateTime"}; * Entity基类字段
*/
public static final String[] BASE_ENTITY = {"tenant_id", "createBy", "createTime", "updateBy", "updateTime"};
/** Tree基类字段 */ /**
* Tree基类字段
*/
public static final String[] TREE_ENTITY = {"parentName", "parentId", "orderNum", "ancestors", "children"}; public static final String[] TREE_ENTITY = {"parentName", "parentId", "orderNum", "ancestors", "children"};
/** 文本框 */ /**
* 文本框
*/
public static final String HTML_INPUT = "input"; public static final String HTML_INPUT = "input";
/** 文本域 */ /**
* 文本域
*/
public static final String HTML_TEXTAREA = "textarea"; public static final String HTML_TEXTAREA = "textarea";
/** 下拉框 */ /**
* 下拉框
*/
public static final String HTML_SELECT = "select"; public static final String HTML_SELECT = "select";
/** 单选框 */ /**
* 单选框
*/
public static final String HTML_RADIO = "radio"; public static final String HTML_RADIO = "radio";
/** 复选框 */ /**
* 复选框
*/
public static final String HTML_CHECKBOX = "checkbox"; public static final String HTML_CHECKBOX = "checkbox";
/** 日期控件 */ /**
* 日期控件
*/
public static final String HTML_DATETIME = "datetime"; public static final String HTML_DATETIME = "datetime";
/** 图片上传控件 */ /**
* 图片上传控件
*/
public static final String HTML_IMAGE_UPLOAD = "imageUpload"; public static final String HTML_IMAGE_UPLOAD = "imageUpload";
/** 文件上传控件 */ /**
* 文件上传控件
*/
public static final String HTML_FILE_UPLOAD = "fileUpload"; public static final String HTML_FILE_UPLOAD = "fileUpload";
/** 富文本控件 */ /**
* 富文本控件
*/
public static final String HTML_EDITOR = "editor"; public static final String HTML_EDITOR = "editor";
/** 字符串类型 */ /**
* 字符串类型
*/
public static final String TYPE_STRING = "String"; public static final String TYPE_STRING = "String";
/** 整型 */ /**
* 整型
*/
public static final String TYPE_INTEGER = "Integer"; public static final String TYPE_INTEGER = "Integer";
/** 长整型 */ /**
* 长整型
*/
public static final String TYPE_LONG = "Long"; public static final String TYPE_LONG = "Long";
/** 浮点型 */ /**
* 浮点型
*/
public static final String TYPE_DOUBLE = "Double"; public static final String TYPE_DOUBLE = "Double";
/** 高精度计算类型 */ /**
* 高精度计算类型
*/
public static final String TYPE_BIGDECIMAL = "BigDecimal"; public static final String TYPE_BIGDECIMAL = "BigDecimal";
/** 时间类型 */ /**
* 时间类型
*/
public static final String TYPE_DATE = "Date"; public static final String TYPE_DATE = "Date";
/** 模糊查询 */ /**
* 模糊查询
*/
public static final String QUERY_LIKE = "LIKE"; public static final String QUERY_LIKE = "LIKE";
/** 相等查询 */ /**
* 相等查询
*/
public static final String QUERY_EQ = "EQ"; public static final String QUERY_EQ = "EQ";
/** 需要 */ /**
* 需要
*/
public static final String REQUIRE = "1"; public static final String REQUIRE = "1";
} }

View File

@ -4,6 +4,7 @@ package com.ruoyi.common.core.constant;
* 租户常量信息 * 租户常量信息
* *
* @author Lion Li * @author Lion Li
* @author 数据小王子
*/ */
public interface TenantConstants { public interface TenantConstants {
@ -25,21 +26,21 @@ public interface TenantConstants {
/** /**
* 超级管理员角色 roleKey * 超级管理员角色 roleKey
*/ */
String SUPER_ADMIN_ROLE_KEY = "superadmin"; String SUPER_ADMIN_ROLE_KEY = "SuperAminRole";
/** /**
* 租户管理员角色 roleKey * 租户管理员角色 roleKey
*/ */
String TENANT_ADMIN_ROLE_KEY = "admin"; String TENANT_ADMIN_ROLE_KEY = "AdminRole";
/** /**
* 租户管理员角色名称 * 租户管理员角色名称
*/ */
String TENANT_ADMIN_ROLE_NAME = "管理员"; String TENANT_ADMIN_ROLE_NAME = "管理员角色";
/** /**
* 默认租户ID * 默认租户ID
*/ */
String DEFAULT_TENANT_ID = "000000"; Long DEFAULT_TENANT_ID = 0L;
} }

View File

@ -11,13 +11,7 @@ import lombok.Data;
*/ */
@Data @Data
public class EmailLoginBody { public class EmailLoginBody extends LoginBody {
/**
* 租户ID
*/
@NotBlank(message = "{tenant.number.not.blank}")
private String tenantId;
/** /**
* 邮箱 * 邮箱

View File

@ -111,6 +111,16 @@ public class LoginUser
*/ */
private Long roleId; private Long roleId;
/**
* 客户端
*/
private String clientKey;
/**
* 设备类型
*/
private String deviceType;
/** /**
* 获取登录id * 获取登录id
*/ */

View File

@ -0,0 +1,33 @@
package com.ruoyi.common.core.core.domain.model;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.hibernate.validator.constraints.Length;
import static com.ruoyi.common.core.constant.UserConstants.*;
/**
* 密码登录对象
*
* @author Lion Li
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class PasswordLoginBody extends LoginBody {
/**
* 用户名
*/
@NotBlank(message = "{user.username.not.blank}")
@Length(min = USERNAME_MIN_LENGTH, max = USERNAME_MAX_LENGTH, message = "{user.username.length.valid}")
private String username;
/**
* 用户密码
*/
@NotBlank(message = "{user.password.not.blank}")
@Length(min = PASSWORD_MIN_LENGTH, max = PASSWORD_MAX_LENGTH, message = "{user.password.length.valid}")
private String password;
}

View File

@ -1,11 +1,9 @@
package com.ruoyi.common.orm.config; package com.ruoyi.common.orm.config;
import com.mybatisflex.annotation.KeyType;
import com.mybatisflex.core.FlexGlobalConfig; import com.mybatisflex.core.FlexGlobalConfig;
import com.mybatisflex.core.audit.AuditManager; import com.mybatisflex.core.audit.AuditManager;
import com.mybatisflex.core.audit.ConsoleMessageCollector; import com.mybatisflex.core.audit.ConsoleMessageCollector;
import com.mybatisflex.core.datasource.DataSourceDecipher; import com.mybatisflex.core.datasource.DataSourceDecipher;
import com.mybatisflex.core.keygen.KeyGenerators;
import com.mybatisflex.core.mybatis.FlexConfiguration; import com.mybatisflex.core.mybatis.FlexConfiguration;
import com.mybatisflex.spring.boot.ConfigurationCustomizer; import com.mybatisflex.spring.boot.ConfigurationCustomizer;
import com.mybatisflex.spring.boot.MyBatisFlexCustomizer; import com.mybatisflex.spring.boot.MyBatisFlexCustomizer;

View File

@ -24,11 +24,10 @@ public class BaseEntity implements Serializable {
@Serial @Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
// /** /**
// * 租户编号 * 租户编号
// */ */
// @Column(ignore = true) private Long tenantId;
// private Long tenantId;
/** /**
* 搜索值 * 搜索值
@ -37,12 +36,6 @@ public class BaseEntity implements Serializable {
@Column(ignore = true) @Column(ignore = true)
private String searchValue; private String searchValue;
/**
* 创建部门
*/
@Column(ignore = true)
private Long createDept;
/** /**
* 创建者 * 创建者
*/ */

View File

@ -58,7 +58,6 @@ public class LoginHelper {
model.setExtra(TENANT_KEY, loginUser.getTenantId()) model.setExtra(TENANT_KEY, loginUser.getTenantId())
.setExtra(USER_KEY, loginUser.getUserId()) .setExtra(USER_KEY, loginUser.getUserId())
.setExtra(DEPT_KEY, loginUser.getDeptId())); .setExtra(DEPT_KEY, loginUser.getDeptId()));
//StpUtil.getSession().set(LOGIN_USER_KEY, loginUser);
StpUtil.getTokenSession().set(LOGIN_USER_KEY, loginUser); StpUtil.getTokenSession().set(LOGIN_USER_KEY, loginUser);
} }

View File

@ -11,13 +11,10 @@ import com.ruoyi.common.tenant.core.TenantSaTokenDao;
import com.ruoyi.common.tenant.handle.MyTenantFactory; import com.ruoyi.common.tenant.handle.MyTenantFactory;
import com.ruoyi.common.tenant.handle.TenantKeyPrefixHandler; import com.ruoyi.common.tenant.handle.TenantKeyPrefixHandler;
import com.ruoyi.common.tenant.manager.TenantSpringCacheManager; import com.ruoyi.common.tenant.manager.TenantSpringCacheManager;
import com.ruoyi.common.tenant.properties.TenantProperties;
import org.redisson.config.ClusterServersConfig; import org.redisson.config.ClusterServersConfig;
import org.redisson.config.SingleServerConfig; import org.redisson.config.SingleServerConfig;
import org.redisson.spring.starter.RedissonAutoConfigurationCustomizer; import org.redisson.spring.starter.RedissonAutoConfigurationCustomizer;
import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.CacheManager; import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary; import org.springframework.context.annotation.Primary;
@ -28,12 +25,9 @@ import org.springframework.context.annotation.Primary;
* @author Lion Li * @author Lion Li
* @author 数据小王子 * @author 数据小王子
*/ */
@EnableConfigurationProperties(TenantProperties.class)
@AutoConfiguration(after = {RedisConfig.class, MyBatisFlexConfig.class}) @AutoConfiguration(after = {RedisConfig.class, MyBatisFlexConfig.class})
@ConditionalOnProperty(value = "tenant.enable", havingValue = "true")
public class TenantConfig { public class TenantConfig {
/** /**
* 多租户工厂用于获取当前租户ID * 多租户工厂用于获取当前租户ID
*/ */

View File

@ -2,7 +2,6 @@ package com.ruoyi.common.tenant.helper;
import cn.dev33.satoken.context.SaHolder; import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.spring.SpringMVCUtil; import cn.dev33.satoken.spring.SpringMVCUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import com.alibaba.ttl.TransmittableThreadLocal; import com.alibaba.ttl.TransmittableThreadLocal;
import com.mybatisflex.core.tenant.TenantManager; import com.mybatisflex.core.tenant.TenantManager;
@ -10,8 +9,6 @@ import lombok.AccessLevel;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import com.ruoyi.common.core.constant.GlobalConstants; import com.ruoyi.common.core.constant.GlobalConstants;
import com.ruoyi.common.core.utils.SpringUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.redis.utils.RedisUtils; import com.ruoyi.common.redis.utils.RedisUtils;
import com.ruoyi.common.security.utils.LoginHelper; import com.ruoyi.common.security.utils.LoginHelper;
@ -31,13 +28,6 @@ public class TenantHelper {
private static final ThreadLocal<Long> TEMP_DYNAMIC_TENANT = new TransmittableThreadLocal<>(); private static final ThreadLocal<Long> TEMP_DYNAMIC_TENANT = new TransmittableThreadLocal<>();
/**
* 租户功能是否启用
*/
public static boolean isEnable() {
return Convert.toBool(SpringUtils.getProperty("tenant.enable"), false);
}
/** /**
* 开启忽略租户(开启后需手动调用 {@link #disableIgnore()} 关闭) * 开启忽略租户(开启后需手动调用 {@link #disableIgnore()} 关闭)
*/ */
@ -109,7 +99,6 @@ public class TenantHelper {
if (ObjectUtil.isNotNull(tenantId)) { if (ObjectUtil.isNotNull(tenantId)) {
return tenantId; return tenantId;
} }
System.out.println("####################RedisUtils.getCacheObject("+cacheKey+")="+RedisUtils.getCacheObject(cacheKey));
if (ObjectUtil.isNotNull(RedisUtils.getCacheObject(cacheKey))) { if (ObjectUtil.isNotNull(RedisUtils.getCacheObject(cacheKey))) {
tenantId = Long.valueOf(RedisUtils.getCacheObject(cacheKey)); tenantId = Long.valueOf(RedisUtils.getCacheObject(cacheKey));
} }
@ -164,9 +153,6 @@ public class TenantHelper {
* 获取当前租户id(动态租户优先) * 获取当前租户id(动态租户优先)
*/ */
public static Long getTenantId() { public static Long getTenantId() {
if (!isEnable()) {
return null;
}
Long tenantId = TenantHelper.getDynamic(); Long tenantId = TenantHelper.getDynamic();
if (ObjectUtil.isNull(tenantId)) { if (ObjectUtil.isNull(tenantId)) {
tenantId = LoginHelper.getTenantId(); tenantId = LoginHelper.getTenantId();

View File

@ -1,22 +0,0 @@
package com.ruoyi.common.tenant.properties;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.List;
/**
* 租户 配置属性
*
* @author Lion Li
*/
@Data
@ConfigurationProperties(prefix = "tenant")
public class TenantProperties {
/**
* 是否启用
*/
private Boolean enable;
}

View File

@ -1,18 +1,22 @@
package com.ruoyi.generator.domain; package com.ruoyi.generator.domain;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.mybatisflex.annotation.Column; import com.mybatisflex.annotation.Column;
import com.mybatisflex.annotation.Id; import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.Table; import com.mybatisflex.annotation.Table;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode;
import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.ArrayUtils;
import com.ruoyi.common.core.constant.GenConstants; import com.ruoyi.common.core.constant.GenConstants;
import com.ruoyi.common.orm.core.domain.BaseEntity;
import com.ruoyi.common.core.utils.StringUtils; import com.ruoyi.common.core.utils.StringUtils;
/** /**
@ -22,9 +26,8 @@ import com.ruoyi.common.core.utils.StringUtils;
* @author 数据小王子 * @author 数据小王子
*/ */
@Data @Data
@EqualsAndHashCode(callSuper = true)
@Table(value = "gen_table") @Table(value = "gen_table")
public class GenTable extends BaseEntity public class GenTable implements Serializable
{ {
@Serial @Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@ -119,9 +122,38 @@ public class GenTable extends BaseEntity
@Column(ignore = true) @Column(ignore = true)
private String parentMenuName; private String parentMenuName;
/**
* 创建者
*/
private Long createBy;
/**
* 创建时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/**
* 更新者
*/
private Long updateBy;
/**
* 更新时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
/** 备注 */ /** 备注 */
private String remark; private String remark;
/**
* 请求参数
*/
@JsonInclude(JsonInclude.Include.NON_EMPTY)
@Column(ignore = true)
private Map<String, Object> params = new HashMap<>();
public boolean isSub() public boolean isSub()
{ {
return isSub(this.tplCategory); return isSub(this.tplCategory);

View File

@ -1,14 +1,15 @@
package com.ruoyi.generator.domain; package com.ruoyi.generator.domain;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.mybatisflex.annotation.Id; import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.Table; import com.mybatisflex.annotation.Table;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import com.ruoyi.common.orm.core.domain.BaseEntity;
import com.ruoyi.common.core.utils.StringUtils; import com.ruoyi.common.core.utils.StringUtils;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/** /**
* 代码生成业务字段表 gen_table_column * 代码生成业务字段表 gen_table_column
@ -17,9 +18,8 @@ import java.io.Serial;
* @author 数据小王子 * @author 数据小王子
*/ */
@Data @Data
@EqualsAndHashCode(callSuper = true)
@Table(value = "gen_table_column") @Table(value = "gen_table_column")
public class GenTableColumn extends BaseEntity public class GenTableColumn implements Serializable
{ {
@Serial @Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@ -80,6 +80,28 @@ public class GenTableColumn extends BaseEntity
/** 排序 */ /** 排序 */
private Integer sort; private Integer sort;
/**
* 创建者
*/
private Long createBy;
/**
* 创建时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/**
* 更新者
*/
private Long updateBy;
/**
* 更新时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
public String getCapJavaField() public String getCapJavaField()
{ {
return StringUtils.capitalize(javaField); return StringUtils.capitalize(javaField);

View File

@ -1,9 +1,11 @@
package com.ruoyi.generator.service; package com.ruoyi.generator.service;
import java.util.Date;
import java.util.List; import java.util.List;
import com.mybatisflex.core.query.QueryWrapper; import com.mybatisflex.core.query.QueryWrapper;
import com.ruoyi.common.orm.core.service.impl.BaseServiceImpl; import com.ruoyi.common.orm.core.service.impl.BaseServiceImpl;
import com.ruoyi.common.security.utils.LoginHelper;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.ruoyi.common.core.core.text.Convert; import com.ruoyi.common.core.core.text.Convert;
@ -54,7 +56,13 @@ public class GenTableColumnServiceImpl extends BaseServiceImpl<GenTableColumnMap
@Override @Override
public int insertGenTableColumn(GenTableColumn genTableColumn) public int insertGenTableColumn(GenTableColumn genTableColumn)
{ {
//return genTableColumnMapper.insertGenTableColumn(genTableColumn); Long loginUserId = LoginHelper.getUserId();
Date createTime = new Date();
genTableColumn.setCreateBy(loginUserId);
genTableColumn.setCreateTime(createTime);
genTableColumn.setUpdateBy(loginUserId);
genTableColumn.setUpdateTime(createTime);
return genTableColumnMapper.insertSelective(genTableColumn); return genTableColumnMapper.insertSelective(genTableColumn);
} }
@ -67,6 +75,11 @@ public class GenTableColumnServiceImpl extends BaseServiceImpl<GenTableColumnMap
@Override @Override
public int updateGenTableColumn(GenTableColumn genTableColumn) public int updateGenTableColumn(GenTableColumn genTableColumn)
{ {
Long loginUserId = LoginHelper.getUserId();
Date createTime = new Date();
genTableColumn.setUpdateBy(loginUserId);
genTableColumn.setUpdateTime(createTime);
return genTableColumnMapper.update(genTableColumn); return genTableColumnMapper.update(genTableColumn);
} }

View File

@ -16,6 +16,7 @@ import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.orm.core.page.PageQuery; import com.ruoyi.common.orm.core.page.PageQuery;
import com.ruoyi.common.orm.core.page.TableDataInfo; import com.ruoyi.common.orm.core.page.TableDataInfo;
import com.ruoyi.common.orm.core.service.impl.BaseServiceImpl; import com.ruoyi.common.orm.core.service.impl.BaseServiceImpl;
import com.ruoyi.common.security.utils.LoginHelper;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
@ -170,11 +171,19 @@ public class GenTableServiceImpl extends BaseServiceImpl<GenTableMapper, GenTabl
{ {
String options = JSON.toJSONString(genTable.getParams()); String options = JSON.toJSONString(genTable.getParams());
genTable.setOptions(options); genTable.setOptions(options);
Long loginUserId = LoginHelper.getUserId();
Date createTime = new Date();
genTable.setUpdateBy(loginUserId);
genTable.setUpdateTime(createTime);
boolean updated = this.updateById(genTable); boolean updated = this.updateById(genTable);
if (updated) if (updated)
{ {
for (GenTableColumn genTableColumn : genTable.getColumns()) for (GenTableColumn genTableColumn : genTable.getColumns())
{ {
genTableColumn.setUpdateBy(loginUserId);
genTableColumn.setUpdateTime(createTime);
genTableColumnMapper.update(genTableColumn); genTableColumnMapper.update(genTableColumn);
} }
} }
@ -209,6 +218,15 @@ public class GenTableServiceImpl extends BaseServiceImpl<GenTableMapper, GenTabl
{ {
String tableName = table.getTableName(); String tableName = table.getTableName();
GenUtils.initTable(table); GenUtils.initTable(table);
Long loginUserId = LoginHelper.getUserId();
Date createTime = new Date();
table.setCreateBy(loginUserId);
table.setCreateTime(createTime);
table.setUpdateBy(loginUserId);
table.setUpdateTime(createTime);
boolean saved = this.save(table); boolean saved = this.save(table);
if (saved) if (saved)
{ {
@ -217,6 +235,10 @@ public class GenTableServiceImpl extends BaseServiceImpl<GenTableMapper, GenTabl
for (GenTableColumn column : genTableColumns) for (GenTableColumn column : genTableColumns)
{ {
GenUtils.initColumnField(column, table); GenUtils.initColumnField(column, table);
column.setCreateBy(loginUserId);
column.setCreateTime(createTime);
column.setUpdateBy(loginUserId);
column.setUpdateTime(createTime);
genTableColumnMapper.insertSelective(column); genTableColumnMapper.insertSelective(column);
} }
} }
@ -337,6 +359,9 @@ public class GenTableServiceImpl extends BaseServiceImpl<GenTableMapper, GenTabl
@Transactional @Transactional
public void synchDb(String tableName) public void synchDb(String tableName)
{ {
Long loginUserId = LoginHelper.getUserId();
Date createTime = new Date();
GenTable table = genTableMapper.selectGenTableByName(tableName); GenTable table = genTableMapper.selectGenTableByName(tableName);
List<GenTableColumn> tableColumns = table.getColumns(); List<GenTableColumn> tableColumns = table.getColumns();
Map<String, GenTableColumn> tableColumnMap = tableColumns.stream().collect(Collectors.toMap(GenTableColumn::getColumnName, Function.identity())); Map<String, GenTableColumn> tableColumnMap = tableColumns.stream().collect(Collectors.toMap(GenTableColumn::getColumnName, Function.identity()));
@ -368,10 +393,17 @@ public class GenTableServiceImpl extends BaseServiceImpl<GenTableMapper, GenTabl
column.setIsRequired(prevColumn.getIsRequired()); column.setIsRequired(prevColumn.getIsRequired());
column.setHtmlType(prevColumn.getHtmlType()); column.setHtmlType(prevColumn.getHtmlType());
} }
column.setUpdateBy(loginUserId);
column.setUpdateTime(createTime);
genTableColumnMapper.update(column); genTableColumnMapper.update(column);
} }
else else
{ {
column.setCreateBy(loginUserId);
column.setCreateTime(createTime);
column.setUpdateBy(loginUserId);
column.setUpdateTime(createTime);
genTableColumnMapper.insertSelective(column); genTableColumnMapper.insertSelective(column);
} }
}); });

View File

@ -3,7 +3,9 @@ package com.ruoyi.system.controller.system;
import java.util.List; import java.util.List;
import cn.dev33.satoken.annotation.SaCheckPermission; import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaCheckRole;
import cn.hutool.core.lang.tree.Tree; import cn.hutool.core.lang.tree.Tree;
import com.ruoyi.common.core.constant.TenantConstants;
import com.ruoyi.common.core.core.domain.R; import com.ruoyi.common.core.core.domain.R;
import com.ruoyi.common.log.annotation.Log; import com.ruoyi.common.log.annotation.Log;
import com.ruoyi.common.log.enums.BusinessType; import com.ruoyi.common.log.enums.BusinessType;
@ -100,6 +102,22 @@ public class SysMenuController extends BaseController
return R.ok(selectVo); return R.ok(selectVo);
} }
/**
* 加载对应租户套餐菜单列表树
*
* @param packageId 租户套餐ID
*/
@SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
@SaCheckPermission("system:menu:query")
@GetMapping(value = "/tenantPackageMenuTreeselect/{packageId}")
public R<MenuTreeSelectVo> tenantPackageMenuTreeselect(@PathVariable("packageId") Long packageId) {
List<SysMenuVo> menus = menuService.selectMenuList(LoginHelper.getUserId());
MenuTreeSelectVo selectVo = new MenuTreeSelectVo();
selectVo.setCheckedKeys(menuService.selectMenuListByPackageId(packageId));
selectVo.setMenus(menuService.buildMenuTreeSelect(menus));
return R.ok(selectVo);
}
/** /**
* 新增菜单 * 新增菜单
*/ */

View File

@ -117,7 +117,7 @@ public class SysUserController extends BaseController {
public R<UserInfoVo> getInfo() { public R<UserInfoVo> getInfo() {
UserInfoVo userInfoVo = new UserInfoVo(); UserInfoVo userInfoVo = new UserInfoVo();
LoginUser loginUser = LoginHelper.getLoginUser(); LoginUser loginUser = LoginHelper.getLoginUser();
if (TenantHelper.isEnable() && LoginHelper.isSuperAdmin()) { if (LoginHelper.isSuperAdmin()) {
// 超级管理员 如果重新加载用户信息需清除动态租户 // 超级管理员 如果重新加载用户信息需清除动态租户
TenantHelper.clearDynamic(); TenantHelper.clearDynamic();
} }

View File

@ -1,5 +1,6 @@
package com.ruoyi.system.domain; package com.ruoyi.system.domain;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.mybatisflex.annotation.Id; import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.Table; import com.mybatisflex.annotation.Table;
import com.ruoyi.common.orm.core.domain.BaseEntity; import com.ruoyi.common.orm.core.domain.BaseEntity;
@ -7,6 +8,8 @@ import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/** /**
* 授权管理对象 sys_client * 授权管理对象 sys_client
@ -14,9 +17,8 @@ import java.io.Serial;
* @author dataprince数据小王子 * @author dataprince数据小王子
*/ */
@Data @Data
@EqualsAndHashCode(callSuper = true)
@Table(value = "sys_client") @Table(value = "sys_client")
public class SysClient extends BaseEntity { public class SysClient implements Serializable {
@Serial @Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@ -72,5 +74,25 @@ public class SysClient extends BaseEntity {
*/ */
private Integer delFlag; private Integer delFlag;
/**
* 创建者
*/
private Long createBy;
/**
* 创建时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/**
* 更新者
*/
private Long updateBy;
/**
* 更新时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
} }

View File

@ -1,6 +1,5 @@
package com.ruoyi.system.domain; package com.ruoyi.system.domain;
import com.mybatisflex.annotation.Column;
import com.mybatisflex.annotation.Id; import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.Table; import com.mybatisflex.annotation.Table;
import lombok.Data; import lombok.Data;
@ -23,12 +22,6 @@ public class SysConfig extends BaseEntity
@Id @Id
private Long configId; private Long configId;
/**
* 租户编号
*/
@Column(tenantId = true)
private Long tenantId;
/** 参数名称 */ /** 参数名称 */
private String configName; private String configName;

View File

@ -38,7 +38,7 @@ public class SysDept extends BaseEntity
private String orderNum; private String orderNum;
/** 负责人 */ /** 负责人 */
private String leader;//TODO:修改为Long类型? private String leader;
/** 联系电话 */ /** 联系电话 */
private String phone; private String phone;

View File

@ -7,6 +7,7 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import com.mybatisflex.annotation.Column;
import com.mybatisflex.annotation.Id; import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.Table; import com.mybatisflex.annotation.Table;
import lombok.Data; import lombok.Data;
@ -27,10 +28,24 @@ public class SysLogininfor implements Serializable
@Id @Id
private Long infoId; private Long infoId;
/**
* 租户编号
*/
private Long tenantId;
/** 用户账号 */ /** 用户账号 */
//@Excel(name = "用户账号")
private String userName; private String userName;
/**
* 客户端
*/
private String clientKey;
/**
* 设备类型
*/
private String deviceType;
/** 登录状态 0成功 1失败 */ /** 登录状态 0成功 1失败 */
private String status; private String status;

View File

@ -1,8 +1,12 @@
package com.ruoyi.system.domain; package com.ruoyi.system.domain;
import java.io.Serial;
import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date;
import java.util.List; import java.util.List;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.mybatisflex.annotation.Column; import com.mybatisflex.annotation.Column;
import com.mybatisflex.annotation.Id; import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.KeyType; import com.mybatisflex.annotation.KeyType;
@ -20,11 +24,11 @@ import com.ruoyi.common.orm.core.domain.BaseEntity;
* @author ruoyi * @author ruoyi
*/ */
@Data @Data
@EqualsAndHashCode(callSuper = true)
@Table(value = "sys_menu") @Table(value = "sys_menu")
public class SysMenu extends BaseEntity public class SysMenu implements Serializable
{ {
@Serial
private static final long serialVersionUID = 1L;
/** 菜单ID */ /** 菜单ID */
@Id @Id
@ -73,6 +77,28 @@ public class SysMenu extends BaseEntity
/** 菜单图标 */ /** 菜单图标 */
private String icon; private String icon;
/**
* 创建者
*/
private Long createBy;
/**
* 创建时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/**
* 更新者
*/
private Long updateBy;
/**
* 更新时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
/** 备注 */ /** 备注 */
private String remark; private String remark;

View File

@ -30,6 +30,11 @@ public class SysOperLog implements Serializable
@Id @Id
private Long operId; private Long operId;
/**
* 租户编号
*/
private Long tenantId;
/** 操作模块 */ /** 操作模块 */
private String title; private String title;

View File

@ -38,7 +38,7 @@ public class SysRole extends BaseEntity {
/** /**
* 角色排序 * 角色排序
*/ */
private String roleSort; private Integer roleSort;
/** /**
* 数据范围1所有数据权限2自定义数据权限3本部门数据权限4本部门及以下数据权限5仅本人数据权限 * 数据范围1所有数据权限2自定义数据权限3本部门数据权限4本部门及以下数据权限5仅本人数据权限

View File

@ -25,11 +25,6 @@ public class SysUser extends BaseEntity
@Id @Id
private Long userId; private Long userId;
/**
* 租户编号
*/
private Long tenantId;
/** 部门ID */ /** 部门ID */
private Long deptId; private Long deptId;

View File

@ -9,6 +9,7 @@ import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.*; import jakarta.validation.constraints.*;
import java.io.Serializable;
import java.util.List; import java.util.List;
/** /**
@ -17,9 +18,8 @@ import java.util.List;
* @author Michelle.Chung * @author Michelle.Chung
*/ */
@Data @Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = SysClient.class, reverseConvertGenerate = false) @AutoMapper(target = SysClient.class, reverseConvertGenerate = false)
public class SysClientBo extends BaseEntity { public class SysClientBo implements Serializable {
/** /**
* id * id

View File

@ -4,6 +4,8 @@ import com.ruoyi.system.domain.SysLogininfor;
import io.github.linpeilie.annotations.AutoMapper; import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data; import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -16,7 +18,10 @@ import java.util.Map;
@Data @Data
@AutoMapper(target = SysLogininfor.class, reverseConvertGenerate = false) @AutoMapper(target = SysLogininfor.class, reverseConvertGenerate = false)
public class SysLogininforBo { public class SysLogininforBo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/** /**
* 访问ID * 访问ID
@ -33,6 +38,16 @@ public class SysLogininforBo {
*/ */
private String userName; private String userName;
/**
* 客户端
*/
private String clientKey;
/**
* 设备类型
*/
private String deviceType;
/** /**
* 登录IP地址 * 登录IP地址
*/ */

View File

@ -10,6 +10,8 @@ import jakarta.validation.constraints.Size;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import java.io.Serializable;
/** /**
* 菜单权限业务对象 sys_menu * 菜单权限业务对象 sys_menu
* *
@ -17,9 +19,8 @@ import lombok.EqualsAndHashCode;
*/ */
@Data @Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = SysMenu.class, reverseConvertGenerate = false) @AutoMapper(target = SysMenu.class, reverseConvertGenerate = false)
public class SysMenuBo extends BaseEntity { public class SysMenuBo implements Serializable {
/** /**
* 菜单ID * 菜单ID

View File

@ -33,6 +33,7 @@ public class SysLogininforVo implements Serializable {
@ExcelProperty(value = "序号") @ExcelProperty(value = "序号")
private Long infoId; private Long infoId;
/** /**
* 租户编号 * 租户编号
*/ */
@ -44,6 +45,19 @@ public class SysLogininforVo implements Serializable {
@ExcelProperty(value = "用户账号") @ExcelProperty(value = "用户账号")
private String userName; private String userName;
/**
* 客户端
*/
@ExcelProperty(value = "客户端")
private String clientKey;
/**
* 设备类型
*/
@ExcelProperty(value = "设备类型", converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = "sys_device_type")
private String deviceType;
/** /**
* 登录状态0成功 1失败 * 登录状态0成功 1失败
*/ */

View File

@ -36,7 +36,7 @@ public class SysOperLogVo implements Serializable {
/** /**
* 租户编号 * 租户编号
*/ */
private String tenantId; private Long tenantId;
/** /**
* 模块标题 * 模块标题

View File

@ -2,9 +2,11 @@ package com.ruoyi.system.domain.vo;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.mybatisflex.annotation.Column;
import com.mybatisflex.annotation.ColumnMask; import com.mybatisflex.annotation.ColumnMask;
import com.mybatisflex.annotation.RelationOneToOne; import com.mybatisflex.annotation.RelationOneToOne;
import com.mybatisflex.core.mask.Masks; import com.mybatisflex.core.mask.Masks;
import com.ruoyi.common.orm.core.domain.BaseEntity;
import com.ruoyi.system.domain.SysUser; import com.ruoyi.system.domain.SysUser;
import io.github.linpeilie.annotations.AutoMapper; import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data; import lombok.Data;
@ -22,7 +24,7 @@ import java.util.List;
*/ */
@Data @Data
@AutoMapper(target = SysUser.class) @AutoMapper(target = SysUser.class)
public class SysUserVo implements Serializable { public class SysUserVo extends BaseEntity {
@Serial @Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@ -32,11 +34,6 @@ public class SysUserVo implements Serializable {
*/ */
private Long userId; private Long userId;
/**
* 租户ID
*/
private Long tenantId;
/** /**
* 部门ID * 部门ID
*/ */

View File

@ -66,6 +66,14 @@ public interface ISysMenuService extends IBaseService<SysMenu>
*/ */
List<Long> selectMenuListByRoleId(Long roleId); List<Long> selectMenuListByRoleId(Long roleId);
/**
* 根据租户套餐ID查询菜单树信息
*
* @param packageId 租户套餐ID
* @return 选中菜单列表
*/
List<Long> selectMenuListByPackageId(Long packageId);
/** /**
* 构建前端路由所需要的菜单 * 构建前端路由所需要的菜单
* *

View File

@ -11,11 +11,13 @@ import com.ruoyi.system.domain.bo.SysNoticeBo;
import com.ruoyi.system.domain.bo.SysRoleBo; import com.ruoyi.system.domain.bo.SysRoleBo;
import com.ruoyi.system.domain.vo.SysNoticeVo; import com.ruoyi.system.domain.vo.SysNoticeVo;
import com.ruoyi.system.domain.vo.SysRoleVo; import com.ruoyi.system.domain.vo.SysRoleVo;
import org.springframework.transaction.annotation.Transactional;
/** /**
* 角色业务层 * 角色业务层
* *
* @author ruoyi * @author ruoyi
* @author 数据小王子
*/ */
public interface ISysRoleService extends IBaseService<SysRole> public interface ISysRoleService extends IBaseService<SysRole>
{ {
@ -66,14 +68,6 @@ public interface ISysRoleService extends IBaseService<SysRole>
*/ */
List<SysRoleVo> selectRoleAll(); List<SysRoleVo> selectRoleAll();
/**
* 根据用户ID获取角色选择框列表
*
* @param userId 用户ID
* @return 选中角色ID列表
*/
List<Long> selectRoleListByUserId(Long userId);
/** /**
* 通过角色ID查询角色 * 通过角色ID查询角色
* *
@ -112,14 +106,6 @@ public interface ISysRoleService extends IBaseService<SysRole>
*/ */
void checkRoleDataScope(Long roleId); void checkRoleDataScope(Long roleId);
// /**
// * 通过角色ID查询角色使用数量
// *
// * @param roleId 角色ID
// * @return 结果
// */
// int countUserRoleByRoleId(Long roleId);
/** /**
* 新增保存角色信息 * 新增保存角色信息
* *
@ -128,6 +114,14 @@ public interface ISysRoleService extends IBaseService<SysRole>
*/ */
boolean insertRole(SysRoleBo roleBo); boolean insertRole(SysRoleBo roleBo);
/**
* 新增角色菜单信息
*
* @param role 角色对象
* @return true 保存成功false 保存失败
*/
boolean insertRoleMenu(SysRole role);
/** /**
* 修改保存角色信息 * 修改保存角色信息
* *
@ -152,14 +146,6 @@ public interface ISysRoleService extends IBaseService<SysRole>
*/ */
boolean authDataScope(SysRoleBo roleBo); boolean authDataScope(SysRoleBo roleBo);
// /**
// * 通过角色ID删除角色
// *
// * @param roleId 角色ID
// * @return 结果
// */
// int deleteRoleById(Long roleId);
/** /**
* 批量删除角色信息 * 批量删除角色信息
* *

View File

@ -57,6 +57,15 @@ public interface ISysUserService extends IBaseService<SysUser>
*/ */
SysUserVo selectUserByUserName(String userName); SysUserVo selectUserByUserName(String userName);
/**
* 登录时通过用户名租户编号查询用户不走Mybatis-Flex租户插件
*
* @param userName 用户名
* @param tenantId 租户编号
* @return 用户对象信息
*/
SysUserVo selectTenantUserByUserName(String userName,Long tenantId);
/** /**
* 通过邮箱查询用户 * 通过邮箱查询用户
* *

View File

@ -8,6 +8,7 @@ import com.mybatisflex.core.util.UpdateEntity;
import com.ruoyi.common.core.utils.MapstructUtils; import com.ruoyi.common.core.utils.MapstructUtils;
import com.ruoyi.common.orm.core.page.PageQuery; import com.ruoyi.common.orm.core.page.PageQuery;
import com.ruoyi.common.orm.core.page.TableDataInfo; import com.ruoyi.common.orm.core.page.TableDataInfo;
import com.ruoyi.common.security.utils.LoginHelper;
import com.ruoyi.system.domain.bo.SysClientBo; import com.ruoyi.system.domain.bo.SysClientBo;
import com.ruoyi.system.domain.vo.SysClientVo; import com.ruoyi.system.domain.vo.SysClientVo;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
@ -18,6 +19,7 @@ import com.ruoyi.system.mapper.SysClientMapper;
import com.mybatisflex.spring.service.impl.ServiceImpl; import com.mybatisflex.spring.service.impl.ServiceImpl;
import java.util.Collection; import java.util.Collection;
import java.util.Date;
import java.util.List; import java.util.List;
import static com.ruoyi.system.domain.table.SysClientTableDef.SYS_CLIENT; import static com.ruoyi.system.domain.table.SysClientTableDef.SYS_CLIENT;
@ -85,6 +87,14 @@ public class SysClientServiceImpl extends ServiceImpl<SysClientMapper, SysClient
String clientKey = sysClientBo.getClientKey(); String clientKey = sysClientBo.getClientKey();
String clientSecret = sysClientBo.getClientSecret(); String clientSecret = sysClientBo.getClientSecret();
sysClient.setClientId(SecureUtil.md5(clientKey + clientSecret)); sysClient.setClientId(SecureUtil.md5(clientKey + clientSecret));
Long loginUserId = LoginHelper.getUserId();
Date createTime = new Date();
sysClient.setCreateBy(loginUserId);
sysClient.setCreateTime(createTime);
sysClient.setUpdateBy(loginUserId);
sysClient.setUpdateTime(createTime);
return this.save(sysClient); return this.save(sysClient);
} }
@ -95,6 +105,12 @@ public class SysClientServiceImpl extends ServiceImpl<SysClientMapper, SysClient
public Boolean update(SysClientBo sysClientBo) { public Boolean update(SysClientBo sysClientBo) {
SysClient sysClient = MapstructUtils.convert(sysClientBo, SysClient.class); SysClient sysClient = MapstructUtils.convert(sysClientBo, SysClient.class);
sysClient.setGrantType(String.join(",", sysClientBo.getGrantTypeList())); sysClient.setGrantType(String.join(",", sysClientBo.getGrantTypeList()));
Long loginUserId = LoginHelper.getUserId();
Date createTime = new Date();
sysClient.setUpdateBy(loginUserId);
sysClient.setUpdateTime(createTime);
return this.updateById(sysClient); return this.updateById(sysClient);
} }
@ -104,7 +120,14 @@ public class SysClientServiceImpl extends ServiceImpl<SysClientMapper, SysClient
@Override @Override
public boolean updateStatus(Long id, String status) { public boolean updateStatus(Long id, String status) {
SysClient sysClient = UpdateEntity.of(SysClient.class, id); SysClient sysClient = UpdateEntity.of(SysClient.class, id);
Long loginUserId = LoginHelper.getUserId();
Date createTime = new Date();
sysClient.setUpdateBy(loginUserId);
sysClient.setUpdateTime(createTime);
sysClient.setStatus(status); sysClient.setStatus(status);
return clientMapper.update(sysClient) > 0; return clientMapper.update(sysClient) > 0;
} }

View File

@ -5,6 +5,7 @@ import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.useragent.UserAgent; import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil; import cn.hutool.http.useragent.UserAgentUtil;
import com.mybatisflex.core.paginate.Page; import com.mybatisflex.core.paginate.Page;
@ -18,8 +19,12 @@ import com.ruoyi.common.log.event.LogininforEvent;
import com.ruoyi.common.orm.core.page.PageQuery; import com.ruoyi.common.orm.core.page.PageQuery;
import com.ruoyi.common.orm.core.page.TableDataInfo; import com.ruoyi.common.orm.core.page.TableDataInfo;
import com.ruoyi.common.orm.core.service.impl.BaseServiceImpl; import com.ruoyi.common.orm.core.service.impl.BaseServiceImpl;
import com.ruoyi.common.security.utils.LoginHelper;
import com.ruoyi.system.domain.SysClient;
import com.ruoyi.system.domain.bo.SysLogininforBo; import com.ruoyi.system.domain.bo.SysLogininforBo;
import com.ruoyi.system.domain.vo.SysLogininforVo; import com.ruoyi.system.domain.vo.SysLogininforVo;
import com.ruoyi.system.service.ISysClientService;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -45,6 +50,9 @@ import static com.ruoyi.system.domain.table.SysLogininforTableDef.SYS_LOGININFOR
@Service @Service
public class SysLogininforServiceImpl extends BaseServiceImpl<SysLogininforMapper, SysLogininfor> implements ISysLogininforService { public class SysLogininforServiceImpl extends BaseServiceImpl<SysLogininforMapper, SysLogininfor> implements ISysLogininforService {
@Resource
private ISysClientService clientService;
@Override @Override
public QueryWrapper query() { public QueryWrapper query() {
return super.query().from(SYS_LOGININFOR); return super.query().from(SYS_LOGININFOR);
@ -61,6 +69,12 @@ public class SysLogininforServiceImpl extends BaseServiceImpl<SysLogininforMappe
HttpServletRequest request = logininforEvent.getRequest(); HttpServletRequest request = logininforEvent.getRequest();
final UserAgent userAgent = UserAgentUtil.parse(request.getHeader("User-Agent")); final UserAgent userAgent = UserAgentUtil.parse(request.getHeader("User-Agent"));
final String ip = ServletUtils.getClientIP(request); final String ip = ServletUtils.getClientIP(request);
// 客户端信息
String clientid = request.getHeader(LoginHelper.CLIENT_KEY);
SysClient client = null;
if (StringUtils.isNotBlank(clientid)) {
client = clientService.selectByClientId(clientid);
}
String address = AddressUtils.getRealAddressByIP(ip); String address = AddressUtils.getRealAddressByIP(ip);
StringBuilder s = new StringBuilder(); StringBuilder s = new StringBuilder();
@ -79,6 +93,10 @@ public class SysLogininforServiceImpl extends BaseServiceImpl<SysLogininforMappe
SysLogininforBo logininfor = new SysLogininforBo(); SysLogininforBo logininfor = new SysLogininforBo();
logininfor.setTenantId(logininforEvent.getTenantId()); logininfor.setTenantId(logininforEvent.getTenantId());
logininfor.setUserName(logininforEvent.getUsername()); logininfor.setUserName(logininforEvent.getUsername());
if (ObjectUtil.isNotNull(client)) {
logininfor.setClientKey(client.getClientKey());
logininfor.setDeviceType(client.getDeviceType());
}
logininfor.setIpaddr(ip); logininfor.setIpaddr(ip);
logininfor.setLoginLocation(address); logininfor.setLoginLocation(address);
logininfor.setBrowser(browser); logininfor.setBrowser(browser);
@ -120,9 +138,7 @@ public class SysLogininforServiceImpl extends BaseServiceImpl<SysLogininforMappe
* @return 查询条件 * @return 查询条件
*/ */
private QueryWrapper buildQueryWrapper(SysLogininforBo logininforBo) { private QueryWrapper buildQueryWrapper(SysLogininforBo logininforBo) {
QueryWrapper queryWrapper = QueryWrapper.create() QueryWrapper queryWrapper = query()
.select(SYS_LOGININFOR.INFO_ID, SYS_LOGININFOR.USER_NAME, SYS_LOGININFOR.IPADDR, SYS_LOGININFOR.LOGIN_LOCATION, SYS_LOGININFOR.BROWSER, SYS_LOGININFOR.OS, SYS_LOGININFOR.STATUS, SYS_LOGININFOR.MSG, SYS_LOGININFOR.LOGIN_TIME)
.from(SYS_LOGININFOR)
.and(SYS_LOGININFOR.IPADDR.like(logininforBo.getIpaddr())) .and(SYS_LOGININFOR.IPADDR.like(logininforBo.getIpaddr()))
.and(SYS_LOGININFOR.STATUS.eq(logininforBo.getStatus())) .and(SYS_LOGININFOR.STATUS.eq(logininforBo.getStatus()))
.and(SYS_LOGININFOR.USER_NAME.like(logininforBo.getUserName())) .and(SYS_LOGININFOR.USER_NAME.like(logininforBo.getUserName()))

View File

@ -1,14 +1,10 @@
package com.ruoyi.system.service.impl; package com.ruoyi.system.service.impl;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.tree.Tree; import cn.hutool.core.lang.tree.Tree;
import java.util.ArrayList; import java.util.*;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import com.mybatisflex.core.query.QueryMethods; import com.mybatisflex.core.query.QueryMethods;
import com.mybatisflex.core.query.QueryWrapper; import com.mybatisflex.core.query.QueryWrapper;
@ -21,6 +17,7 @@ import com.ruoyi.system.domain.*;
import com.ruoyi.system.domain.bo.SysMenuBo; import com.ruoyi.system.domain.bo.SysMenuBo;
import com.ruoyi.system.domain.vo.SysMenuVo; import com.ruoyi.system.domain.vo.SysMenuVo;
import com.ruoyi.system.domain.vo.SysRoleVo; import com.ruoyi.system.domain.vo.SysRoleVo;
import com.ruoyi.system.mapper.SysTenantPackageMapper;
import com.ruoyi.system.service.ISysRoleMenuService; import com.ruoyi.system.service.ISysRoleMenuService;
import com.ruoyi.system.service.ISysRoleService; import com.ruoyi.system.service.ISysRoleService;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
@ -57,6 +54,8 @@ public class SysMenuServiceImpl extends BaseServiceImpl<SysMenuMapper, SysMenu>
@Resource @Resource
private ISysRoleMenuService roleMenuService; private ISysRoleMenuService roleMenuService;
@Resource
private SysTenantPackageMapper tenantPackageMapper;
@Override @Override
public QueryWrapper query() { public QueryWrapper query() {
@ -274,6 +273,26 @@ public class SysMenuServiceImpl extends BaseServiceImpl<SysMenuMapper, SysMenu>
return this.listAs(queryWrapper, Long.class); return this.listAs(queryWrapper, Long.class);
} }
/**
* 根据租户套餐ID查询菜单树信息
*
* @param packageId 租户套餐ID
* @return 选中菜单列表
*/
@Override
public List<Long> selectMenuListByPackageId(Long packageId) {
SysTenantPackage tenantPackage = tenantPackageMapper.selectOneById(packageId);
List<Long> menuIds = StringUtils.splitTo(tenantPackage.getMenuIds(), Convert::toLong);
if (CollUtil.isEmpty(menuIds)) {
return List.of();
}
List<Long> parentIds = null;
if (tenantPackage.getMenuCheckStrictly()) {
parentIds = menuMapper.selectObjectListByQueryAs(QueryWrapper.create().select(SYS_MENU.PARENT_ID).from(SYS_MENU).where(SYS_MENU.MENU_ID.in(menuIds)), Long.class);
}
return menuMapper.selectObjectListByQueryAs(QueryWrapper.create().select(SYS_MENU.MENU_ID).from(SYS_MENU).where(SYS_MENU.MENU_ID.in(menuIds)).and(SYS_MENU.MENU_ID.notIn(parentIds)), Long.class);
}
/** /**
* 构建前端路由所需要的菜单 * 构建前端路由所需要的菜单
* *
@ -386,6 +405,14 @@ public class SysMenuServiceImpl extends BaseServiceImpl<SysMenuMapper, SysMenu>
@Override @Override
public int insertMenu(SysMenuBo menuBo) { public int insertMenu(SysMenuBo menuBo) {
SysMenu menu = MapstructUtils.convert(menuBo, SysMenu.class); SysMenu menu = MapstructUtils.convert(menuBo, SysMenu.class);
Long loginUserId = LoginHelper.getUserId();
Date createTime = new Date();
menu.setCreateBy(loginUserId);
menu.setCreateTime(createTime);
menu.setUpdateBy(loginUserId);
menu.setUpdateTime(createTime);
return menuMapper.insert(menu, false); return menuMapper.insert(menu, false);
} }
@ -398,6 +425,12 @@ public class SysMenuServiceImpl extends BaseServiceImpl<SysMenuMapper, SysMenu>
@Override @Override
public boolean updateMenu(SysMenuBo menuBo) { public boolean updateMenu(SysMenuBo menuBo) {
SysMenu menu = MapstructUtils.convert(menuBo, SysMenu.class); SysMenu menu = MapstructUtils.convert(menuBo, SysMenu.class);
Long loginUserId = LoginHelper.getUserId();
Date createTime = new Date();
menu.setUpdateBy(loginUserId);
menu.setUpdateTime(createTime);
return this.updateById(menu); return this.updateById(menu);
} }

View File

@ -5,6 +5,7 @@ import cn.hutool.core.util.ObjectUtil;
import com.mybatisflex.core.paginate.Page; import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper; import com.mybatisflex.core.query.QueryWrapper;
import com.ruoyi.common.orm.core.service.impl.BaseServiceImpl; import com.ruoyi.common.orm.core.service.impl.BaseServiceImpl;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import com.ruoyi.common.core.constant.CacheNames; import com.ruoyi.common.core.constant.CacheNames;
@ -43,8 +44,6 @@ import static com.ruoyi.system.domain.table.SysOssConfigTableDef.SYS_OSS_CONFIG;
@Service @Service
public class SysOssConfigServiceImpl extends BaseServiceImpl<SysOssConfigMapper, SysOssConfig> implements ISysOssConfigService { public class SysOssConfigServiceImpl extends BaseServiceImpl<SysOssConfigMapper, SysOssConfig> implements ISysOssConfigService {
private final SysOssConfigMapper baseMapper;
@Override @Override
public QueryWrapper query() { public QueryWrapper query() {
return super.query().from(SYS_OSS_CONFIG); return super.query().from(SYS_OSS_CONFIG);

View File

@ -210,28 +210,27 @@ public class SysRoleServiceImpl extends BaseServiceImpl<SysRoleMapper, SysRole>
return SpringUtils.getAopProxy(this).selectRoleList(new SysRoleBo()); return SpringUtils.getAopProxy(this).selectRoleList(new SysRoleBo());
} }
/** // /**
* 根据用户ID获取角色选择框列表 // * 根据用户ID获取角色选择框列表
* // *
* @param userId 用户ID // * @param userId 用户ID
* @return 选中角色ID列表 // * @return 选中角色ID列表
*/ // */
@Override // public List<Long> selectRoleListByUserId(Long userId) {
public List<Long> selectRoleListByUserId(Long userId) { // //return roleMapper.selectRoleListByUserId(userId);
//return roleMapper.selectRoleListByUserId(userId); // /*select r.role_id
/*select r.role_id // from sys_role r
from sys_role r // left join sys_user_role ur on ur.role_id = r.role_id
left join sys_user_role ur on ur.role_id = r.role_id // left join sys_user u on u.user_id = ur.user_id
left join sys_user u on u.user_id = ur.user_id // where u.user_id = #{userId}*/
where u.user_id = #{userId}*/ // QueryWrapper queryWrapper = QueryWrapper.create()
QueryWrapper queryWrapper = QueryWrapper.create() // .select(SYS_ROLE.ROLE_ID)
.select(SYS_ROLE.ROLE_ID) // .from(SYS_ROLE.as("r"))
.from(SYS_ROLE.as("r")) // .leftJoin(SYS_USER_ROLE).as("ur").on(SYS_USER_ROLE.ROLE_ID.eq(SYS_ROLE.ROLE_ID))
.leftJoin(SYS_USER_ROLE).as("ur").on(SYS_USER_ROLE.ROLE_ID.eq(SYS_ROLE.ROLE_ID)) // .leftJoin(SYS_USER).as("u").on(SYS_USER.USER_ID.eq(SYS_USER_ROLE.USER_ID))
.leftJoin(SYS_USER).as("u").on(SYS_USER.USER_ID.eq(SYS_USER_ROLE.USER_ID)) // .where(SYS_USER.USER_ID.eq(userId));
.where(SYS_USER.USER_ID.eq(userId)); // return roleMapper.selectObjectListByQueryAs(queryWrapper, Long.class);
return roleMapper.selectObjectListByQueryAs(queryWrapper, Long.class); // }
}
/** /**
* 通过角色ID查询角色 * 通过角色ID查询角色
@ -417,6 +416,7 @@ public class SysRoleServiceImpl extends BaseServiceImpl<SysRoleMapper, SysRole>
* @param role 角色对象 * @param role 角色对象
* @return true 保存成功false 保存失败 * @return true 保存成功false 保存失败
*/ */
@Override
@Transactional @Transactional
public boolean insertRoleMenu(SysRole role) { public boolean insertRoleMenu(SysRole role) {
boolean inserted = true; boolean inserted = true;

View File

@ -19,6 +19,7 @@ import com.ruoyi.common.orm.core.page.PageQuery;
import com.ruoyi.common.orm.core.page.TableDataInfo; import com.ruoyi.common.orm.core.page.TableDataInfo;
import com.ruoyi.common.orm.core.service.impl.BaseServiceImpl; import com.ruoyi.common.orm.core.service.impl.BaseServiceImpl;
import com.ruoyi.common.security.utils.LoginHelper; import com.ruoyi.common.security.utils.LoginHelper;
import com.ruoyi.common.tenant.helper.TenantHelper;
import com.ruoyi.system.domain.*; import com.ruoyi.system.domain.*;
import com.ruoyi.system.domain.bo.SysUserBo; import com.ruoyi.system.domain.bo.SysUserBo;
import com.ruoyi.system.domain.vo.SysPostVo; import com.ruoyi.system.domain.vo.SysPostVo;
@ -114,7 +115,7 @@ public class SysUserServiceImpl extends BaseServiceImpl<SysUserMapper, SysUser>
if (ObjectUtil.isNotNull(userBo.getDeptId())) { if (ObjectUtil.isNotNull(userBo.getDeptId())) {
queryWrapper.and(SYS_USER.DEPT_ID.eq(userBo.getDeptId()).or(SYS_USER.DEPT_ID.in(select(SYS_DEPT.DEPT_ID).from(SYS_DEPT.as("t")).where(findInSet(number(userBo.getDeptId()), SYS_DEPT.ANCESTORS).gt(0))))); queryWrapper.and(SYS_USER.DEPT_ID.eq(userBo.getDeptId()).or(SYS_USER.DEPT_ID.in(select(SYS_DEPT.DEPT_ID).from(SYS_DEPT.as("t")).where(findInSet(number(userBo.getDeptId()), SYS_DEPT.ANCESTORS).gt(0)))));
} }
queryWrapper.orderBy(SYS_USER.USER_ID.desc());
return queryWrapper; return queryWrapper;
} }
@ -272,6 +273,23 @@ public class SysUserServiceImpl extends BaseServiceImpl<SysUserMapper, SysUser>
return this.getOneAs(queryWrapper, SysUserVo.class); return this.getOneAs(queryWrapper, SysUserVo.class);
} }
/**
* 登录时通过用户名租户编号查询用户不走Mybatis-Flex租户插件
*
* @param userName 用户名
* @param tenantId 租户编号
* @return 用户对象信息
*/
@Override
public SysUserVo selectTenantUserByUserName(String userName, Long tenantId) {
return TenantHelper.ignore(() -> {
QueryWrapper queryWrapper = buildOneQueryWrapper()
.where(SYS_USER.TENANT_ID.eq(tenantId))
.and(SYS_USER.USER_NAME.eq(userName));
return this.getOneAs(queryWrapper, SysUserVo.class);
});
}
/** /**
* 通过邮箱查询用户 * 通过邮箱查询用户
* *
@ -540,6 +558,7 @@ public class SysUserServiceImpl extends BaseServiceImpl<SysUserMapper, SysUser>
/** /**
* 修改用户状态 * 修改用户状态
* update sys_user set status = #{status} where user_id = #{userId} * update sys_user set status = #{status} where user_id = #{userId}
*
* @param user 用户信息 * @param user 用户信息
* @return 结果true 操作成功false 操作失败 * @return 结果true 操作成功false 操作失败
*/ */
@ -566,6 +585,7 @@ public class SysUserServiceImpl extends BaseServiceImpl<SysUserMapper, SysUser>
/** /**
* 修改用户头像 * 修改用户头像
* update sys_user set avatar = #{avatar} where user_id = #{userId} * update sys_user set avatar = #{avatar} where user_id = #{userId}
*
* @param userId 用户ID * @param userId 用户ID
* @param avatar 头像地址 * @param avatar 头像地址
* @return 结果:true 更新成功false 更新失败 * @return 结果:true 更新成功false 更新失败
@ -596,6 +616,7 @@ public class SysUserServiceImpl extends BaseServiceImpl<SysUserMapper, SysUser>
/** /**
* 重置用户密码 * 重置用户密码
* update sys_user set password = #{password} where user_name = #{userName} * update sys_user set password = #{password} where user_name = #{userName}
*
* @param userName 用户名 * @param userName 用户名
* @param password 密码 * @param password 密码
* @return 结果:true 更新成功false 更新失败 * @return 结果:true 更新成功false 更新失败