Compare commits

...

14 Commits

Author SHA1 Message Date
cbs
dc88e8e574 Merge branch 'dev' into cbs
# Conflicts:
#	yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/houselocation/WareHouseLocationDO.java
#	yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/positionmap/PositionMapItemDO.java
#	yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/houselocation/WareHouseLocationMapper.xml
2025-01-18 17:16:51 +08:00
aikai
93999f019b feat(仓储): 重构库区、连线和线库相关功能- 新增库区创建、编辑和删除功能
- 优化连线和线库的增删改查接口
- 增加地图id相关字段和查询条件
- 重构数据结构和业务逻辑,提高系统可维护性
2025-01-18 10:54:31 +08:00
aikai
7099fa02a0 feat(houselane): 优化线库管理功能
- 新增线库列表接口和相关页面
- 实现线库和库位的关联逻辑
- 优化线库创建、编辑和删除功能
- 添加线库相关的错误码和异常处理
2025-01-17 19:20:34 +08:00
aikai
69c1168dcc refactor(ware): 重构线库功能
- 修改 NodeProcessingContext 中的策略判断逻辑
-重命名 NodeTypeEnum 中的字段名称
- 更新 PositionMapItemDO 中的字段注释
- 新增 PositionMapItemService 接口及实现类
- 重构 WareHouseLaneController,改为仅处理线库相关操作
- 更新相关 VO 类,移除巷道相关字段- 重构 WareHouseLaneService接口,新增 createOrEditOrDel 方法
- 实现 WareHouseLaneServiceImpl 中的 createOrEditOrDel 方法
2025-01-17 09:57:58 +08:00
aikai
0a7b1b72d0 优化库位点位处理逻辑
- 移除 HouseAreaDO 中的 areaId 字段
- 修改 WareHouseLocationDO 的处理方式,支持批量导入- 更新 NodeBaseDTO,增加 positionMapId 字段
-调整 PositionMapItemDO 和相关 VO 类,移除 objectId 字段
- 更新数据库映射文件,适应新的数据结构
2025-01-16 16:51:54 +08:00
aikai
df480e1b90 优化库位点位处理逻辑
- 移除 HouseAreaDO 中的 areaId 字段
- 修改 WareHouseLocationDO 的处理方式,支持批量导入- 更新 NodeBaseDTO,增加 positionMapId 字段
-调整 PositionMapItemDO 和相关 VO 类,移除 objectId 字段
- 更新数据库映射文件,适应新的数据结构
2025-01-16 16:51:49 +08:00
aikai
1444a079de Merge branch 'dev' of http://git.znkjfw.com/ak/zn-cloud-wcs into dev
# Conflicts:
#	yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/houselocation/HouseLocationService.java
#	yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/houselocation/HouseLocationServiceImpl.java
2025-01-16 10:35:11 +08:00
aikai
4deea77ed2 feat(system): 实现仓库点位地图节点批量操作功能
- 新增 NodeBaseDTO 类作为节点基础数据传输对象
- 实现 PositionMapItem 和 WareHouseLocation 的批量保存、编辑和删除方法
- 添加 HouseLocationStrategyImpl 类处理库位节点
- 创建 NodeProcessingContext 类协调不同类型的节点处理策略- 定义 NodeProcessingStrategy接口规范节点处理逻辑
- 更新 PositionMapItemController 支持批量操作
- 调整 PositionMapItemDO 和相关 VO 类以支持新功能
2025-01-16 10:34:04 +08:00
aikai
c593611b56 Merge branch 'dev' of http://git.znkjfw.com/ak/zn-cloud-wcs into dev 2025-01-15 16:38:28 +08:00
aikai
6bf1f7da7f 缓存配置 - xxl-job配置 - 前端AGV地图png转base64 2025-01-13 16:23:11 +08:00
aikai
edbea240f8 Merge branch 'dev' of http://git.znkjfw.com/ak/zn-cloud-wcs into aikai 2025-01-13 15:01:16 +08:00
aikai
627d5151ef 前端png文件下载改base64格式 2025-01-13 14:55:22 +08:00
aikai
e490462195 Merge branch 'dev' of http://git.znkjfw.com/ak/zn-cloud-wcs into aikai 2025-01-13 14:54:47 +08:00
aikai
eb580beee0 前端png文件下载改base64格式 2025-01-13 14:54:35 +08:00
49 changed files with 872 additions and 472 deletions

View File

@ -0,0 +1,33 @@
package cn.iocoder.yudao.framework.common.enums;
import cn.hutool.core.util.ObjUtil;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
* 通用状态枚举
*
* @author 芋道源码
*/
@Getter
@AllArgsConstructor
public enum NodeTypeEnum {
ROUTE(1, "路径点位"),
WARE(2, "库位点"),
charging(3, "充电桩"),
PARKING(4, "停车点"),
CHANGE(5, "区域变更点"),
WAIT(6, "等待点");
/**
* 类型
*/
private final Integer type;
/**
* 说明
*/
private final String name;
}

View File

@ -208,4 +208,9 @@ public interface ErrorCodeConstants {
ErrorCode AGV_FILE_UPLOAD_CONTENT_IS_EMPTY = new ErrorCode(1_002_038_002, "AGV文件上传内容为空");
ErrorCode PLEASE_UPLOAD_PNG_AND_YAML_FILES = new ErrorCode(1_002_038_003, "请上传png和yaml两个文件并且文件内容不为空");
ErrorCode AGV_MAP_NOT_FOUND = new ErrorCode(1_002_038_004, "找不到AGV地图信息");
ErrorCode AGV_IMAGE_CONVERSION_TO_BASE64_FAILED = new ErrorCode(1_002_038_005, "AGV图片转base64失败");
ErrorCode THE_LINE_LIBRARY_POINTS_ARE_NOT_LOCATED_IN_THE_SAME_AREA = new ErrorCode(1_002_038_006, "线库点位不在同一区域内");
ErrorCode THERE_ARE_ALREADY_STORAGE_LOCATIONS_IN_OTHER_LINE_WAREHOUSES = new ErrorCode(1_002_038_007, "已有库位在其他线库内");
ErrorCode THERE_ARE_ALREADY_STORAGE_LOCATIONS_IN_OTHER_STORAGE_AREAS = new ErrorCode(1_002_038_008, "已有库位在其他库区内");
}

View File

