diff --git a/server/REST API/认证授权2API.http b/server/REST API/认证授权2API.http
index f10005b..09caea4 100644
--- a/server/REST API/认证授权2API.http
+++ b/server/REST API/认证授权2API.http
@@ -1,11 +1,11 @@
## 安全认证
### 获取验证码
-### http://localhost:18891/auth/captcha/codes?codeKey=5jXzuwcoUzbtnHNh
-GET {{baseUrl}}/auth/captcha/codes?codeKey=applezrgegbtnHNrefh
+### http://localhost:18891/auth/captcha/codes?codeKey=sNHnDNSliZe7ynOLem
+GET {{baseUrl}}/auth/captcha/codes?codeKey=sNHnDNSliZe7ynOLem
-### [master]密码模式登录
+### [google]密码模式登录
POST {{baseUrl}}/auth/login
Content-Type: application/json
x-tenant-id: google
@@ -14,8 +14,8 @@ User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Fi
{
"username": "cb44dedf9846",
"password": "123456",
- "codeKey": "applezrgegbtnHNrefh",
- "codeText": "dxfu"
+ "codeKey": "sNHnDNSliZe7ynOLem",
+ "codeText": "8mp8"
}
> {%
@@ -28,6 +28,7 @@ client.global.set("refreshToken", response.body.data.refresh_token);
POST {{baseUrl}}/auth/logout
Content-Type: application/json
x-tenant-id: google
+x-project-id: 10003
Authorization: Bearer {{tokenValue}}
@@ -42,6 +43,7 @@ Authorization: Bearer {{tokenValue}}
GET {{baseUrl}}/auth/login/user
Content-Type: application/json
x-tenant-id: google
+x-project-id: 10001
Authorization: Bearer {{tokenValue}}
@@ -50,5 +52,6 @@ Authorization: Bearer {{tokenValue}}
GET {{baseUrl}}/cms/project/simple/query?pageIndex=1&pageSize=5&keywords=
Content-Type: application/json
x-tenant-id: google
+x-project-id: 10002
Authorization: Bearer {{tokenValue}}
diff --git a/server/REST API/认证授权API.http b/server/REST API/认证授权API.http
index 2a5ecd7..7ee72c1 100644
--- a/server/REST API/认证授权API.http
+++ b/server/REST API/认证授权API.http
@@ -16,7 +16,7 @@ User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Fi
"username": "admin",
"password": "123456",
"codeKey": "5jXzuwcoUzbtnHNh",
- "codeText": "yjvm"
+ "codeText": "jxcd"
}
> {%
diff --git a/server/internal-api/src/main/java/com/xaaef/molly/internal/api/ApiCmsProjectService.java b/server/internal-api/src/main/java/com/xaaef/molly/internal/api/ApiCmsProjectService.java
index c2e09ae..59d1937 100644
--- a/server/internal-api/src/main/java/com/xaaef/molly/internal/api/ApiCmsProjectService.java
+++ b/server/internal-api/src/main/java/com/xaaef/molly/internal/api/ApiCmsProjectService.java
@@ -3,6 +3,8 @@ package com.xaaef.molly.internal.api;
import com.xaaef.molly.internal.dto.CmsProjectDTO;
import com.xaaef.molly.internal.dto.SysTenantDTO;
+import java.util.Set;
+
/**
*
@@ -42,4 +44,14 @@ public interface ApiCmsProjectService {
*/
long countProjectByDeptId(Long deptId);
+
+ /**
+ * 根据 部门ID 获取 关联的 项目列表
+ *
+ * @author WangChenChen
+ * @date 2023/8/11 10:47
+ */
+ Set listProjectByDeptId(Long deptId);
+
+
}
diff --git a/server/internal-api/src/main/java/com/xaaef/molly/internal/api/ApiSysTenantService.java b/server/internal-api/src/main/java/com/xaaef/molly/internal/api/ApiSysTenantService.java
index 48eb2f6..9be4a2e 100644
--- a/server/internal-api/src/main/java/com/xaaef/molly/internal/api/ApiSysTenantService.java
+++ b/server/internal-api/src/main/java/com/xaaef/molly/internal/api/ApiSysTenantService.java
@@ -1,5 +1,6 @@
package com.xaaef.molly.internal.api;
+import com.xaaef.molly.internal.dto.MultiTenantPropertiesDTO;
import com.xaaef.molly.internal.dto.SysTenantDTO;
/**
@@ -14,6 +15,15 @@ import com.xaaef.molly.internal.dto.SysTenantDTO;
public interface ApiSysTenantService {
+ /**
+ * 判断 租户ID 是否存在
+ *
+ * @author WangChenChen
+ * @date 2023/2/14 10:53
+ */
+ boolean existById(String tenantId);
+
+
/**
* 根据租户ID 获取租户信息
*
@@ -49,4 +59,13 @@ public interface ApiSysTenantService {
String getByDefaultTenantId();
+ /**
+ * 获取 多租户配置
+ *
+ * @author WangChenChen
+ * @date 2023/2/14 10:53
+ */
+ MultiTenantPropertiesDTO getByMultiTenantProperties();
+
+
}
diff --git a/server/internal-api/src/main/java/com/xaaef/molly/internal/dto/CmsProjectDTO.java b/server/internal-api/src/main/java/com/xaaef/molly/internal/dto/CmsProjectDTO.java
index dda640d..219c79e 100644
--- a/server/internal-api/src/main/java/com/xaaef/molly/internal/dto/CmsProjectDTO.java
+++ b/server/internal-api/src/main/java/com/xaaef/molly/internal/dto/CmsProjectDTO.java
@@ -15,6 +15,7 @@ import lombok.experimental.Accessors;
* @date 2021/7/5 9:31
*/
+
@Schema(description = "项目")
@Getter
@Setter
@@ -49,7 +50,13 @@ public class CmsProjectDTO implements java.io.Serializable {
private String contactNumber;
/**
- * 联系地址
+ * 行政地址
+ */
+ @Schema(description = "行政地址")
+ private Long areaCode;
+
+ /**
+ * 联系地址 如:左右云创谷1栋A座
*/
@Schema(description = "联系地址")
private String address;
@@ -72,4 +79,10 @@ public class CmsProjectDTO implements java.io.Serializable {
@Schema(description = "状态 【0.禁用 1.正常 2.锁定 】")
private Byte status;
+ /**
+ * 所属部门
+ */
+ @Schema(description = "所属部门Id")
+ private Long deptId;
+
}
diff --git a/server/internal-api/src/main/java/com/xaaef/molly/internal/dto/MultiTenantPropertiesDTO.java b/server/internal-api/src/main/java/com/xaaef/molly/internal/dto/MultiTenantPropertiesDTO.java
new file mode 100644
index 0000000..55a5bd5
--- /dev/null
+++ b/server/internal-api/src/main/java/com/xaaef/molly/internal/dto/MultiTenantPropertiesDTO.java
@@ -0,0 +1,50 @@
+package com.xaaef.molly.internal.dto;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ *
+ * 多租户全局配置
+ *
+ *
+ * @author WangChenChen
+ * @version 1.1
+ * @date 2022/12/9 11:53
+ */
+
+@Getter
+@Setter
+public class MultiTenantPropertiesDTO {
+
+ /**
+ * 是否开启租户模式
+ */
+ private Boolean enable;
+
+ /**
+ * 是否开启租户模式
+ */
+ private Boolean enableProject;
+
+ /**
+ * 数据库名称前缀
+ */
+ private String prefix;
+
+ /**
+ * 默认租户ID
+ */
+ private String defaultTenantId;
+
+ /**
+ * 默认 项目ID
+ */
+ private Long defaultProjectId;
+
+ /**
+ * 默认 数据库名称
+ */
+ private String dbName;
+
+}
diff --git a/server/molly-cms/src/main/java/com/xaaef/molly/corems/api/impl/ApiCmsProjectServiceImpl.java b/server/molly-cms/src/main/java/com/xaaef/molly/corems/api/impl/ApiCmsProjectServiceImpl.java
index 0b5b871..69811de 100644
--- a/server/molly-cms/src/main/java/com/xaaef/molly/corems/api/impl/ApiCmsProjectServiceImpl.java
+++ b/server/molly-cms/src/main/java/com/xaaef/molly/corems/api/impl/ApiCmsProjectServiceImpl.java
@@ -5,16 +5,21 @@ import com.xaaef.molly.common.enums.StatusEnum;
import com.xaaef.molly.corems.entity.CmsProject;
import com.xaaef.molly.corems.mapper.CmsProjectMapper;
import com.xaaef.molly.internal.api.ApiCmsProjectService;
+import com.xaaef.molly.internal.api.ApiPmsDeptService;
import com.xaaef.molly.internal.api.ApiSysConfigService;
import com.xaaef.molly.internal.dto.CmsProjectDTO;
import com.xaaef.molly.internal.dto.SysTenantDTO;
-import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
import static com.xaaef.molly.auth.jwt.JwtSecurityUtils.encryptPassword;
import static com.xaaef.molly.common.consts.ConfigName.USER_DEFAULT_PASSWORD;
@@ -32,30 +37,41 @@ import static com.xaaef.molly.tenant.util.DelegateUtils.delegate;
@Slf4j
@Service
-@AllArgsConstructor
public class ApiCmsProjectServiceImpl implements ApiCmsProjectService {
+ @Autowired
+ @Lazy
+ private ApiPmsDeptService pmsDeptService;
+
private final CmsProjectMapper projectMapper;
private final ApiSysConfigService configService;
+ public ApiCmsProjectServiceImpl(CmsProjectMapper projectMapper,
+ ApiSysConfigService configService) {
+ this.projectMapper = projectMapper;
+ this.configService = configService;
+ }
+
@Override
public CmsProjectDTO getSimpleById(Long projectId) {
var wrapper = new LambdaQueryWrapper()
- .select(List.of(CmsProject::getProjectId, CmsProject::getProjectName,
- CmsProject::getLinkman, CmsProject::getContactNumber))
+ .select(
+ List.of(
+ CmsProject::getProjectId, CmsProject::getProjectName,
+ CmsProject::getLinkman, CmsProject::getAreaCode, CmsProject::getAddress
+ )
+ )
.eq(CmsProject::getStatus, StatusEnum.NORMAL.getCode())
.eq(CmsProject::getProjectId, projectId);
var source = projectMapper.selectOne(wrapper);
if (source == null) {
return null;
}
- return new CmsProjectDTO()
- .setProjectId(source.getProjectId())
- .setProjectName(source.getProjectName())
- .setLinkman(source.getLinkman())
- .setContactNumber(source.getContactNumber());
+ var target = new CmsProjectDTO();
+ BeanUtils.copyProperties(source, target);
+ return target;
}
@@ -90,4 +106,17 @@ public class ApiCmsProjectServiceImpl implements ApiCmsProjectService {
}
+ @Override
+ public Set listProjectByDeptId(Long deptId) {
+ var deptIds = pmsDeptService.listChildIdByDeptId(deptId);
+ var wrapper = new LambdaQueryWrapper()
+ .select(CmsProject::getProjectId)
+ .in(CmsProject::getDeptId, deptIds);
+ return projectMapper.selectList(wrapper)
+ .stream()
+ .map(CmsProject::getProjectId)
+ .collect(Collectors.toSet());
+ }
+
+
}
diff --git a/server/molly-pms/src/main/java/com/xaaef/molly/perms/controller/PmsUserController.java b/server/molly-pms/src/main/java/com/xaaef/molly/perms/controller/PmsUserController.java
index ee73bce..4106dbe 100644
--- a/server/molly-pms/src/main/java/com/xaaef/molly/perms/controller/PmsUserController.java
+++ b/server/molly-pms/src/main/java/com/xaaef/molly/perms/controller/PmsUserController.java
@@ -3,6 +3,7 @@ package com.xaaef.molly.perms.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.xaaef.molly.auth.jwt.JwtLoginUser;
import com.xaaef.molly.auth.jwt.JwtSecurityUtils;
+import com.xaaef.molly.auth.service.JwtTokenService;
import com.xaaef.molly.common.domain.Pagination;
import com.xaaef.molly.common.util.JsonResult;
import com.xaaef.molly.perms.entity.PmsUser;
@@ -21,8 +22,8 @@ import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
+import java.util.Collection;
import java.util.List;
-import java.util.Set;
import static com.xaaef.molly.tenant.util.DelegateUtils.delegate;
@@ -45,6 +46,8 @@ public class PmsUserController {
private final PmsUserService baseService;
+ private final JwtTokenService jwtTokenService;
+
@Operation(summary = "用户权限", description = "用户权限")
@GetMapping("/rights")
@@ -65,8 +68,8 @@ public class PmsUserController {
@Operation(summary = "在线用户查询", description = "在线用户 查询所有")
@GetMapping("/online/query")
- public JsonResult> pageQuery2() {
- return JsonResult.success(baseService.listLoginUsers());
+ public JsonResult> pageQuery2() {
+ return JsonResult.success(jwtTokenService.mapLoginUser().values());
}
diff --git a/server/molly-pms/src/main/java/com/xaaef/molly/perms/service/PmsUserService.java b/server/molly-pms/src/main/java/com/xaaef/molly/perms/service/PmsUserService.java
index 67238e4..e50db14 100644
--- a/server/molly-pms/src/main/java/com/xaaef/molly/perms/service/PmsUserService.java
+++ b/server/molly-pms/src/main/java/com/xaaef/molly/perms/service/PmsUserService.java
@@ -1,6 +1,5 @@
package com.xaaef.molly.perms.service;
-import com.xaaef.molly.auth.jwt.JwtLoginUser;
import com.xaaef.molly.perms.entity.PmsUser;
import com.xaaef.molly.perms.vo.ResetPasswordVO;
import com.xaaef.molly.perms.vo.UpdatePasswordVO;
@@ -21,15 +20,6 @@ import java.util.Set;
public interface PmsUserService extends BaseService {
- /**
- * TODO 在线的所有用户
- *
- * @author WangChenChen
- * @date 2023/4/22 8:50
- */
- Set listLoginUsers();
-
-
/**
* 修改密码
*
diff --git a/server/molly-pms/src/main/java/com/xaaef/molly/perms/service/impl/PmsUserServiceImpl.java b/server/molly-pms/src/main/java/com/xaaef/molly/perms/service/impl/PmsUserServiceImpl.java
index 7461d90..6dd8ef0 100644
--- a/server/molly-pms/src/main/java/com/xaaef/molly/perms/service/impl/PmsUserServiceImpl.java
+++ b/server/molly-pms/src/main/java/com/xaaef/molly/perms/service/impl/PmsUserServiceImpl.java
@@ -2,19 +2,20 @@ package com.xaaef.molly.perms.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
-import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.tree.TreeNode;
import cn.hutool.core.lang.tree.TreeUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
-import com.xaaef.molly.auth.jwt.JwtLoginUser;
import com.xaaef.molly.auth.jwt.JwtSecurityUtils;
import com.xaaef.molly.auth.service.JwtTokenService;
+import com.xaaef.molly.auth.service.UserLoginService;
import com.xaaef.molly.common.enums.AdminFlag;
import com.xaaef.molly.common.enums.StatusEnum;
+import com.xaaef.molly.common.enums.UserType;
import com.xaaef.molly.common.po.SearchPO;
import com.xaaef.molly.common.util.IdUtils;
+import com.xaaef.molly.internal.api.ApiCmsProjectService;
import com.xaaef.molly.internal.api.ApiSysConfigService;
import com.xaaef.molly.internal.api.ApiSysMenuService;
import com.xaaef.molly.internal.dto.PmsRoleDTO;
@@ -64,8 +65,12 @@ public class PmsUserServiceImpl extends BaseServiceImpl
private final ApiSysConfigService configService;
+ private final ApiCmsProjectService cmsProjectService;
+
private final ApiSysMenuService menuService;
+ private final UserLoginService userLoginService;
+
private final PmsRoleService roleService;
private final PmsDeptService deptService;
@@ -74,6 +79,7 @@ public class PmsUserServiceImpl extends BaseServiceImpl
private final JwtTokenService jwtTokenService;
+
@Override
public IPage pageKeywords(SearchPO params, Collection> columns) {
var result = super.pageKeywords(params, columns);
@@ -87,13 +93,14 @@ public class PmsUserServiceImpl extends BaseServiceImpl
var deptIds = list.stream().map(PmsUser::getDeptId).collect(Collectors.toSet());
var roleMaps = roleService.listByUserIds(userIds);
var deptMaps = deptService.listByIds(deptIds).stream().collect(Collectors.toMap(PmsDept::getDeptId, d -> d));
- var online = jwtTokenService.listUsernames();
+ var loginUserMap = jwtTokenService.mapLoginUser();
list.forEach(r -> {
r.setPassword(null);
r.setRoles(roleMaps.get(r.getUserId()));
r.setDept(deptMaps.get(r.getDeptId()));
// 如果包含,那么就是在线。【 0.离线 1.在线】
- r.setLoginFlag(CollectionUtil.contains(online, r.getUsername()) ? (byte) 1 : (byte) 0);
+ var loginFlag = loginUserMap.containsKey(r.getUserId()) ? (byte) 1 : (byte) 0;
+ r.setLoginFlag(loginFlag);
});
}
}
@@ -194,7 +201,14 @@ public class PmsUserServiceImpl extends BaseServiceImpl
var copyOptions = CopyOptions.create();
copyOptions.setIgnoreNullValue(true);
BeanUtil.copyProperties(entity, loginUser, copyOptions);
- jwtTokenService.updateLoginUser(loginUser);
+ // 非管理员 用户。根据部门Id获取关联的项目Id
+ if (loginUser.getUserType() == UserType.TENANT
+ && Objects.equals(entity.getAdminFlag(), AdminFlag.NO.getCode())) {
+ // 获取当前登录的用户 项目ID 列表
+ var haveProjectIds = cmsProjectService.listProjectByDeptId(entity.getDeptId());
+ loginUser.setHaveProjectIds(haveProjectIds);
+ }
+ userLoginService.refreshAuthoritys(loginUser);
}
return super.updateById(entity);
}
@@ -280,17 +294,6 @@ public class PmsUserServiceImpl extends BaseServiceImpl
}
- @Override
- public Set listLoginUsers() {
- return jwtTokenService.listLoginUsers()
- .stream()
- .peek(r -> {
- r.setPassword(null);
- r.setAuthorities(null);
- }).collect(Collectors.toSet());
- }
-
-
@Transactional(rollbackFor = Exception.class)
@Override
public boolean updatePassword(UpdatePasswordVO pwd) {
diff --git a/server/molly-service/src/main/resources/application-dev.yml b/server/molly-service/src/main/resources/application-dev.yml
index d6fccc6..d37be1f 100644
--- a/server/molly-service/src/main/resources/application-dev.yml
+++ b/server/molly-service/src/main/resources/application-dev.yml
@@ -2,7 +2,7 @@ spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.0.188:3306/${multi.tenant.db-name:molly_master}?useSSL=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowMultiQueries=true
- username: root
+ username: test123
password: mht123456
type: com.zaxxer.hikari.HikariDataSource
@@ -10,7 +10,7 @@ spring:
data:
redis:
host: 192.168.0.188
- database: 6
+ database: 7
port: 6379
timeout: 5000
lettuce:
diff --git a/server/molly-sys/src/main/java/com/xaaef/molly/system/api/impl/ApiSysTenantServiceImpl.java b/server/molly-sys/src/main/java/com/xaaef/molly/system/api/impl/ApiSysTenantServiceImpl.java
index 378a1e8..e9b8efa 100644
--- a/server/molly-sys/src/main/java/com/xaaef/molly/system/api/impl/ApiSysTenantServiceImpl.java
+++ b/server/molly-sys/src/main/java/com/xaaef/molly/system/api/impl/ApiSysTenantServiceImpl.java
@@ -3,9 +3,11 @@ package com.xaaef.molly.system.api.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xaaef.molly.common.util.TenantUtils;
import com.xaaef.molly.internal.api.ApiSysTenantService;
+import com.xaaef.molly.internal.dto.MultiTenantPropertiesDTO;
import com.xaaef.molly.internal.dto.SysTenantDTO;
import com.xaaef.molly.system.entity.SysTenant;
import com.xaaef.molly.system.mapper.SysTenantMapper;
+import com.xaaef.molly.tenant.props.MultiTenantProperties;
import com.xaaef.molly.tenant.service.MultiTenantManager;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -31,6 +33,14 @@ public class ApiSysTenantServiceImpl implements ApiSysTenantService {
private final MultiTenantManager tenantManager;
+ private final MultiTenantProperties multiTenantProperties;
+
+ @Override
+ public boolean existById(String tenantId) {
+ return tenantManager.existById(tenantId);
+ }
+
+
@Override
public SysTenantDTO getByTenantId(String tenantId) {
var source = tenantMapper.selectById(tenantId);
@@ -70,7 +80,15 @@ public class ApiSysTenantServiceImpl implements ApiSysTenantService {
@Override
public String getByDefaultTenantId() {
- return tenantManager.getDefaultTenantId();
+ return multiTenantProperties.getDefaultTenantId();
+ }
+
+
+ @Override
+ public MultiTenantPropertiesDTO getByMultiTenantProperties() {
+ var target = new MultiTenantPropertiesDTO();
+ BeanUtils.copyProperties(multiTenantProperties, target);
+ return target;
}
diff --git a/server/molly-sys/src/main/java/com/xaaef/molly/system/cron/TestCronAsync.java b/server/molly-sys/src/main/java/com/xaaef/molly/system/cron/TestCronAsync.java
index cdf5128..243a886 100644
--- a/server/molly-sys/src/main/java/com/xaaef/molly/system/cron/TestCronAsync.java
+++ b/server/molly-sys/src/main/java/com/xaaef/molly/system/cron/TestCronAsync.java
@@ -70,7 +70,7 @@ public class TestCronAsync {
@Scheduled(fixedRate = 60000)
public void cron2() {
var ind = count2.decrementAndGet();
- tokenService.listLoginUsers().forEach(user -> {
+ tokenService.mapAllLoginUser().forEach((userId, user) -> {
var map = Map.of(
"id", IdUtils.getStandaloneId(),
"title", String.format("推送消息=>%d", RandomUtil.randomInt(10000, 99999)),
diff --git a/server/plugins/auth-jwt/src/main/java/com/xaaef/molly/auth/controller/AuthController.java b/server/plugins/auth-jwt/src/main/java/com/xaaef/molly/auth/controller/AuthController.java
index 829bca1..48e8c6b 100644
--- a/server/plugins/auth-jwt/src/main/java/com/xaaef/molly/auth/controller/AuthController.java
+++ b/server/plugins/auth-jwt/src/main/java/com/xaaef/molly/auth/controller/AuthController.java
@@ -100,7 +100,7 @@ public class AuthController {
try {
var tokenValue = loginService.login(user, request);
return JsonResult.success("登录成功", tokenValue);
- } catch (Exception failed) {
+ } catch (RuntimeException failed) {
String msg = null;
if (failed instanceof UsernameNotFoundException) {
msg = StrUtil.format("用户名 {} 不存在", user.getUsername());
diff --git a/server/plugins/auth-jwt/src/main/java/com/xaaef/molly/auth/enums/OAuth2Error.java b/server/plugins/auth-jwt/src/main/java/com/xaaef/molly/auth/enums/OAuth2Error.java
index b8057cc..77ba08e 100644
--- a/server/plugins/auth-jwt/src/main/java/com/xaaef/molly/auth/enums/OAuth2Error.java
+++ b/server/plugins/auth-jwt/src/main/java/com/xaaef/molly/auth/enums/OAuth2Error.java
@@ -157,7 +157,7 @@ public enum OAuth2Error {
/**
* 此系统用户不包含 此项目ID
*/
- NO_HAVE_PROJECT_PERMISSIONS(400447, "此用户不包含此项目ID");
+ NO_HAVE_PROJECT_PERMISSIONS(400447, "用户没有操作此项目的权限");
OAuth2Error(Integer status, String error) {
diff --git a/server/plugins/auth-jwt/src/main/java/com/xaaef/molly/auth/service/JwtTokenService.java b/server/plugins/auth-jwt/src/main/java/com/xaaef/molly/auth/service/JwtTokenService.java
index 8287543..f5c0723 100644
--- a/server/plugins/auth-jwt/src/main/java/com/xaaef/molly/auth/service/JwtTokenService.java
+++ b/server/plugins/auth-jwt/src/main/java/com/xaaef/molly/auth/service/JwtTokenService.java
@@ -5,6 +5,7 @@ import com.xaaef.molly.auth.jwt.JwtLoginUser;
import com.xaaef.molly.auth.jwt.JwtTokenProperties;
import com.xaaef.molly.auth.jwt.JwtTokenValue;
+import java.util.Map;
import java.util.Set;
@@ -88,13 +89,13 @@ public interface JwtTokenService {
/**
- * 获取 所有的在线的用户名
+ * 获取 当前租户,在线的用户信息
*
* @return String 用户名称
* @author Wang Chen Chen
* @date 2021/7/12 16:29
*/
- Set listUsernames();
+ Set listLoginUsername();
/**
@@ -108,13 +109,27 @@ public interface JwtTokenService {
/**
- * 获取 所有的在线的用户信息
+ * 获取 当前租户,在线的 用户信息
+ * key: 用户ID
+ * value: 用户信息
*
* @return String 用户名称
* @author Wang Chen Chen
* @date 2021/7/12 16:29
*/
- Set listLoginUsers();
+ Map mapLoginUser();
+
+
+ /**
+ * 获取 所有租户 在线的 用户信息
+ * key: 用户ID
+ * value: 用户信息
+ *
+ * @return String 用户名称
+ * @author Wang Chen Chen
+ * @date 2021/7/12 16:29
+ */
+ Map mapAllLoginUser();
/**
diff --git a/server/plugins/auth-jwt/src/main/java/com/xaaef/molly/auth/service/UserLoginService.java b/server/plugins/auth-jwt/src/main/java/com/xaaef/molly/auth/service/UserLoginService.java
index fc80fa7..b1ea170 100644
--- a/server/plugins/auth-jwt/src/main/java/com/xaaef/molly/auth/service/UserLoginService.java
+++ b/server/plugins/auth-jwt/src/main/java/com/xaaef/molly/auth/service/UserLoginService.java
@@ -1,6 +1,7 @@
package com.xaaef.molly.auth.service;
import com.xaaef.molly.auth.exception.JwtAuthException;
+import com.xaaef.molly.auth.jwt.JwtLoginUser;
import com.xaaef.molly.auth.jwt.JwtTokenValue;
import com.xaaef.molly.auth.po.LoginFormPO;
import jakarta.servlet.http.HttpServletRequest;
@@ -37,4 +38,10 @@ public interface UserLoginService {
void refreshAuthoritys();
+ /**
+ * 刷新内存中用户的权限
+ */
+ void refreshAuthoritys(JwtLoginUser loginUser);
+
+
}
diff --git a/server/plugins/auth-jwt/src/main/java/com/xaaef/molly/auth/service/impl/JwtTokenServiceImpl.java b/server/plugins/auth-jwt/src/main/java/com/xaaef/molly/auth/service/impl/JwtTokenServiceImpl.java
index 95b70ce..dc375f6 100644
--- a/server/plugins/auth-jwt/src/main/java/com/xaaef/molly/auth/service/impl/JwtTokenServiceImpl.java
+++ b/server/plugins/auth-jwt/src/main/java/com/xaaef/molly/auth/service/impl/JwtTokenServiceImpl.java
@@ -21,6 +21,8 @@ import org.springframework.security.core.context.SecurityContextHolder;
import java.time.Duration;
import java.time.LocalDateTime;
+import java.util.HashMap;
+import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
@@ -223,7 +225,7 @@ public class JwtTokenServiceImpl implements JwtTokenService {
@Override
- public Set listUsernames() {
+ public Set listLoginUsername() {
var onlineUserKey = ONLINE_USER_KEY + "*";
return Objects.requireNonNull(strRedisTemplate.keys(onlineUserKey))
.stream()
@@ -243,11 +245,43 @@ public class JwtTokenServiceImpl implements JwtTokenService {
@Override
- public Set listLoginUsers() {
- return this.listLoginIds()
+ public Map mapLoginUser() {
+ var onlineUserKey = ONLINE_USER_KEY + "*";
+ var keys = strRedisTemplate.keys(onlineUserKey);
+ if (keys == null || keys.isEmpty()) {
+ return new HashMap<>();
+ }
+ var loginIds = strRedisTemplate.opsForValue().multiGet(keys);
+ if (loginIds == null || loginIds.isEmpty()) {
+ return new HashMap<>();
+ }
+ var loginUserKeys = loginIds
.stream()
- .map(this::getLoginUser)
+ .map(loginId -> LOGIN_TOKEN_KEY + loginId)
.collect(Collectors.toSet());
+ return mapLoginUser(loginUserKeys);
+ }
+
+
+ @Override
+ public Map mapAllLoginUser() {
+ var keys = strRedisTemplate.keys(LOGIN_TOKEN_KEY + "*");
+ return mapLoginUser(keys);
+ }
+
+
+ private Map mapLoginUser(Set keys) {
+ var result = new HashMap();
+ if (keys == null || keys.isEmpty()) {
+ return result;
+ }
+ var objects = redisTemplate.opsForValue().multiGet(keys);
+ if (objects == null || objects.isEmpty()) {
+ return result;
+ }
+ return objects.stream()
+ .map(a -> BeanUtil.copyProperties(a, JwtLoginUser.class))
+ .collect(Collectors.toMap(JwtLoginUser::getUserId, a -> a));
}
@@ -256,4 +290,5 @@ public class JwtTokenServiceImpl implements JwtTokenService {
return props;
}
+
}
diff --git a/server/plugins/auth-jwt/src/main/java/com/xaaef/molly/auth/service/impl/UserLoginServiceImpl.java b/server/plugins/auth-jwt/src/main/java/com/xaaef/molly/auth/service/impl/UserLoginServiceImpl.java
index 275e342..e2ff28a 100644
--- a/server/plugins/auth-jwt/src/main/java/com/xaaef/molly/auth/service/impl/UserLoginServiceImpl.java
+++ b/server/plugins/auth-jwt/src/main/java/com/xaaef/molly/auth/service/impl/UserLoginServiceImpl.java
@@ -31,6 +31,7 @@ import org.springframework.security.authentication.UsernamePasswordAuthenticatio
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
+import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
@@ -70,6 +71,8 @@ public class UserLoginServiceImpl implements UserLoginService {
private final ApiSysUserService sysUserService;
+ private final ApiCmsProjectService cmsProjectService;
+
/**
* 登录表单获取 Token
@@ -111,6 +114,8 @@ public class UserLoginServiceImpl implements UserLoginService {
target.setGrantType(GrantType.PASSWORD);
target.setLoginTime(LocalDateTime.now());
target.setTenantId(currentTenant.getTenantId());
+ // 生成一个随机ID 跟当前用户关联
+ target.setLoginId(IdUtil.simpleUUID());
// 判断当前登录的用户类型。系统用户 还是 租户用户
String defaultTenantId = tenantService.getByDefaultTenantId();
@@ -118,14 +123,20 @@ public class UserLoginServiceImpl implements UserLoginService {
? UserType.SYSTEM : UserType.TENANT;
target.setUserType(userType);
- // 生成一个随机ID 跟当前用户关联
- target.setLoginId(IdUtil.simpleUUID());
+ target.setHaveProjectIds(new HashSet<>());
+ target.setHaveTenantIds(new HashSet<>());
// 如果当前登录的用户,是否系统用户
if (userType == UserType.SYSTEM) {
- target.setHaveTenantIds(
- sysUserService.listHaveTenantIds(target.getUserId())
- );
+ var haveTenantIds = sysUserService.listHaveTenantIds(target.getUserId());
+ target.setHaveTenantIds(haveTenantIds);
+ } else {
+ // 非管理员 用户。根据部门Id获取关联的项目Id
+ if (target.getAdminFlag() == AdminFlag.NO) {
+ // 获取当前登录的用户 项目ID 列表
+ var haveProjectIds = cmsProjectService.listProjectByDeptId(target.getDeptId());
+ target.setHaveProjectIds(haveProjectIds);
+ }
}
// 设置角色和菜单权限
@@ -154,17 +165,21 @@ public class UserLoginServiceImpl implements UserLoginService {
public void refreshAuthoritys() {
// 判断用户是否登录
if (JwtSecurityUtils.isAuthenticated()) {
- // 获取登录用户
- var target = JwtSecurityUtils.getLoginUser();
- target.setAuthorities(List.of());
- // 设置用户的权限
- setAuthoritys(target);
- // 更新用户的权限
- tokenService.updateLoginUser(target);
+ refreshAuthoritys(JwtSecurityUtils.getLoginUser());
}
}
+ @Override
+ public void refreshAuthoritys(JwtLoginUser target) {
+ target.setAuthorities(List.of());
+ // 设置用户的权限
+ setAuthoritys(target);
+ // 更新用户的权限
+ tokenService.updateLoginUser(target);
+ }
+
+
/**
* 设置用户的权限
*
diff --git a/server/plugins/web-config/pom.xml b/server/plugins/web-config/pom.xml
index 7784934..6919bd6 100644
--- a/server/plugins/web-config/pom.xml
+++ b/server/plugins/web-config/pom.xml
@@ -36,7 +36,7 @@
com.xaaef.molly
- mbp-tenant
+ auth-jwt
${project.version}
diff --git a/server/plugins/web-config/src/main/java/com/xaaef/molly/web/CustomSpringWebConfig.java b/server/plugins/web-config/src/main/java/com/xaaef/molly/web/CustomSpringWebConfig.java
index 0533c5f..b24ef43 100644
--- a/server/plugins/web-config/src/main/java/com/xaaef/molly/web/CustomSpringWebConfig.java
+++ b/server/plugins/web-config/src/main/java/com/xaaef/molly/web/CustomSpringWebConfig.java
@@ -4,9 +4,9 @@ import cn.hutool.core.net.Ipv4Util;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xaaef.molly.common.consts.JwtConst;
import com.xaaef.molly.common.util.JsonUtils;
-import com.xaaef.molly.tenant.ProjectIdInterceptor;
-import com.xaaef.molly.tenant.TenantIdInterceptor;
-import com.xaaef.molly.tenant.props.MultiTenantProperties;
+import com.xaaef.molly.internal.api.ApiSysTenantService;
+import com.xaaef.molly.web.interceptor.ProjectIdInterceptor;
+import com.xaaef.molly.web.interceptor.TenantIdInterceptor;
import com.xaaef.molly.web.repeat.NoRepeatSubmitInterceptor;
import jakarta.annotation.PostConstruct;
import lombok.AllArgsConstructor;
@@ -66,7 +66,7 @@ public class CustomSpringWebConfig implements WebMvcConfigurer {
// 获取项目ID 拦截器
private final ProjectIdInterceptor projectIdInterceptor;
- private final MultiTenantProperties multiTenantProperties;
+ private final ApiSysTenantService tenantService;
@Override
@@ -76,6 +76,7 @@ public class CustomSpringWebConfig implements WebMvcConfigurer {
.filter(s -> !JwtConst.LOGIN_URL.equals(s))
.collect(Collectors.toList());
+ var multiTenantProperties = tenantService.getByMultiTenantProperties();
// 启用 租户ID 拦截器
if (multiTenantProperties.getEnable()) {
registry.addInterceptor(tenantIdInterceptor)
diff --git a/server/plugins/mbp-tenant/src/main/java/com/xaaef/molly/tenant/ProjectIdInterceptor.java b/server/plugins/web-config/src/main/java/com/xaaef/molly/web/interceptor/ProjectIdInterceptor.java
similarity index 81%
rename from server/plugins/mbp-tenant/src/main/java/com/xaaef/molly/tenant/ProjectIdInterceptor.java
rename to server/plugins/web-config/src/main/java/com/xaaef/molly/web/interceptor/ProjectIdInterceptor.java
index 7051149..38d1fdd 100644
--- a/server/plugins/mbp-tenant/src/main/java/com/xaaef/molly/tenant/ProjectIdInterceptor.java
+++ b/server/plugins/web-config/src/main/java/com/xaaef/molly/web/interceptor/ProjectIdInterceptor.java
@@ -1,4 +1,4 @@
-package com.xaaef.molly.tenant;
+package com.xaaef.molly.web.interceptor;
import cn.hutool.core.util.NumberUtil;
@@ -8,8 +8,8 @@ import com.xaaef.molly.common.util.JsonResult;
import com.xaaef.molly.common.util.ServletUtils;
import com.xaaef.molly.common.util.TenantUtils;
import com.xaaef.molly.internal.api.ApiCmsProjectService;
+import com.xaaef.molly.internal.api.ApiSysTenantService;
import com.xaaef.molly.internal.dto.CmsProjectDTO;
-import com.xaaef.molly.tenant.props.MultiTenantProperties;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.AllArgsConstructor;
@@ -38,7 +38,8 @@ public class ProjectIdInterceptor implements HandlerInterceptor {
private final ApiCmsProjectService projectService;
- private final MultiTenantProperties multiTenantProperties;
+ private final ApiSysTenantService tenantService;
+
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
@@ -62,7 +63,12 @@ public class ProjectIdInterceptor implements HandlerInterceptor {
TenantUtils.setProjectId(projectId);
} else {
// 使用 默认项目ID
- TenantUtils.setProjectId(multiTenantProperties.getDefaultProjectId());
+ var defaultProjectId = tenantService.getByMultiTenantProperties().getDefaultProjectId();
+ TenantUtils.setProjectId(defaultProjectId);
+ }
+ // 校验 当前用户是否 有操作此项目的权限
+ if (!haveProjectPermissions(response, TenantUtils.getProjectId())) {
+ return false;
}
return HandlerInterceptor.super.preHandle(request, response, handler);
}
@@ -72,8 +78,8 @@ public class ProjectIdInterceptor implements HandlerInterceptor {
* 判断 当前用户是否拥有 此项目的 操作权限
*/
private boolean haveProjectPermissions(HttpServletResponse response, Long projectId) {
- // 如果当前用户是 系统用户
- if (JwtSecurityUtils.isMasterUser()) {
+ // 如果当前用户是 租户的非管理员用户。
+ if (JwtSecurityUtils.isAuthenticated() && (!JwtSecurityUtils.isMasterUser() && !JwtSecurityUtils.isAdminUser())) {
var haveProjectIds = JwtSecurityUtils.getLoginUser().getHaveProjectIds();
if (!haveProjectIds.isEmpty() && !haveProjectIds.contains(projectId)) {
var err = StrUtil.format("您没有 项目ID {} 的操作权限!", projectId);
diff --git a/server/plugins/mbp-tenant/src/main/java/com/xaaef/molly/tenant/TenantIdInterceptor.java b/server/plugins/web-config/src/main/java/com/xaaef/molly/web/interceptor/TenantIdInterceptor.java
similarity index 94%
rename from server/plugins/mbp-tenant/src/main/java/com/xaaef/molly/tenant/TenantIdInterceptor.java
rename to server/plugins/web-config/src/main/java/com/xaaef/molly/web/interceptor/TenantIdInterceptor.java
index 6e900e1..a94384c 100644
--- a/server/plugins/mbp-tenant/src/main/java/com/xaaef/molly/tenant/TenantIdInterceptor.java
+++ b/server/plugins/web-config/src/main/java/com/xaaef/molly/web/interceptor/TenantIdInterceptor.java
@@ -1,4 +1,4 @@
-package com.xaaef.molly.tenant;
+package com.xaaef.molly.web.interceptor;
import cn.hutool.core.util.StrUtil;
@@ -8,7 +8,6 @@ import com.xaaef.molly.common.util.ServletUtils;
import com.xaaef.molly.common.util.TenantUtils;
import com.xaaef.molly.internal.api.ApiSysTenantService;
import com.xaaef.molly.internal.dto.SysTenantDTO;
-import com.xaaef.molly.tenant.service.MultiTenantManager;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.AllArgsConstructor;
@@ -36,8 +35,6 @@ import static com.xaaef.molly.common.util.TenantUtils.X_TENANT_ID;
@AllArgsConstructor
public class TenantIdInterceptor implements HandlerInterceptor {
- private final MultiTenantManager tenantManager;
-
private final ApiSysTenantService tenantService;
@Override
@@ -73,13 +70,13 @@ public class TenantIdInterceptor implements HandlerInterceptor {
}
}
// 校验租户,是否存在系统中
- if (!tenantManager.existById(tenantId)) {
+ if (!tenantService.existById(tenantId)) {
var err = StrUtil.format("租户ID {} 不存在!", tenantId);
ServletUtils.renderError(response, JsonResult.result(TENANT_ID_DOES_NOT_EXIST.getStatus(), err));
return false;
}
TenantUtils.setTenantId(tenantId);
- log.debug("preHandle.tenantId: {}", tenantId);
+ // 校验 当前用户是否 有操作此租户的权限
if (!haveTenantPermissions(response, tenantId)) {
return false;
}
diff --git a/web-ui/src/views/pre/user/index.vue b/web-ui/src/views/pre/user/index.vue
index f9d1179..64bbeef 100644
--- a/web-ui/src/views/pre/user/index.vue
+++ b/web-ui/src/views/pre/user/index.vue
@@ -59,13 +59,16 @@
- 是
+ 是
否
- {{ dictStore.getNormalDisable(scope.row.status) }}
+ 在线
+
+ {{ dictStore.getNormalDisable(scope.row.status) }}
+