feat(system): 增加地图绑定设备功能并优化库位相关功能

- 新增地图绑定设备接口和相关DTO
- 实现地图绑定设备的业务逻辑
- 优化库位信息获取接口,支持按地图点位ID查询- 修复设备信息列表查询接口,增加多种查询条件
-优化库区和库位相关的数据结构和接口
This commit is contained in:
aikai 2025-02-06 16:22:22 +08:00
parent 0adb314b20
commit 46dce91672
14 changed files with 158 additions and 47 deletions

View File

@ -15,6 +15,9 @@ public class HouseAreaSaveReqVO {
@Schema(description = "地图id", example = "芋艿")
private Long positionMapId;
@Schema(description = "地图id", example = "芋艿")
private String skuInfo;
@Schema(description = "库区名称", example = "李四")
private String areaName;

View File

@ -1,35 +1,33 @@
package cn.iocoder.yudao.module.system.controller.admin.houselocation;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.module.system.controller.admin.houselocation.vo.WareHouseLocationPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.houselocation.vo.WareHouseLocationRespVO;
import cn.iocoder.yudao.module.system.controller.admin.houselocation.vo.WareHouseLocationSaveReqVO;
import cn.iocoder.yudao.module.system.controller.admin.houselocation.vo.WareHouseLocationVO;
import cn.iocoder.yudao.module.system.dal.dataobject.houselocation.WareHouseLocationDO;
import cn.iocoder.yudao.module.system.service.houselocation.HouseLocationService;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
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.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.*;
import javax.servlet.http.*;
import java.util.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.List;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
@Tag(name = "管理后台 - 库位")
@RestController
@ -73,6 +71,15 @@ public class WareHouseLocationController {
return success(BeanUtils.toBean(houseLocation, WareHouseLocationRespVO.class));
}
@GetMapping("/getByMapItemId")
@Operation(summary = "根据点位获取库位信息列表")
@Parameter(name = "mapId", description = "地图id", required = true, example = "1024")
@Parameter(name = "mapItemId", description = "地图点位id", required = true, example = "1024")
public CommonResult<List<WareHouseLocationRespVO>> getByMapItemId(@RequestParam("mapId") Long mapId, @RequestParam("mapItemId") Long mapItemId) {
List<WareHouseLocationDO> list = houseLocationService.getByMapItemId(mapId, mapItemId);
return success(BeanUtils.toBean(list, WareHouseLocationRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得库位分页")
@PreAuthorize("@ss.hasPermission('ware:house-location:query')")
@ -86,12 +93,12 @@ public class WareHouseLocationController {
@PreAuthorize("@ss.hasPermission('ware:house-location:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportHouseLocationExcel(@Valid WareHouseLocationPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<WareHouseLocationDO> list = houseLocationService.getHouseLocationPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "库位.xls", "数据", WareHouseLocationRespVO.class,
BeanUtils.toBean(list, WareHouseLocationRespVO.class));
BeanUtils.toBean(list, WareHouseLocationRespVO.class));
}
@PostMapping("/getLocationByName")
@ -101,4 +108,4 @@ public class WareHouseLocationController {
return success(houseLocationService.getLocationByName(requestVO));
}
}
}

View File

@ -1,5 +1,7 @@
package cn.iocoder.yudao.module.system.controller.admin.information;
import cn.iocoder.yudao.module.system.controller.admin.information.dto.DeviceInformationDTO;
import cn.iocoder.yudao.module.system.controller.admin.information.dto.MapBindDeviceInfoDTO;
import cn.iocoder.yudao.module.system.controller.admin.information.vo.DeviceInformationPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.information.vo.DeviceInformationRespVO;
import cn.iocoder.yudao.module.system.controller.admin.information.vo.DeviceInformationSaveReqVO;
@ -74,11 +76,18 @@ public class DeviceInformationController {
@GetMapping("/list")
@Operation(summary = "获得设备信息列表")
public CommonResult<List<DeviceInformationRespVO>> getList(@Valid DeviceInformationPageReqVO pageReqVO) {
List<DeviceInformationDO> list = informationService.getList(pageReqVO);
public CommonResult<List<DeviceInformationRespVO>> getList(@Valid DeviceInformationDTO dto) {
List<DeviceInformationDO> list = informationService.getList(dto);
return success(BeanUtils.toBean(list, DeviceInformationRespVO.class));
}
@PostMapping("/mapBindDeviceInfo")
@Operation(summary = "地图绑定设备")
public CommonResult<Boolean> mapBindDeviceInfo(@Valid MapBindDeviceInfoDTO dto) {
informationService.mapBindDeviceInfo(dto);
return success(true);
}
@GetMapping("/page")
@Operation(summary = "获得设备信息分页")
@PreAuthorize("@ss.hasPermission('device:information:query')")

View File

@ -0,0 +1,25 @@
package cn.iocoder.yudao.module.system.controller.admin.information.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.ToString;
@Schema(description = "管理后台 - 设备信息 DTO")
@Data
@ToString(callSuper = true)
public class DeviceInformationDTO {
@Schema(description = "获取未绑定地图的设备 0否 1是 默认否", example = "6609")
private Integer unboundFlag;
@Schema(description = "地图id", example = "6609")
private Long positionMapId;
@Schema(description = "设备类型1充电桩、2输送线、 3码垛机、4拆垛机、5自动门、6提升机、7信号灯、8按钮盒", example = "2")
private Integer deviceType;
@Schema(description = "设备状态1在线、2离线、 3异常", example = "1")
private Integer deviceStatus;
@Schema(description = "设备启用禁用0禁用、1启用")
private Integer deviceEnable;
}

View File

@ -0,0 +1,16 @@
package cn.iocoder.yudao.module.system.controller.admin.information.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.ToString;
@Schema(description = "管理后台 - 地图绑定设备DTO")
@Data
public class MapBindDeviceInfoDTO {
@Schema(description = "地图id", example = "6609")
private Long positionMapId;
@Schema(description = "设备id", example = "6609")
private Long deviceInfoId;
@Schema(description = "类型 1绑定 2取消绑定")
private Integer type;
}

View File

@ -1,9 +1,11 @@
package cn.iocoder.yudao.module.system.dal.dataobject.housearea;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
/**
* 库区 DO
@ -30,7 +32,10 @@ public class HouseAreaDO extends BaseDO {
* 地图id
*/
private Long positionMapId;
/**
* 物料信息
*/
private String skuInfo;
/**
* 库区名称
*/

View File

@ -1,10 +1,10 @@
package cn.iocoder.yudao.module.system.dal.dataobject.houselocation;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.math.BigDecimal;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.*;
import lombok.*;
import java.math.BigDecimal;
/**
* 库位 DO

View File

@ -1,10 +1,7 @@
package cn.iocoder.yudao.module.system.dal.dataobject.information;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.*;
import lombok.*;
import java.math.BigDecimal;
@ -33,10 +30,12 @@ public class DeviceInformationDO extends BaseDO {
/**
* 地图id
*/
@TableField(updateStrategy = FieldStrategy.IGNORED)
private Long positionMapId;
/**
* 地图子表节点id
*/
@TableField(updateStrategy = FieldStrategy.IGNORED)
private Long positionMapItemId;
/**
* 库位坐标x轴

View File

@ -23,7 +23,6 @@ public class DeviceStrategyImpl implements NodeProcessingStrategy {
public void processNodes(Long positionMapId, List<NodeBaseDTO> nodeBaseDTOS) {
// -- 策略3 处理设备点
// -- 将data里面的json 数据转为实体类 - 再对比节点id - 然后做新增删除修改操作
// --------------- dataJSON里面没有具体的类的id - 然后库位要根据层数添加 多个库位数据 一个点位 对应多个库位
List<DeviceInformationDO> newList = new ArrayList<>();
nodeBaseDTOS.forEach(item -> {
if (item.getId() == null) {
@ -31,9 +30,6 @@ public class DeviceStrategyImpl implements NodeProcessingStrategy {
}
item.setPositionMapId(positionMapId);
DeviceInformationDO deviceInformationDO = JSONUtil.toBean(item.getDataJson(), DeviceInformationDO.class);
if (deviceInformationDO.getId() == null) {
deviceInformationDO.setId(getId());
}
deviceInformationDO.setLocationX(item.getLocationX());
deviceInformationDO.setLocationY(item.getLocationY());

View File

@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.system.handler.mapnode.strategy;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.module.system.controller.admin.positionmap.dto.NodeBaseDTO;
@ -31,16 +32,23 @@ public class HouseLocationStrategyImpl implements NodeProcessingStrategy {
item.setPositionMapId(positionMapId);
// -- 如果是库位点 - 可能是一对多情况 - 需要将多个库位点的id set进去
List<WareHouseLocationDO> wareHouseLocationDOS = JSONUtil.toList(item.getDataJson(), WareHouseLocationDO.class);
wareHouseLocationDOS.forEach(wareHouseLocationDO -> {
// -- 筛选出 库位编号不为空 - 并且第最后一组数据 最大的值 - 如果没有则为0
int max = wareHouseLocationDOS.stream().map(WareHouseLocationDO::getLocationNo).filter(StrUtil::isNotEmpty)
.mapToInt(s -> Integer.parseInt(s.split("_")[2])).max().orElse(0);
for (WareHouseLocationDO wareHouseLocationDO : wareHouseLocationDOS) {
wareHouseLocationDO.setLocationX(item.getLocationX());
wareHouseLocationDO.setLocationY(item.getLocationY());
if (wareHouseLocationDO.getId() == null) {
wareHouseLocationDO.setId(getId());
}
if (StrUtil.isEmpty(wareHouseLocationDO.getLocationNo())) {
// -- 生成库位编号 -
wareHouseLocationDO.setLocationNo(positionMapId + "_" + item.getId() + "_" + max++);
}
wareHouseLocationDO.setMapId(positionMapId);
wareHouseLocationDO.setMapItemId(item.getId());
newList.add(wareHouseLocationDO);
});
}
item.setDataJson(JSONUtil.toJsonStr(wareHouseLocationDOS));
});

View File

@ -71,10 +71,19 @@ public interface HouseLocationService extends IService<WareHouseLocationDO> {
* @return
*/
List<WareHouseLocationDO> getByMapId(Long positionMapId);
/**
*
* @param requestVO
* @return
*/
List<WareHouseLocationRespVO> getLocationByName(WareHouseLocationVO requestVO);
/**
* 根据地图id 点位id 获取库位信息
*
* @param mapId
* @param mapItemId
* @return
*/
List<WareHouseLocationDO> getByMapItemId(Long mapId, Long mapItemId);
}

View File

@ -9,7 +9,7 @@ import cn.iocoder.yudao.module.system.controller.admin.houselocation.vo.WareHous
import cn.iocoder.yudao.module.system.controller.admin.houselocation.vo.WareHouseLocationVO;
import cn.iocoder.yudao.module.system.dal.dataobject.houselocation.WareHouseLocationDO;
import cn.iocoder.yudao.module.system.dal.mysql.houselocation.WareHouseLocationMapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
@ -81,6 +81,13 @@ public class HouseLocationServiceImpl extends ServiceImpl<WareHouseLocationMappe
return houseLocationMapper.getLocationByName(requestVO);
}
@Override
public List<WareHouseLocationDO> getByMapItemId(Long mapId, Long mapItemId) {
return houseLocationMapper.selectList(new LambdaQueryWrapper<WareHouseLocationDO>()
.eq(WareHouseLocationDO::getMapId, mapId)
.eq(WareHouseLocationDO::getMapItemId, mapItemId));
}
@Override
public void batchSaveOrEditOrDel(Long positionMapId, List<List<WareHouseLocationDO>> list) {
//批量添加修改删除

View File

@ -1,6 +1,8 @@
package cn.iocoder.yudao.module.system.service.information;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.system.controller.admin.information.dto.DeviceInformationDTO;
import cn.iocoder.yudao.module.system.controller.admin.information.dto.MapBindDeviceInfoDTO;
import cn.iocoder.yudao.module.system.controller.admin.information.vo.DeviceInformationPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.information.vo.DeviceInformationSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.information.DeviceInformationDO;
@ -72,8 +74,15 @@ public interface DeviceInformationService {
/**
* 获取设备列表
*
* @param pageReqVO
* @param dto
* @return
*/
List<DeviceInformationDO> getList(@Valid DeviceInformationPageReqVO pageReqVO);
List<DeviceInformationDO> getList(@Valid DeviceInformationDTO dto);
/**
* 地图绑定设备
*
* @param dto
*/
void mapBindDeviceInfo(@Valid MapBindDeviceInfoDTO dto);
}

View File

@ -5,6 +5,8 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.grpc.api.GrpcServiceApi;
import cn.iocoder.yudao.module.system.controller.admin.information.dto.DeviceInformationDTO;
import cn.iocoder.yudao.module.system.controller.admin.information.dto.MapBindDeviceInfoDTO;
import cn.iocoder.yudao.module.system.controller.admin.information.vo.DeviceInformationPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.information.vo.DeviceInformationSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.information.DeviceInformationDO;
@ -113,9 +115,25 @@ public class DeviceInformationServiceImpl implements DeviceInformationService {
}
@Override
public List<DeviceInformationDO> getList(DeviceInformationPageReqVO pageReqVO) {
public List<DeviceInformationDO> getList(DeviceInformationDTO dto) {
return informationMapper.selectList(new LambdaQueryWrapper<DeviceInformationDO>()
.eq(pageReqVO.getDeviceType() != null, DeviceInformationDO::getDeviceType, pageReqVO.getDeviceType()));
.isNull(dto.getUnboundFlag() != null && dto.getUnboundFlag() == 1, DeviceInformationDO::getPositionMapId)
.eq(dto.getPositionMapId() != null, DeviceInformationDO::getPositionMapId, dto.getPositionMapId())
.eq(dto.getDeviceType() != null, DeviceInformationDO::getDeviceType, dto.getDeviceType())
.eq(dto.getDeviceStatus() != null, DeviceInformationDO::getDeviceStatus, dto.getDeviceStatus())
.eq(dto.getDeviceEnable() != null, DeviceInformationDO::getDeviceEnable, dto.getDeviceEnable())
);
}
@Override
public void mapBindDeviceInfo(MapBindDeviceInfoDTO dto) {
DeviceInformationDO deviceInformationDO = informationMapper.selectById(dto.getDeviceInfoId());
if (dto.getType() == 1) {
deviceInformationDO.setPositionMapId(dto.getPositionMapId());
} else {
deviceInformationDO.setPositionMapId(null);
deviceInformationDO.setPositionMapItemId(null);
}
informationMapper.updateById(deviceInformationDO);
}
}