@ -2,6 +2,8 @@ package cn.iocoder.yudao.module.system;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Configuration;
/**
* 项目的启动类
@ -13,6 +15,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
* @author 芋道源码
*/
@SpringBootApplication
@EnableCaching
public class SystemServerApplication {
public static void main(String[] args) {

View File

@ -1,65 +0,0 @@
package cn.iocoder.yudao.module.system.config;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @ClassName XxlJobConfig
* @Description: xxl-job依赖配置
* @author
* @date 2022年12月07日 08:37
* @version 1.0
*/
@Configuration //是否开启xxl-job定时任务注释掉 //@Configuration 则不开启定时任务
@Data
@Slf4j
public class XxlJobConfig {
@Value("${xxl.job.admin.addresses}")
private String adminAddresses;
@Value("${xxl.job.accessToken}")
private String accessToken;
@Value("${xxl.job.executor.appname}")
private String appname;
@Value("${xxl.job.executor.address}")
private String address;
@Value("${xxl.job.executor.ip}")
private String ip;
@Value("${xxl.job.executor.port}")
private int port;
@Value("${xxl.job.executor.logpath}")
private String logPath;
@Value("${xxl.job.executor.logretentiondays}")
private int logRetentionDays;
@Bean
public XxlJobSpringExecutor xxlJobExecutor() {
XxlJobHelper.log(">>>>>>>>>>> xxl-job config init.>>>>>>>>>>>");
System.out.println("=============== xxl-job config init.===============");
XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
xxlJobSpringExecutor.setAppname(appname);
xxlJobSpringExecutor.setAddress(address);
xxlJobSpringExecutor.setIp(ip);
xxlJobSpringExecutor.setPort(port);
xxlJobSpringExecutor.setAccessToken(accessToken);
xxlJobSpringExecutor.setLogPath(logPath);
xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);
return xxlJobSpringExecutor;
}
}

View File

@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.system.controller.admin.housearea;
import cn.iocoder.yudao.module.system.controller.admin.housearea.vo.HouseAreaPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.housearea.vo.HouseAreaRespVO;
import cn.iocoder.yudao.module.system.controller.admin.housearea.vo.HouseAreaSaveReqVO;
import cn.iocoder.yudao.module.system.controller.admin.houselane.vo.WareHouseLaneSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.housearea.HouseAreaDO;
import cn.iocoder.yudao.module.system.service.housearea.HouseAreaService;
import org.springframework.web.bind.annotation.*;
@ -40,27 +41,11 @@ public class HouseAreaController {
@Resource
private HouseAreaService houseAreaService;
@PostMapping("/create")
@Operation(summary = "创建库区")
@PostMapping("/createOrEditOrDel")
@Operation(summary = "创建修改删除库区")
@PreAuthorize("@ss.hasPermission('ware:house-area:create')")
public CommonResult<Long> createHouseArea(@Valid @RequestBody HouseAreaSaveReqVO createReqVO) {
return success(houseAreaService.createHouseArea(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新库区")
@PreAuthorize("@ss.hasPermission('ware:house-area:update')")
public CommonResult<Boolean> updateHouseArea(@Valid @RequestBody HouseAreaSaveReqVO updateReqVO) {
houseAreaService.updateHouseArea(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除库区")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('ware:house-area:delete')")
public CommonResult<Boolean> deleteHouseArea(@RequestParam("id") Long id) {
houseAreaService.deleteHouseArea(id);
public CommonResult<Boolean> createOrEditOrDel(@Valid @RequestBody HouseAreaSaveReqVO createReqVO) {
houseAreaService.createOrEditOrDel(createReqVO);
return success(true);
}
@ -94,4 +79,4 @@ public class HouseAreaController {
BeanUtils.toBean(list, HouseAreaRespVO.class));
}
}
}

View File

@ -15,8 +15,8 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
@ToString(callSuper = true)
public class HouseAreaPageReqVO extends PageParam {
@Schema(description = "库区id(自定义)", example = "24710")
private Long areaId;
@Schema(description = "地图id", example = "芋艿")
private Long positionMapId;
@Schema(description = "库区名称", example = "李四")
private String areaName;
@ -28,4 +28,4 @@ public class HouseAreaPageReqVO extends PageParam {
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}
}

View File

@ -16,9 +16,9 @@ public class HouseAreaRespVO {
@ExcelProperty("主键ID")
private Long id;
@Schema(description = "库区id(自定义)", requiredMode = Schema.RequiredMode.REQUIRED, example = "24710")
@ExcelProperty("库区id(自定义)")
private Long areaId;
@Schema(description = "地图id", example = "芋艿")
@ExcelProperty("地图id")
private Long positionMapId;
@Schema(description = "库区名称", example = "李四")
@ExcelProperty("库区名称")
@ -32,4 +32,4 @@ public class HouseAreaRespVO {
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}
}

View File

@ -1,9 +1,9 @@
package cn.iocoder.yudao.module.system.controller.admin.housearea.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import javax.validation.constraints.*;
import lombok.Data;
import java.util.List;
@Schema(description = "管理后台 - 库区新增/修改 Request VO")
@Data
@ -12,9 +12,8 @@ public class HouseAreaSaveReqVO {
@Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "2922")
private Long id;
@Schema(description = "库区id(自定义)", requiredMode = Schema.RequiredMode.REQUIRED, example = "24710")
@NotNull(message = "库区id(自定义)不能为空")
private Long areaId;
@Schema(description = "地图id", example = "芋艿")
private Long positionMapId;
@Schema(description = "库区名称", example = "李四")
private String areaName;
@ -22,4 +21,7 @@ public class HouseAreaSaveReqVO {
@Schema(description = "库区说明")
private String areaMsg;
}
@Schema(description = "地图库位节点ids")
private List<Long> mapItemIds;
}

View File

@ -1,37 +1,27 @@
package cn.iocoder.yudao.module.system.controller.admin.houselane;
import cn.iocoder.yudao.module.system.controller.admin.houselane.vo.WareHouseLanePageReqVO;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.system.controller.admin.houselane.vo.WareHouseLaneRespVO;
import cn.iocoder.yudao.module.system.controller.admin.houselane.vo.WareHouseLaneSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.houselane.WareHouseLaneDO;
import cn.iocoder.yudao.module.system.service.houselane.WareHouseLaneService;
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.constraints.*;
import javax.validation.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.IOException;
import javax.annotation.Resource;
import javax.validation.Valid;
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.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
@RequestMapping("/system/ware/house-lane")
@Validated
@ -40,32 +30,16 @@ public class WareHouseLaneController {
@Resource
private WareHouseLaneService houseLaneService;
@PostMapping("/create")
@Operation(summary = "创建线库/巷道")
@PostMapping("/createOrEditOrDel")
@Operation(summary = "创建修改删除线库")
@PreAuthorize("@ss.hasPermission('ware:house-lane:create')")
public CommonResult<Long> createHouseLane(@Valid @RequestBody WareHouseLaneSaveReqVO createReqVO) {
return success(houseLaneService.createHouseLane(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新线库/巷道")
@PreAuthorize("@ss.hasPermission('ware:house-lane:update')")
public CommonResult<Boolean> updateHouseLane(@Valid @RequestBody WareHouseLaneSaveReqVO updateReqVO) {
houseLaneService.updateHouseLane(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除线库/巷道")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('ware:house-lane:delete')")
public CommonResult<Boolean> deleteHouseLane(@RequestParam("id") Long id) {
houseLaneService.deleteHouseLane(id);
public CommonResult<Boolean> createOrEditOrDel(@Valid @RequestBody WareHouseLaneSaveReqVO createReqVO) {
houseLaneService.createOrEditOrDel(createReqVO);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得线库/巷道")
@Operation(summary = "获得线库")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('ware:house-lane:query')")
public CommonResult<WareHouseLaneRespVO> getHouseLane(@RequestParam("id") Long id) {
@ -73,25 +47,11 @@ public class WareHouseLaneController {
return success(BeanUtils.toBean(houseLane, WareHouseLaneRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得线库/巷道分页")
@PreAuthorize("@ss.hasPermission('ware:house-lane:query')")
public CommonResult<PageResult<WareHouseLaneRespVO>> getHouseLanePage(@Valid WareHouseLanePageReqVO pageReqVO) {
PageResult<WareHouseLaneDO> pageResult = houseLaneService.getHouseLanePage(pageReqVO);
return success(BeanUtils.toBean(pageResult, WareHouseLaneRespVO.class));
@GetMapping("/list")
@Operation(summary = "获得线库列表")
public CommonResult<List<WareHouseLaneRespVO>> list(@RequestParam Long positionMapId) {
List<WareHouseLaneDO> list = houseLaneService.list(new LambdaQueryWrapperX<WareHouseLaneDO>()
.eq(WareHouseLaneDO::getPositionMapId, positionMapId));
return success(BeanUtils.toBean(list, WareHouseLaneRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出线库/巷道 Excel")
@PreAuthorize("@ss.hasPermission('ware:house-lane:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportHouseLaneExcel(@Valid WareHouseLanePageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<WareHouseLaneDO> list = houseLaneService.getHouseLanePage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "线库/巷道.xls", "数据", WareHouseLaneRespVO.class,
BeanUtils.toBean(list, WareHouseLaneRespVO.class));
}
}
}

View File

@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.system.controller.admin.houselane.vo;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
@ -15,8 +16,8 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
@ToString(callSuper = true)
public class WareHouseLanePageReqVO extends PageParam {
@Schema(description = "巷道id(自定义)", example = "276")
private Long laneId;
@Schema(description = "地图id", example = "芋艿")
private Long positionMapId;
@Schema(description = "巷道名称", example = "芋艿")
private String laneName;
@ -28,4 +29,4 @@ public class WareHouseLanePageReqVO extends PageParam {
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}
}

View File

@ -16,9 +16,9 @@ public class WareHouseLaneRespVO {
@ExcelProperty("主键ID")
private Long id;
@Schema(description = "巷道id(自定义)", requiredMode = Schema.RequiredMode.REQUIRED, example = "276")
@ExcelProperty("巷道id(自定义)")
private Long laneId;
@Schema(description = "地图id", example = "芋艿")
@ExcelProperty("地图id")
private Long positionMapId;
@Schema(description = "巷道名称", example = "芋艿")
@ExcelProperty("巷道名称")
@ -32,4 +32,6 @@ public class WareHouseLaneRespVO {
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}
@Schema(description = "节点ids", requiredMode = Schema.RequiredMode.REQUIRED)
private List<Long> mapItemIds;
}

View File

@ -5,21 +5,22 @@ import lombok.*;
import java.util.*;
import javax.validation.constraints.*;
@Schema(description = "管理后台 - 线库/巷道新增/修改 Request VO")
@Schema(description = "管理后台 - 线库新增/修改 Request VO")
@Data
public class WareHouseLaneSaveReqVO {
@Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "4293")
private Long id;
@Schema(description = "巷道id(自定义)", requiredMode = Schema.RequiredMode.REQUIRED, example = "276")
@NotNull(message = "巷道id(自定义)不能为空")
private Long laneId;
@Schema(description = "地图id", example = "芋艿")
private Long positionMapId;
@Schema(description = "巷道名称", example = "芋艿")
@Schema(description = "线库名称", example = "芋艿")
private String laneName;
@Schema(description = "巷道说明(可以拓展为区域说明)")
@Schema(description = "线库说明(可以拓展为说明)")
private String laneMsg;
}
@Schema(description = "地图库位节点ids")
private List<Long> mapItemIds;
}

View File

@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.system.controller.admin.positionmap;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.system.controller.admin.positionmap.vo.PositionMapRespVO;
import cn.iocoder.yudao.module.system.controller.admin.positionmap.vo.PositionMapSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.positionmap.PositionMapDO;
import cn.iocoder.yudao.module.system.service.positionmap.PositionMapService;
import io.swagger.v3.oas.annotations.Operation;
@ -17,7 +16,6 @@ import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.annotation.security.PermitAll;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.List;
import java.util.Map;
@ -34,17 +32,6 @@ public class PositionMapController {
@Resource
private PositionMapService positionMapService;
private static final String UPLOAD_DIR = "/Users/aikai/project/";
@PutMapping("/update")
@Operation(summary = "更新仓库点位地图")
@PreAuthorize("@ss.hasPermission('system:position-map:update')")
public CommonResult<Boolean> updatePositionMap(@Valid @RequestBody PositionMapSaveReqVO updateReqVO) {
positionMapService.updatePositionMap(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除仓库点位地图")
@Parameter(name = "id", description = "编号", required = true)
@ -75,17 +62,18 @@ public class PositionMapController {
@PostMapping("/upload")
@Operation(summary = "文件上传")
@PermitAll
public CommonResult uploadFiles(@RequestParam("files") MultipartFile[] files) {
public CommonResult<Boolean> uploadFiles(@RequestParam("files") MultipartFile[] files) {
// todo aiKai - 这里需要和设备定义好 楼层和区域到底是通过文件名称给 - 还是通过yml内容中给 目前按照以yml给的来写
positionMapService.uploadFiles(files);
return CommonResult.success(true);
}
@GetMapping("/downloadPng")
@GetMapping("/downloadPngBase64")
@Operation(summary = "下载png文件")
@PermitAll
public void downloadPng(@RequestParam Integer floor, @RequestParam String area, HttpServletResponse response) throws IOException {
positionMapService.downloadPng(floor, area, response);
public CommonResult<String> downloadPngBase64(@RequestParam Integer floor, @RequestParam String area) {
String base64 = positionMapService.downloadPngBase64(floor, area);
return CommonResult.success(base64);
}
@GetMapping("/download")

View File

@ -1,15 +1,21 @@
package cn.iocoder.yudao.module.system.controller.admin.positionmap;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
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.positionmap.dto.NodeBaseDTO;
import cn.iocoder.yudao.module.system.controller.admin.positionmap.vo.PositionMapItemPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.positionmap.vo.PositionMapItemRespVO;
import cn.iocoder.yudao.module.system.controller.admin.positionmap.vo.PositionMapItemSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.houselocation.WareHouseLocationDO;
import cn.iocoder.yudao.module.system.dal.dataobject.positionmap.PositionMapItemDO;
import cn.iocoder.yudao.module.system.handler.mapnode.NodeProcessingContext;
import cn.iocoder.yudao.module.system.service.positionmap.PositionMapItemService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
@ -22,7 +28,10 @@ import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@ -35,28 +44,22 @@ public class PositionMapItemController {
@Resource
private PositionMapItemService positionMapItemService;
@PostMapping("/create")
@Operation(summary = "创建仓库点位地图子表")
@PreAuthorize("@ss.hasPermission('system:position-map-item:create')")
public CommonResult<Long> createPositionMapItem(@Valid @RequestBody PositionMapItemSaveReqVO createReqVO) {
return success(positionMapItemService.createPositionMapItem(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新仓库点位地图子表")
@PreAuthorize("@ss.hasPermission('system:position-map-item:update')")
public CommonResult<Boolean> updatePositionMapItem(@Valid @RequestBody PositionMapItemSaveReqVO updateReqVO) {
positionMapItemService.updatePositionMapItem(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除仓库点位地图子表")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('system:position-map-item:delete')")
public CommonResult<Boolean> deletePositionMapItem(@RequestParam("id") Long id) {
positionMapItemService.deletePositionMapItem(id);
@Resource
private NodeProcessingContext nodeProcessingContext;
// -- 前端给所有的节点信息 -
@PostMapping("/batchSaveOrEditOrDel")
@Operation(summary = "批量新增编辑删除节点")
public CommonResult<Boolean> batchSaveOrEditOrDel(@RequestParam Long positionMapId, @Valid @RequestBody List<NodeBaseDTO> nodeBaseDTOS) {
// -- 这里使用策略模式 - 根据各个类型区分 - 如果需要新增类型新增策略实现类即可 - 如果不需要关联存储具体的表直接将json存储到dataJson字段即可
Map<Integer, List<NodeBaseDTO>> map = nodeBaseDTOS.stream().collect(Collectors.groupingBy(NodeBaseDTO::getType));
// -- 获取到对应地图的所有点位
List<PositionMapItemDO> oldList = positionMapItemService.getByMapId(positionMapId);
Map<Integer, List<PositionMapItemDO>> oldMap = oldList.stream().collect(Collectors.groupingBy(PositionMapItemDO::getType));
for (Map.Entry<Integer, List<NodeBaseDTO>> entry : map.entrySet()) {
int key = entry.getKey();
List<PositionMapItemDO> oldItemList = CollectionUtil.isEmpty(oldMap.get(key)) ? Collections.emptyList() : oldMap.get(key);
nodeProcessingContext.processNodesByStrategy(positionMapId, oldItemList, key, entry.getValue());
}
return success(true);
}

View File

@ -1,12 +1,8 @@
package cn.iocoder.yudao.module.system.controller.admin.positionmap;
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.positionmap.vo.PositionMapLinePageReqVO;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.system.controller.admin.positionmap.vo.PositionMapLineRespVO;
import cn.iocoder.yudao.module.system.controller.admin.positionmap.vo.PositionMapLineSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.positionmap.PositionMapLineDO;
@ -19,12 +15,9 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.List;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@Tag(name = "管理后台 - 仓库点位地图连线")
@ -36,19 +29,11 @@ public class PositionMapLineController {
@Resource
private PositionMapLineService positionMapLineService;
@PostMapping("/create")
@Operation(summary = "创建仓库点位地图连线")
@PostMapping("/createOrEdit")
@Operation(summary = "创建编辑仓库点位地图连线")
@PreAuthorize("@ss.hasPermission('system:position-map-line:create')")
public CommonResult<Long> createPositionMapLine(@Valid @RequestBody PositionMapLineSaveReqVO createReqVO) {
return success(positionMapLineService.createPositionMapLine(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新仓库点位地图连线")
@PreAuthorize("@ss.hasPermission('system:position-map-line:update')")
public CommonResult<Boolean> updatePositionMapLine(@Valid @RequestBody PositionMapLineSaveReqVO updateReqVO) {
positionMapLineService.updatePositionMapLine(updateReqVO);
return success(true);
return success(positionMapLineService.createOrEditPositionMapLine(createReqVO));
}
@DeleteMapping("/delete")
@ -69,25 +54,14 @@ public class PositionMapLineController {
return success(BeanUtils.toBean(positionMapLine, PositionMapLineRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得仓库点位地图连线分页")
@GetMapping("/list")
@Operation(summary = "通过地图id获取连线列表")
@PreAuthorize("@ss.hasPermission('system:position-map-line:query')")
public CommonResult<PageResult<PositionMapLineRespVO>> getPositionMapLinePage(@Valid PositionMapLinePageReqVO pageReqVO) {
PageResult<PositionMapLineDO> pageResult = positionMapLineService.getPositionMapLinePage(pageReqVO);
return success(BeanUtils.toBean(pageResult, PositionMapLineRespVO.class));
public CommonResult<List<PositionMapLineRespVO>> list(@RequestParam Long positionMapId) {
List<PositionMapLineDO> list = positionMapLineService.list(new LambdaQueryWrapperX<PositionMapLineDO>()
.eq(PositionMapLineDO::getPositionMapId, positionMapId));
return success(BeanUtils.toBean(list, PositionMapLineRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出仓库点位地图连线 Excel")
@PreAuthorize("@ss.hasPermission('system:position-map-line:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportPositionMapLineExcel(@Valid PositionMapLinePageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<PositionMapLineDO> list = positionMapLineService.getPositionMapLinePage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "仓库点位地图连线.xls", "数据", PositionMapLineRespVO.class,
BeanUtils.toBean(list, PositionMapLineRespVO.class));
}
}

View File

@ -0,0 +1,34 @@
package cn.iocoder.yudao.module.system.controller.admin.positionmap.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.ToString;
@Schema(description = "管理后台 - 仓库点位地图子表 - 节点基础属性")
@Data
public class NodeBaseDTO {
@Schema(description = "id")
private Long id;
@Schema(description = "仓库点位地图表id")
private Long positionMapId;
@Schema(description = "库区id(自定义)")
private Long areaId;
@Schema(description = "巷道id(自定义)")
private Long laneId;
@Schema(description = "坐标x轴")
private String locationX;
@Schema(description = "坐标y轴")
private String locationY;
@Schema(description = "类型 1.路径点位 2.库位点 3.充电桩 4.停车点 5.区域变更点 6.等待点 --- 后续补充", example = "1")
private Integer type;
@Schema(description = "对应各个类型的独有属性Json格式 例如({库位长度:1,库位宽度:2,库位方向:单向}", example = "1")
private String dataJson;
}

View File

@ -0,0 +1,27 @@
package cn.iocoder.yudao.module.system.controller.admin.positionmap.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.List;
@Schema(description = "管理后台 - 仓库点位地图查询")
@Data
@Accessors(chain = true)
public class PositionMapConditionDTO {
@Schema(description = "ids")
private List<Long> ids;
@Schema(description = "仓库点位地图表id")
private Long positionMapId;
@Schema(description = "库区id")
private Long areaId;
@Schema(description = "线库id")
private Long laneId;
@Schema(description = "类型 1.路径点位 2.库位点 3.充电桩 4.停车点 5.区域变更点 6.等待点 --- 后续补充")
private Integer type;
}

View File

@ -31,11 +31,11 @@ public class PositionMapItemPageReqVO extends PageParam {
@Schema(description = "坐标y轴")
private String locationY;
@Schema(description = "类型 1.行走点位 2.库位 3.充电桩 --- 后续补充", example = "1")
@Schema(description = "类型 1.路径点位 2.库位点 3.充电桩 4.停车点 5.区域变更点 6.等待点 --- 后续补充", example = "1")
private Integer type;
@Schema(description = "类型所对应表id", example = "15418")
private Long objectId;
@Schema(description = "对应各个类型的独有属性Json格式 例如({库位长度:1,库位宽度:2,库位方向:单向}", example = "1")
private String dataJson;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)

View File

@ -36,13 +36,12 @@ public class PositionMapItemRespVO {
@ExcelProperty("坐标y轴")
private String locationY;
@Schema(description = "类型 1.行走点位 2.库位 3.充电桩 --- 后续补充", example = "1")
@ExcelProperty("类型 1.行走点位 2.库位 3.充电桩 --- 后续补充")
@Schema(description = "类型 1.路径点位 2.库位点 3.充电桩 4.停车点 5.区域变更点 6.等待点 --- 后续补充", example = "1")
@ExcelProperty("类型 1.路径点位 2.库位点 3.充电桩 4.停车点 5.区域变更点 6.等待点 --- 后续补充")
private Integer type;
@Schema(description = "类型所对应表id", example = "15418")
@ExcelProperty("类型所对应表id")
private Long objectId;
@Schema(description = "对应各个类型的独有属性Json格式 例如({库位长度:1,库位宽度:2,库位方向:单向}", example = "1")
private String dataJson;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")

View File

@ -27,10 +27,9 @@ public class PositionMapItemSaveReqVO {
@Schema(description = "坐标y轴")
private String locationY;
@Schema(description = "类型 1.行走点位 2.库位 3.充电桩 --- 后续补充", example = "1")
@Schema(description = "类型 1.路径点位 2.库位点 3.充电桩 4.停车点 5.区域变更点 6.等待点 --- 后续补充", example = "1")
private Integer type;
@Schema(description = "类型所对应表id", example = "15418")
private Long objectId;
@Schema(description = "对应各个类型的独有属性Json格式 例如({库位长度:1,库位宽度:2,库位方向:单向}", example = "1")
private String dataJson;
}

View File

@ -1,10 +1,13 @@
package cn.iocoder.yudao.module.system.controller.admin.positionmap.vo;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@ -15,15 +18,27 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
@ToString(callSuper = true)
public class PositionMapLinePageReqVO extends PageParam {
@Schema(description = "地图id", example = "20863")
private Long positionMapId;
@Schema(description = "出发点id(点位子表id)", example = "20863")
private Long startingPointId;
@Schema(description = "结束点id(点位子表id)", example = "15890")
private Long endPointId;
@Schema(description = "行走方法 1.直线 2曲线")
@Schema(description = "行走方法 0.直线 1.上左曲线2.上右曲线3.下左曲线 4.下右曲线")
private Integer method;
@Schema(description = "方向 1.单向 2.双向", example = "15890")
private Integer direction;
@Schema(description = "正向限速(m/s)", example = "15890")
private BigDecimal forwardSpeedLimit;
@Schema(description = "反向限速(m/s)", example = "15890")
private BigDecimal reverseSpeedLimit;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;

View File

@ -1,11 +1,12 @@
package cn.iocoder.yudao.module.system.controller.admin.positionmap.vo;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import org.springframework.format.annotation.DateTimeFormat;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import com.alibaba.excel.annotation.*;
@Schema(description = "管理后台 - 仓库点位地图连线 Response VO")
@Data
@ -16,6 +17,10 @@ public class PositionMapLineRespVO {
@ExcelProperty("主键ID")
private Long id;
@Schema(description = "地图id", example = "20863")
@ExcelProperty("地图id")
private Long positionMapId;
@Schema(description = "出发点id(点位子表id)", example = "20863")
@ExcelProperty("出发点id(点位子表id)")
private Long startingPointId;
@ -24,10 +29,22 @@ public class PositionMapLineRespVO {
@ExcelProperty("结束点id(点位子表id)")
private Long endPointId;
@Schema(description = "行走方法 1.直线 2曲线")
@ExcelProperty("行走方法 1.直线 2曲线")
@Schema(description = "行走方法 0.直线 1.上左曲线2.上右曲线3.下左曲线 4.下右曲线")
@ExcelProperty("行走方法 0.直线 1.上左曲线2.上右曲线3.下左曲线 4.下右曲线")
private Integer method;
@Schema(description = "方向 1.单向 2.双向", example = "15890")
@ExcelProperty("方向 1.单向 2.双向")
private Integer direction;
@Schema(description = "正向限速(m/s)", example = "15890")
@ExcelProperty("正向限速(m/s)")
private BigDecimal forwardSpeedLimit;
@Schema(description = "反向限速(m/s)", example = "15890")
@ExcelProperty("反向限速(m/s)")
private BigDecimal reverseSpeedLimit;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;

View File

@ -2,6 +2,8 @@ package cn.iocoder.yudao.module.system.controller.admin.positionmap.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.math.BigDecimal;
import java.util.*;
import javax.validation.constraints.*;
@ -12,13 +14,26 @@ public class PositionMapLineSaveReqVO {
@Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "28062")
private Long id;
@Schema(description = "地图id", example = "20863")
private Long positionMapId;
@Schema(description = "出发点id(点位子表id)", example = "20863")
private Long startingPointId;
@Schema(description = "结束点id(点位子表id)", example = "15890")
private Long endPointId;
@Schema(description = "行走方法 1.直线 2曲线")
@Schema(description = "行走方法 0.直线 1.上左曲线2.上右曲线3.下左曲线 4.下右曲线")
private Integer method;
@Schema(description = "方向 1.单向 2.双向", example = "15890")
private Integer direction;
@Schema(description = "正向限速(m/s)", example = "15890")
private BigDecimal forwardSpeedLimit;
@Schema(description = "反向限速(m/s)", example = "15890")
private BigDecimal reverseSpeedLimit;
}

View File

@ -1,5 +1,6 @@
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;
@ -24,10 +25,12 @@ public class HouseAreaDO extends BaseDO {
*/
@TableId(type = IdType.ASSIGN_ID)
private Long id;
/**
* 库区id(自定义)
* 地图id
*/
private Long areaId;
private Long positionMapId;
/**
* 库区名称
*/
@ -37,4 +40,4 @@ public class HouseAreaDO extends BaseDO {
*/
private String areaMsg;
}
}

View File

@ -1,11 +1,10 @@
package cn.iocoder.yudao.module.system.dal.dataobject.houselane;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.*;
import lombok.*;
import java.util.List;
/**
* 线库/巷道 DO
@ -28,9 +27,9 @@ public class WareHouseLaneDO extends BaseDO {
@TableId(type = IdType.ASSIGN_ID)
private Long id;
/**
* 巷道id(自定义)
* 地图id
*/
private Long laneId;
private Long positionMapId;
/**
* 巷道名称
*/
@ -40,4 +39,10 @@ public class WareHouseLaneDO extends BaseDO {
*/
private String laneMsg;
}
/**
* 节点ids
*/
@TableField(exist = false)
private List<Long> mapItemIds;
}

View File

@ -27,20 +27,24 @@ public class WareHouseLocationDO extends BaseDO {
@TableId(type = IdType.ASSIGN_ID)
private Long id;
/**
* 巷道/线库id
* 线库id
*/
@TableField(updateStrategy = FieldStrategy.IGNORED)
private Long laneId;
/**
* 巷道/线库名称
* 线库名称
*/
@TableField(updateStrategy = FieldStrategy.IGNORED)
private String laneName;
/**
* 库区id(自定义)
*/
@TableField(updateStrategy = FieldStrategy.IGNORED)
private Long areaId;
/**
* 库区名称
*/
@TableField(updateStrategy = FieldStrategy.IGNORED)
private String areaName;
/**
* 库位编号
@ -150,4 +154,4 @@ public class WareHouseLocationDO extends BaseDO {
* ware_position_map_item的id
*/
private Long mapItemId;
}
}

View File

@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.system.dal.dataobject.positionmap;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
@ -25,19 +26,20 @@ public class PositionMapItemDO extends BaseDO {
/**
* 主键ID
*/
@TableId
@TableId(type = IdType.ASSIGN_ID)
private Long id;
/**
* 仓库点位地图表id
*/
private Long positionMapId;
/**
* 库区id(自定义)
* 库区id
*/
private Long areaId;
/**
* 巷道id(自定义)
* 线库id
*/
@TableField(updateStrategy = FieldStrategy.IGNORED)
private Long laneId;
/**
* 坐标x轴
@ -48,16 +50,12 @@ public class PositionMapItemDO extends BaseDO {
*/
private String locationY;
/**
* 对应各个类型的独有属性Json格式 例如{库位长度:1,库位宽度:2,库位方向:单向
*/
private String dataJson;
/**
* 类型 1.行走点位 2.库位 3.充电桩 --- 后续补充
* 类型 1.路径点位 2.库位点 3.充电桩 4.停车点 5.区域变更点 6.等待点 --- 后续补充
*/
private Integer type;
/**
* 类型所对应表id
* 对应各个类型的独有属性Json格式 例如{库位长度:1,库位宽度:2,库位方向:单向}
*/
private Long objectId;
private String dataJson;
}

View File

@ -1,11 +1,13 @@
package cn.iocoder.yudao.module.system.dal.dataobject.positionmap;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
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.*;
import java.math.BigDecimal;
/**
* 仓库点位地图连线 DO
@ -25,8 +27,12 @@ public class PositionMapLineDO extends BaseDO {
/**
* 主键ID
*/
@TableId
@TableId(type = IdType.ASSIGN_ID)
private Long id;
/**
* 地图id
*/
private Long positionMapId;
/**
* 出发点id(点位子表id)
*/
@ -36,8 +42,20 @@ public class PositionMapLineDO extends BaseDO {
*/
private Long endPointId;
/**
* 行走方法 1.直线 2曲线
* 行走方法 0.直线 1.上左曲线2.上右曲线3.下左曲线 4.下右曲线
*/
private Integer method;
/**
* 方向 1.单向 2.双向
*/
private Integer direction;
/**
* 正向限速(m/s)
*/
private BigDecimal forwardSpeedLimit;
/**
* 反向限速(m/s)
*/
private BigDecimal reverseSpeedLimit;
}

View File

@ -19,11 +19,10 @@ public interface HouseAreaMapper extends BaseMapperX<HouseAreaDO> {
default PageResult<HouseAreaDO> selectPage(HouseAreaPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<HouseAreaDO>()
.eqIfPresent(HouseAreaDO::getAreaId, reqVO.getAreaId())
.likeIfPresent(HouseAreaDO::getAreaName, reqVO.getAreaName())
.eqIfPresent(HouseAreaDO::getAreaMsg, reqVO.getAreaMsg())
.betweenIfPresent(HouseAreaDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(HouseAreaDO::getId));
}
}
}

View File

@ -1,13 +1,14 @@
package cn.iocoder.yudao.module.system.dal.mysql.houselane;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.system.controller.admin.houselane.vo.WareHouseLanePageReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.houselane.WareHouseLaneDO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 线库/巷道 Mapper
@ -19,11 +20,10 @@ public interface WareHouseLaneMapper extends BaseMapperX<WareHouseLaneDO> {
default PageResult<WareHouseLaneDO> selectPage(WareHouseLanePageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<WareHouseLaneDO>()
.eqIfPresent(WareHouseLaneDO::getLaneId, reqVO.getLaneId())
.likeIfPresent(WareHouseLaneDO::getLaneName, reqVO.getLaneName())
.eqIfPresent(WareHouseLaneDO::getLaneMsg, reqVO.getLaneMsg())
.betweenIfPresent(WareHouseLaneDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(WareHouseLaneDO::getId));
}
}
}

View File

@ -22,7 +22,6 @@ public interface PositionMapItemMapper extends BaseMapperX<PositionMapItemDO> {
.eqIfPresent(PositionMapItemDO::getLocationX, reqVO.getLocationX())
.eqIfPresent(PositionMapItemDO::getLocationY, reqVO.getLocationY())
.eqIfPresent(PositionMapItemDO::getType, reqVO.getType())
.eqIfPresent(PositionMapItemDO::getObjectId, reqVO.getObjectId())
.betweenIfPresent(PositionMapItemDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(PositionMapItemDO::getId));
}

View File

@ -0,0 +1,83 @@
package cn.iocoder.yudao.module.system.handler.mapnode;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import cn.iocoder.yudao.framework.common.enums.NodeTypeEnum;
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.dal.dataobject.houselocation.WareHouseLocationDO;
import cn.iocoder.yudao.module.system.dal.dataobject.positionmap.PositionMapItemDO;
import cn.iocoder.yudao.module.system.handler.mapnode.strategy.HouseLocationStrategyImpl;
import cn.iocoder.yudao.module.system.handler.mapnode.strategy.NodeProcessingStrategy;
import cn.iocoder.yudao.module.system.service.positionmap.PositionMapItemService;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import static com.baomidou.mybatisplus.core.toolkit.IdWorker.getId;
@Component
public class NodeProcessingContext {
private final Map<Integer, NodeProcessingStrategy> strategyMap = new HashMap<>();
@Autowired
private HouseLocationStrategyImpl houseLocationStrategyImpl;
@Autowired
private PositionMapItemService positionMapItemService;
/**
* 项目启动时 初始化策略
*/
@PostConstruct
public void init() {
// 节点
// strategyMap.put(1, positionMapItemStrategyImpl);
// 库位
strategyMap.put(NodeTypeEnum.WARE.getType(), houseLocationStrategyImpl);
// todo 可以继续添加更多的策略
}
@Transactional(rollbackFor = Exception.class)
public void processNodesByStrategy(Long positionMapId, List<PositionMapItemDO> oldItemList, int key, List<NodeBaseDTO> nodeBaseDTOS) {
// -- 这里处理节点 - 因为所有的类型都要建立在节点之上 - 把所有新增没有节点id的先分配id下 - 后续其他类型的需要绑定该id
nodeBaseDTOS.forEach(item -> {
if (item.getId() == null) {
item.setId(getId());
}
item.setPositionMapId(positionMapId);
// -- 如果是库位点 - 可能是一对多情况 - 需要将多个库位点的id set进去
if (Objects.equals(item.getType(), NodeTypeEnum.WARE.getType())) {
List<WareHouseLocationDO> wareHouseLocationDOS = JSONUtil.toList(item.getDataJson(), WareHouseLocationDO.class);
wareHouseLocationDOS.forEach(wareHouseLocationDO -> {
wareHouseLocationDO.setLocationX(item.getLocationX());
wareHouseLocationDO.setLocationY(item.getLocationY());
if (wareHouseLocationDO.getId() == null) {
wareHouseLocationDO.setId(IdWorker.getId());
}
});
item.setDataJson(JSONUtil.toJsonStr(wareHouseLocationDOS));
}
});
List<PositionMapItemDO> newList = BeanUtil.copyToList(nodeBaseDTOS, PositionMapItemDO.class);
List<List<PositionMapItemDO>> list = CollectionUtils.diffList(oldItemList, newList,
(oldVal, newVal) -> ObjectUtil.equal(oldVal.getId(), newVal.getId()));
positionMapItemService.batchSaveOrEditOrDel(positionMapId, list);
// -- 获取对应的策略 - 如果没有对应的直接 return
NodeProcessingStrategy strategy = strategyMap.get(key);
if (strategy == null) {
return;
}
strategy.processNodes(positionMapId, nodeBaseDTOS);
}
}

View File

@ -0,0 +1,41 @@
package cn.iocoder.yudao.module.system.handler.mapnode.strategy;
import cn.hutool.core.util.ObjectUtil;
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;
import cn.iocoder.yudao.module.system.dal.dataobject.houselocation.WareHouseLocationDO;
import cn.iocoder.yudao.module.system.service.houselocation.HouseLocationService;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
@Component
public class HouseLocationStrategyImpl implements NodeProcessingStrategy {
@Resource
private HouseLocationService houseLocationService;
@Override
public void processNodes(Long positionMapId, List<NodeBaseDTO> nodeBaseDTOS) {
// -- 策略1 处理库位点
// -- 将data里面的json 数据转为实体类 - 再对比节点id - 然后做新增删除修改操作
// --------------- dataJSON里面没有具体的类的id - 然后库位要根据层数添加 多个库位数据 一个点位 对应多个库位
List<WareHouseLocationDO> newList = new ArrayList<>();
for (NodeBaseDTO nodeBaseDTO : nodeBaseDTOS) {
List<WareHouseLocationDO> wareHouseLocationDOS = JSONUtil.toList(nodeBaseDTO.getDataJson(), WareHouseLocationDO.class);
for (WareHouseLocationDO wareHouseLocationDO : wareHouseLocationDOS) {
wareHouseLocationDO.setMapId(positionMapId);
wareHouseLocationDO.setMapItemId(nodeBaseDTO.getId());
newList.add(wareHouseLocationDO);
}
}
List<WareHouseLocationDO> oldList = houseLocationService.getByMapId(positionMapId);
List<List<WareHouseLocationDO>> list = CollectionUtils.diffList(oldList, newList,
(oldVal, newVal) -> ObjectUtil.equal(oldVal.getId(), newVal.getId()));
houseLocationService.batchSaveOrEditOrDel(positionMapId, list);
}
}

View File

@ -0,0 +1,10 @@
package cn.iocoder.yudao.module.system.handler.mapnode.strategy;
import cn.iocoder.yudao.module.system.controller.admin.positionmap.dto.NodeBaseDTO;
import cn.iocoder.yudao.module.system.dal.dataobject.positionmap.PositionMapItemDO;
import java.util.List;
public interface NodeProcessingStrategy {
void processNodes(Long positionMapId, List<NodeBaseDTO> nodeBaseDTOS);
}

View File

@ -1,11 +1,12 @@
package cn.iocoder.yudao.module.system.service.housearea;
import javax.validation.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.system.controller.admin.housearea.vo.HouseAreaPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.housearea.vo.HouseAreaSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.housearea.HouseAreaDO;
import javax.validation.Valid;
/**
* 库区 Service 接口
*
@ -51,4 +52,10 @@ public interface HouseAreaService {
*/
PageResult<HouseAreaDO> getHouseAreaPage(HouseAreaPageReqVO pageReqVO);
}
/**
* 创建修改删除库区
*
* @param createReqVO
*/
void createOrEditOrDel(@Valid HouseAreaSaveReqVO createReqVO);
}

View File

@ -1,19 +1,34 @@
package cn.iocoder.yudao.module.system.service.housearea;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import cn.iocoder.yudao.framework.common.enums.NodeTypeEnum;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.system.controller.admin.housearea.vo.HouseAreaPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.housearea.vo.HouseAreaSaveReqVO;
import cn.iocoder.yudao.module.system.controller.admin.positionmap.dto.PositionMapConditionDTO;
import cn.iocoder.yudao.module.system.dal.dataobject.housearea.HouseAreaDO;
import cn.iocoder.yudao.module.system.dal.dataobject.houselocation.WareHouseLocationDO;
import cn.iocoder.yudao.module.system.dal.dataobject.positionmap.PositionMapItemDO;
import cn.iocoder.yudao.module.system.dal.mysql.housearea.HouseAreaMapper;
import cn.iocoder.yudao.module.system.service.houselocation.HouseLocationService;
import cn.iocoder.yudao.module.system.service.positionmap.PositionMapItemService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.HOUSE_AREA_NOT_EXISTS;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.THERE_ARE_ALREADY_STORAGE_LOCATIONS_IN_OTHER_STORAGE_AREAS;
/**
* 库区 Service 实现类
@ -26,6 +41,10 @@ public class HouseAreaServiceImpl implements HouseAreaService {
@Resource
private HouseAreaMapper houseAreaMapper;
@Resource
private PositionMapItemService positionMapItemService;
@Resource
private HouseLocationService houseLocationService;
@Override
public Long createHouseArea(HouseAreaSaveReqVO createReqVO) {
@ -69,4 +88,70 @@ public class HouseAreaServiceImpl implements HouseAreaService {
return houseAreaMapper.selectPage(pageReqVO);
}
}
@Override
public void createOrEditOrDel(HouseAreaSaveReqVO createReqVO) {
HouseAreaDO houseArea = BeanUtil.copyProperties(createReqVO, HouseAreaDO.class);
houseAreaMapper.insertOrUpdate(houseArea);
// -- 先判定这些点位是否在同一区域内 - 如果不在则提示 哪些点位不在同一区域内
//1.获取原该线库绑定的点位列表
List<PositionMapItemDO> oldList = createReqVO.getId() == null ? Collections.emptyList() :
positionMapItemService.getByCondition(new PositionMapConditionDTO()
.setPositionMapId(createReqVO.getPositionMapId())
.setAreaId(createReqVO.getId())
.setType(NodeTypeEnum.WARE.getType()));
//2.查询目前的点位列表 - 如果没有的话 - 就设为空列表先 -
List<PositionMapItemDO> list = CollUtil.isEmpty(createReqVO.getMapItemIds()) ? Collections.emptyList() :
positionMapItemService.getByCondition(new PositionMapConditionDTO()
.setPositionMapId(createReqVO.getPositionMapId())
.setType(NodeTypeEnum.WARE.getType())
.setIds(createReqVO.getMapItemIds()));
//3.判定当前这些点位是否已经有包含线库了 -
List<PositionMapItemDO> containList = list.stream().filter(a -> a.getAreaId() != null && !a.getAreaId().equals(createReqVO.getId())).collect(Collectors.toList());
// todo - 这里如果设置的库位已经有绑定其他库区了 - 该如何处理 - 目前我们做提示 - 后续看要不要覆盖
if (CollUtil.isNotEmpty(containList)) {
throw exception(THERE_ARE_ALREADY_STORAGE_LOCATIONS_IN_OTHER_STORAGE_AREAS);
}
// -- 这里去判断更新点位的线库信息
List<List<PositionMapItemDO>> allList = CollectionUtils.diffList(oldList, list,
(oldVal, newVal) -> ObjectUtil.equal(oldVal.getAreaId(), newVal.getAreaId()));
List<PositionMapItemDO> editList = new ArrayList<>();
if (CollUtil.isNotEmpty(allList.get(0))) {
List<PositionMapItemDO> editItemList = allList.get(0);
editItemList.forEach(a -> a.setAreaId(houseArea.getId()));
// -- 新增的 就是更改的 - 需要更新的
editList.addAll(editItemList);
}
if (CollUtil.isNotEmpty(allList.get(2))) {
//需要删除的就是取消掉的
List<PositionMapItemDO> editItemList = allList.get(2);
editItemList.forEach(a -> a.setAreaId(null));
editList.addAll(allList.get(2));
}
List<WareHouseLocationDO> wareHouseLocationList = new ArrayList<>();
editList.forEach(item -> {
List<WareHouseLocationDO> wareHouseLocationDOS = JSONUtil.toList(item.getDataJson(), WareHouseLocationDO.class);
wareHouseLocationDOS.forEach(a -> {
if (item.getAreaId() == null) {
a.setAreaId(null);
a.setAreaName(null);
} else {
a.setAreaId(houseArea.getId());
a.setAreaName(houseArea.getAreaName());
}
});
wareHouseLocationList.addAll(wareHouseLocationDOS);
item.setDataJson(JSONUtil.toJsonStr(wareHouseLocationDOS));
});
if (CollUtil.isNotEmpty(editList)) {
positionMapItemService.updateBatchById(editList);
}
if (CollUtil.isNotEmpty(wareHouseLocationList)) {
houseLocationService.updateBatchById(wareHouseLocationList);
}
}
}

View File

@ -1,56 +1,42 @@
package cn.iocoder.yudao.module.system.service.houselane;
import java.util.*;
import javax.validation.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.module.system.controller.admin.houselane.vo.WareHouseLanePageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.houselane.vo.WareHouseLaneSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.houselane.WareHouseLaneDO;
import com.baomidou.mybatisplus.extension.service.IService;
import javax.validation.Valid;
import java.util.List;
/**
* 线库/巷道 Service 接口
* 线库 Service 接口
*
* @author 陈宾顺
*/
public interface WareHouseLaneService {
public interface WareHouseLaneService extends IService<WareHouseLaneDO> {
/**
* 创建线库/巷道
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createHouseLane(@Valid WareHouseLaneSaveReqVO createReqVO);
/**
* 更新线库/巷道
*
* @param updateReqVO 更新信息
*/
void updateHouseLane(@Valid WareHouseLaneSaveReqVO updateReqVO);
/**
* 删除线库/巷道
* 获得线库
*
* @param id 编号
*/
void deleteHouseLane(Long id);
/**
* 获得线库/巷道
*
* @param id 编号
* @return 线库/巷道
* @return 线库
*/
WareHouseLaneDO getHouseLane(Long id);
/**
* 获得线库/巷道分页
* 获得线库分页
*
* @param pageReqVO 分页查询
* @return 线库/巷道分页
* @return 线库分页
*/
PageResult<WareHouseLaneDO> getHouseLanePage(WareHouseLanePageReqVO pageReqVO);
}
/**
* 创建修改删除线库
*
* @param createReqVO
*/
void createOrEditOrDel(@Valid WareHouseLaneSaveReqVO createReqVO);
}

View File

@ -1,19 +1,35 @@
package cn.iocoder.yudao.module.system.service.houselane;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import cn.iocoder.yudao.framework.common.enums.NodeTypeEnum;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.module.system.controller.admin.houselane.vo.WareHouseLanePageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.houselane.vo.WareHouseLaneSaveReqVO;
import cn.iocoder.yudao.module.system.controller.admin.positionmap.dto.PositionMapConditionDTO;
import cn.iocoder.yudao.module.system.dal.dataobject.houselane.WareHouseLaneDO;
import cn.iocoder.yudao.module.system.dal.dataobject.houselocation.WareHouseLocationDO;
import cn.iocoder.yudao.module.system.dal.dataobject.positionmap.PositionMapItemDO;
import cn.iocoder.yudao.module.system.dal.mysql.houselane.WareHouseLaneMapper;
import cn.iocoder.yudao.module.system.service.houselocation.HouseLocationService;
import cn.iocoder.yudao.module.system.service.positionmap.PositionMapItemService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.HOUSE_LANE_NOT_EXISTS;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.THERE_ARE_ALREADY_STORAGE_LOCATIONS_IN_OTHER_LINE_WAREHOUSES;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.THE_LINE_LIBRARY_POINTS_ARE_NOT_LOCATED_IN_THE_SAME_AREA;
/**
@ -23,46 +39,25 @@ import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.HOUSE_LANE
*/
@Service
@Validated
public class WareHouseLaneServiceImpl implements WareHouseLaneService {
public class WareHouseLaneServiceImpl extends ServiceImpl<WareHouseLaneMapper, WareHouseLaneDO> implements WareHouseLaneService {
@Resource
private WareHouseLaneMapper houseLaneMapper;
@Override
public Long createHouseLane(WareHouseLaneSaveReqVO createReqVO) {
// 插入
WareHouseLaneDO houseLane = BeanUtils.toBean(createReqVO, WareHouseLaneDO.class);
houseLaneMapper.insert(houseLane);
// 返回
return houseLane.getId();
}
@Override
public void updateHouseLane(WareHouseLaneSaveReqVO updateReqVO) {
// 校验存在
validateHouseLaneExists(updateReqVO.getId());
// 更新
WareHouseLaneDO updateObj = BeanUtils.toBean(updateReqVO, WareHouseLaneDO.class);
houseLaneMapper.updateById(updateObj);
}
@Override
public void deleteHouseLane(Long id) {
// 校验存在
validateHouseLaneExists(id);
// 删除
houseLaneMapper.deleteById(id);
}
private void validateHouseLaneExists(Long id) {
if (houseLaneMapper.selectById(id) == null) {
throw exception(HOUSE_LANE_NOT_EXISTS);
}
}
@Resource
private PositionMapItemService positionMapItemService;
@Resource
private HouseLocationService houseLocationService;
@Override
public WareHouseLaneDO getHouseLane(Long id) {
return houseLaneMapper.selectById(id);
WareHouseLaneDO wareHouseLaneDO = houseLaneMapper.selectById(id);
List<PositionMapItemDO> mapItemDOS = positionMapItemService.getByCondition(new PositionMapConditionDTO()
.setLaneId(id)
.setType(NodeTypeEnum.WARE.getType())
);
List<Long> mapIds = mapItemDOS.stream().map(PositionMapItemDO::getId).collect(Collectors.toList());
wareHouseLaneDO.setMapItemIds(mapIds);
return wareHouseLaneDO;
}
@Override
@ -70,4 +65,77 @@ public class WareHouseLaneServiceImpl implements WareHouseLaneService {
return houseLaneMapper.selectPage(pageReqVO);
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public void createOrEditOrDel(WareHouseLaneSaveReqVO createReqVO) {
WareHouseLaneDO houseLane = BeanUtil.copyProperties(createReqVO, WareHouseLaneDO.class);
houseLaneMapper.insertOrUpdate(houseLane);
// -- 先判定这些点位是否在同一区域内 - 如果不在则提示 哪些点位不在同一区域内
//1.获取原该线库绑定的点位列表
List<PositionMapItemDO> oldList = createReqVO.getId() == null ? Collections.emptyList() :
positionMapItemService.getByCondition(new PositionMapConditionDTO()
.setPositionMapId(createReqVO.getPositionMapId())
.setLaneId(createReqVO.getId())
.setType(NodeTypeEnum.WARE.getType()));
//2.查询目前的点位列表 - 如果没有的话 - 就设为空列表先 -
List<PositionMapItemDO> list = CollUtil.isEmpty(createReqVO.getMapItemIds()) ? Collections.emptyList() :
positionMapItemService.getByCondition(new PositionMapConditionDTO()
.setPositionMapId(createReqVO.getPositionMapId())
.setType(NodeTypeEnum.WARE.getType())
.setIds(createReqVO.getMapItemIds()));
//3.判定当前这些点位是否已经有包含线库了 -
List<PositionMapItemDO> containList = list.stream().filter(a -> a.getLaneId() != null && !a.getLaneId().equals(createReqVO.getId())).collect(Collectors.toList());
// todo - 这里如果设置的库位已经有绑定其他线库了 - 该如何处理 - 目前我们做提示 - 后续看要不要覆盖
if (CollUtil.isNotEmpty(containList)) {
throw exception(THERE_ARE_ALREADY_STORAGE_LOCATIONS_IN_OTHER_LINE_WAREHOUSES);
}
if (CollUtil.isNotEmpty(list)) {
// 判定是否都在同一区域内
long count = list.stream().map(PositionMapItemDO::getAreaId).distinct().count();
if (count > 1) {
throw exception(THE_LINE_LIBRARY_POINTS_ARE_NOT_LOCATED_IN_THE_SAME_AREA);
}
}
// -- 这里去判断更新点位的线库信息
List<List<PositionMapItemDO>> allList = CollectionUtils.diffList(oldList, list,
(oldVal, newVal) -> ObjectUtil.equal(oldVal.getLaneId(), newVal.getLaneId()));
List<PositionMapItemDO> editList = new ArrayList<>();
if (CollUtil.isNotEmpty(allList.get(0))) {
List<PositionMapItemDO> editItemList = allList.get(0);
editItemList.forEach(a -> a.setLaneId(houseLane.getId()));
// -- 新增的 就是更改的 - 需要更新的
editList.addAll(editItemList);
}
if (CollUtil.isNotEmpty(allList.get(2))) {
//需要删除的就是取消掉的
List<PositionMapItemDO> editItemList = allList.get(2);
editItemList.forEach(a -> a.setLaneId(null));
editList.addAll(allList.get(2));
}
List<WareHouseLocationDO> wareHouseLocationList = new ArrayList<>();
editList.forEach(item -> {
List<WareHouseLocationDO> wareHouseLocationDOS = JSONUtil.toList(item.getDataJson(), WareHouseLocationDO.class);
wareHouseLocationDOS.forEach(a -> {
if (item.getLaneId() == null) {
a.setLaneId(null);
a.setLaneName(null);
} else {
a.setLaneId(houseLane.getId());
a.setLaneName(houseLane.getLaneName());
}
});
wareHouseLocationList.addAll(wareHouseLocationDOS);
item.setDataJson(JSONUtil.toJsonStr(wareHouseLocationDOS));
});
if (CollUtil.isNotEmpty(editList)) {
positionMapItemService.updateBatchById(editList);
}
if (CollUtil.isNotEmpty(wareHouseLocationList)) {
houseLocationService.updateBatchById(wareHouseLocationList);
}
}
}

View File

@ -1,13 +1,14 @@
package cn.iocoder.yudao.module.system.service.houselocation;
import javax.validation.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
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 com.baomidou.mybatisplus.extension.service.IService;
import javax.validation.Valid;
import java.util.List;
/**
@ -15,7 +16,7 @@ import java.util.List;
*
* @author 陈宾顺
*/
public interface HouseLocationService {
public interface HouseLocationService extends IService<WareHouseLocationDO> {
/**
* 创建库位
@ -55,10 +56,25 @@ public interface HouseLocationService {
*/
PageResult<WareHouseLocationDO> getHouseLocationPage(WareHouseLocationPageReqVO pageReqVO);
/**
* 库位批量保存或修改或删除
*
* @param positionMapId
* @param list
*/
void batchSaveOrEditOrDel(Long positionMapId, List<List<WareHouseLocationDO>> list);
/**
* 根据地图查询库位
*
* @param positionMapId
* @return
*/
List<WareHouseLocationDO> getByMapId(Long positionMapId);
/**
*
* @param requestVO
* @return
*/
List<WareHouseLocationRespVO> getLocationByName(WareHouseLocationVO requestVO);
}
}

View File

@ -1,23 +1,25 @@
package cn.iocoder.yudao.module.system.service.houselocation;
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.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.dal.mysql.houselocation.WareHouseLocationMapper;
import cn.iocoder.yudao.module.system.enums.robot.ReleaseTakeEnum;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import javax.annotation.Resource;
import java.util.List;
import static cn.hutool.core.collection.CollUtil.isNotEmpty;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.HOUSE_LOCATION_NOT_EXISTS;
/**
@ -27,7 +29,7 @@ import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.HOUSE_LOCA
*/
@Service
@Validated
public class HouseLocationServiceImpl implements HouseLocationService {
public class HouseLocationServiceImpl extends ServiceImpl<WareHouseLocationMapper, WareHouseLocationDO> implements HouseLocationService {
@Resource
private WareHouseLocationMapper houseLocationMapper;
@ -79,4 +81,24 @@ public class HouseLocationServiceImpl implements HouseLocationService {
return houseLocationMapper.getLocationByName(requestVO);
}
}
@Override
public void batchSaveOrEditOrDel(Long positionMapId, List<List<WareHouseLocationDO>> list) {
//批量添加修改删除
if (isNotEmpty(list.get(0))) {
houseLocationMapper.insertBatch(list.get(0));
}
if (isNotEmpty(list.get(1))) {
houseLocationMapper.updateBatch(list.get(1));
}
if (isNotEmpty(list.get(2))) {
houseLocationMapper.deleteByIds(convertList(list.get(2), WareHouseLocationDO::getId));
}
}
@Override
public List<WareHouseLocationDO> getByMapId(Long positionMapId) {
return houseLocationMapper.selectList(new LambdaQueryWrapperX<WareHouseLocationDO>()
.eq(WareHouseLocationDO::getMapId, positionMapId));
}
}

View File

@ -1,18 +1,21 @@
package cn.iocoder.yudao.module.system.service.positionmap;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.system.controller.admin.positionmap.dto.PositionMapConditionDTO;
import cn.iocoder.yudao.module.system.controller.admin.positionmap.vo.PositionMapItemPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.positionmap.vo.PositionMapItemSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.positionmap.PositionMapItemDO;
import com.baomidou.mybatisplus.extension.service.IService;
import javax.validation.Valid;
import java.util.List;
/**
* 仓库点位地图子表 Service 接口
*
* @author 芋道源码
*/
public interface PositionMapItemService {
public interface PositionMapItemService extends IService<PositionMapItemDO> {
/**
* 创建仓库点位地图子表
@ -52,4 +55,26 @@ public interface PositionMapItemService {
*/
PageResult<PositionMapItemDO> getPositionMapItemPage(PositionMapItemPageReqVO pageReqVO);
/**
* 获取到对应地图的所有点位信息
*
* @param positionMapId
* @return
*/
List<PositionMapItemDO> getByMapId(Long positionMapId);
/**
* 批量新增编辑操作删除操作
*
* @param list
*/
void batchSaveOrEditOrDel(Long positionMapId, List<List<PositionMapItemDO>> list);
/**
* 根据条件搜索地图点位信息
*
* @param positionMapConditionDTO
* @return
*/
List<PositionMapItemDO> getByCondition(PositionMapConditionDTO positionMapConditionDTO);
}

View File

@ -2,14 +2,21 @@ package cn.iocoder.yudao.module.system.service.positionmap;
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.system.controller.admin.positionmap.dto.PositionMapConditionDTO;
import cn.iocoder.yudao.module.system.controller.admin.positionmap.vo.PositionMapItemPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.positionmap.vo.PositionMapItemSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.positionmap.PositionMapItemDO;
import cn.iocoder.yudao.module.system.dal.mysql.positionmap.PositionMapItemMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.util.List;
import static cn.hutool.core.collection.CollUtil.isNotEmpty;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
/**
* 仓库点位地图子表 Service 实现类
@ -18,7 +25,7 @@ import javax.annotation.Resource;
*/
@Service
@Validated
public class PositionMapItemServiceImpl implements PositionMapItemService {
public class PositionMapItemServiceImpl extends ServiceImpl<PositionMapItemMapper, PositionMapItemDO> implements PositionMapItemService {
@Resource
private PositionMapItemMapper positionMapItemMapper;
@ -55,4 +62,36 @@ public class PositionMapItemServiceImpl implements PositionMapItemService {
return positionMapItemMapper.selectPage(pageReqVO);
}
@Override
public List<PositionMapItemDO> getByMapId(Long positionMapId) {
return positionMapItemMapper.selectList(new LambdaQueryWrapperX<PositionMapItemDO>()
.eq(PositionMapItemDO::getPositionMapId, positionMapId));
}
@Override
public void batchSaveOrEditOrDel(Long positionMapId, List<List<PositionMapItemDO>> list) {
//批量添加修改删除
if (isNotEmpty(list.get(0))) {
positionMapItemMapper.insertBatch(list.get(0));
}
if (isNotEmpty(list.get(1))) {
positionMapItemMapper.updateBatch(list.get(1));
}
if (isNotEmpty(list.get(2))) {
positionMapItemMapper.deleteByIds(convertList(list.get(2), PositionMapItemDO::getId));
}
}
@Override
public List<PositionMapItemDO> getByCondition(PositionMapConditionDTO dto) {
return positionMapItemMapper.selectList(new LambdaQueryWrapperX<PositionMapItemDO>()
.eqIfPresent(PositionMapItemDO::getPositionMapId, dto.getPositionMapId())
.eqIfPresent(PositionMapItemDO::getType, dto.getType())
.inIfPresent(PositionMapItemDO::getId, dto.getIds())
.eqIfPresent(PositionMapItemDO::getAreaId, dto.getAreaId())
.eqIfPresent(PositionMapItemDO::getLaneId, dto.getLaneId()));
}
}

View File

@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.system.controller.admin.positionmap.vo.PositionMapLinePageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.positionmap.vo.PositionMapLineSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.positionmap.PositionMapLineDO;
import com.baomidou.mybatisplus.extension.service.IService;
import javax.validation.Valid;
@ -12,22 +13,7 @@ import javax.validation.Valid;
*
* @author 芋道源码
*/
public interface PositionMapLineService {
/**
* 创建仓库点位地图连线
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createPositionMapLine(@Valid PositionMapLineSaveReqVO createReqVO);
/**
* 更新仓库点位地图连线
*
* @param updateReqVO 更新信息
*/
void updatePositionMapLine(@Valid PositionMapLineSaveReqVO updateReqVO);
public interface PositionMapLineService extends IService<PositionMapLineDO> {
/**
* 删除仓库点位地图连线
@ -52,4 +38,11 @@ public interface PositionMapLineService {
*/
PageResult<PositionMapLineDO> getPositionMapLinePage(PositionMapLinePageReqVO pageReqVO);
/**
* 创建编辑仓库点位地图连线
*
* @param createReqVO
* @return
*/
Long createOrEditPositionMapLine(@Valid PositionMapLineSaveReqVO createReqVO);
}

View File

@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.system.controller.admin.positionmap.vo.PositionMa
import cn.iocoder.yudao.module.system.controller.admin.positionmap.vo.PositionMapLineSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.positionmap.PositionMapLineDO;
import cn.iocoder.yudao.module.system.dal.mysql.positionmap.PositionMapLineMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
@ -18,27 +19,11 @@ import javax.annotation.Resource;
*/
@Service
@Validated
public class PositionMapLineServiceImpl implements PositionMapLineService {
public class PositionMapLineServiceImpl extends ServiceImpl<PositionMapLineMapper, PositionMapLineDO> implements PositionMapLineService {
@Resource
private PositionMapLineMapper positionMapLineMapper;
@Override
public Long createPositionMapLine(PositionMapLineSaveReqVO createReqVO) {
// 插入
PositionMapLineDO positionMapLine = BeanUtils.toBean(createReqVO, PositionMapLineDO.class);
positionMapLineMapper.insert(positionMapLine);
// 返回
return positionMapLine.getId();
}
@Override
public void updatePositionMapLine(PositionMapLineSaveReqVO updateReqVO) {
// 更新
PositionMapLineDO updateObj = BeanUtils.toBean(updateReqVO, PositionMapLineDO.class);
positionMapLineMapper.updateById(updateObj);
}
@Override
public void deletePositionMapLine(Long id) {
// 删除
@ -55,4 +40,15 @@ public class PositionMapLineServiceImpl implements PositionMapLineService {
return positionMapLineMapper.selectPage(pageReqVO);
}
@Override
public Long createOrEditPositionMapLine(PositionMapLineSaveReqVO createReqVO) {
PositionMapLineDO positionMapLine = BeanUtils.toBean(createReqVO, PositionMapLineDO.class);
if (positionMapLine.getId() == null) {
positionMapLineMapper.insert(positionMapLine);
} else {
positionMapLineMapper.updateById(positionMapLine);
}
return positionMapLine.getId();
}
}

View File

@ -85,7 +85,6 @@ public interface PositionMapService extends IService<PositionMapDO> {
*
* @param floor
* @param area
* @param response
*/
void downloadPng(Integer floor, String area, HttpServletResponse response) throws IOException;
String downloadPngBase64(Integer floor, String area);
}

View File

@ -10,9 +10,11 @@ import cn.iocoder.yudao.module.system.dal.dataobject.positionmap.PositionMapDO;
import cn.iocoder.yudao.module.system.dal.mysql.positionmap.PositionMapMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
@ -20,6 +22,7 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.multipart.MultipartFile;
import org.yaml.snakeyaml.Yaml;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
@ -41,12 +44,15 @@ import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
*/
@Service
@Validated
@Slf4j
public class PositionMapServiceImpl extends ServiceImpl<PositionMapMapper, PositionMapDO> implements PositionMapService {
@Autowired
@Resource
private PositionMapMapper positionMapMapper;
@Value("${map.file.upload-path}")
private String UPLOAD_DIR;
@Resource
private StringRedisTemplate stringRedisTemplate;
@Override
public Long createPositionMap(PositionMapSaveReqVO createReqVO) {
@ -253,13 +259,14 @@ public class PositionMapServiceImpl extends ServiceImpl<PositionMapMapper, Posit
@Override
public void downloadPng(Integer floor, String area, HttpServletResponse response) throws IOException {
@Cacheable(value = "pngBase64", key = "#floor + '_' + #area")
public String downloadPngBase64(Integer floor, String area) {
// 根据楼层和区域查找对应的PNG文件路径
String basePath = UPLOAD_DIR + floor + "/" + area + "/";
File directory = new File(basePath);
if (!directory.exists() || !directory.isDirectory()) {
response.sendError(HttpStatus.NOT_FOUND.value(), "Directory not found for the given floor and area.");
return;
log.error("Directory not found for floor: {}, area: {}", floor, area);
throw exception(AGV_MAP_NOT_FOUND);
}
// 查找PNG文件
@ -270,18 +277,23 @@ public class PositionMapServiceImpl extends ServiceImpl<PositionMapMapper, Posit
}
if (pngFile == null || !pngFile.exists()) {
response.sendError(HttpStatus.NOT_FOUND.value(), "PNG file not found for the given floor and area.");
return;
log.error("PNG file not found for floor: {}, area: {}", floor, area);
throw exception(AGV_MAP_NOT_FOUND);
}
// 设置响应头以指示浏览器下载文件
response.setContentType("image/png");
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + pngFile.getName() + "\"");
// 将PNG文件写入HTTP响应输出流
try (FileInputStream fis = new FileInputStream(pngFile)) {
IOUtils.copy(fis, response.getOutputStream());
String encodedString = null;
try {
// 读取文件内容
byte[] fileContent = Files.readAllBytes(pngFile.toPath());
// 将文件内容转换为Base64字符串
encodedString = Base64.getEncoder().encodeToString(fileContent);
// 添加MIME类型前缀
encodedString = "data:image/png;base64," + encodedString;
} catch (IOException e) {
log.error("Failed to convert PNG to Base64 for floor: {}, area: {}", floor, area, e);
throw exception(AGV_IMAGE_CONVERSION_TO_BASE64_FAILED);
}
return encodedString;
}
}

View File

@ -14,7 +14,8 @@ spring:
config: # 【注册中心】配置项
namespace: dev # 命名空间。这里使用 dev 开发环境
group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP
cache:
type: redis
--- #################### 数据库相关配置 ####################
spring:
# 数据源配置项
@ -103,16 +104,9 @@ spring:
xxl:
job:
enabled: true # 是否开启调度中心,默认为 true 开启
admin:
addresses: http://127.0.0.1:8080/xxl-job-admin
accessToken: default_token
executor:
appname: xxl-job-executor
address:
ip:
port: 9999
logpath: /data/applogs/xxl-job/jobhandler
logretentiondays: 30
addresses: http://127.0.0.1:9999/xxl-job-admin # 调度中心部署跟地址
--- #################### 服务保障相关配置 ####################

View File

@ -9,4 +9,4 @@
文档可见https://www.iocoder.cn/MyBatis/x-plugins/
-->
</mapper>
</mapper>

View File

@ -671,7 +671,7 @@
</when>
<when test="type == 2">
select
id ,
id as id,
lane_name as locationNo
from
ware_house_lane
@ -680,7 +680,7 @@
</when>
<when test="type == 3">
select
id,
id as id,
area_name as locationNo
from
ware_house_area
@ -690,4 +690,4 @@
</choose>
</select>
</mapper>
</mapper>