|
|
@@ -20,6 +20,7 @@ import com.sckw.contract.model.vo.res.*;
|
|
|
import com.sckw.contract.repository.KwcContractLogisticsGoodsRepository;
|
|
|
import com.sckw.contract.repository.KwcContractLogisticsRepository;
|
|
|
import com.sckw.contract.repository.KwcContractLogisticsUnitRepository;
|
|
|
+import com.sckw.contract.repository.KwcContractTradeRepository;
|
|
|
import com.sckw.contract.service.*;
|
|
|
import com.sckw.core.common.enums.enums.DictEnum;
|
|
|
import com.sckw.core.common.enums.enums.DictTypeEnum;
|
|
|
@@ -39,12 +40,17 @@ import com.sckw.product.api.dubbo.GoodsInfoService;
|
|
|
import com.sckw.product.api.model.KwpGoods;
|
|
|
import com.sckw.stream.enums.MessageEnum;
|
|
|
import com.sckw.stream.model.UserInfo;
|
|
|
+import com.sckw.system.api.feign.DataPermissionFeignService;
|
|
|
import com.sckw.system.api.RemoteSystemService;
|
|
|
import com.sckw.system.api.RemoteUserService;
|
|
|
+import com.sckw.system.api.model.dto.req.DataPermissionFilterReqDto;
|
|
|
+import com.sckw.system.api.model.dto.res.DataPermissionDTO;
|
|
|
import com.sckw.system.api.model.dto.res.EntCacheResDto;
|
|
|
import com.sckw.system.api.model.dto.res.KwsUserResDto;
|
|
|
import com.sckw.system.api.model.dto.res.SysDictResDto;
|
|
|
import com.sckw.system.api.model.dto.res.UserCacheResDto;
|
|
|
+import com.sckw.order.api.dubbo.TradeOrderInfoService;
|
|
|
+import com.sckw.order.api.model.TradeOrderContractVo;
|
|
|
import com.sckw.transport.api.dubbo.TransportRemoteService;
|
|
|
import com.sckw.transport.api.model.vo.KwtLogisticsOrderVO;
|
|
|
import com.sckw.transport.api.model.vo.RWaybillSubOrderVo;
|
|
|
@@ -52,6 +58,7 @@ import com.sckw.transport.api.model.vo.WayContaractbillOrderVo;
|
|
|
import jakarta.servlet.http.HttpServletResponse;
|
|
|
import lombok.RequiredArgsConstructor;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.apache.commons.collections4.MapUtils;
|
|
|
import org.apache.dubbo.config.annotation.DubboReference;
|
|
|
import org.jetbrains.annotations.NotNull;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
@@ -98,6 +105,8 @@ public class KwcContractLogisticsService {
|
|
|
private final KwcContractLogisticsRepository kwcContractLogisticsRepository;
|
|
|
private final KwcContractLogisticsUnitRepository kwcContractLogisticsUnitRepository;
|
|
|
private final KwcContractLogisticsGoodsRepository kwcContractLogisticsGoodsRepository;
|
|
|
+ private final KwcContractTradeRepository kwcContractTradeRepository;
|
|
|
+ private final DataPermissionFeignService dataPermissionFeignService;
|
|
|
|
|
|
@DubboReference(version = "1.0.0", group = "design", check = false)
|
|
|
private RemoteSystemService remoteSystemService;
|
|
|
@@ -108,6 +117,9 @@ public class KwcContractLogisticsService {
|
|
|
@DubboReference(version = "1.0.0", group = "design", check = false)
|
|
|
private GoodsInfoService goodsInfoService;
|
|
|
|
|
|
+ @DubboReference(version = "1.0.0", group = "design", check = false, timeout = 8000)
|
|
|
+ private TradeOrderInfoService tradeOrderInfoService;
|
|
|
+
|
|
|
@DubboReference(version = "1.0.0", group = "design", check = false)
|
|
|
private TransportRemoteService transportRemoteService;
|
|
|
|
|
|
@@ -1092,6 +1104,22 @@ public class KwcContractLogisticsService {
|
|
|
if (CollectionUtils.isEmpty(contractIdList) && CollectionUtils.isNotEmpty(entIdList)){
|
|
|
return PageDataResult.empty(req.getPageNum(),req.getPageSize());
|
|
|
}
|
|
|
+ // 获取当前用户的数据权限配置
|
|
|
+ DataPermissionDTO perm = fetchDataPermissionForCurrentUser();
|
|
|
+ // 如果存在数据权限且需要过滤,则执行权限过滤逻辑
|
|
|
+ if (perm != null && perm.needFilter()) {
|
|
|
+ // 根据合同ID列表及查询条件获取物流合同列表
|
|
|
+ List<KwcContractLogistics> permissionSource = kwcContractLogisticsRepository.queryList(contractIdList,
|
|
|
+ req.getContractNo(), req.getContractName(), req.getStatus());
|
|
|
+ // 根据数据权限规则过滤合同列表
|
|
|
+ permissionSource = filterLogisticsContractsByPermission(permissionSource, perm);
|
|
|
+ // 如果过滤后无数据,直接返回空分页结果
|
|
|
+ if (CollectionUtils.isEmpty(permissionSource)) {
|
|
|
+ return PageDataResult.empty(req.getPageNum(), req.getPageSize());
|
|
|
+ }
|
|
|
+ // 将过滤后的合同ID重新赋值给contractIdList,用于后续的分页查询
|
|
|
+ contractIdList = permissionSource.stream().map(KwcContractLogistics::getId).collect(Collectors.toSet());
|
|
|
+ }
|
|
|
|
|
|
IPage<KwcContractLogistics> page =kwcContractLogisticsRepository.queryByPage(req.getPageNum(),req.getPageSize(),
|
|
|
req.getContractNo(),
|
|
|
@@ -1686,7 +1714,11 @@ public class KwcContractLogisticsService {
|
|
|
|
|
|
|
|
|
List<KwcContractLogistics> contractLogistics = kwcContractLogisticsRepository.queryList(contractIdList,req.getContractNo(),req.getContractName(),req.getStatus());
|
|
|
+ // 应用数据权限过滤:获取当前用户的数据权限配置,并对物流合同列表进行过滤(个人数据权限与企业层级数据权限为并集关系)
|
|
|
+ DataPermissionDTO perm = fetchDataPermissionForCurrentUser();
|
|
|
+ contractLogistics = filterLogisticsContractsByPermission(contractLogistics, perm);
|
|
|
|
|
|
+ // 如果过滤后无数据,则返回各状态计数均为0的结果
|
|
|
if (CollectionUtils.isEmpty(contractLogistics)){
|
|
|
Map<Integer, List<KwcContractLogistics>> statusAndLogOrdersMap = new HashMap<>();
|
|
|
List<ContractStatusCountResp.ContractStatusCount> statusCounts = statusEnums.stream()
|
|
|
@@ -1719,4 +1751,154 @@ public class KwcContractLogisticsService {
|
|
|
contractStatusCount.setOrderNum(String.valueOf(finalStatusAndLogOrdersMap1.getOrDefault(statusEnum.getCode(), new ArrayList<>()).size()));
|
|
|
return contractStatusCount;
|
|
|
}
|
|
|
-}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取当前用户的数据权限配置
|
|
|
+ * <p>
|
|
|
+ * 通过远程服务获取当前登录用户的数据权限过滤条件,包括可见企业ID、个人数据权限开关等。
|
|
|
+ * 如果获取失败,记录警告日志并返回null,后续逻辑将跳过权限过滤。
|
|
|
+ * </p>
|
|
|
+ *
|
|
|
+ * @return 数据权限DTO,如果获取失败则返回null
|
|
|
+ */
|
|
|
+ private DataPermissionDTO fetchDataPermissionForCurrentUser() {
|
|
|
+ try {
|
|
|
+ DataPermissionFilterReqDto reqDto = new DataPermissionFilterReqDto();
|
|
|
+ reqDto.setUserId(LoginUserHolder.getUserId());
|
|
|
+ reqDto.setRoleId(LoginUserHolder.getCurrentRoleId());
|
|
|
+ reqDto.setManager(LoginUserHolder.isManager());
|
|
|
+ return dataPermissionFeignService.getDataPermissionFilter(reqDto);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("获取物流合同数据权限失败,跳过权限过滤: {}", e.getMessage());
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据数据权限过滤物流合同列表
|
|
|
+ * <p>
|
|
|
+ * 过滤逻辑:
|
|
|
+ * 1. 通过物流合同ID查询关联的运单子单信息,获取贸易订单ID。
|
|
|
+ * 2. 通过贸易订单ID查询关联的交易合同ID。
|
|
|
+ * 3. 根据交易合同ID查询交易合同详情。
|
|
|
+ * 4. 结合数据权限配置(可见企业ID、个人数据权限),判断当前用户是否有权限查看该物流合同。
|
|
|
+ * - 若非全部可见,则检查交易合同所属企业是否在可见企业列表中。
|
|
|
+ * - 若启用个人数据权限,则检查交易合同的销售员是否为当前用户。
|
|
|
+ * - 只有当至少一个关联的交易合同满足权限要求时,该物流合同才会被保留。
|
|
|
+ * </p>
|
|
|
+ *
|
|
|
+ * @param records 待过滤的物流合同列表
|
|
|
+ * @param perm 数据权限配置
|
|
|
+ * @return 过滤后的物流合同列表
|
|
|
+ */
|
|
|
+ private List<KwcContractLogistics> filterLogisticsContractsByPermission(List<KwcContractLogistics> records, DataPermissionDTO perm) {
|
|
|
+ // 如果记录为空、权限对象为空或不需要过滤,直接返回原列表
|
|
|
+ if (CollectionUtils.isEmpty(records) || perm == null || !perm.needFilter()) {
|
|
|
+ return records;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 1. 提取所有物流合同ID
|
|
|
+ Set<Long> logContractIds = records.stream().map(KwcContractLogistics::getId).collect(Collectors.toSet());
|
|
|
+
|
|
|
+ // 2. 查询关联的运单子单信息
|
|
|
+ List<RWaybillSubOrderVo> orderLinks = transportRemoteService.queryWaybillOrderByLogContractIds(logContractIds);
|
|
|
+ if (CollectionUtils.isEmpty(orderLinks)) {
|
|
|
+ return Collections.emptyList();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 提取贸易订单ID
|
|
|
+ Set<Long> tradeOrderIds = orderLinks.stream()
|
|
|
+ .map(RWaybillSubOrderVo::getTradeId)
|
|
|
+ .filter(Objects::nonNull)
|
|
|
+ .collect(Collectors.toSet());
|
|
|
+ if (CollectionUtils.isEmpty(tradeOrderIds)) {
|
|
|
+ return Collections.emptyList();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 4. 查询贸易订单关联的交易合同信息
|
|
|
+ List<TradeOrderContractVo> tradeOrderContracts = tradeOrderInfoService.queryTradeOrderIds(tradeOrderIds);
|
|
|
+ if (CollectionUtils.isEmpty(tradeOrderContracts)) {
|
|
|
+ return Collections.emptyList();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 5. 构建物流合同ID到交易合同ID集合的映射关系
|
|
|
+ Map<Long, Set<Long>> logContractIdTradeContractIdsMap = buildLogContractTradeContractIdsMap(orderLinks, tradeOrderContracts);
|
|
|
+ if (MapUtils.isEmpty(logContractIdTradeContractIdsMap)) {
|
|
|
+ return Collections.emptyList();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 6. 收集所有相关的交易合同ID
|
|
|
+ Set<Long> tradeContractIds = logContractIdTradeContractIdsMap.values().stream()
|
|
|
+ .flatMap(Collection::stream)
|
|
|
+ .collect(Collectors.toSet());
|
|
|
+
|
|
|
+ // 7. 批量查询交易合同详情,并构建ID到对象的映射
|
|
|
+ Map<Long, KwcContractTrade> tradeContractMap = kwcContractTradeRepository.findByContractIds(tradeContractIds).stream()
|
|
|
+ .collect(Collectors.toMap(KwcContractTrade::getId, Function.identity(), (a, b) -> a));
|
|
|
+
|
|
|
+ // 8. 根据权限规则过滤物流合同
|
|
|
+ return records.stream().filter(record -> {
|
|
|
+ // 获取当前物流合同关联的所有交易合同ID
|
|
|
+ Set<Long> relationTradeContractIds = logContractIdTradeContractIdsMap.get(record.getId());
|
|
|
+ if (CollectionUtils.isEmpty(relationTradeContractIds)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 只要有一个关联的交易合同满足权限要求,则该物流合同可见
|
|
|
+ return relationTradeContractIds.stream()
|
|
|
+ .map(tradeContractMap::get)
|
|
|
+ .filter(Objects::nonNull)
|
|
|
+ .anyMatch(contract -> {
|
|
|
+ // 校验企业权限
|
|
|
+ boolean entOk = true;
|
|
|
+ if (!perm.isAllVisible()) {
|
|
|
+ if (CollectionUtils.isEmpty(perm.getVisibleEntIds())) {
|
|
|
+ entOk = false;
|
|
|
+ } else {
|
|
|
+ entOk = contract.getEntId() != null && perm.getVisibleEntIds().contains(contract.getEntId());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 校验个人数据权限(销售员权限)
|
|
|
+ boolean salesOk = true;
|
|
|
+ if (perm.isPersonalDataEnabled()) {
|
|
|
+ salesOk = perm.getUserId() != null && perm.getUserId().equals(contract.getSalesmanId());
|
|
|
+ }
|
|
|
+
|
|
|
+ return entOk && salesOk;
|
|
|
+ });
|
|
|
+ }).collect(Collectors.toList());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 构建物流合同ID与关联的交易合同ID集合的映射关系
|
|
|
+ *
|
|
|
+ * @param orderLinks 运单子单信息列表,包含物流合同ID和贸易订单ID
|
|
|
+ * @param tradeOrderContracts 贸易订单与交易合同的关联信息列表
|
|
|
+ * @return Map<物流合同ID, 交易合同ID集合>
|
|
|
+ */
|
|
|
+ private Map<Long, Set<Long>> buildLogContractTradeContractIdsMap(List<RWaybillSubOrderVo> orderLinks,
|
|
|
+ List<TradeOrderContractVo> tradeOrderContracts) {
|
|
|
+ // 构建贸易订单ID到交易合同ID的映射关系,过滤掉无效数据
|
|
|
+ Map<Long, Long> tradeOrderIdTradeContractIdMap = tradeOrderContracts.stream()
|
|
|
+ .filter(item -> item.getTOrderId() != null && item.getContractId() != null)
|
|
|
+ .collect(Collectors.toMap(TradeOrderContractVo::getTOrderId, TradeOrderContractVo::getContractId, (a, b) -> a));
|
|
|
+
|
|
|
+ // 初始化结果Map,key为物流合同ID,value为关联的交易合同ID集合
|
|
|
+ Map<Long, Set<Long>> result = new HashMap<>();
|
|
|
+ for (RWaybillSubOrderVo orderLink : orderLinks) {
|
|
|
+ // 跳过物流合同ID或贸易订单ID为空的数据
|
|
|
+ if (orderLink.getLogContractId() == null || orderLink.getTradeId() == null) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ // 获取贸易订单对应的交易合同ID
|
|
|
+ Long tradeContractId = tradeOrderIdTradeContractIdMap.get(orderLink.getTradeId());
|
|
|
+ if (tradeContractId == null) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ // 将交易合同ID添加到对应物流合同ID的集合中
|
|
|
+ result.computeIfAbsent(orderLink.getLogContractId(), key -> new HashSet<>()).add(tradeContractId);
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+}
|