mirror of
http://192.168.1.205:9980/cf_devdept2/cf_imes_server.git
synced 2026-08-12 21:02:08 +08:00
新增组织产品有效性的检查能力
This commit is contained in:
+1
@@ -25,6 +25,7 @@ public class GlobalErrorCodeConstants {
|
|||||||
public static final ErrorCode METHOD_NOT_ALLOWED = new ErrorCode(405, "请求方法不正确");
|
public static final ErrorCode METHOD_NOT_ALLOWED = new ErrorCode(405, "请求方法不正确");
|
||||||
public static final ErrorCode LOCKED = new ErrorCode(423, "请求失败,请稍后重试"); // 并发请求,不允许
|
public static final ErrorCode LOCKED = new ErrorCode(423, "请求失败,请稍后重试"); // 并发请求,不允许
|
||||||
public static final ErrorCode TOO_MANY_REQUESTS = new ErrorCode(429, "请求过于频繁,请稍后重试");
|
public static final ErrorCode TOO_MANY_REQUESTS = new ErrorCode(429, "请求过于频繁,请稍后重试");
|
||||||
|
public static final ErrorCode ORG_PRODUCT_EXPIRED = new ErrorCode(410, "组织产品套餐已过期,请续费后继续使用");
|
||||||
|
|
||||||
// ========== 服务端错误段 ==========
|
// ========== 服务端错误段 ==========
|
||||||
|
|
||||||
|
|||||||
+5
@@ -32,6 +32,11 @@ public class OrganProperties {
|
|||||||
*/
|
*/
|
||||||
private Set<String> ignoreUrls = Collections.emptySet();
|
private Set<String> ignoreUrls = Collections.emptySet();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 需要忽略产品检查的请求
|
||||||
|
*/
|
||||||
|
private Set<String> ignoreProductUrls = Collections.emptySet();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 需要忽略多组织的表
|
* 需要忽略多组织的表
|
||||||
*
|
*
|
||||||
|
|||||||
+35
-2
@@ -2,6 +2,7 @@ package com.cf.imes.framework.organ.core.security;
|
|||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import com.cf.imes.framework.common.enums.UserTypeEnum;
|
||||||
import com.cf.imes.framework.common.exception.ServiceException;
|
import com.cf.imes.framework.common.exception.ServiceException;
|
||||||
import com.cf.imes.framework.common.exception.enums.GlobalErrorCodeConstants;
|
import com.cf.imes.framework.common.exception.enums.GlobalErrorCodeConstants;
|
||||||
import com.cf.imes.framework.common.pojo.CommonResult;
|
import com.cf.imes.framework.common.pojo.CommonResult;
|
||||||
@@ -23,6 +24,7 @@ import jakarta.servlet.FilterChain;
|
|||||||
import jakarta.servlet.ServletException;
|
import jakarta.servlet.ServletException;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@@ -31,7 +33,7 @@ import java.util.Objects;
|
|||||||
* 1. 如果是登陆的用户,校验是否有权限访问该组织,避免越权问题。
|
* 1. 如果是登陆的用户,校验是否有权限访问该组织,避免越权问题。
|
||||||
* 2. 如果请求未带组织的编号,检查是否是忽略的 URL,否则也不允许访问。
|
* 2. 如果请求未带组织的编号,检查是否是忽略的 URL,否则也不允许访问。
|
||||||
* 3. 校验组织是合法,例如说被禁用、到期
|
* 3. 校验组织是合法,例如说被禁用、到期
|
||||||
*
|
* <p>
|
||||||
* 校验用户访问的组织,是否是其所在的组织,
|
* 校验用户访问的组织,是否是其所在的组织,
|
||||||
*
|
*
|
||||||
* @author 晨丰科技
|
* @author 晨丰科技
|
||||||
@@ -70,7 +72,7 @@ public class OrganSecurityWebFilter extends ApiRequestFilter {
|
|||||||
if (organId == null) {
|
if (organId == null) {
|
||||||
organId = user.getOrganId();
|
organId = user.getOrganId();
|
||||||
OrganContextHolder.setOrganId(organId);
|
OrganContextHolder.setOrganId(organId);
|
||||||
// 如果传递了组织编号,则进行比对组织编号,避免越权问题
|
// 如果传递了组织编号,则进行比对组织编号,避免越权问题
|
||||||
} else if (!Objects.equals(user.getOrganId(), OrganContextHolder.getOrganId())) { // Cloud 特殊逻辑:如果是 RPC 请求,就不校验了。主要考虑,一些场景下,会调用 OrganUtils 去切换组织
|
} else if (!Objects.equals(user.getOrganId(), OrganContextHolder.getOrganId())) { // Cloud 特殊逻辑:如果是 RPC 请求,就不校验了。主要考虑,一些场景下,会调用 OrganUtils 去切换组织
|
||||||
log.error("[doFilterInternal][组织({}) User({}/{}) 越权访问组织({}) URL({}/{})]",
|
log.error("[doFilterInternal][组织({}) User({}/{}) 越权访问组织({}) URL({}/{})]",
|
||||||
user.getOrganId(), user.getId(), user.getUserType(),
|
user.getOrganId(), user.getId(), user.getUserType(),
|
||||||
@@ -98,6 +100,10 @@ public class OrganSecurityWebFilter extends ApiRequestFilter {
|
|||||||
// 校验部门
|
// 校验部门
|
||||||
organFrameworkService.validDept(deptId);
|
organFrameworkService.validDept(deptId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 校验组织产品有效性
|
||||||
|
validOrgnProduct(user, request);
|
||||||
|
|
||||||
} catch (Throwable ex) {
|
} catch (Throwable ex) {
|
||||||
CommonResult<?> result = globalExceptionHandler.allExceptionHandler(request, ex);
|
CommonResult<?> result = globalExceptionHandler.allExceptionHandler(request, ex);
|
||||||
// 组织失效返回401踢出系统
|
// 组织失效返回401踢出系统
|
||||||
@@ -115,6 +121,19 @@ public class OrganSecurityWebFilter extends ApiRequestFilter {
|
|||||||
chain.doFilter(request, response);
|
chain.doFilter(request, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验组织产品有效性
|
||||||
|
*
|
||||||
|
* @param user
|
||||||
|
* @param request
|
||||||
|
*/
|
||||||
|
private void validOrgnProduct(LoginUser user, HttpServletRequest request) {
|
||||||
|
// 非管理端校验产品的有效性
|
||||||
|
if (!Objects.equals(user.getUserType(), UserTypeEnum.ADMIN.getValue()) && !isProductIgnoreUrl(request)) {
|
||||||
|
organFrameworkService.validOrgProduct(user.getOrganId(), user.getProductId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private boolean isIgnoreUrl(HttpServletRequest request) {
|
private boolean isIgnoreUrl(HttpServletRequest request) {
|
||||||
// 快速匹配,保证性能
|
// 快速匹配,保证性能
|
||||||
if (CollUtil.contains(organProperties.getIgnoreUrls(), request.getRequestURI())) {
|
if (CollUtil.contains(organProperties.getIgnoreUrls(), request.getRequestURI())) {
|
||||||
@@ -129,6 +148,20 @@ public class OrganSecurityWebFilter extends ApiRequestFilter {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isProductIgnoreUrl(HttpServletRequest request) {
|
||||||
|
// 快速匹配,保证性能
|
||||||
|
if (CollUtil.contains(organProperties.getIgnoreProductUrls(), request.getRequestURI())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// 逐个 Ant 路径匹配
|
||||||
|
for (String url : organProperties.getIgnoreProductUrls()) {
|
||||||
|
if (pathMatcher.match(url, request.getRequestURI())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否组织失效设置未登录回调
|
* 是否组织失效设置未登录回调
|
||||||
*
|
*
|
||||||
|
|||||||
+8
@@ -29,4 +29,12 @@ public interface OrganFrameworkService {
|
|||||||
* @param id
|
* @param id
|
||||||
*/
|
*/
|
||||||
void validDept(Long id);
|
void validDept(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验组织产品是否有效
|
||||||
|
*
|
||||||
|
* @param organId
|
||||||
|
* @param productId
|
||||||
|
*/
|
||||||
|
void validOrgProduct(Long organId, Long productId);
|
||||||
}
|
}
|
||||||
|
|||||||
+21
@@ -1,5 +1,6 @@
|
|||||||
package com.cf.imes.framework.organ.core.service;
|
package com.cf.imes.framework.organ.core.service;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.Pair;
|
||||||
import com.cf.imes.framework.common.pojo.CommonResult;
|
import com.cf.imes.framework.common.pojo.CommonResult;
|
||||||
import com.cf.imes.framework.common.util.cache.CacheUtils;
|
import com.cf.imes.framework.common.util.cache.CacheUtils;
|
||||||
import com.cf.imes.module.system.api.dept.DeptApi;
|
import com.cf.imes.module.system.api.dept.DeptApi;
|
||||||
@@ -66,6 +67,20 @@ public class OrganFrameworkServiceImpl implements OrganFrameworkService {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 针对 {@link #validOrgProduct(Long, Long)} 的缓存
|
||||||
|
*/
|
||||||
|
private final LoadingCache<Pair<Long, Long>, CommonResult<Boolean>> validOrgProduct = CacheUtils.buildCache(
|
||||||
|
Duration.ofMinutes(1L), // 过期时间 1 分钟
|
||||||
|
new CacheLoader<>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResult<Boolean> load(Pair<Long, Long> pair) {
|
||||||
|
return organApi.validOrganProduct(pair.getKey(), pair.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public List<Long> getOrganIds() {
|
public List<Long> getOrganIds() {
|
||||||
@@ -83,4 +98,10 @@ public class OrganFrameworkServiceImpl implements OrganFrameworkService {
|
|||||||
public void validDept(Long id) {
|
public void validDept(Long id) {
|
||||||
validOrganDept.get(id).checkError();
|
validOrganDept.get(id).checkError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SneakyThrows
|
||||||
|
public void validOrgProduct(Long organId, Long productId) {
|
||||||
|
validOrgProduct.get(new Pair<>(organId, productId)).checkError();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
@@ -85,4 +85,9 @@ public class LoginUser {
|
|||||||
* 用户昵称
|
* 用户昵称
|
||||||
*/
|
*/
|
||||||
private String nickname;
|
private String nickname;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 产品id
|
||||||
|
*/
|
||||||
|
private Long productId;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -101,7 +101,8 @@ public class TokenAuthenticationFilter extends OncePerRequestFilter {
|
|||||||
// 构建登录用户
|
// 构建登录用户
|
||||||
return new LoginUser().setId(accessToken.getUserId()).setUserType(accessToken.getUserType())
|
return new LoginUser().setId(accessToken.getUserId()).setUserType(accessToken.getUserType())
|
||||||
.setOrganId(accessToken.getOrganId()).setScopes(accessToken.getScopes()).setIsSupAdmin(accessToken.getIsSupAdmin())
|
.setOrganId(accessToken.getOrganId()).setScopes(accessToken.getScopes()).setIsSupAdmin(accessToken.getIsSupAdmin())
|
||||||
.setLarge(accessToken.getLarge()).setDbNo(accessToken.getDbNo()).setTableNo(accessToken.getTableNo());
|
.setLarge(accessToken.getLarge()).setDbNo(accessToken.getDbNo()).setTableNo(accessToken.getTableNo())
|
||||||
|
.setProductId(accessToken.getProductId());
|
||||||
} catch (ServiceException serviceException) {
|
} catch (ServiceException serviceException) {
|
||||||
// 校验 Token 不通过时,考虑到一些接口是无需登录的,所以直接返回 null 即可
|
// 校验 Token 不通过时,考虑到一些接口是无需登录的,所以直接返回 null 即可
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
+13
@@ -178,4 +178,17 @@ public class SecurityFrameworkUtils {
|
|||||||
Long organId = (organIds != null && organIds.length > 0) ? organIds[0] : getUserOrganId();
|
Long organId = (organIds != null && organIds.length > 0) ? organIds[0] : getUserOrganId();
|
||||||
return Objects.equals(organId, CF_ORGANID);
|
return Objects.equals(organId, CF_ORGANID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前登录用户的productId
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static Long getProductId() {
|
||||||
|
LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
|
||||||
|
if (ObjectUtil.isNull(loginUser)) {
|
||||||
|
throw new ServiceException(GlobalErrorCodeConstants.UNAUTHORIZED);
|
||||||
|
}
|
||||||
|
return loginUser.getProductId();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,4 +69,10 @@ public class LoginUser {
|
|||||||
* 灰度默认版本号
|
* 灰度默认版本号
|
||||||
*/
|
*/
|
||||||
private String grayDefaultVersion;
|
private String grayDefaultVersion;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 产品id
|
||||||
|
*/
|
||||||
|
private Long productId;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -151,7 +151,8 @@ public class TokenAuthenticationFilter implements GlobalFilter, Ordered {
|
|||||||
.setLarge(tokenInfo.getLarge()).setDbNo(tokenInfo.getDbNo()).setTableNo(tokenInfo.getTableNo())
|
.setLarge(tokenInfo.getLarge()).setDbNo(tokenInfo.getDbNo()).setTableNo(tokenInfo.getTableNo())
|
||||||
.setDataCode(tokenInfo.getDataCode()).setIsSupAdmin(tokenInfo.getIsSupAdmin())
|
.setDataCode(tokenInfo.getDataCode()).setIsSupAdmin(tokenInfo.getIsSupAdmin())
|
||||||
.setNickname(tokenInfo.getNickname()).setDeptId(tokenInfo.getDeptId())
|
.setNickname(tokenInfo.getNickname()).setDeptId(tokenInfo.getDeptId())
|
||||||
.setGrayVersion(tokenInfo.getGrayVersion()).setGrayDefaultVersion(tokenInfo.getGrayDefaultVersion());
|
.setGrayVersion(tokenInfo.getGrayVersion()).setGrayDefaultVersion(tokenInfo.getGrayDefaultVersion())
|
||||||
|
.setProductId(tokenInfo.getProductId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+3
@@ -43,4 +43,7 @@ public class OAuth2AccessTokenCheckRespDTO implements Serializable {
|
|||||||
|
|
||||||
@Schema(description = "灰度默认版本号", example = "1")
|
@Schema(description = "灰度默认版本号", example = "1")
|
||||||
private String grayDefaultVersion;
|
private String grayDefaultVersion;
|
||||||
|
|
||||||
|
@Schema(description = "产品id", example = "1")
|
||||||
|
private Long productId;
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-1
@@ -53,5 +53,9 @@ public interface OrganApi {
|
|||||||
@Operation(summary = "根据组织名称获取组织的信息")
|
@Operation(summary = "根据组织名称获取组织的信息")
|
||||||
CommonResult<List<OrganizationDTO>> getOrganDetailsByName(@RequestParam("organName") String organName);
|
CommonResult<List<OrganizationDTO>> getOrganDetailsByName(@RequestParam("organName") String organName);
|
||||||
|
|
||||||
|
@GetMapping(PREFIX + "/valid/product")
|
||||||
|
@Operation(summary = "校验组织产品是否有效")
|
||||||
|
@Parameter(name = "organId", description = "组织编号", required = true, example = "1024")
|
||||||
|
@Parameter(name = "productId", description = "产品编号", required = true, example = "1024")
|
||||||
|
CommonResult<Boolean> validOrganProduct(@RequestParam("organId") Long organId, @RequestParam("id") Long productId);
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-3
@@ -8,7 +8,8 @@ import com.cf.imes.module.system.api.organ.dto.OrgStatisticsIsLapseRespDTO;
|
|||||||
import com.cf.imes.module.system.api.organ.dto.OrgStatisticsReqDTO;
|
import com.cf.imes.module.system.api.organ.dto.OrgStatisticsReqDTO;
|
||||||
import com.cf.imes.module.system.api.organ.dto.OrganizationDTO;
|
import com.cf.imes.module.system.api.organ.dto.OrganizationDTO;
|
||||||
import com.cf.imes.module.system.controller.admin.organ.vo.organ.OrganRespVO;
|
import com.cf.imes.module.system.controller.admin.organ.vo.organ.OrganRespVO;
|
||||||
import com.cf.imes.module.system.dal.mysql.organ.OrganMapper;
|
import com.cf.imes.module.system.dal.dataobject.funds.purchase.PurchaseRecordDO;
|
||||||
|
import com.cf.imes.module.system.service.funds.purchase.PurchaseService;
|
||||||
import com.cf.imes.module.system.service.organ.OrganService;
|
import com.cf.imes.module.system.service.organ.OrganService;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
@@ -19,6 +20,8 @@ import java.time.LocalDateTime;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static com.cf.imes.framework.common.exception.enums.GlobalErrorCodeConstants.ORG_PRODUCT_EXPIRED;
|
||||||
|
import static com.cf.imes.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
import static com.cf.imes.framework.common.pojo.CommonResult.success;
|
import static com.cf.imes.framework.common.pojo.CommonResult.success;
|
||||||
import static com.cf.imes.framework.common.util.time.StatisticsChangeUtils.generateDateRangeAxis;
|
import static com.cf.imes.framework.common.util.time.StatisticsChangeUtils.generateDateRangeAxis;
|
||||||
import static com.cf.imes.framework.common.util.time.StatisticsChangeUtils.getDateList;
|
import static com.cf.imes.framework.common.util.time.StatisticsChangeUtils.getDateList;
|
||||||
@@ -30,9 +33,8 @@ public class OrganApiImpl implements OrganApi {
|
|||||||
@Resource
|
@Resource
|
||||||
private OrganService organService;
|
private OrganService organService;
|
||||||
|
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private OrganMapper organMapper;
|
private PurchaseService purchaseService;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -139,4 +141,15 @@ public class OrganApiImpl implements OrganApi {
|
|||||||
LocalDate[] time = reqVO.getCreateTime();
|
LocalDate[] time = reqVO.getCreateTime();
|
||||||
reqVO.setCreateTime(new LocalDate[]{time[0], time[1]});
|
reqVO.setCreateTime(new LocalDate[]{time[0], time[1]});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResult<Boolean> validOrganProduct(Long organId, Long productId) {
|
||||||
|
List<PurchaseRecordDO> purchaseList = purchaseService.getOrgProductPurchaseList(organId, productId);
|
||||||
|
// 如果购买记录存在大于等于当前时间的记录,则是有效期内
|
||||||
|
boolean anyMatch = purchaseList.stream().anyMatch(p -> p.getEndTime().isAfter(LocalDate.now()) || p.getEndTime().isEqual(LocalDate.now()));
|
||||||
|
if (!anyMatch) {
|
||||||
|
throw exception(ORG_PRODUCT_EXPIRED);
|
||||||
|
}
|
||||||
|
return success(anyMatch);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
-1
@@ -54,6 +54,5 @@ public class TenantPackageDO extends BaseDO {
|
|||||||
/**
|
/**
|
||||||
* 产品id
|
* 产品id
|
||||||
*/
|
*/
|
||||||
@TableField(exist = false)
|
|
||||||
private Long productId;
|
private Long productId;
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-1
@@ -161,9 +161,12 @@ public class AdminAuthServiceImpl implements AdminAuthService {
|
|||||||
|
|
||||||
// 使用账号密码,进行登录
|
// 使用账号密码,进行登录
|
||||||
AdminUserDO user = authenticate(reqVO);
|
AdminUserDO user = authenticate(reqVO);
|
||||||
Long userId = user.getId();
|
|
||||||
|
// 非管理端设置产品id到token
|
||||||
|
user.setProductId(!isManageEndPoint ? productProperties.getImesProduct() : null);
|
||||||
|
|
||||||
// 管理端只允许超管登录
|
// 管理端只允许超管登录
|
||||||
|
Long userId = user.getId();
|
||||||
boolean isSuperAdmin = securityFrameworkService.hasAnyRoles(userId, "super_admin");
|
boolean isSuperAdmin = securityFrameworkService.hasAnyRoles(userId, "super_admin");
|
||||||
user.setSuperAdmin(isSuperAdmin);
|
user.setSuperAdmin(isSuperAdmin);
|
||||||
if (isSuperAdmin || SecurityFrameworkUtils.isCfOrg(user.getOrganId())) {
|
if (isSuperAdmin || SecurityFrameworkUtils.isCfOrg(user.getOrganId())) {
|
||||||
|
|||||||
+9
@@ -116,6 +116,15 @@ public interface PurchaseService {
|
|||||||
*/
|
*/
|
||||||
PurchaseRecordDO getOrgInitialPurchaseRecord(Long organId, Long productId);
|
PurchaseRecordDO getOrgInitialPurchaseRecord(Long organId, Long productId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取组织产品购买记录
|
||||||
|
*
|
||||||
|
* @param organId
|
||||||
|
* @param productId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<PurchaseRecordDO> getOrgProductPurchaseList(Long organId, Long productId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取组织续费定价规则列表
|
* 获取组织续费定价规则列表
|
||||||
*
|
*
|
||||||
|
|||||||
+9
@@ -235,6 +235,15 @@ public class PurchaseServiceImpl implements PurchaseService {
|
|||||||
.eq(PurchaseRecordDO::getInitial, true));
|
.eq(PurchaseRecordDO::getInitial, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<PurchaseRecordDO> getOrgProductPurchaseList(Long organId, Long productId) {
|
||||||
|
return purchaseRecordMapper.selectList(new LambdaQueryWrapper<PurchaseRecordDO>()
|
||||||
|
.eq(PurchaseRecordDO::getOrganId, organId)
|
||||||
|
.eq(PurchaseRecordDO::getProductId, productId)
|
||||||
|
.eq(PurchaseRecordDO::getDeleted, false)
|
||||||
|
.ne(PurchaseRecordDO::getStatus, PurchaseRecordStatusEnum.PENDING.getStatus()));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ProductsDetailDO> getOrgProductDetailList(Long organId, Long productId) {
|
public List<ProductsDetailDO> getOrgProductDetailList(Long organId, Long productId) {
|
||||||
// 校验产品
|
// 校验产品
|
||||||
|
|||||||
+9
@@ -6,6 +6,7 @@ import com.cf.imes.module.system.controller.admin.organ.vo.packages.TenantPackag
|
|||||||
import com.cf.imes.module.system.dal.dataobject.organ.TenantPackageDO;
|
import com.cf.imes.module.system.dal.dataobject.organ.TenantPackageDO;
|
||||||
|
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@@ -80,4 +81,12 @@ public interface TenantPackageService {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
Set<Long> getTenantPackageMenuIds(Long id);
|
Set<Long> getTenantPackageMenuIds(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取产品套餐下的权限菜单id
|
||||||
|
*
|
||||||
|
* @param productId 产品id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Set<Long> getProductTenantPackageMenuIds(Long productId);
|
||||||
}
|
}
|
||||||
|
|||||||
+11
@@ -166,4 +166,15 @@ public class TenantPackageServiceImpl implements TenantPackageService {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Cacheable(value = RedisKeyConstants.TENANT_PACKAGE_MENU_IDS, key = "#productId", unless = "#result == null or #result.isEmpty()", cacheManager = "redisCacheManager")
|
||||||
|
public Set<Long> getProductTenantPackageMenuIds(Long productId) {
|
||||||
|
TenantPackageDO tenantPackageDO = tenantPackageMapper.selectOne(new LambdaQueryWrapper<TenantPackageDO>().eq(TenantPackageDO::getProductId, productId).select(TenantPackageDO::getMenuIds));
|
||||||
|
if (ObjectUtil.isNotNull(tenantPackageDO)) {
|
||||||
|
return tenantPackageDO.getMenuIds();
|
||||||
|
} else {
|
||||||
|
return Set.of();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-5
@@ -388,7 +388,7 @@ public class PermissionServiceImpl implements PermissionService {
|
|||||||
if (roleService.hasAnySuperAdmin(roleIds)) {
|
if (roleService.hasAnySuperAdmin(roleIds)) {
|
||||||
return convertSet(menuService.getMenuList(), MenuDO::getId);
|
return convertSet(menuService.getMenuList(), MenuDO::getId);
|
||||||
} else {
|
} else {
|
||||||
List<Long> buildinRoleIdList = new ArrayList<>(){{
|
List<Long> buildinRoleIdList = new ArrayList<>() {{
|
||||||
add(InternalRoleConstants.ORGAN_ADMIN_ROLE_ID);
|
add(InternalRoleConstants.ORGAN_ADMIN_ROLE_ID);
|
||||||
add(InternalRoleConstants.ORGAN_STAFF_ROLE_ID);
|
add(InternalRoleConstants.ORGAN_STAFF_ROLE_ID);
|
||||||
}};
|
}};
|
||||||
@@ -402,10 +402,7 @@ public class PermissionServiceImpl implements PermissionService {
|
|||||||
roleMenuIds = convertSet(roleMenuMapper.selectListByRoleIdsAndOrganId(roleIds, OrganContextHolder.getOrganId()), RoleMenuDO::getMenuId);
|
roleMenuIds = convertSet(roleMenuMapper.selectListByRoleIdsAndOrganId(roleIds, OrganContextHolder.getOrganId()), RoleMenuDO::getMenuId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 校验、获取可用的组织
|
Set<Long> tenantPackageMenuIds = tenantPackageService.getProductTenantPackageMenuIds(SecurityFrameworkUtils.getProductId());
|
||||||
OrganizationDO organ = organService.validOrgan(organId);
|
|
||||||
|
|
||||||
Set<Long> tenantPackageMenuIds = tenantPackageService.getTenantPackageMenuIds(organ.getPackageId());
|
|
||||||
|
|
||||||
return Sets.intersection(roleMenuIds, tenantPackageMenuIds);
|
return Sets.intersection(roleMenuIds, tenantPackageMenuIds);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -196,6 +196,9 @@ chenfeng:
|
|||||||
#- /rpc-api/system/error-code/* # 错误码的自动创建与下载的接口,无法带上组织编号
|
#- /rpc-api/system/error-code/* # 错误码的自动创建与下载的接口,无法带上组织编号
|
||||||
#- /rpc-api/system/oauth2/token/check # 访问令牌校验时,无需传递组织编号;主要解决上传文件的场景,前端不会传递 tenant-id!
|
#- /rpc-api/system/oauth2/token/check # 访问令牌校验时,无需传递组织编号;主要解决上传文件的场景,前端不会传递 tenant-id!
|
||||||
#- /rpc-api/system/permission/has-any-permissions
|
#- /rpc-api/system/permission/has-any-permissions
|
||||||
|
ignore-product-urls:
|
||||||
|
- /admin-api/system/auth/get-permission-info
|
||||||
|
- /admin-api/system/dict-data/list-all-simple
|
||||||
ignore-tables:
|
ignore-tables:
|
||||||
- system_organization
|
- system_organization
|
||||||
- system_tenant_package
|
- system_tenant_package
|
||||||
@@ -278,6 +281,8 @@ chenfeng:
|
|||||||
publicKeyString: F+bPjhy/AwNvl16dMdqHCgKYIfA9c8Tho+g+fAeNOb7GjQf0NCX36B2ZH7yngpN6v82Q10/PfblVrPGrvMbDZcU4gxomhXN22L2hfaijPESgodEuoAd89Z31WYFuRRCKxAWWzjhXa+E5bBSUpMkuToLlgZgqiLmAmjfTJO9NOIM0i0+D/2foka4ALixhyklznefk8Dz2RwFb60luZSUE03NFoqp1/uifn6LB4r/Lery1wH8b1EN5rgjvJXDIRGsyaHWbtdQr0sB0NW6LoR5PzZPeq4X4DE6iBDzG7u55kFCFwVQXmxCgHN4bdniVHcu28m9piCTuvyGQHXZ2J6prsytv/N24ef/xBVTHMMx+bcj+AIB0z44/OfgK4DF2U4JURNsCmD9h6dY60Hi6kFHOe8Y9GcR8T9V2LrfOJdm2mX19U+ziCE7jo0zllxo6vzLCMwjfm61gWhxU30fOaZgXbhGHps3z/TS5LlYiLgZcv3LE+Ttvl3fl0Cm3SitvNqxwQTnLxxKjcr2+ZE523Azr6/6JF1t8wSBKz4MAH9FrNvHVbziu7QrrWOFpCUL22sbBXtglQvQ1fjHqQ84qcGh6fDJC9k3f+lWVX1jAQiJT6h2MjfwaSIbhUGFS1BG6mQ==
|
publicKeyString: F+bPjhy/AwNvl16dMdqHCgKYIfA9c8Tho+g+fAeNOb7GjQf0NCX36B2ZH7yngpN6v82Q10/PfblVrPGrvMbDZcU4gxomhXN22L2hfaijPESgodEuoAd89Z31WYFuRRCKxAWWzjhXa+E5bBSUpMkuToLlgZgqiLmAmjfTJO9NOIM0i0+D/2foka4ALixhyklznefk8Dz2RwFb60luZSUE03NFoqp1/uifn6LB4r/Lery1wH8b1EN5rgjvJXDIRGsyaHWbtdQr0sB0NW6LoR5PzZPeq4X4DE6iBDzG7u55kFCFwVQXmxCgHN4bdniVHcu28m9piCTuvyGQHXZ2J6prsytv/N24ef/xBVTHMMx+bcj+AIB0z44/OfgK4DF2U4JURNsCmD9h6dY60Hi6kFHOe8Y9GcR8T9V2LrfOJdm2mX19U+ziCE7jo0zllxo6vzLCMwjfm61gWhxU30fOaZgXbhGHps3z/TS5LlYiLgZcv3LE+Ttvl3fl0Cm3SitvNqxwQTnLxxKjcr2+ZE523Azr6/6JF1t8wSBKz4MAH9FrNvHVbziu7QrrWOFpCUL22sbBXtglQvQ1fjHqQ84qcGh6fDJC9k3f+lWVX1jAQiJT6h2MjfwaSIbhUGFS1BG6mQ==
|
||||||
privateKeyString: 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
|
privateKeyString: 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
|
||||||
notifyUrl: RIEeHCoPHaAryuVN6mEYskBSl+EPvhsxRpjIbuIE7f7jABVxm46bLc01WQUe4Fn9NPYyNTv0xCxM68iRrmFDjAUjQ/hkIVNG+yD/kNsjcYCWa2gtOQPrvWZzDA==
|
notifyUrl: RIEeHCoPHaAryuVN6mEYskBSl+EPvhsxRpjIbuIE7f7jABVxm46bLc01WQUe4Fn9NPYyNTv0xCxM68iRrmFDjAUjQ/hkIVNG+yD/kNsjcYCWa2gtOQPrvWZzDA==
|
||||||
|
product-id:
|
||||||
|
imes-product: 4
|
||||||
|
|
||||||
justauth:
|
justauth:
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|||||||
@@ -212,6 +212,9 @@ chenfeng:
|
|||||||
#- /rpc-api/system/error-code/* # 错误码的自动创建与下载的接口,无法带上组织编号
|
#- /rpc-api/system/error-code/* # 错误码的自动创建与下载的接口,无法带上组织编号
|
||||||
#- /rpc-api/system/oauth2/token/check # 访问令牌校验时,无需传递组织编号;主要解决上传文件的场景,前端不会传递 tenant-id!
|
#- /rpc-api/system/oauth2/token/check # 访问令牌校验时,无需传递组织编号;主要解决上传文件的场景,前端不会传递 tenant-id!
|
||||||
#- /rpc-api/system/permission/has-any-permissions
|
#- /rpc-api/system/permission/has-any-permissions
|
||||||
|
ignore-product-urls:
|
||||||
|
- /admin-api/system/auth/get-permission-info
|
||||||
|
- /admin-api/system/dict-data/list-all-simple
|
||||||
ignore-tables:
|
ignore-tables:
|
||||||
- system_organization
|
- system_organization
|
||||||
- system_tenant_package
|
- system_tenant_package
|
||||||
|
|||||||
Reference in New Issue
Block a user