Merge branch 'main' of ssh://192.168.1.205:9922/cf_devdept2/cf_imes_server

This commit is contained in:
lym
2024-11-08 09:24:54 +08:00
54 changed files with 797 additions and 4282 deletions
@@ -1,12 +1,18 @@
package com.cf.imes.module.system.controller.admin.auth;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.cf.imes.framework.common.enums.CommonStatusEnum;
import com.cf.imes.framework.common.enums.UserTypeEnum;
import com.cf.imes.framework.common.exception.ServiceException;
import com.cf.imes.framework.common.exception.enums.GlobalErrorCodeConstants;
import com.cf.imes.framework.common.pojo.CommonResult;
import com.cf.imes.framework.common.validation.Mobile;
import com.cf.imes.framework.ip.core.service.IPQueryService;
import com.cf.imes.framework.ip.core.service.dto.IPQueryDataRespDTO;
import com.cf.imes.framework.operatelog.core.annotations.OperateLog;
import com.cf.imes.framework.security.config.SecurityProperties;
import com.cf.imes.framework.security.core.LoginUser;
import com.cf.imes.framework.security.core.util.SecurityFrameworkUtils;
import com.cf.imes.module.system.api.sms.dto.code.SmsCodeSendReqDTO;
import com.cf.imes.module.system.controller.admin.auth.vo.AuthLoginReqVO;
@@ -14,11 +20,13 @@ import com.cf.imes.module.system.controller.admin.auth.vo.AuthLoginSmsCheckReqVO
import com.cf.imes.module.system.controller.admin.auth.vo.AuthPermissionInfoRespVO;
import com.cf.imes.module.system.controller.admin.auth.vo.AuthSocialLoginReqVO;
import com.cf.imes.module.system.convert.auth.AuthConvert;
import com.cf.imes.module.system.dal.dataobject.organ.OrganizationDO;
import com.cf.imes.module.system.dal.dataobject.permission.MenuDO;
import com.cf.imes.module.system.dal.dataobject.permission.RoleDO;
import com.cf.imes.module.system.dal.dataobject.user.AdminUserDO;
import com.cf.imes.module.system.enums.logger.LoginLogTypeEnum;
import com.cf.imes.module.system.service.auth.AdminAuthService;
import com.cf.imes.module.system.service.organ.OrganService;
import com.cf.imes.module.system.service.permission.MenuService;
import com.cf.imes.module.system.service.permission.PermissionService;
import com.cf.imes.module.system.service.permission.RoleService;
@@ -35,6 +43,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@@ -50,7 +59,6 @@ import java.util.Set;
import static com.cf.imes.framework.common.pojo.CommonResult.success;
import static com.cf.imes.framework.common.util.collection.CollectionUtils.convertSet;
import static com.cf.imes.framework.common.util.servlet.ServletUtils.getClientIP;
import static com.cf.imes.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
@Tag(name = "管理后台 - 认证")
@RestController
@@ -78,11 +86,23 @@ public class AuthController {
@Resource
private SmsCodeService smsCodeService;
@Resource
private OrganService organService;
@Resource
private IPQueryService ipQueryService;
/**
* ip服务开关,默认为 false不开启
*/
@Value("${chenfeng.ipquery.enable:false}")
private boolean ipQueryEnable;
@PostMapping("/login")
@PermitAll
@Operation(summary = "使用账号密码登录")
@OperateLog(enable = false) // 避免 Post 请求被记录操作日志
public CommonResult<AuthLoginRespVO> login(@Valid @RequestBody AuthLoginReqVO reqVO) {
public CommonResult<AuthLoginRespVO> login(@Valid @RequestBody AuthLoginReqVO reqVO, HttpServletRequest request) {
return success(authService.login(reqVO));
}
@@ -128,28 +148,40 @@ public class AuthController {
@GetMapping("/get-permission-info")
@Operation(summary = "获取登录用户的权限信息")
public CommonResult<AuthPermissionInfoRespVO> getPermissionInfo() {
public CommonResult<AuthPermissionInfoRespVO> getPermissionInfo(HttpServletRequest request) {
LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
if (ObjectUtil.isNull(loginUser)) {
throw new ServiceException(GlobalErrorCodeConstants.UNAUTHORIZED);
}
Long userId = loginUser.getId();
// 1.1 获得用户信息
AdminUserDO user = userService.getUser(getLoginUserId());
AdminUserDO user = userService.getUser(userId);
if (user == null) {
return null;
}
// 获取机构的有效期
OrganizationDO organizationDO = organService.validOrgan(user.getOrganId());
IPQueryDataRespDTO ipQueryDataRespDTO = null;
if (ipQueryService.serviceEnable()) {
// 从ip获取地域信息
ipQueryDataRespDTO = ipQueryService.querySource(getClientIP(request));
}
// 1.2 获得角色列表
Set<Long> roleIds = permissionService.getUserRoleIdListByUserId(getLoginUserId());
Set<Long> roleIds = permissionService.getUserRoleIdListByUserId(userId);
if (CollUtil.isEmpty(roleIds)) {
return success(AuthConvert.INSTANCE.convert(user, Collections.emptyList(), Collections.emptyList()));
return success(AuthConvert.INSTANCE.convert(user, organizationDO, ipQueryDataRespDTO, Collections.emptyList(), Collections.emptyList()));
}
List<RoleDO> roles = roleService.getRoleList1(roleIds);
roles.removeIf(role -> !CommonStatusEnum.ENABLE.getStatus().equals(role.getStatus())); // 移除禁用的角色
// 1.3 获得菜单列表
Set<Long> menuIds = permissionService.getRoleMenuListByRoleId2(convertSet(roles, RoleDO::getId));
Set<Long> menuIds = permissionService.getRoleMenuListByRoleId2(convertSet(roles, RoleDO::getId), loginUser.getOrganId());
List<MenuDO> menuList = menuService.getMenuList1(menuIds);
menuList.removeIf(menu -> !CommonStatusEnum.ENABLE.getStatus().equals(menu.getStatus())); // 移除禁用的菜单
// 2. 拼接结果返回
return success(AuthConvert.INSTANCE.convert(user, roles, menuList));
return success(AuthConvert.INSTANCE.convert(user, organizationDO, ipQueryDataRespDTO, roles, menuList));
}
// ========== 短信登录相关 ==========
@@ -6,6 +6,7 @@ import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Set;
@@ -49,6 +50,15 @@ public class AuthPermissionInfoRespVO {
@Schema(description = "是否需要设置密码")
private boolean needSetPwd;
@Schema(description = "ip地址")
private String ip;
@Schema(description = "所属区域")
private String region;
@Schema(description = "有效期限")
private LocalDateTime expireTime;
}
@Schema(description = "管理后台 - 登录用户的菜单信息 Response VO")
@@ -1,5 +0,0 @@
### 获得地区树
GET {{baseUrl}}/system/area/tree
Authorization: Bearer {{token}}
organ-id: {{adminTenentId}}
@@ -1,50 +0,0 @@
package com.cf.imes.module.system.controller.admin.ip;
import cn.hutool.core.lang.Assert;
import com.cf.imes.framework.common.pojo.CommonResult;
import com.cf.imes.framework.common.util.object.BeanUtils;
import com.cf.imes.framework.ip.core.Area;
import com.cf.imes.framework.ip.core.utils.AreaUtils;
import com.cf.imes.framework.ip.core.utils.IPUtils;
import com.cf.imes.module.system.controller.admin.ip.vo.AreaNodeRespVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import static com.cf.imes.framework.common.pojo.CommonResult.success;
@Tag(name = "管理后台 - 地区")
@RestController
@RequestMapping("/system/area")
@Validated
public class AreaController {
@GetMapping("/tree")
@Operation(summary = "获得地区树")
public CommonResult<List<AreaNodeRespVO>> getAreaTree() {
Area area = AreaUtils.getArea(Area.ID_CHINA);
Assert.notNull(area, "获取不到中国");
return success(BeanUtils.toBean(area.getChildren(), AreaNodeRespVO.class));
}
@GetMapping("/get-by-ip")
@Operation(summary = "获得 IP 对应的地区名")
@Parameter(name = "ip", description = "IP", required = true)
public CommonResult<String> getAreaByIp(@RequestParam("ip") String ip) {
// 获得城市
Area area = IPUtils.getArea(ip);
if (area == null) {
return success("未知");
}
// 格式化返回
return success(AreaUtils.format(area.getId()));
}
}
@@ -1,23 +0,0 @@
package com.cf.imes.module.system.controller.admin.ip.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
@Schema(description = "管理后台 - 地区节点 Response VO")
@Data
public class AreaNodeRespVO {
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "110000")
private Integer id;
@Schema(description = "名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "北京")
private String name;
/**
* 子节点
*/
private List<AreaNodeRespVO> children;
}
@@ -54,4 +54,8 @@ public class LoginLogRespVO {
@ExcelProperty("登录时间")
private LocalDateTime createTime;
@Schema(description = "所属地区")
@ExcelProperty("所属地区")
private String region;
}
@@ -40,10 +40,25 @@ public class OrganPageReqVO extends PageParam {
/**
* 拼音首字母
*/
@Schema(hidden = true)
private String pyFirstChar;
/**
* 全拼
*/
@Schema(hidden = true)
private String pyAll;
@Schema(description = "")
@Size(max = 64, message = "省名称长度不能超过64个字符")
private String province;
@Schema(description = "")
@Size(max = 64, message = "市名称长度不能超过64个字符")
private String city;
@Schema(description = "")
@Size(max = 64, message = "区名称长度不能超过64个字符")
private String county;
}
@@ -65,4 +65,28 @@ public class OrganRespVO {
@ExcelProperty("备注")
private String remark;
@Schema(description = "")
@ExcelProperty("")
private String province;
@Schema(description = "")
@ExcelProperty("")
private String city;
@Schema(description = "")
@ExcelProperty("")
private String county;
@Schema(description = "地区编码")
@ExcelProperty("地区编码")
private String areaCode;
@Schema(description = "经度")
@ExcelProperty("经度")
private String longitude;
@Schema(description = "纬度")
@ExcelProperty("纬度")
private String latitude;
}
@@ -80,4 +80,28 @@ public class OrganSaveReqVO {
@Size(max = 200, message = "备注长度不能超过200个字符")
private String remark;
@Schema(description = "")
@Size(max = 64, message = "省名称长度不能超过64个字符")
private String province;
@Schema(description = "")
@Size(max = 64, message = "市名称长度不能超过64个字符")
private String city;
@Schema(description = "")
@Size(max = 64, message = "区名称长度不能超过64个字符")
private String county;
@Schema(description = "地区编码")
@Size(max = 64, message = "地区编码长度不能超过64个字符")
private String areaCode;
@Schema(description = "经度")
@Size(max = 64, message = "经度长度不能超过64个字符")
private String longitude;
@Schema(description = "纬度")
@Size(max = 64, message = "纬度长度不能超过64个字符")
private String latitude;
}
@@ -1,7 +1,10 @@
package com.cf.imes.module.system.controller.admin.permission;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.cf.imes.framework.common.enums.CommonStatusEnum;
import com.cf.imes.framework.common.exception.ServiceException;
import com.cf.imes.framework.common.exception.enums.GlobalErrorCodeConstants;
import com.cf.imes.framework.common.pojo.CommonResult;
import com.cf.imes.framework.common.util.object.BeanUtils;
import com.cf.imes.framework.security.core.LoginUser;
@@ -30,7 +33,6 @@ import java.util.*;
import static com.cf.imes.framework.common.pojo.CommonResult.success;
import static com.cf.imes.framework.common.util.collection.CollectionUtils.convertSet;
import static com.cf.imes.framework.security.core.util.SecurityFrameworkUtils.getLoginUser;
import static com.cf.imes.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
@Tag(name = "管理后台 - 菜单")
@RestController
@@ -79,24 +81,29 @@ public class MenuController {
@Operation(summary = "获取菜单列表", description = "用于【菜单管理】界面")
//@PreAuthorize("@ss.hasPermission('system:menu:query')")
public CommonResult<List<MenuRespVO>> getMenuList(MenuListReqVO reqVO) {
List <MenuDO> list = null;
List <MenuDO> list;
LoginUser loginUser = getLoginUser();
if (ObjectUtil.isNull(loginUser)) {
throw new ServiceException(GlobalErrorCodeConstants.UNAUTHORIZED);
}
if(loginUser.getIsSupAdmin()) {
list = menuService.getMenuList(reqVO);
}else {
AdminUserDO user = userService.getUser(getLoginUserId());
AdminUserDO user = userService.getUser(loginUser.getId());
if (user == null) {
return success(new ArrayList<>());
}
Set<Long> roleIds = permissionService.getUserRoleIdListByUserId(getLoginUserId());
// 获取登录用户所属角色
Set<Long> roleIds = permissionService.getUserRoleIdListByUserId(loginUser.getId());
if (CollUtil.isEmpty(roleIds)) {
return success(new ArrayList<>());
}
//List<RoleDO> roles = roleService.getRoleList(roleIds);
// 查询角色并过滤无效的
List<RoleDO> roles = roleService.getRoleList1(roleIds);
roles.removeIf(role -> !CommonStatusEnum.ENABLE.getStatus().equals(role.getStatus())); // 移除禁用的角色
Set<Long> menuIds = permissionService.getRoleMenuListByRoleId2(convertSet(roles, RoleDO::getId));
//List<MenuDO> menuList = menuService.getMenuList(menuIds);
// 查询角色拥有权限的菜单id
Set<Long> menuIds = permissionService.getRoleMenuListByRoleId2(convertSet(roles, RoleDO::getId), loginUser.getOrganId());
list = menuService.getMenuList1(menuIds);
list.removeIf(menu -> !CommonStatusEnum.ENABLE.getStatus().equals(menu.getStatus())); // 移除禁用的菜单
}
@@ -11,6 +11,7 @@ import com.cf.imes.module.system.controller.admin.permission.vo.permission.Permi
import com.cf.imes.module.system.controller.admin.permission.vo.permission.PermissionAssignRoleMenuReqVO;
import com.cf.imes.module.system.controller.admin.permission.vo.permission.PermissionAssignRoleUserReqVO;
import com.cf.imes.module.system.controller.admin.permission.vo.permission.PermissionAssignUserRoleReqVO;
import com.cf.imes.module.system.enums.ErrorCodeConstants;
import com.cf.imes.module.system.service.permission.PermissionService;
import com.cf.imes.module.system.service.organ.OrganService;
import io.swagger.v3.oas.annotations.Operation;
@@ -59,14 +60,14 @@ public class PermissionController {
LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
boolean isOrganRole = Objects.equals(reqVO.getRoleId(), InternalRoleConstants.ORGAN_ADMIN_ROLE_ID) || Objects.equals(reqVO.getRoleId(), InternalRoleConstants.ORGAN_STAFF_ROLE_ID);
if(!loginUser.getIsSupAdmin() && (isOrganRole)) {
throw new ServiceException(11541, "内置角色无权修改菜单权限");
throw new ServiceException(ErrorCodeConstants.BUILDIN_ROLE_MODIFY_PERMISSION_ERROR);
}
if(Objects.equals(reqVO.getRoleId(), 1L)) {
throw new ServiceException(11541, "内置角色无权修改菜单权限");
throw new ServiceException(ErrorCodeConstants.BUILDIN_ROLE_MODIFY_PERMISSION_ERROR);
}
Set<Long> roleIds = permissionService.getUserRoleIdListByUserId(loginUser.getId());
if (roleIds.contains(reqVO.getRoleId())) {
throw new ServiceException(11541, "无法修改自身的角色菜单权限");
throw new ServiceException(ErrorCodeConstants.SELF_ROLE_MODIFY_PERMISSION_ERROR);
}
if (!isOrganRole) {
@@ -1,34 +0,0 @@
package com.cf.imes.module.system.controller.app.ip;
import cn.hutool.core.lang.Assert;
import com.cf.imes.framework.common.pojo.CommonResult;
import com.cf.imes.framework.common.util.object.BeanUtils;
import com.cf.imes.framework.ip.core.Area;
import com.cf.imes.framework.ip.core.utils.AreaUtils;
import com.cf.imes.module.system.controller.app.ip.vo.AppAreaNodeRespVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import static com.cf.imes.framework.common.pojo.CommonResult.success;
@Tag(name = "用户 App - 地区")
@RestController
@RequestMapping("/system/area")
@Validated
public class AppAreaController {
@GetMapping("/tree")
@Operation(summary = "获得地区树")
public CommonResult<List<AppAreaNodeRespVO>> getAreaTree() {
Area area = AreaUtils.getArea(Area.ID_CHINA);
Assert.notNull(area, "获取不到中国");
return success(BeanUtils.toBean(area.getChildren(), AppAreaNodeRespVO.class));
}
}
@@ -1,23 +0,0 @@
package com.cf.imes.module.system.controller.app.ip.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
@Schema(description = "用户 App - 地区节点 Response VO")
@Data
public class AppAreaNodeRespVO {
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "110000")
private Integer id;
@Schema(description = "名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "北京")
private String name;
/**
* 子节点
*/
private List<AppAreaNodeRespVO> children;
}
@@ -1,6 +1,9 @@
package com.cf.imes.module.system.convert.auth;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ObjectUtil;
import com.cf.imes.framework.ip.core.service.dto.IPQueryDataRespDTO;
import com.cf.imes.module.system.api.sms.dto.code.SmsCodeSendReqDTO;
import com.cf.imes.module.system.api.sms.dto.code.SmsCodeUseReqDTO;
import com.cf.imes.module.system.api.social.dto.SocialUserBindReqDTO;
@@ -10,6 +13,7 @@ import com.cf.imes.module.system.controller.admin.auth.vo.AuthSmsLoginReqVO;
import com.cf.imes.module.system.controller.admin.auth.vo.AuthSmsSendReqVO;
import com.cf.imes.module.system.controller.admin.auth.vo.AuthSocialLoginReqVO;
import com.cf.imes.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO;
import com.cf.imes.module.system.dal.dataobject.organ.OrganizationDO;
import com.cf.imes.module.system.dal.dataobject.permission.MenuDO;
import com.cf.imes.module.system.dal.dataobject.permission.RoleDO;
import com.cf.imes.module.system.dal.dataobject.user.AdminUserDO;
@@ -31,10 +35,24 @@ public interface AuthConvert {
AuthLoginRespVO convert(OAuth2AccessTokenDO bean);
default AuthPermissionInfoRespVO convert(AdminUserDO user, List<RoleDO> roleList, List<MenuDO> menuList) {
default AuthPermissionInfoRespVO convert(AdminUserDO user, OrganizationDO organizationDO, IPQueryDataRespDTO ipQueryDataRespDTO, List<RoleDO> roleList, List<MenuDO> menuList) {
boolean ipQuerySuccess = ObjectUtil.isNotNull(ipQueryDataRespDTO);
String region = null;
if (ipQuerySuccess) {
String prov = ipQueryDataRespDTO.getProv();
if (CharSequenceUtil.contains(prov, "未知")) {
region = prov;
} else {
region = StringUtils.join(List.of(prov, ipQueryDataRespDTO.getCity(), ipQueryDataRespDTO.getArea()), "/");
}
}
return AuthPermissionInfoRespVO.builder()
.user(AuthPermissionInfoRespVO.UserVO.builder()
.id(user.getId()).nickname(user.getNickname()).avatar(user.getAvatar()).organId(user.getOrganId()).needSetPwd(StringUtils.isEmpty(user.getPassword())).build())
.id(user.getId()).nickname(user.getNickname()).avatar(user.getAvatar()).organId(user.getOrganId()).needSetPwd(StringUtils.isEmpty(user.getPassword()))
.expireTime(organizationDO.getExpireTime()).ip(ipQuerySuccess ? ipQueryDataRespDTO.getIp() : "")
.region(region)
.build())
.roles(convertSet(roleList, RoleDO::getCode))
// 权限标识信息
.permissions(convertSet(menuList, MenuDO::getPermission))
@@ -1,20 +0,0 @@
package com.cf.imes.module.system.convert.ip;
import com.cf.imes.framework.ip.core.Area;
import com.cf.imes.module.system.controller.admin.ip.vo.AreaNodeRespVO;
import com.cf.imes.module.system.controller.app.ip.vo.AppAreaNodeRespVO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
@Mapper
public interface AreaConvert {
AreaConvert INSTANCE = Mappers.getMapper(AreaConvert.class);
List<AreaNodeRespVO> convertList(List<Area> list);
List<AppAreaNodeRespVO> convertList3(List<Area> list);
}
@@ -69,4 +69,8 @@ public class LoginLogDO extends BaseDO {
*/
private String userAgent;
/**
* 所属地区
*/
private String region;
}
@@ -112,4 +112,34 @@ public class OrganizationDO extends BaseDO {
* 备注
*/
private String remark;
/**
* 省份
*/
private String province;
/**
* 市
*/
private String city;
/**
* 区县
*/
private String county;
/**
* 地区代码
*/
private String areaCode;
/**
* 经度
*/
private String longitude;
/**
* 纬度
*/
private String latitude;
}
@@ -31,6 +31,9 @@ public interface OrganMapper extends BaseMapperX<OrganizationDO> {
.likeIfPresent(OrganizationDO::getContactMobile, reqVO.getContactMobile())
.eqIfPresent(OrganizationDO::getStatus, reqVO.getStatus())
.eqIfPresent(OrganizationDO::getName, reqVO.getExactName())
.eqIfPresent(OrganizationDO::getProvince, reqVO.getProvince())
.eqIfPresent(OrganizationDO::getCity, reqVO.getCity())
.eqIfPresent(OrganizationDO::getCounty, reqVO.getCounty())
.and(CharSequenceUtil.isNotBlank(reqVO.getName()), wrapper ->{
wrapper.or(Boolean.TRUE).like(OrganizationDO::getName, reqVO.getName());
wrapper.or(CharSequenceUtil.isNotBlank(reqVO.getPyAll())).like(OrganizationDO::getPinyinFull, reqVO.getPyAll());
@@ -108,4 +108,10 @@ public class RedisKeyConstants {
* 短信验证码次数上限的缓存
*/
public static final String SMS_CAPTCHA_VERIFICATION_LIMIT = "sms_captcha_verification_limit:%s";
}
/**
* 套餐下的权限菜单id:12h代表key的ttl为12小时
* !!!!注意同步修改OrganRedisCacheManager中的key字符串
*/
public static final String TENANT_PACKAGE_MENU_IDS = "tenant_package_menu_ids#12h";
}
@@ -3,6 +3,7 @@ package com.cf.imes.module.system.dal.redis.listener;
import com.cf.imes.framework.mq.redis.core.pubsub.AbstractRedisSimpleMessageListener;
import com.cf.imes.framework.security.core.service.SecurityFrameworkService;
import com.cf.imes.module.system.dal.redis.RedisRefreshChannelTopicConstants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.stereotype.Component;
@@ -14,6 +15,7 @@ import org.springframework.stereotype.Component;
* @since 2024/6/13 10:32
*/
@Component
@Slf4j
public class SystemPermissionRefreshRedisListener extends AbstractRedisSimpleMessageListener {
private final SecurityFrameworkService securityFrameworkService;
@@ -25,6 +27,7 @@ public class SystemPermissionRefreshRedisListener extends AbstractRedisSimpleMes
@Override
public void onMessage(Message message, byte[] bytes) {
log.info("[SystemPermissionRefreshRedisListener][onMessage][{}收到刷新本地权限缓存]", message);
securityFrameworkService.invalidateAllPermissionsCache();
}
}
@@ -1,38 +0,0 @@
package com.cf.imes.module.system.framework.operatelog.core;
import cn.hutool.core.util.StrUtil;
import com.cf.imes.framework.ip.core.utils.AreaUtils;
import com.mzt.logapi.service.IParseFunction;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
* 地名的 {@link IParseFunction} 实现类
*
* @author HUIHUI
*/
@Slf4j
@Component
public class AreaParseFunction implements IParseFunction {
public static final String NAME = "getArea";
@Override
public boolean executeBefore() {
return true; // 先转换值后对比
}
@Override
public String functionName() {
return NAME;
}
@Override
public String apply(Object value) {
if (StrUtil.isEmptyIfStr(value)) {
return "";
}
return AreaUtils.format(Integer.parseInt(value.toString()));
}
}
@@ -7,9 +7,10 @@ import com.cf.imes.framework.common.exception.util.ServiceExceptionUtil;
import com.cf.imes.framework.common.util.monitor.TracerUtils;
import com.cf.imes.framework.common.util.servlet.ServletUtils;
import com.cf.imes.framework.common.util.validation.ValidationUtils;
import com.cf.imes.framework.ip.core.service.IPQueryService;
import com.cf.imes.framework.ip.core.service.dto.IPQueryDataRespDTO;
import com.cf.imes.module.system.api.logger.dto.LoginLogCreateReqDTO;
import com.cf.imes.module.system.api.sms.SmsCodeApi;
import com.cf.imes.module.system.api.social.dto.SocialUserBindReqDTO;
import com.cf.imes.module.system.api.social.dto.SocialUserRespDTO;
import com.cf.imes.module.system.controller.admin.auth.vo.AuthLoginReqVO;
import com.cf.imes.module.system.controller.admin.auth.vo.AuthLoginRespVO;
@@ -83,6 +84,9 @@ public class AdminAuthServiceImpl implements AdminAuthService {
@Resource
private SmsCodeService smsCodeService;
@Resource
private IPQueryService ipQueryService;
/**
* 验证码的开关,默认为 true
*/
@@ -116,6 +120,7 @@ public class AdminAuthServiceImpl implements AdminAuthService {
return user;
}
@Override
public AuthLoginRespVO login(AuthLoginReqVO reqVO) {
// 校验验证码
@@ -124,11 +129,6 @@ public class AdminAuthServiceImpl implements AdminAuthService {
// 使用账号密码,进行登录
AdminUserDO user = authenticate(reqVO);
// 如果 socialType 非空,说明需要绑定社交用户
if (reqVO.getSocialType() != null) {
socialUserService.bindSocialUser(new SocialUserBindReqDTO(user.getId(), getUserType().getValue(),
reqVO.getSocialType(), reqVO.getSocialCode(), reqVO.getSocialState()));
}
Long organId = user.getOrganId();
OrganizationDO organ = organService.getOrgan(organId);
String dataSourceCode = organ.getDataSourceCode();
@@ -203,6 +203,7 @@ public class AdminAuthServiceImpl implements AdminAuthService {
private void createLoginLog(Long userId, String username,
LoginLogTypeEnum logTypeEnum, LoginResultEnum loginResult) {
String clientIP = getClientIP();
// 插入登录日志
LoginLogCreateReqDTO reqDTO = new LoginLogCreateReqDTO();
reqDTO.setLogType(logTypeEnum.getType());
@@ -211,12 +212,17 @@ public class AdminAuthServiceImpl implements AdminAuthService {
reqDTO.setUserType(getUserType().getValue());
reqDTO.setUsername(username);
reqDTO.setUserAgent(ServletUtils.getUserAgent());
reqDTO.setUserIp(ServletUtils.getClientIP());
reqDTO.setUserIp(clientIP);
reqDTO.setResult(loginResult.getResult());
IPQueryDataRespDTO ipQueryDataRespDTO = ipQueryService.querySource(clientIP);
// 设置登录时通过ip云服务查询到的地域信息
if (ipQueryService.serviceEnable() && ObjectUtil.isNotNull(ipQueryDataRespDTO)) {
reqDTO.setRegion(StringUtils.join(ipQueryDataRespDTO.getProv(), ipQueryDataRespDTO.getCity(), ipQueryDataRespDTO.getArea()));
}
loginLogService.createLoginLog(reqDTO);
// 更新最后登录时间
if (userId != null && Objects.equals(LoginResultEnum.SUCCESS.getResult(), loginResult.getResult())) {
userService.updateUserLogin(userId, ServletUtils.getClientIP());
userService.updateUserLogin(userId, clientIP);
}
}
@@ -311,6 +317,7 @@ public class AdminAuthServiceImpl implements AdminAuthService {
}
private void createLogoutLog(Long userId, Integer userType, Integer logType) {
String clientIP = getClientIP();
LoginLogCreateReqDTO reqDTO = new LoginLogCreateReqDTO();
reqDTO.setLogType(logType);
reqDTO.setTraceId(TracerUtils.getTraceId());
@@ -321,8 +328,13 @@ public class AdminAuthServiceImpl implements AdminAuthService {
} else {
reqDTO.setUsername(memberService.getMemberUserMobile(userId));
}
IPQueryDataRespDTO ipQueryDataRespDTO = ipQueryService.querySource(clientIP);
// 设置登录时通过ip云服务查询到的地域信息
if (ipQueryService.serviceEnable() && ObjectUtil.isNotNull(ipQueryDataRespDTO)) {
reqDTO.setRegion(StringUtils.join(ipQueryDataRespDTO.getProv(), ipQueryDataRespDTO.getCity(), ipQueryDataRespDTO.getArea()));
}
reqDTO.setUserAgent(ServletUtils.getUserAgent());
reqDTO.setUserIp(ServletUtils.getClientIP());
reqDTO.setUserIp(clientIP);
reqDTO.setResult(LoginResultEnum.SUCCESS.getResult());
loginLogService.createLoginLog(reqDTO);
}
@@ -131,7 +131,7 @@ public interface OrganService {
*
* @param id 组织编号
*/
void validOrgan(Long id);
OrganizationDO validOrgan(Long id);
List<OrganSimpleRespVO> getSimpleOrganList(String name);
@@ -101,7 +101,7 @@ public class OrganServiceImpl implements OrganService {
}
@Override
public void validOrgan(Long id) {
public OrganizationDO validOrgan(Long id) {
OrganizationDO organizationDO = getOrgan(id);
if (organizationDO == null) {
throw exception(ORGAN_NOT_EXISTS);
@@ -112,6 +112,10 @@ public class OrganServiceImpl implements OrganService {
if (DateUtils.isExpired(organizationDO.getExpireTime())) {
throw exception(ORGAN_EXPIRE, organizationDO.getName());
}
if (ObjectUtil.isNull(organizationDO.getPackageId())) {
throw exception(TENANT_PACKAGE_NOT_EXISTS);
}
return organizationDO;
}
@Override
@@ -216,7 +220,7 @@ public class OrganServiceImpl implements OrganService {
organMapper.updateById(updateObj);
// 如果套餐发生变化,则修改其角色的权限
if (ObjectUtil.notEqual(tenant.getPackageId(), updateReqVO.getPackageId())) {
updateOrganRoleMenu(tenant.getId(), tenantPackage.getMenuIds());
permissionService.flushCacheWhenTenantPackageChange(List.of(tenant.getId()));
}
}
@@ -7,6 +7,7 @@ import com.cf.imes.module.system.dal.dataobject.organ.TenantPackageDO;
import javax.validation.Valid;
import java.util.List;
import java.util.Set;
/**
* 组织套餐 Service 接口
@@ -72,4 +73,11 @@ public interface TenantPackageService {
*/
List<TenantPackageDO> getTenantPackageListByStatus(Integer status);
/**
* 获取组织套餐下的权限菜单id
*
* @param id 组织套餐id
* @return
*/
Set<Long> getTenantPackageMenuIds(Long id);
}
@@ -5,6 +5,7 @@ import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.cf.imes.framework.common.enums.CommonStatusEnum;
import com.cf.imes.framework.common.pojo.PageResult;
import com.cf.imes.framework.common.util.collection.CollectionUtils;
import com.cf.imes.framework.common.util.object.BeanUtils;
import com.cf.imes.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.cf.imes.framework.security.core.util.SecurityFrameworkUtils;
@@ -14,6 +15,10 @@ import com.cf.imes.module.system.dal.dataobject.organ.OrganizationDO;
import com.cf.imes.module.system.dal.dataobject.organ.TenantPackageDO;
import com.cf.imes.module.system.dal.mysql.organ.TenantPackageMapper;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.cf.imes.module.system.dal.redis.RedisKeyConstants;
import com.cf.imes.module.system.service.permission.PermissionService;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
@@ -21,6 +26,7 @@ import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import static com.cf.imes.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.*;
@@ -41,7 +47,11 @@ public class TenantPackageServiceImpl implements TenantPackageService {
@Lazy // 避免循环依赖的报错
private OrganService organService;
@Resource
private PermissionService permissionService;
@Override
@CacheEvict(value = RedisKeyConstants.TENANT_PACKAGE_MENU_IDS, key = "#createReqVO.id")
public Long createTenantPackage(TenantPackageSaveReqVO createReqVO) {
// 唯一性校验
validateTenantPackageUnique(createReqVO);
@@ -54,6 +64,7 @@ public class TenantPackageServiceImpl implements TenantPackageService {
@Override
@DSTransactional // 多数据源,使用 @DSTransactional 保证本地事务,以及数据源的切换
@CacheEvict(value = RedisKeyConstants.TENANT_PACKAGE_MENU_IDS, key = "#updateReqVO.id")
public void updateTenantPackage(TenantPackageSaveReqVO updateReqVO) {
// 唯一性校验
validateTenantPackageUnique(updateReqVO);
@@ -70,11 +81,12 @@ public class TenantPackageServiceImpl implements TenantPackageService {
// 如果菜单发生变化,则修改每个组织的菜单
if (!CollUtil.isEqualList(tenantPackage.getMenuIds(), updateReqVO.getMenuIds())) {
List<OrganizationDO> tenants = organService.getOrganListByPackageId(tenantPackage.getId());
tenants.forEach(tenant -> organService.updateOrganRoleMenu(tenant.getId(), updateReqVO.getMenuIds()));
permissionService.flushCacheWhenTenantPackageChange(CollectionUtils.convertList(tenants, OrganizationDO::getId));
}
}
@Override
@CacheEvict(value = RedisKeyConstants.TENANT_PACKAGE_MENU_IDS, key = "#id")
public void deleteTenantPackage(Long id) {
// 校验存在
validateTenantPackageExists(id);
@@ -144,4 +156,15 @@ public class TenantPackageServiceImpl implements TenantPackageService {
return tenantPackageMapper.selectListByStatus(status);
}
@Override
@Cacheable(value = RedisKeyConstants.TENANT_PACKAGE_MENU_IDS, key = "#id", unless = "#result == null", cacheManager = "redisCacheManager")
public Set<Long> getTenantPackageMenuIds(Long id) {
validateTenantPackageExists(id);
TenantPackageDO tenantPackageDO = tenantPackageMapper.selectOne(new LambdaQueryWrapper<TenantPackageDO>().eq(TenantPackageDO::getId, id).select(TenantPackageDO::getMenuIds));
if (ObjectUtil.isNotNull(tenantPackageDO)) {
return tenantPackageDO.getMenuIds();
} else {
return null;
}
}
}
@@ -154,7 +154,14 @@ public interface PermissionService {
*/
DeptDataPermissionRespDTO getDeptDataPermission(Long userId);
Set<Long> getRoleMenuListByRoleId2(Set<Long> roleIds);
/**
* 查询角色id列表下所拥有的权限菜单,通过组织所配的菜单做过滤
*
* @param roleIds 角色id列表
* @param organId 组织id
* @return
*/
Set<Long> getRoleMenuListByRoleId2(Set<Long> roleIds,Long organId);
void bathAssignUserRole(List<PermissionAssignUserRoleReqVO> listReqVO);
@@ -181,4 +188,11 @@ public interface PermissionService {
* 判断用户是否拥有相对应的权限
*/
Boolean hasPermission(Long userId, String permission);
/**
* 组织套餐发生改变刷新缓存
*
* @param organIds 组织id列表
*/
void flushCacheWhenTenantPackageChange(List<Long> organIds);
}
@@ -6,6 +6,7 @@ import cn.hutool.core.util.ObjectUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.cf.imes.framework.common.enums.CommonStatusEnum;
import com.cf.imes.framework.common.exception.ServiceException;
import com.cf.imes.framework.common.exception.enums.GlobalErrorCodeConstants;
import com.cf.imes.framework.common.util.collection.CollectionUtils;
import com.cf.imes.framework.common.util.json.JsonUtils;
import com.cf.imes.framework.datapermission.core.annotation.DataPermission;
@@ -19,10 +20,12 @@ import com.cf.imes.module.system.constants.permission.InternalRoleConstants;
import com.cf.imes.module.system.controller.admin.permission.vo.permission.PermissionAssignRoleUserReqVO;
import com.cf.imes.module.system.controller.admin.permission.vo.permission.PermissionAssignUserRoleReqVO;
import com.cf.imes.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO;
import com.cf.imes.module.system.dal.dataobject.organ.OrganizationDO;
import com.cf.imes.module.system.dal.dataobject.permission.MenuDO;
import com.cf.imes.module.system.dal.dataobject.permission.RoleDO;
import com.cf.imes.module.system.dal.dataobject.permission.RoleMenuDO;
import com.cf.imes.module.system.dal.dataobject.permission.UserRoleDO;
import com.cf.imes.module.system.dal.dataobject.user.AdminUserDO;
import com.cf.imes.module.system.dal.mysql.permission.RoleMenuMapper;
import com.cf.imes.module.system.dal.mysql.permission.UserRoleMapper;
import com.cf.imes.module.system.dal.redis.RedisKeyConstants;
@@ -30,6 +33,8 @@ import com.cf.imes.module.system.dal.redis.RedisRefreshChannelTopicConstants;
import com.cf.imes.module.system.enums.ErrorCodeConstants;
import com.cf.imes.module.system.enums.permission.DataScopeEnum;
import com.cf.imes.module.system.service.dept.DeptService;
import com.cf.imes.module.system.service.organ.OrganService;
import com.cf.imes.module.system.service.organ.TenantPackageService;
import com.cf.imes.module.system.service.user.AdminUserService;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.cf.imes.module.system.util.organ.OrganUtils;
@@ -40,6 +45,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.core.StringRedisTemplate;
@@ -56,7 +62,7 @@ import java.util.stream.Collectors;
import static com.cf.imes.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.cf.imes.framework.common.util.collection.CollectionUtils.convertSet;
import static com.cf.imes.framework.common.util.json.JsonUtils.toJsonString;
import static com.cf.imes.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
import static com.cf.imes.framework.security.core.util.SecurityFrameworkUtils.getLoginUser;
import static com.cf.imes.module.system.dal.redis.RedisKeyConstants.OAUTH2_ACCESS_TOKEN;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.ROLE_ME_ERROR;
@@ -86,6 +92,14 @@ public class PermissionServiceImpl implements PermissionService {
@Resource
private StringRedisTemplate stringRedisTemplate;
@Resource
@Lazy // 延迟,避免循环依赖报错
private TenantPackageService tenantPackageService;
@Resource
@Lazy // 延迟,避免循环依赖报错
private OrganService organService;
@Override
public boolean hasAnyPermissions(Long userId, String... permissions) {
// 如果为空,说明已经有权限
@@ -99,9 +113,15 @@ public class PermissionServiceImpl implements PermissionService {
return false;
}
AdminUserDO user = userService.getUser(userId);
if (ObjectUtil.isNull(user)) {
throw new ServiceException(ErrorCodeConstants.USER_NOT_EXISTS);
}
OrganizationDO organizationDO = organService.validOrgan(user.getOrganId());
// 情况一:遍历判断每个权限,如果有一满足,说明有权限
for (String permission : permissions) {
if (hasAnyPermission(roles, permission)) {
if (hasAnyPermission(roles, permission, organizationDO.getPackageId())) {
return true;
}
}
@@ -117,13 +137,16 @@ public class PermissionServiceImpl implements PermissionService {
* @param permission 权限标识
* @return 是否拥有
*/
private boolean hasAnyPermission(List<RoleDO> roles, String permission) {
private boolean hasAnyPermission(List<RoleDO> roles, String permission, Long packageId) {
List<Long> menuIds = menuService.getMenuIdListByPermissionFromCache(permission);
// 采用严格模式,如果权限找不到对应的 Menu 的话,也认为没有权限
if (CollUtil.isEmpty(menuIds)) {
return false;
}
// 组织套餐下的菜单
Set<Long> tenantPackageMenuIds = tenantPackageService.getTenantPackageMenuIds(packageId);
// 判断是否有权限
Set<Long> roleIds = convertSet(roles, RoleDO::getId);
for (Long menuId : menuIds) {
@@ -131,7 +154,8 @@ public class PermissionServiceImpl implements PermissionService {
//Set<Long> menuRoleIds = getSelf().getMenuRoleIdListByMenuIdFromCache(menuId);
Set<Long> menuRoleIds = getSelf().getMenuRoleIdListByMenuIdFromCache1(menuId);
// 如果有交集,说明有权限
if (CollUtil.containsAny(menuRoleIds, roleIds)) {
// 角色下菜单id和组织套餐内菜单id必须同时满足
if (CollUtil.containsAny(menuRoleIds, roleIds) && tenantPackageMenuIds.contains(menuId)) {
return true;
}
}
@@ -241,7 +265,9 @@ public class PermissionServiceImpl implements PermissionService {
} else {
userIds = userRoleMapper.selectOrgRoleUserIds(roleId).stream().map(UserRoleDO::getUserId).toList();
}
scanAndCompareUserAndDelKeys(String.format(OAUTH2_ACCESS_TOKEN, "*"), userIds);
if (CollUtil.isNotEmpty(userIds)) {
scanAndCompareUserAndDelKeys(String.format(OAUTH2_ACCESS_TOKEN, "*"), userIds);
}
})
.exceptionally(e -> {
log.error("[assignRoleMenu][flushRoleMenuCache]失败, 异常:{}", e);
@@ -353,7 +379,7 @@ public class PermissionServiceImpl implements PermissionService {
@Override
@OrganIgnore
public Set<Long> getRoleMenuListByRoleId2(Set<Long> roleIds) {
public Set<Long> getRoleMenuListByRoleId2(Set<Long> roleIds, Long organId) {
if (CollUtil.isEmpty(roleIds)) {
return Collections.emptySet();
}
@@ -361,17 +387,27 @@ public class PermissionServiceImpl implements PermissionService {
// 如果是管理员的情况下,获取全部菜单编号
if (roleService.hasAnySuperAdmin(roleIds)) {
return convertSet(menuService.getMenuList(), MenuDO::getId);
}
List<Long> buildinRoleIdList = new ArrayList<>(){{
add(InternalRoleConstants.ORGAN_ADMIN_ROLE_ID);
add(InternalRoleConstants.ORGAN_STAFF_ROLE_ID);
}};
if (CollUtil.containsAny(roleIds, buildinRoleIdList)) {
// 内置角色不限制组织id
return convertSet(roleMenuMapper.selectListByRoleId(roleIds), RoleMenuDO::getMenuId);
} else {
// 普通成员只能看组织id下的菜单
return convertSet(roleMenuMapper.selectListByRoleIdsAndOrganId(roleIds, OrganContextHolder.getOrganId()), RoleMenuDO::getMenuId);
List<Long> buildinRoleIdList = new ArrayList<>(){{
add(InternalRoleConstants.ORGAN_ADMIN_ROLE_ID);
add(InternalRoleConstants.ORGAN_STAFF_ROLE_ID);
}};
Set<Long> roleMenuIds;
if (CollUtil.containsAny(roleIds, buildinRoleIdList)) {
// 内置角色不限制组织id
roleMenuIds = convertSet(roleMenuMapper.selectListByRoleId(roleIds), RoleMenuDO::getMenuId);
} else {
// 普通成员只能看组织id下的菜单
roleMenuIds = convertSet(roleMenuMapper.selectListByRoleIdsAndOrganId(roleIds, OrganContextHolder.getOrganId()), RoleMenuDO::getMenuId);
}
// 校验、获取可用的组织
OrganizationDO organ = organService.validOrgan(organId);
Set<Long> tenantPackageMenuIds = tenantPackageService.getTenantPackageMenuIds(organ.getPackageId());
return Sets.intersection(roleMenuIds, tenantPackageMenuIds);
}
}
@@ -677,8 +713,12 @@ public class PermissionServiceImpl implements PermissionService {
*/
@Override
public Set<String> getUserPermissions(Long userId) {
LoginUser loginUser = getLoginUser();
if (ObjectUtil.isNull(loginUser)) {
throw new ServiceException(GlobalErrorCodeConstants.UNAUTHORIZED);
}
// 1.2 获得角色列表
Set<Long> roleIds = getUserRoleIdListByUserId(getLoginUserId());
Set<Long> roleIds = getUserRoleIdListByUserId(loginUser.getId());
if (CollUtil.isEmpty(roleIds)) {
return Collections.emptySet();
}
@@ -686,7 +726,7 @@ public class PermissionServiceImpl implements PermissionService {
roles.removeIf(role -> !CommonStatusEnum.ENABLE.getStatus().equals(role.getStatus())); // 移除禁用的角色
// 1.3 获得菜单列表
Set<Long> menuIds = getRoleMenuListByRoleId2(convertSet(roles, RoleDO::getId));
Set<Long> menuIds = getRoleMenuListByRoleId2(convertSet(roles, RoleDO::getId), loginUser.getOrganId());
List<MenuDO> menuList = menuService.getMenuList1(menuIds);
menuList.removeIf(menu -> !CommonStatusEnum.ENABLE.getStatus().equals(menu.getStatus())); // 移除禁用的菜单
@@ -699,4 +739,28 @@ public class PermissionServiceImpl implements PermissionService {
return permissions.contains(permission);
}
@Override
public void flushCacheWhenTenantPackageChange(List<Long> organIds) {
if (CollUtil.isEmpty(organIds)) {
return;
}
CompletableFuture.runAsync(() -> {
for (Long organId : organIds) {
// 清空机构下的用户的token缓存
List<AdminUserDO> organUsers = userService.getOrganUsers(organId);
if (CollUtil.isNotEmpty(organUsers)) {
List<Long> userIds = CollectionUtils.convertList(organUsers, AdminUserDO::getId);
scanAndCompareUserAndDelKeys(String.format(OAUTH2_ACCESS_TOKEN, "*"), userIds);
}
}
})
.thenRunAsync(() -> {
//通知刷新本地权限缓存
stringRedisTemplate.convertAndSend(RedisRefreshChannelTopicConstants.PERMISSION_REFRESH, "");
})
.exceptionally(e -> {
log.error("[PermissionService][flushCacheWhenTenantPackageChange]失败, 异常:{}", e);
return null;
});
}
}
@@ -281,4 +281,12 @@ public interface AdminUserService {
* @param reqVO 用户个人信息
*/
void updateUserSecurityPhone(Long id, @Valid UserMobileUpdateReqVO reqVO);
/**
* 获取机构下的用户
*
* @param organId
* @return
*/
List<AdminUserDO> getOrganUsers(Long organId);
}
@@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.cf.imes.framework.common.enums.CommonStatusEnum;
import com.cf.imes.framework.common.enums.UserTypeEnum;
@@ -784,4 +785,10 @@ public class AdminUserServiceImpl implements AdminUserService {
// 将时间设置为 0 点
return LocalDateTime.of(firstDayOfMonth, LocalTime.MIDNIGHT);
}
@Override
@OrganIgnore
public List<AdminUserDO> getOrganUsers(Long organId) {
return userMapper.selectList(new LambdaQueryWrapper<AdminUserDO>().eq(AdminUserDO::getOrganId, organId));
}
}
@@ -213,4 +213,8 @@ chenfeng:
encrypt:
enable: false
publicKey: cfimes
ipquery:
enable: true
apiUrl: https://ipquery.market.alicloudapi.com/query
appCode: hBeRhmOnCR8f/XiD8zJ3lDaBSjbBA5ZZA2OEGswEOYQOK/hXVaT8E+AUOnEBcgFiw0R+39BvQ6TOVe2k
debug: false