Merge branch 'refs/heads/dev_qinhongzhan' into dev

# Conflicts:
#	mhd-auth/src/main/resources/bootstrap.yml
#	mhd-gateway/src/main/resources/bootstrap.yml
#	mhd-modules/mhd-system/src/main/resources/bootstrap.yml
#	mhd-user-center/src/main/java/com/mhd/user/domain/userAggregate/entity/UserShipperEntity.java
#	mhd-user-center/src/main/resources/bootstrap.yml
#	mhd_finance/src/main/java/com/linke/finance/application/server/reconciliation/ReconciliationApplicationService.java
#	mhd_transport/src/main/java/com/linke/transport/application/service/warehouse/material/command/CreateMaterialCommand.java
This commit is contained in:
1745237360-cloud
2026-01-10 16:45:38 +08:00
104 changed files with 3099 additions and 537 deletions
@@ -139,6 +139,20 @@ public class VehicleApplicationService {
*/
@NeedSetValueMethod
public List<VehiclePo> selectVehicleList(VehiclePo vehiclePo, DataPermission dataPermission) {
// 获取登录人信息
LoginUser loginUser = SecurityUtils.getLoginUser();
if (loginUser == null || loginUser.getUserPo() == null) {
log.warn("车辆列表查询 - 未获取到登录用户信息,跳过数据权限过滤");
return vehicleDomainService.selectVehicleList(vehiclePo);
}
UserPo userPo = loginUser.getUserPo();
Long loginUserOrganizationId = userPo.getOrganizationId();
Long topOrganizationId = userPo.getTopOrganizationId();
// 先保存前端传递的 organizationId(如果存在)
Long frontendOrganizationId = vehiclePo.getOrganizationId();
if (dataPermission != null) {
if (CollUtil.isNotEmpty(dataPermission.getOrganizationIdList())) {
vehiclePo.setOrganizationIdList(dataPermission.getOrganizationIdList());
@@ -147,13 +161,52 @@ public class VehicleApplicationService {
vehiclePo.setCreateBy(dataPermission.getCreateBy());
}
}
//获取登录人信息
LoginUser loginUser = SecurityUtils.getLoginUser();
if (loginUser.getUserPo().getBusinessType() == 2) {
vehiclePo.setCreateBy(loginUser.getUserPo().getUserId());
vehiclePo.setOrganizationId(null);
vehiclePo.setOrganizationIdList(null);
// businessType == 2 时(司机),设置创建人过滤
if (userPo.getBusinessType() == 2) {
vehiclePo.setCreateBy(userPo.getUserId());
}
// 数据权限:根据 organizationId 来设置查询权限
// 当前登录用户的 organizationId 为 2827 时,可查全部组织数据;其他组织只能查自己
if (loginUserOrganizationId != null && loginUserOrganizationId.equals(2827L)) {
// 南光组织(organizationId=2827):可以查询所有组织的数据
// 如果前端传递了 organizationId,使用前端传递的值进行过滤
// 如果前端没有传递 organizationId,清空组织过滤条件,查询所有组织的数据
if (frontendOrganizationId != null) {
vehiclePo.setOrganizationId(frontendOrganizationId);
vehiclePo.setTopOrganizationId(null);
vehiclePo.setOrganizationIdList(null);
} else {
vehiclePo.setOrganizationId(null);
vehiclePo.setTopOrganizationId(null);
vehiclePo.setOrganizationIdList(null);
}
} else {
// 其他组织:设置 organizationId,只查询当前组织的数据
if (frontendOrganizationId != null) {
// 前端传递了 organizationId,验证是否与当前登录用户的组织ID一致
if (!frontendOrganizationId.equals(loginUserOrganizationId)) {
log.warn("车辆列表查询 - 前端传递的组织ID {} 与当前登录用户的组织ID {} 不一致,使用当前登录用户的组织ID进行过滤",
frontendOrganizationId, loginUserOrganizationId);
vehiclePo.setOrganizationId(loginUserOrganizationId);
} else {
vehiclePo.setOrganizationId(frontendOrganizationId);
}
vehiclePo.setTopOrganizationId(topOrganizationId);
if (loginUserOrganizationId != null) {
vehiclePo.setOrganizationIdList(Collections.singletonList(loginUserOrganizationId));
}
} else {
// 前端没有传递 organizationId,使用当前登录用户的组织ID
if (loginUserOrganizationId != null) {
vehiclePo.setOrganizationId(loginUserOrganizationId);
vehiclePo.setOrganizationIdList(Collections.singletonList(loginUserOrganizationId));
}
vehiclePo.setTopOrganizationId(topOrganizationId);
}
}
//查询所有已经被绑定的车辆
// try {
// R<List<Long>> vehicleIdList = userServiceFeign.getBindListByUserId(loginUser.getUserPo().getUserId());
@@ -193,6 +246,18 @@ public class VehicleApplicationService {
*/
@NeedSetValueMethod
public List<VehiclePo> getUnBindList(VehiclePo vehiclePo, DataPermission dataPermission) {
// 获取登录人信息
LoginUser loginUser = SecurityUtils.getLoginUser();
if (loginUser == null || loginUser.getUserPo() == null) {
log.warn("未绑定车辆列表查询 - 未获取到登录用户信息,跳过数据权限过滤");
return vehicleDomainService.selectVehicleList(vehiclePo);
}
UserPo userPo = loginUser.getUserPo();
Long loginUserOrganizationId = userPo.getOrganizationId();
Long topOrganizationId = userPo.getTopOrganizationId();
Long frontendOrganizationId = vehiclePo.getOrganizationId();
if (dataPermission != null) {
if (CollUtil.isNotEmpty(dataPermission.getOrganizationIdList())) {
vehiclePo.setOrganizationIdList(dataPermission.getOrganizationIdList());
@@ -201,12 +266,35 @@ public class VehicleApplicationService {
vehiclePo.setCreateBy(dataPermission.getCreateBy());
}
}
//获取登录人信息
LoginUser loginUser = SecurityUtils.getLoginUser();
if (loginUser.getUserPo().getBusinessType() == 2) {
vehiclePo.setCreateBy(loginUser.getUserPo().getUserId());
vehiclePo.setOrganizationId(null);
// businessType == 2 时(司机),设置创建人过滤
if (userPo.getBusinessType() == 2) {
vehiclePo.setCreateBy(userPo.getUserId());
}
// 数据权限:根据 organizationId 来设置查询权限
if (loginUserOrganizationId != null && loginUserOrganizationId.equals(2827L)) {
// 南光组织(organizationId=2827):可以查询所有组织的数据
if (frontendOrganizationId != null) {
vehiclePo.setOrganizationId(frontendOrganizationId);
} else {
vehiclePo.setOrganizationId(null);
}
vehiclePo.setTopOrganizationId(null);
vehiclePo.setOrganizationIdList(null);
} else {
// 其他组织:只查询当前组织的数据
if (frontendOrganizationId != null && !frontendOrganizationId.equals(loginUserOrganizationId)) {
log.warn("未绑定车辆列表查询 - 前端传递的组织ID {} 与当前登录用户的组织ID {} 不一致,使用当前登录用户的组织ID进行过滤",
frontendOrganizationId, loginUserOrganizationId);
vehiclePo.setOrganizationId(loginUserOrganizationId);
} else if (frontendOrganizationId == null) {
vehiclePo.setOrganizationId(loginUserOrganizationId);
}
vehiclePo.setTopOrganizationId(topOrganizationId);
if (loginUserOrganizationId != null) {
vehiclePo.setOrganizationIdList(Collections.singletonList(loginUserOrganizationId));
}
}
//查询所有已经被绑定的车辆
try {
@@ -247,12 +335,49 @@ public class VehicleApplicationService {
*/
@NeedSetValueMethod
public List<VehiclePo> selectBindVehicleList(VehiclePo vehiclePo, DataPermission dataPermission) {
// 获取登录人信息
LoginUser loginUser = SecurityUtils.getLoginUser();
if (loginUser == null || loginUser.getUserPo() == null) {
log.warn("绑定车辆列表查询 - 未获取到登录用户信息,跳过数据权限过滤");
return vehicleDomainService.selectVehicleList(vehiclePo);
}
UserPo userPo = loginUser.getUserPo();
Long loginUserOrganizationId = userPo.getOrganizationId();
Long topOrganizationId = userPo.getTopOrganizationId();
Long frontendOrganizationId = vehiclePo.getOrganizationId();
if (dataPermission != null) {
if (dataPermission.getOrganizationIdList() != null
&& dataPermission.getOrganizationIdList().size() > 0) {
vehiclePo.setOrganizationIdList(dataPermission.getOrganizationIdList());
}
}
// 数据权限:根据 organizationId 来设置查询权限
if (loginUserOrganizationId != null && loginUserOrganizationId.equals(2827L)) {
// 南光组织(organizationId=2827):可以查询所有组织的数据
if (frontendOrganizationId != null) {
vehiclePo.setOrganizationId(frontendOrganizationId);
} else {
vehiclePo.setOrganizationId(null);
}
vehiclePo.setTopOrganizationId(null);
vehiclePo.setOrganizationIdList(null);
} else {
// 其他组织:只查询当前组织的数据
if (frontendOrganizationId != null && !frontendOrganizationId.equals(loginUserOrganizationId)) {
log.warn("绑定车辆列表查询 - 前端传递的组织ID {} 与当前登录用户的组织ID {} 不一致,使用当前登录用户的组织ID进行过滤",
frontendOrganizationId, loginUserOrganizationId);
vehiclePo.setOrganizationId(loginUserOrganizationId);
} else if (frontendOrganizationId == null) {
vehiclePo.setOrganizationId(loginUserOrganizationId);
}
vehiclePo.setTopOrganizationId(topOrganizationId);
if (loginUserOrganizationId != null) {
vehiclePo.setOrganizationIdList(Collections.singletonList(loginUserOrganizationId));
}
}
List<VehiclePo> vehiclePos = vehicleDomainService.selectVehicleList(vehiclePo);
for (VehiclePo po : vehiclePos) {
Map<String, String> map = userServiceFeign.selectUserBindByVehicleId(po.getVehicleId());
@@ -269,24 +394,43 @@ public class VehicleApplicationService {
*/
@NeedSetValueMethod
public List<VehiclePo> selectStowageVehiclelist(VehiclePo vehiclePo) {
// if(dataPermission != null){
// if(dataPermission.getOrganizationIdList() != null && dataPermission.getOrganizationIdList().size() > 0){
// vehiclePo.setOrganizationIdList(dataPermission.getOrganizationIdList());
// }
// if(dataPermission.getCreateBy() != null){
// vehiclePo.setCreateBy(dataPermission.getCreateBy());
// }
// }
//获取登录人信息
// 获取登录人信息
LoginUser loginUser = SecurityUtils.getLoginUser();
if (loginUser == null || loginUser.getUserPo() == null) {
log.warn("配载车辆列表查询 - 未获取到登录用户信息,跳过数据权限过滤");
return vehicleDomainService.selectStowageVehiclelist(vehiclePo);
}
UserPo userPo = loginUser.getUserPo();
Long loginUserOrganizationId = userPo.getOrganizationId();
Long topOrganizationId = userPo.getTopOrganizationId();
Long frontendOrganizationId = vehiclePo.getOrganizationId();
if (ObjectUtil.equals(userPo.getUserAccountType(), 3)) {
vehiclePo.setUserAccountType(3);
vehiclePo.setTopOrganizationId(userPo.getTopOrganizationId());
} else {
vehiclePo.setTopOrganizationId(userPo.getTopOrganizationId());
vehiclePo.setOrganizationId(userPo.getOrganizationId());
}
// 数据权限:根据 organizationId 来设置查询权限
if (loginUserOrganizationId != null && loginUserOrganizationId.equals(2827L)) {
// 南光组织(organizationId=2827):可以查询所有组织的数据
if (frontendOrganizationId != null) {
vehiclePo.setOrganizationId(frontendOrganizationId);
} else {
vehiclePo.setOrganizationId(null);
}
vehiclePo.setTopOrganizationId(null);
} else {
// 其他组织:只查询当前组织的数据
if (frontendOrganizationId != null && !frontendOrganizationId.equals(loginUserOrganizationId)) {
log.warn("配载车辆列表查询 - 前端传递的组织ID {} 与当前登录用户的组织ID {} 不一致,使用当前登录用户的组织ID进行过滤",
frontendOrganizationId, loginUserOrganizationId);
vehiclePo.setOrganizationId(loginUserOrganizationId);
} else if (frontendOrganizationId == null) {
vehiclePo.setOrganizationId(loginUserOrganizationId);
}
vehiclePo.setTopOrganizationId(topOrganizationId);
}
return vehicleDomainService.selectStowageVehiclelist(vehiclePo);
}
@@ -585,8 +729,18 @@ public class VehicleApplicationService {
if (currentVehiclePo != null) {
Vehicle vehicleForWlhy = new Vehicle(); // 使用领域对象
BeanUtils.copyProperties(currentVehiclePo, vehicleForWlhy);
vehicleWlhyDomainService.addVehicleInfo(vehicleForWlhy, 1); // 2 代表某种类型或状态
vehiclePendingReviewPush(loginUser);
vehicleForWlhy.setUserId(currentVehiclePo.getUserId());
try {
vehicleWlhyDomainService.addVehicleInfo(vehicleForWlhy, 1); // 1 代表绑定类型
vehiclePendingReviewPush(loginUser);
} catch (ServiceException e) {
// 同步网货失败时,记录日志但不影响车辆保存
// 第一次新增时,用户信息可能还未同步到网货系统,导致失败
// 第二次新增时,用户信息已存在,可以成功同步
log.warn("同步网货信息失败,但不影响车辆保存: {}", e.getMessage());
// 如果业务要求必须同步成功,可以取消下面的注释,让异常抛出
// throw e;
}
} else {
log.warn("未能找到刚保存的车辆信息用于同步网货,VehicleId: {}", vehicle.getVehicleId());
}
@@ -607,11 +761,18 @@ public class VehicleApplicationService {
LoginUser loginUser = SecurityUtils.getLoginUser();
//当前组织id
Long organizationId = 0L;
Long topOrganizationId = 0L;
String organizationName = "";
if (loginUser != null) {
if (loginUser.getUserPo() != null && loginUser.getUserPo().getOrganizationId() != null) {
organizationId = loginUser.getUserPo().getOrganizationId();
organizationName = loginUser.getUserPo().getOrganizationName();
UserPo userPo = loginUser.getUserPo();
if (userPo != null) {
if (userPo.getOrganizationId() != null) {
organizationId = userPo.getOrganizationId();
organizationName = userPo.getOrganizationName();
}
if (userPo.getTopOrganizationId() != null) {
topOrganizationId = userPo.getTopOrganizationId();
}
}
}
UserConfigSwitchPo userConfigSwitchPo = commonApplicationService.getUserConfigSwitch();
@@ -660,8 +821,10 @@ public class VehicleApplicationService {
}
}
// 设置当前登录用户的组织信息
vehicle.setOrganizationId(organizationId);
vehicle.setOrganizationName(organizationName);
vehicle.setTopOrganizationId(topOrganizationId);
VehiclePo oldVehiclePo = null;
if (ObjectUtil.isNotNull(vehicle.getVehicleId())) {
@@ -830,12 +993,8 @@ public class VehicleApplicationService {
// }
// 6. 持久化操作 (统一的 insert 或 update)
// 注意:组织信息已在前面设置(第670-673行),这里不需要重复设置
if (ObjectUtil.isNull(vehicle.getVehicleId())) { // 新增
if (loginUser != null) {
vehicle.setOrganizationId(loginUser.getUserPo().getOrganizationId());
vehicle.setOrganizationName(loginUser.getUserPo().getOrganizationName());
vehicle.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId());
}
vehicleDomainService.insertVehicle(vehicle);
} else {
// 确保 vehicleId 是从 DTO 传递过来的,并且 oldVehiclePo 已被正确加载
@@ -875,8 +1034,17 @@ public class VehicleApplicationService {
Vehicle vehicleForWlhy = new Vehicle(); // 使用领域对象
BeanUtils.copyProperties(currentVehiclePo, vehicleForWlhy);
vehicleForWlhy.setUserId(currentVehiclePo.getUserId());
vehicleWlhyDomainService.addVehicleInfo(vehicleForWlhy, 1); // 2 代表某种类型或状态
vehiclePendingReviewPush(loginUser);
try {
vehicleWlhyDomainService.addVehicleInfo(vehicleForWlhy, 1); // 1 代表绑定类型
vehiclePendingReviewPush(loginUser);
} catch (ServiceException e) {
// 同步网货失败时,记录日志但不影响车辆保存
// 第一次新增时,用户信息可能还未同步到网货系统,导致失败
// 第二次新增时,用户信息已存在,可以成功同步
log.warn("同步网货信息失败,但不影响车辆保存: {}", e.getMessage());
// 如果业务要求必须同步成功,可以取消下面的注释,让异常抛出
// throw e;
}
} else {
log.warn("未能找到刚保存的车辆信息用于同步网货,VehicleId: {}", vehicle.getVehicleId());
}
@@ -22,6 +22,7 @@ import com.linke.transport.interfaces.dto.warehouse.inBoundOrder.InboundOrderDTO
import com.linke.transport.interfaces.dto.warehouse.inBoundOrder.InboundOrderDTO.Create;
import com.mhd.common.core.utils.OrderSequence;
import com.mhd.common.security.utils.SecurityUtils;
import com.mhd.system.api.model.LoginUser;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
@@ -292,7 +293,7 @@ public class InboundOrderService extends ServiceImpl<InboundOrderMapper, Inbound
* 构建查询条件(函数式封装)
*/
private LambdaQueryWrapper<InboundOrder> buildQueryWrapper(InboundOrderDTO.Query queryDTO) {
return new LambdaQueryWrapper<InboundOrder>()
LambdaQueryWrapper<InboundOrder> wrapper = new LambdaQueryWrapper<InboundOrder>()
.like(StringUtils.hasText(queryDTO.getInboundOrderNo()),
InboundOrder::getInboundOrderNo, queryDTO.getInboundOrderNo())
.eq(Objects.nonNull(queryDTO.getOwnerId()),
@@ -304,8 +305,44 @@ public class InboundOrderService extends ServiceImpl<InboundOrderMapper, Inbound
.ge(Objects.nonNull(queryDTO.getInboundTimeStart()),
InboundOrder::getInboundTime,queryDTO.getInboundTimeStart())
.lt(Objects.nonNull(queryDTO.getInboundTimeEnd()),
InboundOrder::getInboundTime,queryDTO.getInboundTimeEnd())
.orderByDesc(InboundOrder::getInboundTime);
InboundOrder::getInboundTime,queryDTO.getInboundTimeEnd());
// 添加组织数据权限过滤
applyOrganizationDataPermission(wrapper);
return wrapper.orderByDesc(InboundOrder::getInboundTime);
}
/**
* 应用组织数据权限过滤
* 通过关联Material表来过滤组织数据
*/
private void applyOrganizationDataPermission(LambdaQueryWrapper<InboundOrder> wrapper) {
try {
com.mhd.system.api.model.LoginUser loginUser = SecurityUtils.getLoginUser();
if (loginUser != null && loginUser.getUserPo() != null) {
Long loginUserOrganizationId = loginUser.getUserPo().getOrganizationId();
// 如果当前登录用户的organizationId为2827(南光组织),可以查询全部组织数据
// 其他组织只能查询自己组织的数据
if (loginUserOrganizationId != null && !loginUserOrganizationId.equals(2827L)) {
// 其他组织:需要通过Material关联来过滤
// 由于InboundOrder没有直接的组织字段,需要通过明细关联Material来过滤
// 使用EXISTS子查询:只查询包含当前组织物料的入库单
wrapper.exists(String.format(
"SELECT 1 FROM inbound_order_detail iod " +
"INNER JOIN material m ON iod.material_id = m.id AND m.is_deleted = 0 " +
"WHERE iod.inbound_order_id = inbound_order.id " +
"AND iod.is_deleted = 0 " +
"AND m.organization_id = '%s'",
loginUserOrganizationId));
}
// 如果是2827组织,不添加过滤条件,可以查询全部
}
} catch (Exception e) {
log.warn("应用组织数据权限过滤失败,将不进行组织过滤: {}", e.getMessage());
// 如果获取登录用户信息失败,不添加过滤条件,避免影响正常查询
}
}
/**
@@ -14,6 +14,7 @@ import com.linke.transport.domain.warehouse.material.repository.MaterialReposito
import com.linke.transport.infrastructure.warehouse.inventory.persistence.InventoryMapper;
import com.linke.transport.interfaces.dto.warehouse.inventory.InventoryDTO;
import com.mhd.common.security.utils.SecurityUtils;
import com.mhd.system.api.model.LoginUser;
import java.math.BigDecimal;
import java.util.List;
import java.util.NoSuchElementException;
@@ -50,12 +51,63 @@ public class InventoryService extends ServiceImpl<InventoryMapper, Inventory> {
// 1. 创建分页请求对象 (注意泛型是 VO)
Page<InventoryVO> page = new Page<>(queryDTO.getPageNo(), queryDTO.getPageSize());
// 2. 调用 Mapper 的自定义分页查询方法 (该方法执行 JOIN)
// 2. 应用组织数据权限过滤(在XML中通过Material表的organizationId过滤)
applyOrganizationDataPermission(queryDTO);
// 3. 调用 Mapper 的自定义分页查询方法 (该方法执行 JOIN)
return inventoryMapper.findInventoryList(page, queryDTO);
}
/**
* 应用组织数据权限过滤
* 设置organizationId到queryDTO中,供XML使用
*/
private void applyOrganizationDataPermission(InventoryDTO.Query queryDTO) {
try {
com.mhd.system.api.model.LoginUser loginUser = SecurityUtils.getLoginUser();
if (loginUser != null && loginUser.getUserPo() != null) {
Long loginUserOrganizationId = loginUser.getUserPo().getOrganizationId();
// 如果当前登录用户的organizationId为2827(南光组织),可以查询全部组织数据
// 其他组织只能查询自己组织的数据
if (loginUserOrganizationId != null && !loginUserOrganizationId.equals(2827L)) {
// 设置organizationId到queryDTO中,供XML使用
// 注意:需要在InventoryDTO.Query中添加organizationId字段
// 由于Material的organizationId是String类型,需要转换为String
if (queryDTO.getOrganizationId() == null) {
queryDTO.setOrganizationId(String.valueOf(loginUserOrganizationId));
}
}
// 如果是2827组织,不设置organizationId,可以查询全部
}
} catch (Exception e) {
log.warn("应用组织数据权限过滤失败,将不进行组织过滤: {}", e.getMessage());
}
}
public List<InventoryVO> listAllInventory(Long ownerId,String machineSerialNo) {
return inventoryMapper.findAllInventoryList(ownerId,machineSerialNo);
// 应用组织数据权限过滤
String organizationId = getOrganizationIdForFilter();
return inventoryMapper.findAllInventoryList(ownerId, machineSerialNo, organizationId);
}
/**
* 获取用于过滤的组织IDString类型,因为Material表的organizationId是String
* @return 如果不是2827组织,返回组织ID字符串;如果是2827,返回null(可查全部)
*/
private String getOrganizationIdForFilter() {
try {
LoginUser loginUser = SecurityUtils.getLoginUser();
if (loginUser != null && loginUser.getUserPo() != null) {
Long loginUserOrganizationId = loginUser.getUserPo().getOrganizationId();
if (loginUserOrganizationId != null && !loginUserOrganizationId.equals(2827L)) {
return String.valueOf(loginUserOrganizationId);
}
}
} catch (Exception e) {
log.warn("获取组织ID失败: {}", e.getMessage());
}
return null; // 2827组织或获取失败时返回null,可查全部
}
/**
@@ -51,8 +51,12 @@ public class InventoryLedgerService extends ServiceImpl<InventoryLedgerMapper, I
.ge(Objects.nonNull(query.getEventTimeStart()),
InventoryLedger::getEventTime,query.getEventTimeStart())
.lt(Objects.nonNull(query.getEventTimeEnd()),
InventoryLedger::getEventTime,query.getEventTimeEnd())
.orderByDesc(InventoryLedger :: getId);
InventoryLedger::getEventTime,query.getEventTimeEnd());
// 添加组织数据权限过滤
applyOrganizationDataPermission(wrapper);
wrapper.orderByDesc(InventoryLedger :: getId);
return this.page(new Page<>(query.getPageNo(), query.getPageSize()), wrapper)
.convert(item -> {
@@ -62,6 +66,34 @@ public class InventoryLedgerService extends ServiceImpl<InventoryLedgerMapper, I
});
}
/**
* 应用组织数据权限过滤
* 通过关联Material表来过滤组织数据
*/
private void applyOrganizationDataPermission(LambdaQueryWrapper<InventoryLedger> wrapper) {
try {
com.mhd.system.api.model.LoginUser loginUser = com.mhd.common.security.utils.SecurityUtils.getLoginUser();
if (loginUser != null && loginUser.getUserPo() != null) {
Long loginUserOrganizationId = loginUser.getUserPo().getOrganizationId();
// 如果当前登录用户的organizationId为2827(南光组织),可以查询全部组织数据
// 其他组织只能查询自己组织的数据
if (loginUserOrganizationId != null && !loginUserOrganizationId.equals(2827L)) {
// 其他组织:需要通过Material关联来过滤
// 由于InventoryLedger表中有materialId字段,我们通过EXISTS子查询关联Material来过滤
wrapper.exists(String.format(
"SELECT 1 FROM material m " +
"WHERE m.id = inventory_ledger.material_id " +
"AND m.organization_id = '%s' AND m.is_deleted = 0",
loginUserOrganizationId));
}
// 如果是2827组织,不添加过滤条件,可以查询全部
}
} catch (Exception e) {
// 如果获取登录用户信息失败,不添加过滤条件,避免影响正常查询
}
}
/**
* 根据货主ID更新货主名称
* @param ownerId 货主ID
@@ -59,4 +59,6 @@ public class CreateMaterialCommand {
private String topOrganizationId;
/**组织相关*/
private String organizationId;
}
/**组织相关*/
private String organizationName;
}
@@ -41,7 +41,7 @@ public class MaterialCommandService {
command.getWeight(),
command.getMaterialVolume(),
command.getMaterialContent(),
command.getRemark(),command.getTopOrganizationId(),command.getOrganizationId(),
command.getRemark(),command.getTopOrganizationId(),command.getOrganizationId(),command.getOrganizationName(),
codeGenerator
);
return materialRepository.save(material).getId();
@@ -67,7 +67,7 @@ public class MaterialCommandService {
command.getWeight(),
command.getMaterialVolume(),
command.getMaterialContent(),
command.getRemark(),command.getTopOrganizationId(),command.getOrganizationId()
command.getRemark(),command.getTopOrganizationId(),command.getOrganizationId(),command.getOrganizationName()
);
materialRepository.update(material);
@@ -51,4 +51,6 @@ public class UpdateMaterialCommand {
private String topOrganizationId;
/**组织相关*/
private String organizationId;
/**组织相关*/
private String organizationName;
}
@@ -34,4 +34,10 @@ public class MaterialQueryCommand {
private BigDecimal materialVolume;
@ApiModelProperty(value = "物料内容")
private String materialContent;
@ApiModelProperty(value = "组织ID")
private String organizationId;
@ApiModelProperty(value = "组织名称")
private String organizationName;
@ApiModelProperty(value = "一级组织ID")
private String topOrganizationId;
}
@@ -5,6 +5,9 @@ import com.linke.transport.application.service.warehouse.material.vo.MaterialVO;
import com.linke.transport.domain.warehouse.material.exception.MaterialDomainException;
import com.linke.transport.domain.warehouse.material.repository.MaterialRepository;
import com.linke.transport.infrastructure.warehouse.material.converter.MaterialConverter;
import com.mhd.common.core.utils.StringUtils;
import com.mhd.system.api.model.LoginUser;
import com.mhd.common.security.utils.SecurityUtils;
import java.util.List;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
@@ -20,15 +23,79 @@ public class MaterialQueryService {
* 分页查询物料
*/
public IPage<MaterialVO> queryMaterials(MaterialQueryCommand param) {
return materialRepository.search(
// 先保存前端传递的 organizationId(如果存在)
String frontendOrganizationId = param.getOrganizationId();
// 获取当前登录用户的组织信息
LoginUser loginUser = SecurityUtils.getLoginUser();
Long loginUserOrganizationId = null;
Long topOrganizationId = null;
if (loginUser != null && loginUser.getUserPo() != null) {
loginUserOrganizationId = loginUser.getUserPo().getOrganizationId();
topOrganizationId = loginUser.getUserPo().getTopOrganizationId();
}
// 数据权限:根据organizationId来设置查询权限
// organizationId等于2827时查询全部,其他仅查询各自组织的信息
if (loginUserOrganizationId != null && loginUserOrganizationId.equals(2827L)) {
// 南光组织(organizationId=2827):可以查询所有组织的数据
// 如果前端传递了 organizationId,使用前端传递的值进行过滤(包括2827)
// 如果前端没有传递 organizationId,清空组织过滤条件,查询所有组织的数据
if (StringUtils.isNotBlank(frontendOrganizationId)) {
// 前端传递了 organizationId,使用前端传递的值进行过滤
param.setOrganizationId(frontendOrganizationId);
param.setTopOrganizationId(null);
} else {
// 前端没有传递 organizationId,清空组织过滤条件,查询所有组织的数据
param.setOrganizationId(null);
param.setTopOrganizationId(null);
}
} else {
// 其他组织:设置organizationId,只查询当前组织的数据
// 其他组织只能查询自己组织的数据,不能查询其他组织(包括南光)的数据
// 如果其他组织尝试查询南光(organizationId=2827)的数据,返回空数据
if (StringUtils.isNotBlank(frontendOrganizationId)) {
// 前端传递了 organizationId,验证是否与当前登录用户的组织ID一致
if ("2827".equals(frontendOrganizationId)) {
// 其他组织尝试查询南光的数据,设置一个不存在的 organizationId,返回空数据
param.setOrganizationId("-1");
param.setTopOrganizationId(null);
} else if (!frontendOrganizationId.equals(String.valueOf(loginUserOrganizationId))) {
// 前端传递了其他组织的 organizationId,强制使用当前登录用户的组织ID,防止越权查询
param.setOrganizationId(String.valueOf(loginUserOrganizationId));
if (topOrganizationId != null) {
param.setTopOrganizationId(String.valueOf(topOrganizationId));
}
} else {
// 前端传递的 organizationId 与当前登录用户的组织ID一致,使用前端传递的值
param.setOrganizationId(frontendOrganizationId);
if (topOrganizationId != null) {
param.setTopOrganizationId(String.valueOf(topOrganizationId));
}
}
} else {
// 前端没有传递 organizationId,使用当前登录用户的组织ID
if (loginUserOrganizationId != null) {
param.setOrganizationId(String.valueOf(loginUserOrganizationId));
}
if (topOrganizationId != null) {
param.setTopOrganizationId(String.valueOf(topOrganizationId));
}
}
}
return materialRepository.search(
param.getShipper(),
param.getCategory(),
param.getName(),
param.getModel(),
param.getMaterialCode(),
param.getCodeManaged(),
param.getRemark(),
param.getCodeManaged(),
param.getRemark(),
param.getMaterialContent(),
param.getOrganizationId(),
param.getOrganizationName(),
param.getTopOrganizationId(),
param.getPageNo(),
param.getPageSize()
).convert(MaterialConverter :: convertToVO);
@@ -51,7 +118,32 @@ public class MaterialQueryService {
* @return 所有材料的列表,以MaterialVO形式表示
*/
public List<MaterialVO> getAllMaterials(Long ownerId) {
return materialRepository.findAllMaterials(ownerId)
// 获取当前登录用户的组织信息
LoginUser loginUser = SecurityUtils.getLoginUser();
String organizationId = null;
String topOrganizationId = null;
if (loginUser != null && loginUser.getUserPo() != null) {
Long loginUserOrganizationId = loginUser.getUserPo().getOrganizationId();
Long topOrgId = loginUser.getUserPo().getTopOrganizationId();
// 数据权限:根据organizationId来设置查询权限
// organizationId等于2827时查询全部,其他仅查询各自组织的信息
if (loginUserOrganizationId != null && loginUserOrganizationId.equals(2827L)) {
// 南光组织(organizationId=2827):不设置组织过滤条件,可以查询所有组织的数据
organizationId = null;
topOrganizationId = null;
} else {
// 其他组织:设置organizationId,只查询当前组织的数据
if (loginUserOrganizationId != null) {
organizationId = String.valueOf(loginUserOrganizationId);
}
if (topOrgId != null) {
topOrganizationId = String.valueOf(topOrgId);
}
}
}
return materialRepository.findAllMaterials(ownerId, organizationId, null, topOrganizationId)
.stream()
.map(MaterialConverter :: convertToVO)
.collect(Collectors.toList());
@@ -53,4 +53,10 @@ public class MaterialVO{
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private LocalDateTime updateTime;
@ApiModelProperty("组织ID")
private String organizationId;
@ApiModelProperty("组织名称")
private String organizationName;
@ApiModelProperty("一级组织ID")
private String topOrganizationId;
}
@@ -21,6 +21,7 @@ import com.linke.transport.interfaces.dto.warehouse.outBoundOrder.OutboundOrderD
import com.linke.transport.interfaces.dto.warehouse.outBoundOrder.OutboundOrderDTO.Create;
import com.mhd.common.core.utils.OrderSequence;
import com.mhd.common.security.utils.SecurityUtils;
import com.mhd.system.api.model.LoginUser;
import java.math.BigDecimal;
import java.util.ArrayList;
@@ -311,7 +312,7 @@ public class OutboundOrderService extends ServiceImpl<OutboundOrderMapper, Outbo
* 构建出库列表查询条件
*/
private LambdaQueryWrapper<OutboundOrder> buildListQueryWrapper(OutboundOrderDTO.Query queryDTO) {
return new LambdaQueryWrapper<OutboundOrder>()
LambdaQueryWrapper<OutboundOrder> wrapper = new LambdaQueryWrapper<OutboundOrder>()
.like(StringUtils.hasText(queryDTO.getOutboundOrderNo()),
OutboundOrder::getOutboundOrderNo, queryDTO.getOutboundOrderNo())
.eq(Objects.nonNull(queryDTO.getOwnerId()),
@@ -323,9 +324,44 @@ public class OutboundOrderService extends ServiceImpl<OutboundOrderMapper, Outbo
.ge(Objects.nonNull(queryDTO.getOutboundTimeStart()),
OutboundOrder::getOutboundTime,queryDTO.getOutboundTimeStart())
.lt(Objects.nonNull(queryDTO.getOutboundTimeEnd()),
OutboundOrder::getOutboundTime,queryDTO.getOutboundTimeEnd())
// 添加时间等其他查询条件
.orderByDesc(OutboundOrder::getOutboundTime); // 按出库时间降序
OutboundOrder::getOutboundTime,queryDTO.getOutboundTimeEnd());
// 添加组织数据权限过滤
applyOrganizationDataPermission(wrapper);
return wrapper.orderByDesc(OutboundOrder::getOutboundTime); // 按出库时间降序
}
/**
* 应用组织数据权限过滤
* 通过关联Material表来过滤组织数据
*/
private void applyOrganizationDataPermission(LambdaQueryWrapper<OutboundOrder> wrapper) {
try {
com.mhd.system.api.model.LoginUser loginUser = SecurityUtils.getLoginUser();
if (loginUser != null && loginUser.getUserPo() != null) {
Long loginUserOrganizationId = loginUser.getUserPo().getOrganizationId();
// 如果当前登录用户的organizationId为2827(南光组织),可以查询全部组织数据
// 其他组织只能查询自己组织的数据
if (loginUserOrganizationId != null && !loginUserOrganizationId.equals(2827L)) {
// 其他组织:需要通过Material关联来过滤
// 由于OutboundOrder没有直接的组织字段,需要通过明细关联Material来过滤
// 使用EXISTS子查询:只查询包含当前组织物料的出库单
wrapper.exists(String.format(
"SELECT 1 FROM outbound_order_detail ood " +
"INNER JOIN material m ON ood.material_id = m.id AND m.is_deleted = 0 " +
"WHERE ood.outbound_order_id = outbound_order.id " +
"AND ood.is_deleted = 0 " +
"AND m.organization_id = '%s'",
loginUserOrganizationId));
}
// 如果是2827组织,不添加过滤条件,可以查询全部
}
} catch (Exception e) {
log.warn("应用组织数据权限过滤失败,将不进行组织过滤: {}", e.getMessage());
// 如果获取登录用户信息失败,不添加过滤条件,避免影响正常查询
}
}
/**
@@ -243,9 +243,17 @@ public class VehicleWlhyDomainService
tmsVehicleDTO.setDrivingPermitExpDate(vehicle.getVehicleCheckoutPeriodValidity());
tmsVehicleDTO.setDrivingPermitNumber(vehicle.getVehicleFileNumber());
tmsVehicleDTO.setTransportPermitNumber(vehicle.getRoadTransportCertificateNo());
tmsVehicleDTO.setOrganizationId(loginUser.getUserPo().getOrganizationId());
tmsVehicleDTO.setOrganizationName(loginUser.getUserPo().getOrganizationName());
tmsVehicleDTO.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId());
// 优先使用 vehicle 对象中保存的组织信息,确保与数据库中的组织ID一致
// 如果 vehicle 中没有组织信息,则使用当前登录用户的组织信息作为后备
if (vehicle.getOrganizationId() != null) {
tmsVehicleDTO.setOrganizationId(vehicle.getOrganizationId());
tmsVehicleDTO.setOrganizationName(vehicle.getOrganizationName());
tmsVehicleDTO.setTopOrganizationId(vehicle.getTopOrganizationId());
} else if (loginUser.getUserPo() != null) {
tmsVehicleDTO.setOrganizationId(loginUser.getUserPo().getOrganizationId());
tmsVehicleDTO.setOrganizationName(loginUser.getUserPo().getOrganizationName());
tmsVehicleDTO.setTopOrganizationId(loginUser.getUserPo().getTopOrganizationId());
}
if (vehicle.getUseStatus() == 2){
tmsVehicleDTO.setBlacklistStatus(1);
}else {
@@ -37,6 +37,8 @@ public class Material {
private String topOrganizationId;
/**组织相关*/
private String organizationId;
/**组织相关*/
private String organizationName;
// 私有构造方法
@@ -51,7 +53,7 @@ public class Material {
BigDecimal weight,
BigDecimal materialVolume,
String materialContent,
String remark,String topOrganizationId,String organizationId ) {
String remark,String topOrganizationId,String organizationId,String organizationName ) {
validateRequiredFields( category, name, unit);
this.ownerId = ownerId;
this.shipper = shipper;
@@ -69,6 +71,7 @@ public class Material {
this.updateTime = LocalDateTime.now();
this.topOrganizationId = topOrganizationId;
this.organizationId = organizationId;
this.organizationName = organizationName;
}
@@ -84,11 +87,11 @@ public class Material {
BigDecimal weight,
BigDecimal materialVolume,
String materialContent,
String remark,String topOrganizationId,String organizationId,
String remark,String topOrganizationId,String organizationId,String organizationName,
MaterialCodeGenerator codeGenerator) {
Material material = new Material(ownerId, shipper, category, name, model,
unit, value, codeManaged, weight, materialVolume, materialContent, remark,
topOrganizationId,organizationId
topOrganizationId,organizationId,organizationName
);
material.materialCode = codeGenerator.generate();
return material;
@@ -104,7 +107,7 @@ public class Material {
BigDecimal weight,
BigDecimal materialVolume,
String materialContent,
String remark,String topOrganizationId,String organizationId ) {
String remark,String topOrganizationId,String organizationId,String organizationName ) {
this.ownerId = ownerId;
this.shipper = shipper;
this.category = category;
@@ -120,6 +123,7 @@ public class Material {
this.updateTime = LocalDateTime.now();
this.topOrganizationId = topOrganizationId;
this.organizationId = organizationId;
this.organizationName = organizationName;
}
// 保留的核心校验
@@ -57,15 +57,19 @@ public interface MaterialRepository {
* @return 分页的物料数据
*/
IPage<Material> search(String shipper, String category, String name,String model,String materialCode,Boolean codeManaged,String remark,String materialContent,
String organizationId, String organizationName, String topOrganizationId,
Long current, Long size);
/**
* 获取所有物料。
*
* @param ownerId 物料所属者ID
* @param organizationId 组织ID
* @param organizationName 组织名称
* @param topOrganizationId 一级组织ID
* @return 物料对象列表
*/
List<Material> findAllMaterials(Long ownerId);
List<Material> findAllMaterials(Long ownerId, String organizationId, String organizationName, String topOrganizationId);
/**
* 根据所属者ID更新所属者名称。
@@ -44,5 +44,7 @@ public interface InventoryMapper extends BaseMapper<Inventory> {
*/
Page<InventoryVO> findInventoryList(@Param("page") Page<InventoryVO> page, @Param("query") InventoryDTO.Query query);
List<InventoryVO> findAllInventoryList(@Param("ownerId") Long ownerId,@Param("machineSerialNo")String machineSerialNo);
List<InventoryVO> findAllInventoryList(@Param("ownerId") Long ownerId,
@Param("machineSerialNo") String machineSerialNo,
@Param("organizationId") String organizationId);
}
@@ -40,4 +40,6 @@ public class MaterialDO {
private String topOrganizationId;
/**组织相关*/
private String organizationId;
/**组织相关*/
private String organizationName;
}
@@ -59,6 +59,7 @@ public class MaterialRepositoryImpl implements MaterialRepository {
@Override
public IPage<Material> search(String shipper, String category, String name, String model,String materialCode,Boolean codeManaged,String remark,String materialContent,
String organizationId, String organizationName, String topOrganizationId,
Long current, Long size) {
LambdaQueryWrapper<MaterialDO> wrapper = Wrappers.<MaterialDO>lambdaQuery()
.eq(StringUtils.isNotBlank(shipper), MaterialDO :: getShipper, shipper)
@@ -69,6 +70,12 @@ public class MaterialRepositoryImpl implements MaterialRepository {
.eq(null!=codeManaged, MaterialDO :: getCodeManaged, codeManaged)
.like(StringUtils.isNotBlank(remark), MaterialDO :: getRemark, remark)
.like(StringUtils.isNotBlank(materialContent), MaterialDO :: getMaterialContent, materialContent)
.eq(StringUtils.isNotBlank(organizationId), MaterialDO :: getOrganizationId, organizationId)
.like(StringUtils.isNotBlank(organizationName), MaterialDO :: getOrganizationName, organizationName)
.eq(StringUtils.isNotBlank(topOrganizationId), MaterialDO :: getTopOrganizationId, topOrganizationId)
// 当设置了 organizationId 或 topOrganizationId 时,排除 organizationName 为 null 的数据
.and(StringUtils.isNotBlank(organizationId) || StringUtils.isNotBlank(topOrganizationId),
w -> w.isNotNull(MaterialDO::getOrganizationName))
.orderByDesc(MaterialDO :: getCreateTime);
return materialMapper.selectPage(new Page<>(current, size), wrapper)
@@ -86,9 +93,18 @@ public class MaterialRepositoryImpl implements MaterialRepository {
}
@Override
public List<Material> findAllMaterials(Long ownerId) {
public List<Material> findAllMaterials(Long ownerId, String organizationId, String organizationName, String topOrganizationId) {
LambdaQueryWrapper<MaterialDO> wrapper = Wrappers.<MaterialDO>lambdaQuery()
.eq(Objects.nonNull(ownerId), MaterialDO :: getOwnerId, ownerId)
.eq(StringUtils.isNotBlank(organizationId), MaterialDO :: getOrganizationId, organizationId)
.like(StringUtils.isNotBlank(organizationName), MaterialDO :: getOrganizationName, organizationName)
.eq(StringUtils.isNotBlank(topOrganizationId), MaterialDO :: getTopOrganizationId, topOrganizationId)
// 当设置了 organizationId 或 topOrganizationId 时,排除 organizationName 为 null 的数据
.and(StringUtils.isNotBlank(organizationId) || StringUtils.isNotBlank(topOrganizationId),
w -> w.isNotNull(MaterialDO::getOrganizationName));
return materialMapper
.selectList(Wrappers.<MaterialDO>lambdaQuery().eq(Objects.nonNull(ownerId),MaterialDO :: getOwnerId, ownerId))
.selectList(wrapper)
.stream()
.map(MaterialConverter :: convert)
.collect(Collectors.toList());
@@ -51,7 +51,8 @@ public class InventoryDTO {
@ApiModelProperty(value = "创建时间")
private Date createdAtEnd;
@ApiModelProperty(value = "组织ID(用于数据权限过滤,内部使用)", hidden = true)
private String organizationId;
@ApiModelProperty(value = "页码,从1开始", required = true, example = "1")
@NotNull(message = "页码不能为空")
@@ -39,6 +39,19 @@ public class MaterialApi {
@PostMapping
@Log(title = "物料管理(PC)", description = "TMS-创建物料", businessType = BusinessType.INSERT)
public R<Long> createMaterial(@Valid @RequestBody CreateMaterialCommand command) {
// 设置当前登录用户的组织信息
com.mhd.system.api.model.LoginUser loginUser = com.mhd.common.security.utils.SecurityUtils.getLoginUser();
if (loginUser != null && loginUser.getUserPo() != null) {
if (command.getTopOrganizationId() == null) {
command.setTopOrganizationId(String.valueOf(loginUser.getUserPo().getTopOrganizationId()));
}
if (command.getOrganizationId() == null) {
command.setOrganizationId(String.valueOf(loginUser.getUserPo().getOrganizationId()));
}
if (command.getOrganizationName() == null) {
command.setOrganizationName(loginUser.getUserPo().getOrganizationName());
}
}
return R.ok(commandService.handle(command));
}
@@ -47,6 +47,10 @@
material m ON i.material_id = m.id AND m.is_deleted = 0
WHERE
i.is_deleted = 0
<!-- 组织数据权限过滤:通过Material表的organizationId过滤 -->
<if test="query.organizationId != null and query.organizationId != ''">
AND m.organization_id = #{query.organizationId}
</if>
<if test="query.ownerId != null">
AND i.owner_id = #{query.ownerId}
</if>
@@ -101,6 +105,10 @@
LEFT JOIN
material m ON i.material_id = m.id AND m.is_deleted = 0
WHERE i.is_deleted = 0
<!-- 组织数据权限过滤:通过Material表的organizationId过滤 -->
<if test="organizationId != null and organizationId != ''">
AND m.organization_id = #{organizationId}
</if>
<if test="ownerId != null">
AND i.owner_id = #{ownerId}
</if>
@@ -196,7 +196,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</if>
<if test="useStatus != null "> and use_status = #{useStatus}</if>
<if test="organizationId != null "> and organization_id = #{organizationId}</if>
<if test="organizationName != null "> and organization_id like concat('%', #{organizationName}, '%')</if>
<if test="organizationName != null and organizationName != ''"> and organization_name like concat('%', #{organizationName}, '%')</if>
<if test="checkoutPersonName != null and checkoutPersonName != ''"> and checkout_person_name like concat('%', #{checkoutPersonName}, '%')</if>
<if test="checkoutDateStart != null">
AND checkout_date >= #{checkoutDateStart}