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 = "芋艿") @Schema(description = "地图id", example = "芋艿")
private Long positionMapId; private Long positionMapId;
@Schema(description = "地图id", example = "芋艿")
private String skuInfo;
@Schema(description = "库区名称", example = "李四") @Schema(description = "库区名称", example = "李四")
private String areaName; private String areaName;

View File

@ -1,35 +1,33 @@
package cn.iocoder.yudao.module.system.controller.admin.houselocation; 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.WareHouseLocationPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.houselocation.vo.WareHouseLocationRespVO; 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.WareHouseLocationSaveReqVO;
import cn.iocoder.yudao.module.system.controller.admin.houselocation.vo.WareHouseLocationVO; 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.dataobject.houselocation.WareHouseLocationDO;
import cn.iocoder.yudao.module.system.service.houselocation.HouseLocationService; 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.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.annotation.Resource;
import javax.servlet.http.*; import javax.servlet.http.HttpServletResponse;
import java.util.*; import javax.validation.Valid;
import java.io.IOException; import java.io.IOException;
import java.util.List;
import cn.iocoder.yudao.framework.common.pojo.PageParam; import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
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.common.pojo.CommonResult.success; 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 = "管理后台 - 库位") @Tag(name = "管理后台 - 库位")
@RestController @RestController
@ -73,6 +71,15 @@ public class WareHouseLocationController {
return success(BeanUtils.toBean(houseLocation, WareHouseLocationRespVO.class)); 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") @GetMapping("/page")
@Operation(summary = "获得库位分页") @Operation(summary = "获得库位分页")
@PreAuthorize("@ss.hasPermission('ware:house-location:query')") @PreAuthorize("@ss.hasPermission('ware:house-location:query')")

View File

@ -1,5 +1,7 @@
package cn.iocoder.yudao.module.system.controller.admin.information; 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.DeviceInformationPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.information.vo.DeviceInformationRespVO; import cn.iocoder.yudao.module.system.controller.admin.information.vo.DeviceInformationRespVO;
import cn.iocoder.yudao.module.system.controller.admin.information.vo.DeviceInformationSaveReqVO; import cn.iocoder.yudao.module.system.controller.admin.information.vo.DeviceInformationSaveReqVO;
@ -74,11 +76,18 @@ public class DeviceInformationController {
@GetMapping("/list") @GetMapping("/list")
@Operation(summary = "获得设备信息列表") @Operation(summary = "获得设备信息列表")
public CommonResult<List<DeviceInformationRespVO>> getList(@Valid DeviceInformationPageReqVO pageReqVO) { public CommonResult<List<DeviceInformationRespVO>> getList(@Valid DeviceInformationDTO dto) {
List<DeviceInformationDO> list = informationService.getList(pageReqVO); List<DeviceInformationDO> list = informationService.getList(dto);
return success(BeanUtils.toBean(list, DeviceInformationRespVO.class)); 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") @GetMapping("/page")
@Operation(summary = "获得设备信息分页") @Operation(summary = "获得设备信息分页")
@PreAuthorize("@ss.hasPermission('device:information:query')") @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; 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 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 * 库区 DO
@ -30,7 +32,10 @@ public class HouseAreaDO extends BaseDO {
* 地图id * 地图id
*/ */
private Long positionMapId; private Long positionMapId;
/**
* 物料信息
*/
private String skuInfo;
/** /**
* 库区名称 * 库区名称
*/ */

View File

@ -1,10 +1,10 @@
package cn.iocoder.yudao.module.system.dal.dataobject.houselocation; 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 cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.*;
import lombok.*;
import java.math.BigDecimal;
/** /**
* 库位 DO * 库位 DO

View File

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

View File

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

View File

@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.system.handler.mapnode.strategy; package cn.iocoder.yudao.module.system.handler.mapnode.strategy;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil; import cn.hutool.json.JSONUtil;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.module.system.controller.admin.positionmap.dto.NodeBaseDTO; import cn.iocoder.yudao.module.system.controller.admin.positionmap.dto.NodeBaseDTO;
@ -31,16 +32,23 @@ public class HouseLocationStrategyImpl implements NodeProcessingStrategy {
item.setPositionMapId(positionMapId); item.setPositionMapId(positionMapId);
// -- 如果是库位点 - 可能是一对多情况 - 需要将多个库位点的id set进去 // -- 如果是库位点 - 可能是一对多情况 - 需要将多个库位点的id set进去
List<WareHouseLocationDO> wareHouseLocationDOS = JSONUtil.toList(item.getDataJson(), WareHouseLocationDO.class); 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.setLocationX(item.getLocationX());
wareHouseLocationDO.setLocationY(item.getLocationY()); wareHouseLocationDO.setLocationY(item.getLocationY());
if (wareHouseLocationDO.getId() == null) { if (wareHouseLocationDO.getId() == null) {
wareHouseLocationDO.setId(getId()); wareHouseLocationDO.setId(getId());
} }
if (StrUtil.isEmpty(wareHouseLocationDO.getLocationNo())) {
// -- 生成库位编号 -
wareHouseLocationDO.setLocationNo(positionMapId + "_" + item.getId() + "_" + max++);
}
wareHouseLocationDO.setMapId(positionMapId); wareHouseLocationDO.setMapId(positionMapId);
wareHouseLocationDO.setMapItemId(item.getId()); wareHouseLocationDO.setMapItemId(item.getId());
newList.add(wareHouseLocationDO); newList.add(wareHouseLocationDO);
}); }
item.setDataJson(JSONUtil.toJsonStr(wareHouseLocationDOS)); item.setDataJson(JSONUtil.toJsonStr(wareHouseLocationDOS));
}); });

View File

@ -71,10 +71,19 @@ public interface HouseLocationService extends IService<WareHouseLocationDO> {
* @return * @return
*/ */
List<WareHouseLocationDO> getByMapId(Long positionMapId); List<WareHouseLocationDO> getByMapId(Long positionMapId);
/** /**
*
* @param requestVO * @param requestVO
* @return * @return
*/ */
List<WareHouseLocationRespVO> getLocationByName(WareHouseLocationVO requestVO); 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.controller.admin.houselocation.vo.WareHouseLocationVO;
import cn.iocoder.yudao.module.system.dal.dataobject.houselocation.WareHouseLocationDO; import cn.iocoder.yudao.module.system.dal.dataobject.houselocation.WareHouseLocationDO;
import cn.iocoder.yudao.module.system.dal.mysql.houselocation.WareHouseLocationMapper; 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 com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
@ -81,6 +81,13 @@ public class HouseLocationServiceImpl extends ServiceImpl<WareHouseLocationMappe
return houseLocationMapper.getLocationByName(requestVO); 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 @Override
public void batchSaveOrEditOrDel(Long positionMapId, List<List<WareHouseLocationDO>> list) { public void batchSaveOrEditOrDel(Long positionMapId, List<List<WareHouseLocationDO>> list) {
//批量添加修改删除 //批量添加修改删除

View File

@ -1,6 +1,8 @@
package cn.iocoder.yudao.module.system.service.information; package cn.iocoder.yudao.module.system.service.information;
import cn.iocoder.yudao.framework.common.pojo.PageResult; 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.DeviceInformationPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.information.vo.DeviceInformationSaveReqVO; import cn.iocoder.yudao.module.system.controller.admin.information.vo.DeviceInformationSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.information.DeviceInformationDO; import cn.iocoder.yudao.module.system.dal.dataobject.information.DeviceInformationDO;
@ -72,8 +74,15 @@ public interface DeviceInformationService {
/** /**
* 获取设备列表 * 获取设备列表
* *
* @param pageReqVO * @param dto
* @return * @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.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.grpc.api.GrpcServiceApi; 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.DeviceInformationPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.information.vo.DeviceInformationSaveReqVO; import cn.iocoder.yudao.module.system.controller.admin.information.vo.DeviceInformationSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.information.DeviceInformationDO; import cn.iocoder.yudao.module.system.dal.dataobject.information.DeviceInformationDO;
@ -113,9 +115,25 @@ public class DeviceInformationServiceImpl implements DeviceInformationService {
} }
@Override @Override
public List<DeviceInformationDO> getList(DeviceInformationPageReqVO pageReqVO) { public List<DeviceInformationDO> getList(DeviceInformationDTO dto) {
return informationMapper.selectList(new LambdaQueryWrapper<DeviceInformationDO>() 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);
}
} }