feat(B10): 产品<->设备反向查询 - 设备列表可按产品过滤并展示所属产品
后端: - DeviceQuery 新增 productId(精确) 与 productKeyword(按产品名/编码模糊) - DeviceServiceImpl.pageDevices 支持两种产品维度过滤 productKeyword 场景: 先解析匹配的 product_id 集合再约束 device, 集合为空时用 1=0 保证不误返回全部 - 新增 fillProductInfo(): 批量回填设备所属产品名称与业务编码 (一次 selectBatchIds, 避免 N+1) - Device 实体新增非持久化展示字段 productName / productKey 验证: mvn -pl iot-common,iot-device -am compile 通过
This commit is contained in:
parent
d7e34efb58
commit
a8c2d005a8
@ -49,6 +49,12 @@ public class DeviceQuery {
|
||||
@Schema(description = "是否为网关(1=网关)")
|
||||
private Integer isGateway;
|
||||
|
||||
@Schema(description = "所属产品ID(按产品过滤设备)")
|
||||
private Long productId;
|
||||
|
||||
@Schema(description = "所属产品关键字(按产品名/编码模糊查询)")
|
||||
private String productKeyword;
|
||||
|
||||
@Schema(description = "页码")
|
||||
@Builder.Default
|
||||
private Integer pageNum = 1;
|
||||
|
||||
@ -130,6 +130,16 @@ public class Device extends BaseEntity {
|
||||
@Schema(description = "备注")
|
||||
private String remark;
|
||||
|
||||
// ===== 关联展示字段(非持久化,列表查询时按 product_id 批量回填)=====
|
||||
|
||||
@Schema(description = "所属产品名称")
|
||||
@TableField(exist = false)
|
||||
private String productName;
|
||||
|
||||
@Schema(description = "所属产品业务编码")
|
||||
@TableField(exist = false)
|
||||
private String productKey;
|
||||
|
||||
// ===== 中控屏本地执行相关(executionSource=LOCAL_PANEL 时生效) =====
|
||||
|
||||
/**
|
||||
|
||||
@ -26,6 +26,9 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 设备服务实现
|
||||
@ -150,9 +153,53 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
|
||||
// 网关→子设备:按父网关过滤
|
||||
.eq(StringUtils.hasText(query.getParentDeviceId()), Device::getParentDeviceId, query.getParentDeviceId())
|
||||
.eq(query.getIsGateway() != null, Device::getIsGateway, query.getIsGateway())
|
||||
// 产品维度过滤:支持按 productId 精确查,或按产品名/编码模糊查
|
||||
.eq(query.getProductId() != null && query.getProductId() > 0, Device::getProductId, query.getProductId())
|
||||
.orderByDesc(Device::getUpdateTime);
|
||||
|
||||
return page(new Page<>(query.getPageNum(), query.getPageSize()), wrapper);
|
||||
// 按产品关键字过滤:先解析出匹配的 product_id 集合,再约束 device
|
||||
if (StringUtils.hasText(query.getProductKeyword())) {
|
||||
List<Long> pids = productMapper.selectList(new LambdaQueryWrapper<Product>()
|
||||
.like(StringUtils.hasText(query.getProductKeyword()), Product::getName, query.getProductKeyword())
|
||||
.or().like(StringUtils.hasText(query.getProductKeyword()), Product::getProductKey, query.getProductKeyword()))
|
||||
.stream().map(Product::getId).toList();
|
||||
wrapper.and(w -> {
|
||||
if (pids.isEmpty()) {
|
||||
w.apply("1 = 0");
|
||||
} else {
|
||||
w.in(Device::getProductId, pids);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Page<Device> result = page(new Page<>(query.getPageNum(), query.getPageSize()), wrapper);
|
||||
fillProductInfo(result.getRecords());
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量回填设备所属产品名称与业务编码(供后台设备列表展示"所属产品"列)。
|
||||
*/
|
||||
private void fillProductInfo(List<Device> devices) {
|
||||
if (devices == null || devices.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Set<Long> pids = devices.stream()
|
||||
.map(Device::getProductId)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toSet());
|
||||
if (pids.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Map<Long, Product> productMap = productMapper.selectBatchIds(pids).stream()
|
||||
.collect(Collectors.toMap(Product::getId, p -> p));
|
||||
for (Device d : devices) {
|
||||
Product p = d.getProductId() == null ? null : productMap.get(d.getProductId());
|
||||
if (p != null) {
|
||||
d.setProductName(p.getName());
|
||||
d.setProductKey(p.getProductKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user