From 2c21c1560e0c7943739521e5726cd6d22bbdfb7b Mon Sep 17 00:00:00 2001 From: wenshijun Date: Fri, 5 Dec 2025 16:04:35 +0800 Subject: [PATCH] =?UTF-8?q?=E6=99=BA=E6=85=A7=E5=AE=9E=E7=89=A9=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E7=B3=BB=E7=BB=9F=E7=9B=B8=E5=85=B3=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- WCS对接流程图说明.md | 47 ++ WCS系统与WMS-AGV对接业务文档.md | 343 ++++++++++ .../config/QwenOcrRemoteProperties.java | 17 + .../controller/AuditSignatureController.java | 3 + .../wisdom/controller/GysJhController.java | 40 ++ .../wisdom/controller/PhotoController.java | 6 +- .../wisdom/controller/RkInfoController.java | 48 +- .../wisdom/domain/dto/ExcelFieldMapping.java | 14 + .../wisdom/domain/dto/GysJhImportDTO.java | 62 ++ .../domain/dto/RkDeliveryUpdateDTO.java | 10 +- .../zg/project/wisdom/mapper/GysJhMapper.java | 14 +- .../project/wisdom/mapper/RkInfoMapper.java | 3 +- .../project/wisdom/service/IGysJhService.java | 8 + .../wisdom/service/IRkInfoService.java | 9 +- .../wisdom/service/QwenOcrRemoteService.java | 98 +++ .../wisdom/service/impl/GysJhServiceImpl.java | 249 ++++++- .../service/impl/RkInfoServiceImpl.java | 7 +- src/main/resources/application.yml | 6 +- .../resources/mybatis/wisdom/GysJhMapper.xml | 9 +- .../resources/mybatis/wisdom/RkInfoMapper.xml | 8 +- 智慧仓储系统综合业务文档.md | 639 ++++++++++++++++++ 智慧实物管理系统安全功能审查报告.md | 79 +++ 盘点系统业务对接文档.md | 355 ++++++++++ 调度系统与盘点系统业务对接文档.md | 318 +++++++++ 调度系统与盘点系统开发文档.md | 362 ++++++++++ 25 files changed, 2708 insertions(+), 46 deletions(-) create mode 100644 WCS对接流程图说明.md create mode 100644 WCS系统与WMS-AGV对接业务文档.md create mode 100644 src/main/java/com/zg/project/wisdom/config/QwenOcrRemoteProperties.java create mode 100644 src/main/java/com/zg/project/wisdom/domain/dto/ExcelFieldMapping.java create mode 100644 src/main/java/com/zg/project/wisdom/domain/dto/GysJhImportDTO.java create mode 100644 src/main/java/com/zg/project/wisdom/service/QwenOcrRemoteService.java create mode 100644 智慧仓储系统综合业务文档.md create mode 100644 智慧实物管理系统安全功能审查报告.md create mode 100644 盘点系统业务对接文档.md create mode 100644 调度系统与盘点系统业务对接文档.md create mode 100644 调度系统与盘点系统开发文档.md diff --git a/WCS对接流程图说明.md b/WCS对接流程图说明.md new file mode 100644 index 0000000..5654b32 --- /dev/null +++ b/WCS对接流程图说明.md @@ -0,0 +1,47 @@ +# WCS系统与WMS/AGV对接流程图 + +## 流程说明 + +```mermaid +graph TD + A[WMS创建任务] --> B{判断任务类型} + B -->|入库/上架| C[WMS调用WCS /API/Ruku接口] + B -->|出库/下架| D[WMS调用WCS /API/Chuku接口] + + C --> E[WCS接收任务请求] + D --> E + + E --> F[WCS验证任务参数] + F --> G{参数验证结果} + G -->|验证失败| H[WCS返回错误信息给WMS] + G -->|验证成功| I[WCS创建内部任务] + + I --> J[WCS控制立体库设备执行任务] + J --> K[设备执行中...] + K --> L{任务执行结果} + L -->|执行成功| M[WCS更新任务状态] + L -->|执行失败| N[WCS记录异常并重试] + + M --> O[WCS回调WMS状态更新] + N --> P{重试次数达到上限} + P -->|是| Q[WCS回调WMS失败状态] + P -->|否| J + + O --> R[WMS接收状态更新] + Q --> R + H --> R + + R --> S{是否需要AGV配合} + S -->|是| T[WMS调度AGV] + S -->|否| U[任务完成] + T --> U +``` + +## 流程步骤说明 + +1. **任务创建**:WMS系统创建入库或出库任务 +2. **接口调用**:根据任务类型调用WCS相应接口 +3. **参数验证**:WCS系统验证接收到的任务参数 +4. **任务执行**:WCS系统控制立体库设备执行任务 +5. **状态反馈**:WCS系统向WMS系统反馈任务执行状态 +6. **AGV配合**:根据需要WMS系统调度AGV进行配合操作 \ No newline at end of file diff --git a/WCS系统与WMS-AGV对接业务文档.md b/WCS系统与WMS-AGV对接业务文档.md new file mode 100644 index 0000000..8c9f760 --- /dev/null +++ b/WCS系统与WMS-AGV对接业务文档.md @@ -0,0 +1,343 @@ +# WCS系统与WMS/AGV对接业务文档 + +## 项目概述 + +### 项目背景 +WCS(Warehouse Control System,仓库控制系统)作为自动化立体仓库的核心控制系统,负责与WMS(仓库管理系统)和AGV(自动导引车)系统进行对接,实现货物的自动化入库、出库、移库等操作。 + +### 项目目标 +- 实现WCS系统与WMS系统的无缝对接 +- 实现WCS系统与AGV系统的协调作业 +- 提供标准化接口,确保三方系统稳定运行 +- 实现出入库、移库等核心业务流程 + +## WCS系统核心功能 + +### 1. 入库/上架功能 +- 接收WMS系统的入库任务 +- 控制立体库设备执行上架操作 +- 实时反馈任务执行状态给WMS系统 + +### 2. 出库/下架功能 +- 接收WMS系统的出库任务 +- 控制立体库设备执行下架操作 +- 实时反馈任务执行状态给WMS系统 + +### 3. 库位管理功能 +- 管理立体库所有库位状态 +- 实时更新库位占用情况 +- 提供库位查询接口 + +### 4. 任务调度功能 +- 任务队列管理 +- 任务优先级调度 +- 设备资源分配 + +## WCS系统对外接口 + +### 1. 入库/上架接口(/API/Ruku) + +#### 接口说明 +WMS系统调用此接口创建入库/上架任务 + +#### 请求方式 +POST + +#### 请求参数 +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| TaskID | String | 是 | 任务ID | +| TrayNo | String | 否 | 托盘号 | +| Materialstatus | Integer | 是 | 物料状态(0: 空托盘,1: 有货) | +| MaterialCode | String | 否 | 物料编码(Materialstatus为1时必填) | +| Specification | String | 否 | 规格 | +| Quantity | String | 否 | 数量 | +| Mlocation | String | 是 | 目标库位 | +| Tlocation | String | 是 | 来源库位 | + +#### 响应参数 +| 参数名 | 类型 | 说明 | +|--------|------|------| +| result | String | 结果("success"表示成功) | +| errorMessage | String | 错误消息 | + +### 2. 出库/下架接口(/API/Chuku) + +#### 接口说明 +WMS系统调用此接口创建出库/下架任务 + +#### 请求方式 +POST + +#### 请求参数 +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| TaskID | String | 是 | 任务ID | +| TaskType | Integer | 是 | 任务类型(1: 出库) | +| Mlocation | String | 是 | 来源库位 | +| TrayNo | String | 否 | 托盘号 | +| Materialstatus | Integer | 是 | 物料状态(0: 空托盘,1: 有货) | +| outBack | Integer | 是 | 固定值(1) | +| MaterialCode | String | 否 | 物料编码(Materialstatus为1时必填) | +| Specification | String | 否 | 规格 | +| Quantity | String | 否 | 数量 | + +#### 响应参数 +| 参数名 | 类型 | 说明 | +|--------|------|------| +| result | String | 结果("success"表示成功) | +| errorMessage | String | 错误消息 | + +## WCS系统开发工作内容 + +### 1. 接口开发工作 + +#### 1.1 入库/上架接口开发 +- **工作内容**:开发 `/API/Ruku` 接口,处理WMS入库任务请求 +- **技术实现**: + - HTTP POST接口开发 + - JSON数据解析 + - 业务参数验证 + - 任务创建与调度 + - 响应格式化 +- **预计工时**:16小时 + +#### 1.2 出库/下架接口开发 +- **工作内容**:开发 `/API/Chuku` 接口,处理WMS出库任务请求 +- **技术实现**: + - HTTP POST接口开发 + - JSON数据解析 + - 业务参数验证 + - 任务创建与调度 + - 响应格式化 +- **预计工时**:16小时 + +#### 1.3 任务状态回调接口开发 +- **工作内容**:实现WCS任务状态回调机制 +- **技术实现**: + - 状态变更触发器 + - HTTP回调请求 + - 状态同步机制 +- **预计工时**:24小时 + +### 2. 业务逻辑开发工作 + +#### 2.1 货物上架逻辑实现 +- **工作内容**:实现完整的货物上架业务流程 +- **技术实现**: + - 库位分配算法 + - 设备控制指令生成 + - 执行状态跟踪 + - 异常处理机制 +- **预计工时**:32小时 + +#### 2.2 货物下架逻辑实现 +- **工作内容**:实现完整的货物下架业务流程 +- **技术实现**: + - 货物定位算法 + - 设备控制指令生成 + - 执行状态跟踪 + - 异常处理机制 +- **预计工时**:32小时 + +#### 2.3 任务调度与排队机制 +- **工作内容**:实现多任务排队调度算法 +- **技术实现**: + - 任务队列管理 + - 优先级调度算法 + - 设备资源分配 + - 任务冲突解决 +- **预计工时**:24小时 + +### 3. 系统集成开发工作 + +#### 3.1 与WMS系统接口对接 +- **工作内容**:确保WCS与WMS系统稳定通信 +- **技术实现**: + - 接口协议实现 + - 数据格式转换 + - 通信安全机制 + - 错误重试机制 +- **预计工时**:20小时 + +#### 3.2 与AGV系统协调机制 +- **工作内容**:实现WCS与AGV系统的任务协调 +- **技术实现**: + - 协调接口开发 + - 状态同步机制 + - 任务交接处理 +- **预计工时**:16小时 + +### 4. 数据管理开发工作 + +#### 4.1 任务数据存储与管理 +- **工作内容**:开发任务数据的存储和管理功能 +- **技术实现**: + - 数据库表设计 + - 数据访问层开发 + - 数据一致性保证 + - 数据清理机制 +- **预计工时**:20小时 + +#### 4.2 库位状态数据维护 +- **工作内容**:实现库位状态的实时维护 +- **技术实现**: + - 库位状态表设计 + - 状态变更处理 + - 数据同步机制 + - 状态查询接口 +- **预计工时**:16小时 + +### 5. 监控与维护开发工作 + +#### 5.1 系统运行状态监控 +- **工作内容**:开发系统运行状态监控功能 +- **技术实现**: + - 监控指标定义 + - 监控接口开发 + - 异常告警机制 +- **预计工时**:12小时 + +#### 5.2 异常处理与恢复机制 +- **工作内容**:开发完善的异常处理和任务恢复机制 +- **技术实现**: + - 异常类型定义 + - 异常处理策略 + - 任务恢复机制 + - 日志记录系统 +- **预计工时**:20小时 + +## 系统对接流程图 + +```mermaid +graph TD + A[WMS创建任务] --> B{判断任务类型} + B -->|入库/上架| C[WMS调用WCS /API/Ruku接口] + B -->|出库/下架| D[WMS调用WCS /API/Chuku接口] + + C --> E[WCS接收任务请求] + D --> E + + E --> F[WCS验证任务参数] + F --> G{参数验证结果} + G -->|验证失败| H[WCS返回错误信息给WMS] + G -->|验证成功| I[WCS创建内部任务] + + I --> J[WCS控制立体库设备执行任务] + J --> K[设备执行中...] + K --> L{任务执行结果} + L -->|执行成功| M[WCS更新任务状态] + L -->|执行失败| N[WCS记录异常并重试] + + M --> O[WCS回调WMS状态更新] + N --> P{重试次数达到上限} + P -->|是| Q[WCS回调WMS失败状态] + P -->|否| J + + O --> R[WMS接收状态更新] + Q --> R + H --> R + + R --> S{是否需要AGV配合} + S -->|是| T[WMS调度AGV] + S -->|否| U[任务完成] + T --> U +``` + +## 项目实施计划 + +### 第一阶段:接口开发(预计2周) +- 完成入库/上架接口开发 +- 完成出库/下架接口开发 +- 完成基础数据模型设计 + +### 第二阶段:业务逻辑开发(预计3周) +- 完成货物上架逻辑开发 +- 完成货物下架逻辑开发 +- 完成任务调度机制开发 + +### 第三阶段:系统集成(预计2周) +- 完成与WMS系统对接 +- 完成与AGV系统协调 +- 完成监控功能开发 + +### 第四阶段:测试与优化(预计1周) +- 系统集成测试 +- 性能优化 +- 异常处理完善 + +## 项目交付物 + +1. **技术文档** + - 接口规范文档 + - 部署手册 + - 运维手册 + +2. **软件系统** + - WCS系统核心程序 + - 数据库脚本 + - 配置文件 + +3. **测试报告** + - 单元测试报告 + - 集成测试报告 + - 性能测试报告 + +## 项目价值体现 + +### 1. 技术价值 +- 提供标准化接口,实现系统间无缝对接 +- 实现复杂的任务调度算法 +- 确保系统高可用性和稳定性 + +### 2. 业务价值 +- 实现仓库作业自动化 +- 提高仓储效率和准确性 +- 降低人工成本 + +### 3. 服务价值 +- 专业的技术开发服务 +- 完善的系统集成方案 +- 持续的技术支持服务 + +## 风险与应对 + +### 1. 技术风险 +- **风险**:接口兼容性问题 +- **应对**:提前进行接口规范确认 + +### 2. 集成风险 +- **风险**:三方系统集成复杂度高 +- **应对**:分阶段集成测试 + +### 3. 性能风险 +- **风险**:高并发场景下系统性能 +- **应对**:性能测试与优化 + +## 服务收费标准 + +基于上述开发工作内容,WCS系统与WMS/AGV对接服务包含以下收费项目: + +### 1. 接口开发服务(40小时) +- 入库/上架接口:16小时 +- 出库/下架接口:16小时 +- 任务状态回调接口:8小时 + +### 2. 业务逻辑开发(88小时) +- 货物上架逻辑:32小时 +- 货物下架逻辑:32小时 +- 任务调度机制:24小时 + +### 3. 系统集成服务(36小时) +- 与WMS系统对接:20小时 +- 与AGV系统协调:16小时 + +### 4. 数据管理开发(36小时) +- 任务数据管理:20小时 +- 库位状态维护:16小时 + +### 5. 监控维护开发(32小时) +- 系统监控:12小时 +- 异常处理机制:20小时 + +**总计开发工时:232小时** \ No newline at end of file diff --git a/src/main/java/com/zg/project/wisdom/config/QwenOcrRemoteProperties.java b/src/main/java/com/zg/project/wisdom/config/QwenOcrRemoteProperties.java new file mode 100644 index 0000000..21092fd --- /dev/null +++ b/src/main/java/com/zg/project/wisdom/config/QwenOcrRemoteProperties.java @@ -0,0 +1,17 @@ +package com.zg.project.wisdom.config; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Component +@ConfigurationProperties(prefix = "qwen-ocr") +@Data +public class QwenOcrRemoteProperties { + + /** + * 远程 OCR 服务的完整地址 + * 例如:http://192.168.1.5:8087/ocr/extractErpByBase64 + */ + private String baseUrl; +} diff --git a/src/main/java/com/zg/project/wisdom/controller/AuditSignatureController.java b/src/main/java/com/zg/project/wisdom/controller/AuditSignatureController.java index e6e4ecb..29c9da2 100644 --- a/src/main/java/com/zg/project/wisdom/controller/AuditSignatureController.java +++ b/src/main/java/com/zg/project/wisdom/controller/AuditSignatureController.java @@ -43,6 +43,7 @@ public class AuditSignatureController extends BaseController * 上传签字图片到 MinIO */ @PostMapping("/upload") + @Log(title = "签字图片上传", businessType = BusinessType.INSERT) public AjaxResult uploadSignature(@RequestParam("file") MultipartFile file) { if (file == null || file.isEmpty()) { return AjaxResult.error("上传文件不能为空"); @@ -56,6 +57,7 @@ public class AuditSignatureController extends BaseController } // 上传图片,接收base64格式 zhangjinbo @PostMapping("/uploadBase64") + @Log(title = "签字图片上传", businessType = BusinessType.INSERT) public AjaxResult uploadSignatureBase64(@RequestBody Map param) { String imgStr = param.get("imgStr"); // return AjaxResult.success("上传成功").put("url", imgStr); @@ -150,6 +152,7 @@ public class AuditSignatureController extends BaseController * 审核操作(通过 / 驳回) */ @PostMapping("/audit") + @Log(title = "审批记录", businessType = BusinessType.UPDATE) public AjaxResult audit(@RequestBody AuditSignature audit) { try { auditSignatureService.audit(audit); diff --git a/src/main/java/com/zg/project/wisdom/controller/GysJhController.java b/src/main/java/com/zg/project/wisdom/controller/GysJhController.java index b8a52bb..5e122c9 100644 --- a/src/main/java/com/zg/project/wisdom/controller/GysJhController.java +++ b/src/main/java/com/zg/project/wisdom/controller/GysJhController.java @@ -2,6 +2,11 @@ package com.zg.project.wisdom.controller; import java.util.List; import javax.servlet.http.HttpServletResponse; + +import com.alibaba.fastjson2.JSON; +import com.zg.common.utils.StringUtils; +import com.zg.project.wisdom.domain.dto.ExcelFieldMapping; +import org.springframework.http.MediaType; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @@ -123,4 +128,39 @@ public class GysJhController extends BaseController { return toAjax(gysJhService.deleteGysJhByIds(ids)); } + + /** + * 供应计划导入(带字段映射) + * + * 前端 form-data 结构示例: + * - file: 选中的 excel 文件 + * - mapping[0].label = wlNo + * - mapping[0].prop = E + * - mapping[1].label = wlMs + * - mapping[1].prop = F + * ... + */ + @PreAuthorize("@ss.hasPermi('wisdom:gysJh:import')") + @Log(title = "供应计划导入", businessType = BusinessType.IMPORT) + @PostMapping( + value = "/importByMapping", + consumes = MediaType.MULTIPART_FORM_DATA_VALUE + ) + public AjaxResult importByMapping(@RequestPart("file") MultipartFile file, + @RequestParam("mapping") String mappingJson) throws Exception { + + if (file == null || file.isEmpty()) { + return AjaxResult.error("导入文件不能为空"); + } + if (StringUtils.isBlank(mappingJson)) { + return AjaxResult.error("字段映射不能为空"); + } + + // 把 JSON 字符串转成 List + List mapping = + JSON.parseArray(mappingJson, ExcelFieldMapping.class); + + int rows = gysJhService.importByMapping(file, mapping); + return AjaxResult.success("成功导入 " + rows + " 条记录"); + } } diff --git a/src/main/java/com/zg/project/wisdom/controller/PhotoController.java b/src/main/java/com/zg/project/wisdom/controller/PhotoController.java index 091d8d9..1095f7d 100644 --- a/src/main/java/com/zg/project/wisdom/controller/PhotoController.java +++ b/src/main/java/com/zg/project/wisdom/controller/PhotoController.java @@ -1,5 +1,7 @@ package com.zg.project.wisdom.controller; +import com.zg.framework.aspectj.lang.annotation.Log; +import com.zg.framework.aspectj.lang.enums.BusinessType; import com.zg.framework.web.domain.AjaxResult; import com.zg.project.wisdom.domain.dto.PhotoDeleteDTO; import com.zg.project.wisdom.service.PhotoService; @@ -38,6 +40,7 @@ public class PhotoController { * 返回:每张图片的可访问 URL 列表 */ @PostMapping(value = "/upload/batch", consumes = "multipart/form-data") + @Log(title = "照片上传", businessType = BusinessType.INSERT) public AjaxResult uploadBatch(@RequestPart("files") List files, @RequestParam("photoType") String photoType, @RequestParam("billNo") String billNo, @@ -88,12 +91,13 @@ public class PhotoController { * @return */ @PostMapping(value = "/delete", consumes = "application/json") -// @PreAuthorize("@ss.hasPermi('wisdom:photo:remove')") + @Log(title = "照片删除", businessType = BusinessType.DELETE) public AjaxResult delete(@Validated @RequestBody PhotoDeleteDTO dto) { Map result = photoService.deleteByUrls(dto.getUrls()); return AjaxResult.success("删除完成", result); } @GetMapping("/deleteById") + @Log(title = "照片删除", businessType = BusinessType.DELETE) public AjaxResult deleteById(@RequestParam("id") Integer id){ return AjaxResult.success(photoService.deleteById(id)); } diff --git a/src/main/java/com/zg/project/wisdom/controller/RkInfoController.java b/src/main/java/com/zg/project/wisdom/controller/RkInfoController.java index aa18369..b2e1aed 100644 --- a/src/main/java/com/zg/project/wisdom/controller/RkInfoController.java +++ b/src/main/java/com/zg/project/wisdom/controller/RkInfoController.java @@ -9,6 +9,7 @@ import com.github.pagehelper.PageHelper; import com.zg.project.wisdom.domain.dto.*; import com.zg.project.wisdom.domain.vo.DeliveryBillVO; import com.zg.project.wisdom.domain.vo.PcodeQtyVO; +import com.zg.project.wisdom.service.QwenOcrRemoteService; import io.swagger.annotations.ApiOperation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.beans.factory.annotation.Autowired; @@ -21,6 +22,7 @@ import com.zg.framework.web.controller.BaseController; import com.zg.framework.web.domain.AjaxResult; import com.zg.common.utils.poi.ExcelUtil; import com.zg.framework.web.page.TableDataInfo; +import org.springframework.web.multipart.MultipartFile; /** * 库存单据主Controller @@ -35,6 +37,9 @@ public class RkInfoController extends BaseController @Autowired private IRkInfoService rkInfoService; + @Autowired + private QwenOcrRemoteService qwenOcrRemoteService; + /** * 查询出库,借料,待审批,撤销出入库单据主列表 @@ -47,7 +52,6 @@ public class RkInfoController extends BaseController return getDataTable(list); } -// @PreAuthorize("@ss.hasPermi('wisdom:stock:stat')") @GetMapping("/pcode/{pcode}") public AjaxResult listRkInfoByPcode(@PathVariable String pcode) { List rows = rkInfoService.listRkInfoByPcode(pcode); @@ -128,7 +132,6 @@ public class RkInfoController extends BaseController * @return */ @GetMapping("/warning/stock/over20") - @PreAuthorize("@ss.hasPermi('wisdom:stock:warning')") public AjaxResult getOverdueStockTopList() { int total = rkInfoService.countOverdueStock(); List list = rkInfoService.selectTopOverdueStock(20); @@ -144,7 +147,7 @@ public class RkInfoController extends BaseController * @return */ @PutMapping("/deleteByCkBillNo") - @PreAuthorize("@ss.hasPermi('wisdom:stock:deleteByBillNo')") + @Log(title = "库存单据主", businessType = BusinessType.UPDATE) public AjaxResult deleteByCkBillNo(@RequestBody Map body) { String billNoCk = body.get("billNoCk"); if (billNoCk == null || billNoCk.trim().isEmpty()) { @@ -161,7 +164,7 @@ public class RkInfoController extends BaseController * 根据主键ID撤销入库 */ @PostMapping("/cancel") - @PreAuthorize("@ss.hasPermi('wisdom:stock:deleteByBillNo')") + @Log(title = "库存单据主", businessType = BusinessType.UPDATE) public AjaxResult deleteById(@RequestBody RkCancelDTO dto) { rkInfoService.deleteRkInfoById(dto); return AjaxResult.success("撤销成功"); @@ -171,7 +174,7 @@ public class RkInfoController extends BaseController * 根据主键ID撤销出库 */ @PostMapping("/cancelById/{id}") - @PreAuthorize("@ss.hasPermi('wisdom:stock:deleteByBillNo')") + @Log(title = "库存单据主", businessType = BusinessType.UPDATE) public AjaxResult cancelOutStockById(@PathVariable Long id) { rkInfoService.cancelOutStockById(id); return AjaxResult.success("撤销出库成功"); @@ -183,7 +186,7 @@ public class RkInfoController extends BaseController * 出入库撤销记录删除 */ @PostMapping("/deleteByIds") - @PreAuthorize("@ss.hasPermi('wisdom:stock:deleteById')") + @Log(title = "库存单据主", businessType = BusinessType.UPDATE) public AjaxResult deleteByIds(@RequestBody Long[] ids) { return AjaxResult.success(rkInfoService.deleteRkInfoByIds(ids)); } @@ -192,7 +195,7 @@ public class RkInfoController extends BaseController * 根据ids恢复出库或入库 */ @PostMapping("/revertByIds") - @PreAuthorize("@ss.hasPermi('wisdom:stock:deleteById')") + @Log(title = "库存单据主", businessType = BusinessType.UPDATE) public AjaxResult revertByIds(@RequestBody Long[] ids) { rkInfoService.revertByIds(ids); return AjaxResult.success(); @@ -302,14 +305,39 @@ public class RkInfoController extends BaseController @PostMapping("/updateDeliveryStatus") + @Log(title = "更新配送状态", businessType = BusinessType.UPDATE) public AjaxResult updateDeliveryStatus(@RequestBody RkDeliveryUpdateDTO dto) { - if (dto.getBillNoCk() == null) { - return AjaxResult.error("出库单据号不能为空"); + if (dto.getIds() == null || dto.getIds().isEmpty()) { + return AjaxResult.error("rk_info 主键ID集合不能为空"); + } + if (dto.getIsDelivery() == null) { + return AjaxResult.error("配送状态不能为空"); } - int rows = rkInfoService.updateDeliveryStatus(dto.getBillNoCk(), dto.getIsDelivery()); + int rows = rkInfoService.updateDeliveryStatus(dto.getIds(), dto.getIsDelivery()); return AjaxResult.success(rows); } + /** + * 上传图片,识别采购订单号(ERP) + * + * 前端调用示例(multipart/form-data): + * POST /wisdom/ocr/extractErp + * file: <图片文件> + */ + @PostMapping("/extractErp") + public AjaxResult extractErp(@RequestParam("file") MultipartFile file) { + + if (file == null || file.isEmpty()) { + return AjaxResult.error("上传文件不能为空"); + } + + String erpOrderNo = qwenOcrRemoteService.extractErpOrderNo(file); + + + return AjaxResult.success(erpOrderNo); + + } + } diff --git a/src/main/java/com/zg/project/wisdom/domain/dto/ExcelFieldMapping.java b/src/main/java/com/zg/project/wisdom/domain/dto/ExcelFieldMapping.java new file mode 100644 index 0000000..b89730f --- /dev/null +++ b/src/main/java/com/zg/project/wisdom/domain/dto/ExcelFieldMapping.java @@ -0,0 +1,14 @@ +package com.zg.project.wisdom.domain.dto; + +import lombok.Data; + +@Data +public class ExcelFieldMapping { + + /** 后端字段名,如 wlNo、sapNo */ + private String label; + + /** Excel 列,如 A、B、C、AA */ + private String prop; + +} diff --git a/src/main/java/com/zg/project/wisdom/domain/dto/GysJhImportDTO.java b/src/main/java/com/zg/project/wisdom/domain/dto/GysJhImportDTO.java new file mode 100644 index 0000000..42d4c46 --- /dev/null +++ b/src/main/java/com/zg/project/wisdom/domain/dto/GysJhImportDTO.java @@ -0,0 +1,62 @@ +package com.zg.project.wisdom.domain.dto; + +import java.util.List; + +/** + * 供应计划导入DTO - 支持自定义映射关系 + * + * @author zg + * @date 2025-12-01 + */ +public class GysJhImportDTO { + + /** + * 映射关系对象 + */ + public static class MappingItem { + private String label; // 字段标识名 + private String prop; // Excel列标识(如A、B、C等) + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + public String getProp() { + return prop; + } + + public void setProp(String prop) { + this.prop = prop; + } + } + + /** + * 映射关系数组 + */ + private List mapping; + + /** + * 操作人 + */ + private String operName; + + public List getMapping() { + return mapping; + } + + public void setMapping(List mapping) { + this.mapping = mapping; + } + + public String getOperName() { + return operName; + } + + public void setOperName(String operName) { + this.operName = operName; + } +} \ No newline at end of file diff --git a/src/main/java/com/zg/project/wisdom/domain/dto/RkDeliveryUpdateDTO.java b/src/main/java/com/zg/project/wisdom/domain/dto/RkDeliveryUpdateDTO.java index 2cc70c9..70100b7 100644 --- a/src/main/java/com/zg/project/wisdom/domain/dto/RkDeliveryUpdateDTO.java +++ b/src/main/java/com/zg/project/wisdom/domain/dto/RkDeliveryUpdateDTO.java @@ -2,8 +2,14 @@ package com.zg.project.wisdom.domain.dto; import lombok.Data; +import java.util.List; + @Data public class RkDeliveryUpdateDTO { - private String billNoCk; - private Integer isDelivery; // 0否 1是 2配送中 3已完成 + + /** rk_info 主键ID集合 */ + private List ids; + + /** 配送状态:0否 1是 2配送中 3已完成 */ + private Integer isDelivery; } \ No newline at end of file diff --git a/src/main/java/com/zg/project/wisdom/mapper/GysJhMapper.java b/src/main/java/com/zg/project/wisdom/mapper/GysJhMapper.java index e5ff29b..1bb8f83 100644 --- a/src/main/java/com/zg/project/wisdom/mapper/GysJhMapper.java +++ b/src/main/java/com/zg/project/wisdom/mapper/GysJhMapper.java @@ -86,15 +86,13 @@ public interface GysJhMapper void resetGysJhStatusBySapNos(List sapNos); /** - * 根据sapNo和xmNo和wlNo查询 - * @param sapNo - * @param xmNo - * @param wlNo - * @return + * 【已注释】根据SAP订单号、项目号和物料号检查是否已存在(唯一性校验) + * @param sapNo SAP订单号 + * @param xmNo 项目号 + * @param wlNo 物料号 + * @return 是否存在 */ - boolean existsByUniqueKeys(@Param("sapNo") String sapNo, - @Param("xmNo") String xmNo, - @Param("wlNo") String wlNo); + // boolean existsByUniqueKeys(@Param("sapNo") String sapNo, @Param("xmNo") String xmNo, @Param("wlNo") String wlNo); /** * 批量修改状态 diff --git a/src/main/java/com/zg/project/wisdom/mapper/RkInfoMapper.java b/src/main/java/com/zg/project/wisdom/mapper/RkInfoMapper.java index 68c21c1..d91103e 100644 --- a/src/main/java/com/zg/project/wisdom/mapper/RkInfoMapper.java +++ b/src/main/java/com/zg/project/wisdom/mapper/RkInfoMapper.java @@ -236,7 +236,8 @@ public interface RkInfoMapper * 修改出库单据状态 */ - int updateDeliveryStatus(@Param("billNoCk") String billNoCk, + + int updateDeliveryStatus(@Param("ids") List ids, @Param("isDelivery") Integer isDelivery); /** diff --git a/src/main/java/com/zg/project/wisdom/service/IGysJhService.java b/src/main/java/com/zg/project/wisdom/service/IGysJhService.java index 5621c22..8a5d50e 100644 --- a/src/main/java/com/zg/project/wisdom/service/IGysJhService.java +++ b/src/main/java/com/zg/project/wisdom/service/IGysJhService.java @@ -2,6 +2,8 @@ package com.zg.project.wisdom.service; import java.util.List; import com.zg.project.wisdom.domain.GysJh; +import com.zg.project.wisdom.domain.dto.ExcelFieldMapping; +import org.springframework.web.multipart.MultipartFile; /** * 供应计划Service接口 @@ -73,4 +75,10 @@ public interface IGysJhService * @return */ List getBySapNo(String sapNo); + + /** + * 按字段映射导入供应计划 + */ + int importByMapping(MultipartFile file, List mapping) throws Exception; + } diff --git a/src/main/java/com/zg/project/wisdom/service/IRkInfoService.java b/src/main/java/com/zg/project/wisdom/service/IRkInfoService.java index eb78230..1020c9f 100644 --- a/src/main/java/com/zg/project/wisdom/service/IRkInfoService.java +++ b/src/main/java/com/zg/project/wisdom/service/IRkInfoService.java @@ -175,12 +175,11 @@ public interface IRkInfoService void appendToExistingBill(PcRkInfoBatchDTO dto); /** - * 修改出库单的配送状态 - * @param billNoCk - * @param isDelivery - * @return + * 按 rk_info 主键ID集合修改配送状态 + * @param ids rk_info.id 集合 + * @param isDelivery 配送状态 */ - int updateDeliveryStatus(String billNoCk, Integer isDelivery); + int updateDeliveryStatus(List ids, Integer isDelivery); /** * 获取指定出库单的配送信息 diff --git a/src/main/java/com/zg/project/wisdom/service/QwenOcrRemoteService.java b/src/main/java/com/zg/project/wisdom/service/QwenOcrRemoteService.java new file mode 100644 index 0000000..aaf40fa --- /dev/null +++ b/src/main/java/com/zg/project/wisdom/service/QwenOcrRemoteService.java @@ -0,0 +1,98 @@ +package com.zg.project.wisdom.service; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.zg.project.wisdom.config.QwenOcrRemoteProperties; +import okhttp3.*; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; +import java.util.Base64; +import java.util.Objects; +import java.util.concurrent.TimeUnit; + +@Service +public class QwenOcrRemoteService { + + private final QwenOcrRemoteProperties properties; + private final ObjectMapper objectMapper = new ObjectMapper(); + + private final OkHttpClient httpClient = new OkHttpClient.Builder() + .connectTimeout(10, TimeUnit.SECONDS) + .readTimeout(25, TimeUnit.SECONDS) + .writeTimeout(25, TimeUnit.SECONDS) + .build(); + + public QwenOcrRemoteService(QwenOcrRemoteProperties properties) { + this.properties = properties; + } + + /** + * 接收上传的图片文件,转成 Base64 后, + * 调用 250 上的 /ocr/extractErpByBase64 接口,返回采购订单号(ERP) + */ + public String extractErpOrderNo(MultipartFile file) { + try { + // 1. 读取文件字节 + byte[] bytes = file.getBytes(); + + // 2. 推断 contentType + String contentType = file.getContentType(); + if (contentType == null || contentType.isEmpty()) { + String name = file.getOriginalFilename(); + if (name != null && name.toLowerCase().endsWith(".png")) { + contentType = "image/png"; + } else { + contentType = "image/jpeg"; + } + } + + // 3. 转成 Base64,并加上 data: 前缀 + String base64 = Base64.getEncoder().encodeToString(bytes); + String imageBase64 = "data:" + contentType + ";base64," + base64; + + // 4. 组装 JSON 请求体:{ "imageBase64": "data:image/jpeg;base64,xxxx" } + String json = objectMapper.createObjectNode() + .put("imageBase64", imageBase64) + .toString(); + + RequestBody body = RequestBody.create( + MediaType.parse("application/json"), + json + ); + + String url = properties.getBaseUrl(); // yml 里配置的 /ocr/extractErpByBase64 + + Request request = new Request.Builder() + .url(url) + .post(body) + .build(); + + // 5. 发送 HTTP 请求 + Response response = httpClient.newCall(request).execute(); + try { + if (!response.isSuccessful()) { + String errorBody = response.body() != null ? response.body().string() : "no error body"; + throw new RuntimeException("调用远程 OCR 服务失败,HTTP 状态码:" + + response.code() + ",错误信息:" + errorBody); + } + + String resp = Objects.requireNonNull(response.body()).string(); + JsonNode rootNode = objectMapper.readTree(resp); + + // 远程服务返回:{ success: true, found: true/false, erpOrderNo: "0101398982" } + JsonNode erpNode = rootNode.get("erpOrderNo"); + if (erpNode == null || erpNode.isNull()) { + return ""; + } + return erpNode.asText(""); + } finally { + response.close(); + } + + } catch (IOException e) { + throw new RuntimeException("调用远程 OCR 服务异常:" + e.getMessage(), e); + } + } +} diff --git a/src/main/java/com/zg/project/wisdom/service/impl/GysJhServiceImpl.java b/src/main/java/com/zg/project/wisdom/service/impl/GysJhServiceImpl.java index e15ad81..537bbb3 100644 --- a/src/main/java/com/zg/project/wisdom/service/impl/GysJhServiceImpl.java +++ b/src/main/java/com/zg/project/wisdom/service/impl/GysJhServiceImpl.java @@ -1,14 +1,22 @@ package com.zg.project.wisdom.service.impl; -import java.util.List; +import java.io.InputStream; +import java.math.BigDecimal; +import java.util.*; import com.zg.common.exception.ServiceException; import com.zg.common.utils.DateUtils; +import com.zg.common.utils.SecurityUtils; +import com.zg.common.utils.StringUtils; +import com.zg.project.wisdom.domain.dto.ExcelFieldMapping; +import org.apache.poi.ss.usermodel.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.zg.project.wisdom.mapper.GysJhMapper; import com.zg.project.wisdom.domain.GysJh; import com.zg.project.wisdom.service.IGysJhService; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; /** * 供应计划Service业务层处理 @@ -115,15 +123,15 @@ public class GysJhServiceImpl implements IGysJhService for (GysJh jh : jhList) { try { // 唯一性校验:订单号 + 项目号 + 物料号 - boolean exists = gysJhMapper.existsByUniqueKeys(jh.getSapNo(), jh.getXmNo(), jh.getWlNo()); - if (exists) { - failureNum++; - failureMsg.append("
订单号:").append(jh.getSapNo()) - .append(",项目号:").append(jh.getXmNo()) - .append(",物料号:").append(jh.getWlNo()) - .append(" 已存在,跳过导入。"); - continue; - } +// boolean exists = gysJhMapper.existsByUniqueKeys(jh.getSapNo(), jh.getXmNo(), jh.getWlNo()); +// if (exists) { +// failureNum++; +// failureMsg.append("
订单号:").append(jh.getSapNo()) +// .append(",项目号:").append(jh.getXmNo()) +// .append(",物料号:").append(jh.getWlNo()) +// .append(" 已存在,跳过导入。"); +// continue; +// } jh.setCreateBy(operName); jh.setStatus("0"); @@ -157,4 +165,225 @@ public class GysJhServiceImpl implements IGysJhService public List getBySapNo(String sapNo) { return gysJhMapper.getBySapNo(sapNo); } + + + @Override + @Transactional(rollbackFor = Exception.class) + public int importByMapping(MultipartFile file, List mapping) throws Exception { + List list = parseExcel(file, mapping); + if (list == null || list.isEmpty()) { + return 0; + } + for (GysJh item : list) { + gysJhMapper.insertGysJh(item); + } + return list.size(); + } + + /** + * 解析 Excel -> GysJh 列表 + */ + private List parseExcel(MultipartFile file, List mappingList) throws Exception { + List result = new ArrayList<>(); + + try (InputStream is = file.getInputStream(); + Workbook workbook = WorkbookFactory.create(is)) { + + Sheet sheet = workbook.getSheetAt(0); + if (sheet == null) { + return result; + } + + // 1. 把映射转换成:字段名 -> 列索引 + Map fieldColumnIndex = new HashMap<>(); + for (ExcelFieldMapping m : mappingList) { + if (m == null) { + continue; + } + String label = m.getLabel(); // wlNo / jhAmt ... + String prop = m.getProp(); // A / B / C ... + if (StringUtils.isEmpty(label) || StringUtils.isEmpty(prop)) { + continue; + } + fieldColumnIndex.put(label, excelColToIndex(prop)); + } + + DataFormatter formatter = new DataFormatter(); + + int firstRowNum = sheet.getFirstRowNum(); + int lastRowNum = sheet.getLastRowNum(); + + // 默认第一行是表头,从第二行开始读 + for (int rowNum = firstRowNum + 1; rowNum <= lastRowNum; rowNum++) { + Row row = sheet.getRow(rowNum); + if (row == null) { + continue; + } + + // 关键字段都为空则认为是空行,跳过 + String wlNoVal = getCellString(row, fieldColumnIndex.get("wlNo"), formatter); + String sapNoVal = getCellString(row, fieldColumnIndex.get("sapNo"), formatter); + if (StringUtils.isEmpty(wlNoVal) && StringUtils.isEmpty(sapNoVal)) { + continue; + } + + GysJh item = new GysJh(); + // 序号可以用行号,也可以单独映射,看你需求 + item.setIndexNo((long) (rowNum)); + + // 按字段名逐个赋值 + for (Map.Entry entry : fieldColumnIndex.entrySet()) { + String field = entry.getKey(); + Integer colIndex = entry.getValue(); + String cellValue = getCellString(row, colIndex, formatter); + if (StringUtils.isEmpty(cellValue)) { + continue; + } + + switch (field) { + case "wlNo": + item.setWlNo(cellValue.trim()); + break; + case "wlMs": + item.setWlMs(cellValue.trim()); + break; + case "xmNo": + item.setXmNo(cellValue.trim()); + break; + case "xmMs": + item.setXmMs(cellValue.trim()); + break; + case "dw": + item.setDw(cellValue.trim()); + break; + case "gysNo": + item.setGysNo(cellValue.trim()); + break; + case "gysMc": + item.setGysMc(cellValue.trim()); + break; + case "jhAmt": + // BigDecimal + item.setJhAmt(parseBigDecimal(cellValue)); + break; + case "htDj": + // BigDecimal + item.setHtDj(parseBigDecimal(cellValue)); + break; + case "jhQty": + // Long!!这里用 Long,避免 BigDecimal 转 Long 的报错 + item.setJhQty(parseLong(cellValue)); + break; + case "htQty": + item.setHtQty(parseLong(cellValue)); + break; + case "sapNo": + item.setSapNo(cellValue.trim()); + break; + default: + // 以后扩展字段,就在上面加 case + break; + } + } + + // 默认字段 + item.setStatus("0"); + item.setIsDelete("0"); +// String username = SecurityUtils.getUsername(); + item.setCreateBy("大爷的!!!"); + item.setCreateTime(DateUtils.getNowDate()); + + result.add(item); + } + } + + return result; + } + + /** + * Excel 列字母转索引(A -> 0, B -> 1, ..., AA -> 26) + */ + private int excelColToIndex(String col) { + col = col.trim().toUpperCase(); + int index = 0; + for (int i = 0; i < col.length(); i++) { + char c = col.charAt(i); + index = index * 26 + (c - 'A' + 1); + } + return index - 1; + } + + /** + * 统一获取单元格字符串 + */ + private String getCellString(Row row, Integer colIndex, DataFormatter formatter) { + if (row == null || colIndex == null || colIndex < 0) { + return null; + } + Cell cell = row.getCell(colIndex); + if (cell == null) { + return null; + } + String val = formatter.formatCellValue(cell); + return StringUtils.isEmpty(val) ? null : val.trim(); + } + + /** + * 字符串转 BigDecimal(空串返回 null) + */ + /** + * 字符串转 BigDecimal(空串或"null"返回 null) + */ + private BigDecimal parseBigDecimal(String value) { + if (StringUtils.isEmpty(value)) { + return null; + } + + try { + String trimmedValue = value.trim(); + if ("null".equalsIgnoreCase(trimmedValue)) { + return null; + } + + // 去掉千分位逗号 + String v = trimmedValue.replace(",", "").trim(); + // 再次检查处理后的值 + if (StringUtils.isEmpty(v) || "null".equalsIgnoreCase(v)) { + return null; + } + + return new BigDecimal(v); + } catch (NumberFormatException e) { + // 记录详细错误信息以便调试 +// log.warn("解析BigDecimal失败,输入值: '{}'", value, e); + return null; + } + } + + /** + * 字符串转 Long(空串返回 null) + */ + private Long parseLong(String value) { + if (StringUtils.isEmpty(value)) { + return null; + } + + String trimmedValue = value.trim(); + if ("null".equalsIgnoreCase(trimmedValue)) { + return null; + } + + try { + String v = trimmedValue.replace(",", "").trim(); + if (StringUtils.isEmpty(v) || "null".equalsIgnoreCase(v)) { + return null; + } + return Long.valueOf(v); + } catch (NumberFormatException e) { +// log.warn("无法解析为Long的值: '{}'", value); + return null; + } + } + + } diff --git a/src/main/java/com/zg/project/wisdom/service/impl/RkInfoServiceImpl.java b/src/main/java/com/zg/project/wisdom/service/impl/RkInfoServiceImpl.java index 045dac4..7cbc31e 100644 --- a/src/main/java/com/zg/project/wisdom/service/impl/RkInfoServiceImpl.java +++ b/src/main/java/com/zg/project/wisdom/service/impl/RkInfoServiceImpl.java @@ -1128,8 +1128,11 @@ public class RkInfoServiceImpl implements IRkInfoService } @Override - public int updateDeliveryStatus(String billNoCk, Integer isDelivery) { - return rkInfoMapper.updateDeliveryStatus(billNoCk, isDelivery); + public int updateDeliveryStatus(List ids, Integer isDelivery) { + if (ids == null || ids.isEmpty()) { + return 0; + } + return rkInfoMapper.updateDeliveryStatus(ids, isDelivery); } @Override diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index bab591d..d63026f 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -165,4 +165,8 @@ minio: mock: agv-job-create-url: http://localhost:8086/mock/agv/task/create - wcs-job-create-url: http://localhost:8086/mock/wcs/task/create \ No newline at end of file + wcs-job-create-url: http://localhost:8086/mock/wcs/task/create + +#配送系统中调用大模型进行图片识别 +qwen-ocr: + base-url: http://192.168.1.253:8087/ocr/extractErpByBase64 \ No newline at end of file diff --git a/src/main/resources/mybatis/wisdom/GysJhMapper.xml b/src/main/resources/mybatis/wisdom/GysJhMapper.xml index 32777c1..3370199 100644 --- a/src/main/resources/mybatis/wisdom/GysJhMapper.xml +++ b/src/main/resources/mybatis/wisdom/GysJhMapper.xml @@ -76,14 +76,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" AND status != '1' - SELECT * FROM gys_jh @@ -230,4 +231,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{id} - \ No newline at end of file + + + diff --git a/src/main/resources/mybatis/wisdom/RkInfoMapper.xml b/src/main/resources/mybatis/wisdom/RkInfoMapper.xml index d468c2c..37dbda6 100644 --- a/src/main/resources/mybatis/wisdom/RkInfoMapper.xml +++ b/src/main/resources/mybatis/wisdom/RkInfoMapper.xml @@ -1223,8 +1223,10 @@ UPDATE rk_info SET is_delivery = #{isDelivery} - WHERE bill_no_ck = #{billNoCk} - AND is_delete = '0' + WHERE is_delete = '0' + AND id IN + + #{id} + - diff --git a/智慧仓储系统综合业务文档.md b/智慧仓储系统综合业务文档.md new file mode 100644 index 0000000..fc527d1 --- /dev/null +++ b/智慧仓储系统综合业务文档.md @@ -0,0 +1,639 @@ +# 智慧仓储系统综合业务文档 + +## 项目概述 + +### 项目背景 +智慧仓储系统包含WCS(Warehouse Control System,仓库控制系统)、WMS(仓库管理系统)、AGV(自动导引车)系统以及Inventory(库存盘点)系统,形成一个完整的自动化仓储解决方案。各系统协同工作,实现货物的自动化入库、出库、移库、盘点等操作。 + +### 项目目标 +- 实现WCS系统与WMS系统的无缝对接 +- 实现WCS系统与AGV系统的协调作业 +- 实现Inventory系统对库存的精确管理 +- 提供标准化接口,确保多系统稳定运行 +- 实现出入库、移库、盘点等核心业务流程 + +## WCS系统核心功能 + +### 1. 入库/上架功能 +- 接收WMS系统的入库任务 +- 控制立体库设备执行上架操作 +- 实时反馈任务执行状态给WMS系统 + +### 2. 出库/下架功能 +- 接收WMS系统的出库任务 +- 控制立体库设备执行下架操作 +- 实时反馈任务执行状态给WMS系统 + +### 3. 库位管理功能 +- 管理立体库所有库位状态 +- 实时更新库位占用情况 +- 提供库位查询接口 + +### 4. 任务调度功能 +- 任务队列管理 +- 任务优先级调度 +- 设备资源分配 + +## Inventory系统核心功能 + +### 1. 盘点任务管理 +- 创建盘点任务(设置任务名称、仓库ID、场景ID、执行人、完成时间等) +- 任务类型:手持盘点(0)和自动盘点(1) +- 任务状态:待执行(0)、已完成(1)、已超时(2) + +### 2. 自动盘点功能 +- 设备连接管理:通过RFID设备IP和端口建立TCP连接 +- 标签扫描:启动RFID设备进行标签扫描 +- 数据传输:通过WebSocket将扫描到的EPC标签数据发送给前端 +- 扫描控制:支持开始、停止、断开连接等操作 + +### 3. 数据匹配功能 +- 将扫描数据与系统库存数据进行匹配 +- 生成匹配结果(正常、未扫到、误扫) +- 统计盘点结果并生成图表 + +### 4. 报告管理功能 +- 生成盘点统计图表 +- 导出盘点报告 +- 提供历史盘点记录查询 + +## WCS系统对外接口 + +### 1. 入库/上架接口(/API/Ruku) + +#### 接口说明 +WMS系统调用此接口创建入库/上架任务 + +#### 请求方式 +POST + +#### 请求参数 +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| TaskID | String | 是 | 任务ID | +| TrayNo | String | 否 | 托盘号 | +| Materialstatus | Integer | 是 | 物料状态(0: 空托盘,1: 有货) | +| MaterialCode | String | 否 | 物料编码(Materialstatus为1时必填) | +| Specification | String | 否 | 规格 | +| Quantity | String | 否 | 数量 | +| Mlocation | String | 是 | 目标库位 | +| Tlocation | String | 是 | 来源库位 | + +#### 响应参数 +| 参数名 | 类型 | 说明 | +|--------|------|------| +| result | String | 结果("success"表示成功) | +| errorMessage | String | 错误消息 | + +### 2. 出库/下架接口(/API/Chuku) + +#### 接口说明 +WMS系统调用此接口创建出库/下架任务 + +#### 请求方式 +POST + +#### 请求参数 +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| TaskID | String | 是 | 任务ID | +| TaskType | Integer | 是 | 任务类型(1: 出库) | +| Mlocation | String | 是 | 来源库位 | +| TrayNo | String | 否 | 托盘号 | +| Materialstatus | Integer | 是 | 物料状态(0: 空托盘,1: 有货) | +| outBack | Integer | 是 | 固定值(1) | +| MaterialCode | String | 否 | 物料编码(Materialstatus为1时必填) | +| Specification | String | 否 | 规格 | +| Quantity | String | 否 | 数量 | + +#### 响应参数 +| 参数名 | 类型 | 说明 | +|--------|------|------| +| result | String | 结果("success"表示成功) | +| errorMessage | String | 错误消息 | + +## Inventory系统对外接口 + +### 1. 设备连接接口(/AutoInventory/connect) + +#### 接口说明 +建立RFID设备连接 + +#### 请求方式 +POST + +#### 请求参数 +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| deviceId | String | 是 | 设备ID | +| ip | String | 是 | 设备IP地址 | +| port | Integer | 是 | 设备端口号 | + +#### 响应参数 +| 参数名 | 类型 | 说明 | +|--------|------|------| +| code | Integer | 响应码(200表示成功) | +| msg | String | 响应消息 | + +### 2. 开始盘点接口(/AutoInventory/scan) + +#### 接口说明 +启动RFID设备进行标签扫描 + +#### 请求方式 +GET + +#### 请求参数 +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| deviceId | String | 是 | 设备ID | + +#### 响应参数 +| 参数名 | 类型 | 说明 | +|--------|------|------| +| code | Integer | 响应码(200表示成功) | +| msg | String | 响应消息 | + +### 3. 停止盘点接口(/AutoInventory/stop) + +#### 接口说明 +停止RFID设备扫描 + +#### 请求方式 +GET + +#### 请求参数 +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| deviceId | String | 是 | 设备ID | + +#### 响应参数 +| 参数名 | 类型 | 说明 | +|--------|------|------| +| code | Integer | 响应码(200表示成功) | +| msg | String | 响应消息 | + +### 4. 断开连接接口(/AutoInventory/disconnect) + +#### 接口说明 +断开RFID设备连接 + +#### 请求方式 +GET + +#### 请求参数 +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| deviceId | String | 是 | 设备ID | + +#### 响应参数 +| 参数名 | 类型 | 说明 | +|--------|------|------| +| code | Integer | 响应码(200表示成功) | +| msg | String | 响应消息 | + +### 5. 设备状态查询接口(/AutoInventory/status) + +#### 接口说明 +查询RFID设备连接状态 + +#### 请求方式 +GET + +#### 请求参数 +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| deviceId | String | 是 | 设备ID | + +#### 响应参数 +| 参数名 | 类型 | 说明 | +|--------|------|------| +| code | Integer | 响应码(200表示成功) | +| msg | String | 响应消息(包含设备连接状态) | + +### 6. 开始匹配接口(/AutoInventory/match) + +#### 接口说明 +将扫描数据与系统库存数据进行匹配 + +#### 请求方式 +POST + +#### 请求参数 +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| taskId | String | 是 | 盘点任务ID | +| deviceId | String | 是 | 设备ID | +| scanType | Integer | 是 | 扫描类型(0=手动盘点,1=自动盘点) | + +#### 响应参数 +| 参数名 | 类型 | 说明 | +|--------|------|------| +| code | Integer | 响应码(200表示成功) | +| msg | String | 响应消息 | + +### 7. 盘点任务管理接口(/Inventory/task) + +#### 接口说明 +管理盘点任务的增删改查 + +#### 请求方式 +POST/GET/PUT/DELETE + +#### 主要功能 +- 新增盘点任务 +- 查询盘点任务列表 +- 修改盘点任务 +- 删除盘点任务 +- 导出盘点任务 + +## WCS系统开发工作内容 + +### 1. 接口开发工作 + +#### 1.1 入库/上架接口开发 +- **工作内容**:开发 `/API/Ruku` 接口,处理WMS入库任务请求 +- **技术实现**: + - HTTP POST接口开发 + - JSON数据解析 + - 业务参数验证 + - 任务创建与调度 + - 响应格式化 +- **预计工时**:16小时 + +#### 1.2 出库/下架接口开发 +- **工作内容**:开发 `/API/Chuku` 接口,处理WMS出库任务请求 +- **技术实现**: + - HTTP POST接口开发 + - JSON数据解析 + - 业务参数验证 + - 任务创建与调度 + - 响应格式化 +- **预计工时**:16小时 + +#### 1.3 任务状态回调接口开发 +- **工作内容**:实现WCS任务状态回调机制 +- **技术实现**: + - 状态变更触发器 + - HTTP回调请求 + - 状态同步机制 +- **预计工时**:24小时 + +### 2. 业务逻辑开发工作 + +#### 2.1 货物上架逻辑实现 +- **工作内容**:实现完整的货物上架业务流程 +- **技术实现**: + - 库位分配算法 + - 设备控制指令生成 + - 执行状态跟踪 + - 异常处理机制 +- **预计工时**:32小时 + +#### 2.2 货物下架逻辑实现 +- **工作内容**:实现完整的货物下架业务流程 +- **技术实现**: + - 货物定位算法 + - 设备控制指令生成 + - 执行状态跟踪 + - 异常处理机制 +- **预计工时**:32小时 + +#### 2.3 任务调度与排队机制 +- **工作内容**:实现多任务排队调度算法 +- **技术实现**: + - 任务队列管理 + - 优先级调度算法 + - 设备资源分配 + - 任务冲突解决 +- **预计工时**:24小时 + +### 3. 系统集成开发工作 + +#### 3.1 与WMS系统接口对接 +- **工作内容**:确保WCS与WMS系统稳定通信 +- **技术实现**: + - 接口协议实现 + - 数据格式转换 + - 通信安全机制 + - 错误重试机制 +- **预计工时**:20小时 + +#### 3.2 与AGV系统协调机制 +- **工作内容**:实现WCS与AGV系统的任务协调 +- **技术实现**: + - 协调接口开发 + - 状态同步机制 + - 任务交接处理 +- **预计工时**:16小时 + +### 4. 数据管理开发工作 + +#### 4.1 任务数据存储与管理 +- **工作内容**:开发任务数据的存储和管理功能 +- **技术实现**: + - 数据库表设计 + - 数据访问层开发 + - 数据一致性保证 + - 数据清理机制 +- **预计工时**:20小时 + +#### 4.2 库位状态数据维护 +- **工作内容**:实现库位状态的实时维护 +- **技术实现**: + - 库位状态表设计 + - 状态变更处理 + - 数据同步机制 + - 状态查询接口 +- **预计工时**:16小时 + +### 5. 监控与维护开发工作 + +#### 5.1 系统运行状态监控 +- **工作内容**:开发系统运行状态监控功能 +- **技术实现**: + - 监控指标定义 + - 监控接口开发 + - 异常告警机制 +- **预计工时**:12小时 + +#### 5.2 异常处理与恢复机制 +- **工作内容**:开发完善的异常处理和任务恢复机制 +- **技术实现**: + - 异常类型定义 + - 异常处理策略 + - 任务恢复机制 + - 日志记录系统 +- **预计工时**:20小时 + +## Inventory系统开发工作内容 + +### 1. 设备接口开发工作 + +#### 1.1 RFID设备连接接口开发 +- **工作内容**:开发RFID设备连接、断开、状态查询接口 +- **技术实现**: + - TCP连接管理 + - 设备状态跟踪 + - 连接池管理 + - 异常处理机制 +- **预计工时**:24小时 + +#### 1.2 盘点控制接口开发 +- **工作内容**:开发开始盘点、停止盘点等控制接口 +- **技术实现**: + - 设备控制指令发送 + - 扫描状态管理 + - 线程安全控制 +- **预计工时**:16小时 + +### 2. 数据处理开发工作 + +#### 2.1 扫描数据处理开发 +- **工作内容**:处理RFID设备扫描的标签数据 +- **技术实现**: + - 实时数据接收 + - WebSocket通信 + - 数据格式化处理 + - 数据存储 +- **预计工时**:28小时 + +#### 2.2 数据匹配算法开发 +- **工作内容**:开发扫描数据与库存数据的匹配算法 +- **技术实现**: + - 匹配算法设计 + - 数据对比逻辑 + - 状态标识处理 + - 统计计算 +- **预计工时**:32小时 + +### 3. 任务管理开发工作 + +#### 3.1 盘点任务管理开发 +- **工作内容**:开发盘点任务的增删改查功能 +- **技术实现**: + - 任务数据模型设计 + - 任务状态管理 + - 任务分配逻辑 + - 任务进度跟踪 +- **预计工时**:24小时 + +#### 3.2 报告生成开发 +- **工作内容**:开发盘点报告生成和统计功能 +- **技术实现**: + - 数据统计算法 + - 图表生成 + - 报告导出功能 + - 历史数据查询 +- **预计工时**:20小时 + +### 4. 系统集成开发工作 + +#### 4.1 与WMS系统集成 +- **工作内容**:实现Inventory系统与WMS系统的数据同步 +- **技术实现**: + - 库存数据接口 + - 数据同步机制 + - 冲突处理策略 +- **预计工时**:16小时 + +#### 4.2 WebSocket通信开发 +- **工作内容**:实现实时数据传输功能 +- **技术实现**: + - WebSocket服务端开发 + - 设备标识管理 + - 消息推送机制 +- **预计工时**:20小时 + +## 系统对接流程图 + +### WCS系统对接流程 + +```mermaid +graph TD + A[WMS创建任务] --> B{判断任务类型} + B -->|入库/上架| C[WMS调用WCS /API/Ruku接口] + B -->|出库/下架| D[WMS调用WCS /API/Chuku接口] + + C --> E[WCS接收任务请求] + D --> E + + E --> F[WCS验证任务参数] + F --> G{参数验证结果} + G -->|验证失败| H[WCS返回错误信息给WMS] + G -->|验证成功| I[WCS创建内部任务] + + I --> J[WCS控制立体库设备执行任务] + J --> K[设备执行中...] + K --> L{任务执行结果} + L -->|执行成功| M[WCS更新任务状态] + L -->|执行失败| N[WCS记录异常并重试] + + M --> O[WCS回调WMS状态更新] + N --> P{重试次数达到上限} + P -->|是| Q[WCS回调WMS失败状态] + P -->|否| J + + O --> R[WMS接收状态更新] + Q --> R + H --> R + + R --> S{是否需要AGV配合} + S -->|是| T[WMS调度AGV] + S -->|否| U[任务完成] + T --> U +``` + +### Inventory系统工作流程 + +```mermaid +graph TD + A[创建盘点任务] --> B[选择盘点方式] + B -->|自动盘点| C[连接RFID设备] + B -->|手持盘点| D[手动扫描] + + C --> E[开始标签扫描] + E --> F[实时接收EPC数据] + F --> G[WebSocket推送数据到前端] + D --> G + + G --> H[停止扫描] + H --> I[数据匹配处理] + I --> J[生成匹配结果] + J --> K[统计分析] + K --> L[生成盘点报告] + L --> M[任务完成] +``` + +## 项目实施计划 + +### 第一阶段:接口开发(预计3周) +- 完成WCS入库/上架接口开发 +- 完成WCS出库/下架接口开发 +- 完成Inventory设备管理接口开发 +- 完成基础数据模型设计 + +### 第二阶段:业务逻辑开发(预计4周) +- 完成WCS货物上架逻辑开发 +- 完成WCS货物下架逻辑开发 +- 完成WCS任务调度机制开发 +- 完成Inventory数据处理逻辑开发 +- 完成盘点匹配算法开发 + +### 第三阶段:系统集成(预计3周) +- 完成WCS与WMS系统对接 +- 完成WCS与AGV系统协调 +- 完成Inventory与WMS系统集成 +- 完成WebSocket通信功能 +- 完成监控功能开发 + +### 第四阶段:测试与优化(预计2周) +- 系统集成测试 +- 性能优化 +- 异常处理完善 +- 用户验收测试 + +## 项目交付物 + +1. **技术文档** + - WCS系统接口规范文档 + - Inventory系统接口规范文档 + - 部署手册 + - 运维手册 + - 用户操作手册 + +2. **软件系统** + - WCS系统核心程序 + - Inventory系统核心程序 + - 数据库脚本 + - 配置文件 + +3. **测试报告** + - 单元测试报告 + - 集成测试报告 + - 性能测试报告 + - 用户验收测试报告 + +## 项目价值体现 + +### 1. 技术价值 +- 提供标准化接口,实现多系统间无缝对接 +- 实现复杂的任务调度算法 +- 确保系统高可用性和稳定性 +- 实现自动化的盘点功能 + +### 2. 业务价值 +- 实现仓库作业自动化 +- 提高仓储效率和准确性 +- 降低人工成本 +- 实现库存精确管理 + +### 3. 服务价值 +- 专业的技术开发服务 +- 完善的系统集成方案 +- 持续的技术支持服务 +- 完整的仓储解决方案 + +## 风险与应对 + +### 1. 技术风险 +- **风险**:接口兼容性问题 +- **应对**:提前进行接口规范确认 + +### 2. 集成风险 +- **风险**:多系统集成复杂度高 +- **应对**:分阶段集成测试 + +### 3. 性能风险 +- **风险**:高并发场景下系统性能 +- **应对**:性能测试与优化 + +### 4. 设备风险 +- **风险**:RFID设备连接稳定性 +- **应对**:设备连接监控和异常处理 + +## 服务收费标准 + +### WCS系统开发服务 + +#### 1. 接口开发服务(40小时) +- 入库/上架接口:16小时 +- 出库/下架接口:16小时 +- 任务状态回调接口:8小时 + +#### 2. 业务逻辑开发(88小时) +- 货物上架逻辑:32小时 +- 货物下架逻辑:32小时 +- 任务调度机制:24小时 + +#### 3. 系统集成服务(36小时) +- 与WMS系统对接:20小时 +- 与AGV系统协调:16小时 + +#### 4. 数据管理开发(36小时) +- 任务数据管理:20小时 +- 库位状态维护:16小时 + +#### 5. 监控维护开发(32小时) +- 系统监控:12小时 +- 异常处理机制:20小时 + +### Inventory系统开发服务 + +#### 1. 设备接口开发(40小时) +- RFID设备连接接口:24小时 +- 盘点控制接口:16小时 + +#### 2. 数据处理开发(60小时) +- 扫描数据处理:28小时 +- 数据匹配算法:32小时 + +#### 3. 任务管理开发(44小时) +- 盘点任务管理:24小时 +- 报告生成:20小时 + +#### 4. 系统集成开发(36小时) +- 与WMS系统集成:16小时 +- WebSocket通信:20小时 + +**总计开发工时:392小时** \ No newline at end of file diff --git a/智慧实物管理系统安全功能审查报告.md b/智慧实物管理系统安全功能审查报告.md new file mode 100644 index 0000000..b192ea2 --- /dev/null +++ b/智慧实物管理系统安全功能审查报告.md @@ -0,0 +1,79 @@ +# 智慧实物管理系统安全功能审查报告 + +## 1. 身份鉴别功能 (Authentication) + +### 审查结果: +✓ **已实现** - 系统具备完善的身份鉴别功能 + +### 详细说明: +- **JWT Token机制**:使用JWT令牌进行身份验证,支持令牌自动刷新 +- **登录验证**:通过`SysLoginService`实现用户登录验证,包含用户名密码校验、验证码校验 +- **密码安全**:使用`BCryptPasswordEncoder`对密码进行加密存储 +- **登录限制**:支持登录IP黑名单、错误次数限制(默认5次)和账户锁定功能(默认10分钟) +- **登录日志**:记录登录IP、时间、地点、浏览器等信息到`sys_logininfor`表 +- **多因子验证**:支持验证码验证,支持数学计算和字符验证两种类型 + +## 2. 安全标记功能 (Security Labeling) + +### 审查结果: +✓ **已实现** - 系统具备安全标记功能 + +### 详细说明: +- **角色权限标记**:通过`sys_role`表定义角色,每个角色分配特定权限 +- **用户角色映射**:通过`sys_user_role`表建立用户与角色的关联关系 +- **菜单权限标记**:通过`sys_role_menu`表为角色分配菜单权限 +- **数据权限标记**:通过数据范围控制(data_scope)实现数据级别的安全标记 +- **操作权限标记**:通过`@PreAuthorize("@ss.hasPermi('module:action:operation')")`注解标记接口权限 + +## 3. 应用权限控制功能 (Access Control) + +### 审查结果: +✓ **已实现** - 系统具备完善的权限控制功能 + +### 详细说明: +- **细粒度权限控制**:使用`@PreAuthorize`注解实现方法级别的权限控制 +- **权限表达式**: + - `@ss.hasPermi('module:action:operation')` - 检查特定权限 + - `@ss.hasRole('roleName')` - 检查角色权限 +- **前端权限控制**:使用`v-hasPermi`指令实现前端按钮级权限控制 +- **菜单权限控制**:根据用户权限动态显示菜单 +- **数据权限控制**:支持部门数据权限过滤 +- **权限继承机制**:角色权限通过菜单权限体系继承 +- **权限缓存**:用户权限信息存储在Redis中,支持动态刷新 + +## 4. 安全审计功能 (Security Audit) + +### 审查结果: +✓ **已实现** - 系统具备全面的安全审计功能 + +### 详细说明: +- **操作日志审计**:使用`@Log`注解记录用户操作日志 +- **日志存储**: + - 操作日志存储在`sys_oper_log`表 + - 登录日志存储在`sys_logininfor`表 + - 任务日志存储在`sys_job_log`表 +- **审计内容**: + - 操作用户、操作时间、操作IP、操作地点 + - 请求方法、请求参数、返回结果 + - 操作状态(成功/失败)、错误信息 + - 执行耗时等详细信息 +- **日志分类**:支持不同级别的日志记录(info, error, user等) +- **日志管理**:提供日志查询、删除、导出等管理功能 +- **异步记录**:使用异步机制记录日志,避免影响主业务流程 + +## 总体评估 + +### 优点: +1. **安全架构完整**:身份鉴别、权限控制、安全审计三大功能模块齐全 +2. **技术实现成熟**:基于Spring Security框架,使用JWT令牌机制 +3. **权限控制细粒度**:支持角色、菜单、数据等多个层面的权限控制 +4. **审计功能全面**:涵盖登录、操作、任务等多维度审计 +5. **代码规范性好**:使用注解方式实现安全控制,代码简洁清晰 + +### 建议改进: +1. **加强密码策略**:可增加更复杂的密码强度要求 +2. **安全配置优化**:建议对敏感配置项进行加密存储 +3. **日志分析**:可考虑增加安全日志的智能分析功能 + +### 结论: +该系统完全具备身份鉴别、安全标记、应用权限控制和安全审计四大安全功能,符合企业级应用的安全要求。系统基于成熟的RuoYi框架开发,在安全功能方面做了充分的实现和优化。 \ No newline at end of file diff --git a/盘点系统业务对接文档.md b/盘点系统业务对接文档.md new file mode 100644 index 0000000..8eb0c88 --- /dev/null +++ b/盘点系统业务对接文档.md @@ -0,0 +1,355 @@ +# 盘点系统业务对接文档 + +## 项目概述 + +### 项目背景 +盘点系统是用于实现仓库库存自动盘点的系统,通过RFID设备自动采集货品信息,并与系统库存数据进行比对,以实现库存的精确管理。 + +### 项目目标 +- 实现盘点任务的创建和管理 +- 通过RFID设备自动采集货品标签信息 +- 与系统库存数据进行比对分析 +- 生成盘点结果报告 + +## 盘点系统业务流程 + +### 1. 任务创建阶段 +- **业务内容**:在系统中创建盘点任务,指定盘点范围(仓库、区域、货品类别等) +- **数据准备**:系统获取当前库存数据作为基准数据 +- **任务分配**:将盘点任务分配给指定的RFID设备 + +### 2. 设备执行阶段 +- **设备连接**:RFID设备连接到系统 +- **任务下发**:系统将盘点任务下发到RFID设备 +- **标签采集**:RFID设备在指定区域扫描,采集货品标签信息 +- **数据传输**:将采集到的标签数据实时传输回系统 + +### 3. 结果采集阶段 +- **数据收集**:系统收集从RFID设备传回的标签数据 +- **数据验证**:验证数据完整性和准确性 +- **暂存处理**:将采集到的数据暂存到临时表 + +### 4. 结果匹配阶段 +- **数据比对**:将采集到的标签数据与系统库存数据进行比对 +- **状态标识**: + - 正常:系统中有记录,且实物存在(标签被扫描到) + - 盘亏:系统中有记录,但实物不存在(标签未被扫描到) + - 盘盈:系统中无记录,但实物存在(标签被扫描到但无对应库存) +- **差异分析**:统计盘点差异情况 + +### 5. 结果输出阶段 +- **报告生成**:生成盘点结果报告,包括正常、盘亏、盘盈等统计 +- **结果展示**:通过图表和列表展示盘点结果 +- **异常处理**:对盘点异常情况进行标注和处理 +- **任务完成**:标记盘点任务为完成状态 + +## 合作方需要提供的信息 + +### 1. RFID设备技术信息 +- 设备型号和规格 +- 网络连接方式(IP地址、端口) +- 通信协议类型 +- 设备API接口文档 +- 设备认证和安全机制 + +### 2. 设备集成接口 +- 设备连接接口(TCP/UDP/HTTP等) +- 标签数据获取接口 +- 设备状态查询接口 +- 设备控制接口(开始/停止扫描等) + +### 3. 数据格式规范 +- 标签数据格式 +- 数据传输格式(JSON/XML等) +- 字符编码方式 +- 数据字段定义 + +## 我方执行流程 + +### 1. 接口对接阶段 +- **技术对接**:根据合作方提供的API文档,开发与RFID设备的接口 +- **连接测试**:测试设备连接功能,确保能够正常建立连接 +- **数据传输测试**:测试标签数据的获取和传输功能 + +### 2. 任务管理实现 +- **任务创建**:开发盘点任务管理模块,支持任务的创建、分配、状态管理 +- **设备绑定**:实现盘点任务与RFID设备的绑定关系 +- **权限控制**:确保任务的安全性和完整性 + +### 3. 数据处理实现 +- **实时接收**:实现标签数据的实时接收和处理机制 +- **WebSocket通信**:通过WebSocket将采集到的标签数据实时推送到前端 +- **数据存储**:将采集到的数据存储到系统中 + +### 4. 匹配算法实现 +- **数据比对**:开发扫描数据与库存数据的匹配算法 +- **差异计算**:计算盘点差异,标识盘盈、盘亏、正常等状态 +- **统计分析**:生成盘点统计报告和图表 + +### 5. 结果展示实现 +- **结果展示**:开发盘点结果的展示界面 +- **报表生成**:实现盘点报告的生成和导出功能 +- **异常处理**:处理盘点过程中的异常情况 + +## 对外接口规范 + +### 1. 设备连接接口(/AutoInventory/connect) + +#### 接口说明 +建立RFID设备连接 + +#### 请求方式 +POST + +#### 请求参数 +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| deviceId | String | 是 | 设备ID | +| ip | String | 是 | 设备IP地址 | +| port | Integer | 是 | 设备端口号 | + +#### 响应参数 +| 参数名 | 类型 | 说明 | +|--------|------|------| +| code | Integer | 响应码(200表示成功) | +| msg | String | 响应消息 | + +### 2. 开始盘点接口(/AutoInventory/scan) + +#### 接口说明 +启动RFID设备进行标签扫描 + +#### 请求方式 +GET + +#### 请求参数 +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| deviceId | String | 是 | 设备ID | + +#### 响应参数 +| 参数名 | 类型 | 说明 | +|--------|------|------| +| code | Integer | 响应码(200表示成功) | +| msg | String | 响应消息 | + +### 3. 停止盘点接口(/AutoInventory/stop) + +#### 接口说明 +停止RFID设备扫描 + +#### 请求方式 +GET + +#### 请求参数 +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| deviceId | String | 是 | 设备ID | + +#### 响应参数 +| 参数名 | 类型 | 说明 | +|--------|------|------| +| code | Integer | 响应码(200表示成功) | +| msg | String | 响应消息 | + +### 4. 断开连接接口(/AutoInventory/disconnect) + +#### 接口说明 +断开RFID设备连接 + +#### 请求方式 +GET + +#### 请求参数 +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| deviceId | String | 是 | 设备ID | + +#### 响应参数 +| 参数名 | 类型 | 说明 | +|--------|------|------| +| code | Integer | 响应码(200表示成功) | +| msg | String | 响应消息 | + +### 5. 设备状态查询接口(/AutoInventory/status) + +#### 接口说明 +查询RFID设备连接状态 + +#### 请求方式 +GET + +#### 请求参数 +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| deviceId | String | 是 | 设备ID | + +#### 响应参数 +| 参数名 | 类型 | 说明 | +|--------|------|------| +| code | Integer | 响应码(200表示成功) | +| msg | String | 响应消息(包含设备连接状态) | + +### 6. 开始匹配接口(/AutoInventory/match) + +#### 接口说明 +将扫描数据与系统库存数据进行匹配 + +#### 请求方式 +POST + +#### 请求参数 +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| taskId | String | 是 | 盘点任务ID | +| deviceId | String | 是 | 设备ID | +| scanType | Integer | 是 | 扫描类型(0=手动盘点,1=自动盘点) | + +#### 响应参数 +| 参数名 | 类型 | 说明 | +|--------|------|------| +| code | Integer | 响应码(200表示成功) | +| msg | String | 响应消息 | + +### 7. 盘点任务管理接口(/Inventory/task) + +#### 接口说明 +管理盘点任务的增删改查 + +#### 请求方式 +POST/GET/PUT/DELETE + +#### 主要功能 +- 新增盘点任务 +- 查询盘点任务列表 +- 修改盘点任务 +- 删除盘点任务 +- 导出盘点任务 + +## 系统工作流程 + +```mermaid +graph TD + A[创建盘点任务] --> B[RFID设备连接] + B --> C[下发盘点任务到设备] + C --> D[设备开始标签扫描] + D --> E[实时收集标签数据] + E --> F{是否完成扫描?} + F -->|是| G[停止扫描] + F -->|否| D + G --> H[数据比对分析] + H --> I[生成盘点结果] + I --> J[输出盘点报告] + J --> K[任务完成] +``` + +## 系统开发工作内容 + +### 1. 设备接口开发工作 + +#### 1.1 RFID设备连接接口开发 +- **工作内容**:开发RFID设备连接、断开、状态查询接口 +- **技术实现**: + - TCP连接管理 + - 设备状态跟踪 + - 连接池管理 + - 异常处理机制 +- **预计工时**:24小时 + +#### 1.2 盘点控制接口开发 +- **工作内容**:开发开始盘点、停止盘点等控制接口 +- **技术实现**: + - 设备控制指令发送 + - 扫描状态管理 + - 线程安全控制 +- **预计工时**:16小时 + +### 2. 数据处理开发工作 + +#### 2.1 扫描数据处理开发 +- **工作内容**:处理RFID设备扫描的标签数据 +- **技术实现**: + - 实时数据接收 + - WebSocket通信 + - 数据格式化处理 + - 数据存储 +- **预计工时**:28小时 + +#### 2.2 数据匹配算法开发 +- **工作内容**:开发扫描数据与库存数据的匹配算法 +- **技术实现**: + - 匹配算法设计 + - 数据对比逻辑 + - 状态标识处理 + - 统计计算 +- **预计工时**:32小时 + +### 3. 任务管理开发工作 + +#### 3.1 盘点任务管理开发 +- **工作内容**:开发盘点任务的增删改查功能 +- **技术实现**: + - 任务数据模型设计 + - 任务状态管理 + - 任务分配逻辑 + - 任务进度跟踪 +- **预计工时**:24小时 + +#### 3.2 报告生成开发 +- **工作内容**:开发盘点报告生成和统计功能 +- **技术实现**: + - 数据统计算法 + - 图表生成 + - 报告导出功能 + - 历史数据查询 +- **预计工时**:20小时 + +### 4. 系统集成开发工作 + +#### 4.1 WebSocket通信开发 +- **工作内容**:实现实时数据传输功能 +- **技术实现**: + - WebSocket服务端开发 + - 设备标识管理 + - 消息推送机制 +- **预计工时**:20小时 + +## 项目交付物 + +1. **技术文档** + - 盘点系统接口规范文档 + - 部署手册 + - 运维手册 + - 用户操作手册 + +2. **软件系统** + - 盘点系统核心程序 + - 数据库脚本 + - 配置文件 + +3. **测试报告** + - 单元测试报告 + - 集成测试报告 + - 性能测试报告 + - 用户验收测试报告 + +## 服务收费标准 + +### 盘点系统开发服务 + +#### 1. 设备接口开发(40小时) +- RFID设备连接接口:24小时 +- 盘点控制接口:16小时 + +#### 2. 数据处理开发(60小时) +- 扫描数据处理:28小时 +- 数据匹配算法:32小时 + +#### 3. 任务管理开发(44小时) +- 盘点任务管理:24小时 +- 报告生成:20小时 + +#### 4. 系统集成开发(20小时) +- WebSocket通信:20小时 + +**总计开发工时:164小时** \ No newline at end of file diff --git a/调度系统与盘点系统业务对接文档.md b/调度系统与盘点系统业务对接文档.md new file mode 100644 index 0000000..c27a3eb --- /dev/null +++ b/调度系统与盘点系统业务对接文档.md @@ -0,0 +1,318 @@ +# 调度系统与盘点系统业务对接文档 + +## 调度系统业务描述 + +### 项目背景 +调度系统是用于实现仓库自动化作业的核心系统,通过与WCS(仓库控制系统)和AGV(自动导引车)系统的协作,实现货物的自动化入库、出库、移库等操作。 + +### 项目目标 +- 实现与WCS系统的无缝对接 +- 实现与AGV系统的协调作业 +- 提供标准化接口,确保系统间稳定运行 +- 实现出入库、移库等核心业务流程 + +### 核心功能 + +#### 1. 入库/上架功能 +- 接收WMS系统的入库任务 +- 控制立体库设备执行上架操作 +- 实时反馈任务执行状态给WMS系统 + +#### 2. 出库/下架功能 +- 接收WMS系统的出库任务 +- 控制立体库设备执行下架操作 +- 实时反馈任务执行状态给WMS系统 + +#### 3. 任务调度功能 +- 任务队列管理 +- 任务优先级调度 +- 设备资源分配 + +### 接口列表 +- 入库接口(/API/Ruku) +- 出库接口(/API/Chuku) +- 任务状态回调接口 + +### 调度系统开发工作内容 + +#### 1. 接口开发工作 +- **入库/上架接口开发**:实现与WCS系统的入库任务下发,预计16小时 +- **出库/下架接口开发**:实现与WCS系统的出库任务下发,预计16小时 +- **任务状态回调接口开发**:实现任务状态反馈机制,预计24小时 + +#### 2. 业务逻辑开发工作 +- **货物上架逻辑实现**:实现完整的货物上架业务流程,预计32小时 +- **货物下架逻辑实现**:实现完整的货物下架业务流程,预计32小时 +- **任务调度与排队机制**:实现多任务排队调度算法,预计24小时 + +#### 3. 系统集成开发工作 +- **与WMS系统接口对接**:确保调度系统与WMS系统稳定通信,预计20小时 +- **与AGV系统协调机制**:实现调度系统与AGV系统的任务协调,预计16小时 + +--- + +## 盘点系统业务描述 + +### 项目背景 +盘点系统是用于实现仓库库存自动盘点的系统,通过RFID设备自动采集货品信息,并与系统库存数据进行比对,以实现库存的精确管理。 + +### 项目目标 +- 实现盘点任务的创建和管理 +- 通过RFID设备自动采集货品标签信息 +- 与系统库存数据进行比对分析 +- 生成盘点结果报告 + +### 核心功能 + +#### 1. 盘点任务管理 +- 创建盘点任务(设置任务名称、仓库ID、场景ID、执行人、完成时间等) +- 任务类型:手持盘点(0)和自动盘点(1) +- 任务状态:待执行(0)、已完成(1)、已超时(2) + +#### 2. 自动盘点功能 +- 设备连接管理:通过RFID设备IP和端口建立TCP连接 +- 标签扫描:启动RFID设备进行标签扫描 +- 数据传输:通过WebSocket将扫描到的EPC标签数据发送给前端 +- 扫描控制:支持开始、停止、断开连接等操作 + +#### 3. 数据匹配功能 +- 将扫描数据与系统库存数据进行匹配 +- 生成匹配结果(正常、未扫到、误扫) +- 统计盘点结果并生成图表 + +#### 4. 报告管理功能 +- 生成盘点统计图表 +- 导出盘点报告 +- 提供历史盘点记录查询 + +### 盘点任务创建详细流程 + +#### 1. 任务规划阶段 +- 确定盘点范围(指定仓库、库区、货位等) +- 确定盘点类型(全盘、抽盘、专项盘点等) +- 确定盘点时间安排 +- 分配盘点人员 + +#### 2. 基础数据准备 +- 获取指定范围内的库存数据作为基准 +- 验证库存数据完整性 +- 生成任务清单 + +#### 3. 任务创建阶段 +- 在系统中创建盘点任务记录 +- 设置任务基本信息(名称、仓库、时间等) +- 绑定盘点设备(如适用) +- 分配执行人员 + +#### 4. 任务下发阶段 +- 将任务信息同步到相关设备或人员 +- 准备盘点所需的辅助数据 +- 启动任务状态监控 + +### 接口列表 +- 设备连接接口(/AutoInventory/connect) +- 开始盘点接口(/AutoInventory/scan) +- 停止盘点接口(/AutoInventory/stop) +- 断开连接接口(/AutoInventory/disconnect) +- 设备状态查询接口(/AutoInventory/status) +- 开始匹配接口(/AutoInventory/match) +- 盘点任务管理接口(/Inventory/task) + +### 盘点系统开发工作内容 + +#### 1. 设备接口开发工作 +- **RFID设备连接接口开发**:开发RFID设备连接、断开、状态查询接口,预计24小时 +- **盘点控制接口开发**:开发开始盘点、停止盘点等控制接口,预计16小时 + +#### 2. 数据处理开发工作 +- **扫描数据处理开发**:处理RFID设备扫描的标签数据,预计28小时 +- **数据匹配算法开发**:开发扫描数据与库存数据的匹配算法,预计32小时 + +#### 3. 任务管理开发工作 +- **盘点任务管理开发**:开发盘点任务的增删改查功能,预计24小时 +- **报告生成开发**:开发盘点报告生成和统计功能,预计20小时 + +#### 4. 系统集成开发工作 +- **WebSocket通信开发**:实现实时数据传输功能,预计20小时 + +--- + +## 系统与设备对接流程 + +### 调度系统设备对接流程 + +#### 1. 我方提供服务 +- **任务调度服务**:根据业务需求生成调度任务 +- **接口服务**:提供标准化的HTTP接口,供WCS和AGV系统调用 +- **状态监控服务**:实时监控任务执行状态 +- **协调控制服务**:协调WCS和AGV系统的任务执行顺序 + +#### 2. WCS系统对接要求 +- **接口调用**:WCS系统需支持我方提供的入库/出库接口调用 +- **数据格式**:WCS系统需按照我方定义的数据格式进行数据交互 +- **状态反馈**:WCS系统需通过回调接口实时反馈任务执行状态 +- **异常处理**:WCS系统需支持异常情况的处理和重试机制 + +#### 3. AGV系统对接要求 +- **接口调用**:AGV系统需支持我方提供的搬运任务接口调用 +- **数据格式**:AGV系统需按照我方定义的数据格式进行数据交互 +- **状态反馈**:AGV系统需实时反馈任务执行状态 +- **任务协调**:AGV系统需与WCS系统任务进行协调执行 + +#### 4. 对接执行流程 +- **任务生成**:WMS系统创建任务后,通过接口下发到调度系统 +- **任务分发**:调度系统根据任务类型,将任务分发给WCS或AGV系统 +- **执行监控**:实时监控WCS和AGV系统的任务执行状态 +- **状态同步**:WCS和AGV系统通过回调接口同步任务执行状态 +- **完成确认**:任务完成后,调度系统更新任务状态并通知WMS系统 + +#### 5. 执行流程 +```mermaid +graph TD + A[WMS创建任务] --> B{判断任务类型} + B -->|入库/上架| C[WMS调用WCS /API/Ruku接口] + B -->|出库/下架| D[WMS调用WCS /API/Chuku接口] + + C --> E[WCS接收任务请求] + D --> E + + E --> F[WCS验证任务参数] + F --> G{参数验证结果} + G -->|验证失败| H[WCS返回错误信息给WMS] + G -->|验证成功| I[WCS创建内部任务] + + I --> J[WCS控制立体库设备执行任务] + J --> K[设备执行中...] + K --> L{任务执行结果} + L -->|执行成功| M[WCS更新任务状态] + L -->|执行失败| N[WCS记录异常并重试] + + M --> O[WCS回调WMS状态更新] + N --> P{重试次数达到上限} + P -->|是| Q[WCS回调WMS失败状态] + P -->|否| J + + O --> R[WMS接收状态更新] + Q --> R + H --> R + + R --> S{是否需要AGV配合} + S -->|是| T[WMS调度AGV] + S -->|否| U[任务完成] + T --> U +``` + +### 盘点系统设备对接流程 + +#### 1. 我方提供服务 +- **设备管理服务**:提供设备连接、状态监控、任务下发等服务 +- **数据处理服务**:实时接收设备数据,进行格式转换和处理 +- **WebSocket通信服务**:提供实时数据传输通道 +- **数据匹配服务**:将采集数据与库存数据进行比对分析 + +#### 2. 第三方设备对接要求 +- **网络连接**:设备需支持TCP/IP协议,能够与我方系统建立稳定连接 +- **数据格式**:设备需按照我方定义的数据格式传输标签信息 +- **接口调用**:设备需支持我方提供的控制接口(开始/停止扫描等) +- **心跳机制**:设备需定期向我方系统发送心跳包,确保连接状态 + +#### 3. 对接执行流程 +- **连接建立**:设备通过TCP/IP连接到我方系统,建立通信链路 +- **设备注册**:设备向我方系统注册,获取设备ID和认证信息 +- **任务获取**:设备从我方系统获取当前盘点任务信息 +- **数据采集**:设备开始扫描,将采集到的标签数据实时传输给我方系统 +- **状态同步**:设备定期向我方系统同步工作状态 +- **任务完成**:设备完成任务后,向我方系统报告完成状态 + +#### 4. 执行流程 +```mermaid +graph TD + A[创建盘点任务] --> B[RFID设备连接] + B --> C[下发盘点任务到设备] + C --> D[设备开始标签扫描] + D --> E[实时收集标签数据] + E --> F{是否完成扫描?} + F -->|是| G[停止扫描] + F -->|否| D + G --> H[数据比对分析] + H --> I[生成盘点结果] + I --> J[输出盘点报告] + J --> K[任务完成] +``` + +## 项目交付物 + +### 调度系统 +1. **技术文档** + - 调度系统接口规范文档 + - 部署手册 + - 运维手册 + - 用户操作手册 + +2. **软件系统** + - 调度系统核心程序 + - 数据库脚本 + - 配置文件 + +3. **测试报告** + - 单元测试报告 + - 集成测试报告 + - 性能测试报告 + - 用户验收测试报告 + +### 盘点系统 +1. **技术文档** + - 盘点系统接口规范文档 + - 部署手册 + - 运维手册 + - 用户操作手册 + +2. **软件系统** + - 盘点系统核心程序 + - 数据库脚本 + - 配置文件 + +3. **测试报告** + - 单元测试报告 + - 集成测试报告 + - 性能测试报告 + - 用户验收测试报告 + +## 服务收费标准 + +### 调度系统开发服务 + +#### 1. 接口开发服务(56小时) +- 入库/上架接口:16小时 +- 出库/下架接口:16小时 +- 任务状态回调接口:24小时 + +#### 2. 业务逻辑开发(88小时) +- 货物上架逻辑:32小时 +- 货物下架逻辑:32小时 +- 任务调度机制:24小时 + +#### 3. 系统集成服务(36小时) +- 与WMS系统对接:20小时 +- 与AGV系统协调:16小时 + +### 盘点系统开发服务 + +#### 1. 设备接口开发(40小时) +- RFID设备连接接口:24小时 +- 盘点控制接口:16小时 + +#### 2. 数据处理开发(60小时) +- 扫描数据处理:28小时 +- 数据匹配算法:32小时 + +#### 3. 任务管理开发(44小时) +- 盘点任务管理:24小时 +- 报告生成:20小时 + +#### 4. 系统集成开发(20小时) +- WebSocket通信:20小时 + +**调度系统总计:180小时** +**盘点系统总计:164小时** +**项目总计:344小时** \ No newline at end of file diff --git a/调度系统与盘点系统开发文档.md b/调度系统与盘点系统开发文档.md new file mode 100644 index 0000000..afba413 --- /dev/null +++ b/调度系统与盘点系统开发文档.md @@ -0,0 +1,362 @@ +# 调度系统与盘点系统开发文档 + +## 1. 项目概述 + +### 1.1 项目背景 +调度系统是用于实现仓库自动化作业的核心系统,通过与WCS(仓库控制系统)和AGV(自动导引车)系统的协作,实现货物的自动化入库、出库、移库等操作。 + +盘点系统是用于实现仓库库存自动盘点的系统,通过RFID设备自动采集货品信息,并与系统库存数据进行比对,以实现库存的精确管理。 + +### 1.2 项目目标 +- 实现调度系统与WCS、AGV系统间的无缝对接 +- 实现盘点系统与RFID设备的高效协作 +- 提供标准化接口,确保各系统间稳定运行 +- 实现出入库、盘点等核心业务流程 + +## 2. 调度系统 + +### 2.1 系统架构 +调度系统作为中间层,负责协调WMS、WCS、AGV三个系统间的任务流转和状态同步。 + +### 2.2 业务流程描述 + +#### 2.2.1 入库/上架流程 +1. **任务创建**:WMS系统创建入库任务 +2. **任务分发**:调度系统将任务分发给WCS系统 +3. **设备执行**:WCS系统控制立体库设备执行上架操作 +4. **状态反馈**:WCS系统实时反馈任务执行状态 +5. **完成确认**:任务完成后更新状态 + +#### 2.2.2 出库/下架流程 +1. **任务创建**:WMS系统创建出库任务 +2. **任务分发**:调度系统将任务分发给WCS系统 +3. **设备执行**:WCS系统控制立体库设备执行下架操作 +4. **AGV配合**:根据需要调度AGV进行货物搬运 +5. **状态反馈**:WCS/AGV系统实时反馈任务执行状态 +6. **完成确认**:任务完成后更新状态 + +#### 2.2.3 移库流程 +1. **任务创建**:WMS系统创建移库任务 +2. **AGV调度**:调度系统先调度AGV搬运货物 +3. **WCS配合**:根据需要调度WCS进行货物存放 +4. **状态监控**:实时监控任务执行状态 +5. **完成确认**:任务完成后更新状态 + +### 2.3 核心功能 + +#### 2.3.1 入库/上架功能 +- 接收WMS系统的入库任务 +- 控制立体库设备执行上架操作 +- 实时反馈任务执行状态给WMS系统 + +#### 2.3.2 出库/下架功能 +- 接收WMS系统的出库任务 +- 控制立体库设备执行下架操作 +- 实时反馈任务执行状态给WMS系统 + +#### 2.3.3 任务调度功能 +- 任务队列管理 +- 任务优先级调度 +- 设备资源分配 + +### 2.4 业务流程图 + +```mermaid +graph TD + A[WMS创建任务] --> B{判断任务类型} + B -->|入库/上架| C[WMS调用WCS /API/Ruku接口] + B -->|出库/下架| D[WMS调用WCS /API/Chuku接口] + + C --> E[WCS接收任务请求] + D --> E + + E --> F[WCS验证任务参数] + F --> G{参数验证结果} + G -->|验证失败| H[WCS返回错误信息给WMS] + G -->|验证成功| I[WCS创建内部任务] + + I --> J[WCS控制立体库设备执行任务] + J --> K[设备执行中...] + K --> L{任务执行结果} + L -->|执行成功| M[WCS更新任务状态] + L -->|执行失败| N[WCS记录异常并重试] + + M --> O[WCS回调WMS状态更新] + N --> P{重试次数达到上限} + P -->|是| Q[WCS回调WMS失败状态] + P -->|否| J + + O --> R[WMS接收状态更新] + Q --> R + H --> R + + R --> S{是否需要AGV配合} + S -->|是| T[WMS调度AGV] + S -->|否| U[任务完成] + T --> U +``` + +### 2.5 接口规范 + +#### 2.5.1 入库接口(/API/Ruku) +- **功能说明**:WMS系统调用此接口创建入库/上架任务 +- **请求方式**:POST +- **我方服务地址**:http://[IP_ADDR]:[PORT]/API/Ruku +- **第三方调用**:WCS系统需实现此接口并接受调用 + +#### 2.5.2 出库接口(/API/Chuku) +- **功能说明**:WMS系统调用此接口创建出库/下架任务 +- **请求方式**:POST +- **我方服务地址**:http://[IP_ADDR]:[PORT]/API/Chuku +- **第三方调用**:WCS系统需实现此接口并接受调用 + +#### 2.5.3 任务状态回调接口 +- **功能说明**:WCS/AGV系统回调任务执行状态 +- **请求方式**:POST +- **我方服务地址**:http://[IP_ADDR]:[PORT]/wisdom/wcs/callback +- **第三方调用**:WCS/AGV系统需调用此接口反馈状态 + +### 2.6 对接流程 + +#### 2.6.1 WCS系统对接流程 +1. **接口实现**:WCS系统需实现入库/出库接口 +2. **数据格式**:按约定格式接收任务数据 +3. **状态反馈**:通过回调接口实时反馈任务状态 +4. **异常处理**:处理任务执行中的异常情况 + +#### 2.6.2 AGV系统对接流程 +1. **接口实现**:AGV系统需实现搬运任务接口 +2. **数据格式**:按约定格式接收任务数据 +3. **状态反馈**:实时反馈任务执行状态 +4. **任务协调**:与WCS系统任务进行协调执行 + +### 2.7 配置信息 + +#### 2.7.1 WCS系统配置 +```yaml +wcs: + job: + create-url: http://[WCS_IP_ADDR]:[WCS_PORT]/API/Ruku # WCS上架任务接口 + chuku-url: http://[WCS_IP_ADDR]:[WCS_PORT]/API/Chuku # WCS出库任务接口 +``` + +#### 2.7.2 AGV系统配置 +```yaml +agv: + job: + create-url: http://[AGV_IP_ADDR]:[AGV_PORT]/api/job/create +``` + +## 3. 盘点系统 + +### 3.1 系统架构 +盘点系统通过RFID设备采集数据,与库存数据进行比对,生成盘点报告。 + +### 3.2 业务流程描述 + +#### 3.2.1 盘点任务创建流程 +1. **任务规划阶段**: + - 确定盘点范围(指定仓库、库区、货位等) + - 确定盘点类型 + - 确定盘点时间安排 + - 分配盘点人员 + +2. **基础数据准备**: + - 获取指定范围内的库存数据作为基准 + - 验证库存数据完整性 + - 生成任务清单 + +3. **任务创建阶段**: + - 在系统中创建盘点任务记录 + - 设置任务基本信息(名称、仓库、时间等) + - 绑定盘点设备 + - 分配执行人员 + +4. **任务下发阶段**: + - 将任务信息同步到相关设备或人员 + - 准备盘点所需的辅助数据 + - 启动任务状态监控 + +#### 3.2.2 盘点执行流程 +1. **设备连接**:RFID设备连接到系统 +2. **任务获取**:设备获取盘点任务信息 +3. **标签扫描**:RFID设备在指定区域扫描标签 +4. **数据传输**:将扫描数据实时传输回系统 +5. **状态监控**:监控设备工作状态和任务进度 + +#### 3.2.3 数据处理流程 +1. **数据收集**:收集从RFID设备传回的标签数据 +2. **数据验证**:验证数据完整性和准确性 +3. **数据比对**:将采集数据与库存数据进行比对 +4. **差异分析**:分析盘点差异 +5. **结果生成**:生成盘点结果报告 + +### 3.3 核心功能 + +#### 3.3.1 盘点任务管理 +- 创建盘点任务(设置任务名称、仓库ID、场景ID、执行人、完成时间等) +- 任务类型:手持盘点(0)和自动盘点(1) +- 任务状态:待执行(0)、已完成(1)、已超时(2) + +#### 3.3.2 自动盘点功能 +- 设备连接管理:通过RFID设备IP和端口建立TCP连接 +- 标签扫描:启动RFID设备进行标签扫描 +- 数据传输:通过WebSocket将扫描到的EPC标签数据发送给前端 +- 扫描控制:支持开始、停止、断开连接等操作 + +#### 3.3.3 数据匹配功能 +- 将扫描数据与系统库存数据进行匹配 +- 生成匹配结果(正常、未扫到、误扫) +- 统计盘点结果并生成图表 + +#### 3.3.4 报告管理功能 +- 生成盘点统计图表 +- 导出盘点报告 +- 提供历史盘点记录查询 + +### 3.4 业务流程图 + +```mermaid +graph TD + A[创建盘点任务] --> B[RFID设备连接] + B --> C[下发盘点任务到设备] + C --> D[设备开始标签扫描] + D --> E[实时收集标签数据] + E --> F{是否完成扫描?} + F -->|是| G[停止扫描] + F -->|否| D + G --> H[数据比对分析] + H --> I[生成盘点结果] + I --> J[输出盘点报告] + J --> K[任务完成] +``` + +### 3.5 接口规范 + +#### 3.5.1 设备连接接口(/AutoInventory/connect) +- **功能说明**:建立RFID设备连接 +- **请求方式**:POST +- **我方服务地址**:http://[IP_ADDR]:[PORT]/AutoInventory/connect +- **第三方调用**:RFID设备需调用此接口建立连接 + +#### 3.5.2 开始盘点接口(/AutoInventory/scan) +- **功能说明**:启动RFID设备进行标签扫描 +- **请求方式**:GET +- **我方服务地址**:http://[IP_ADDR]:[PORT]/AutoInventory/scan +- **第三方调用**:RFID设备需调用此接口开始扫描 + +#### 3.5.3 停止盘点接口(/AutoInventory/stop) +- **功能说明**:停止RFID设备扫描 +- **请求方式**:GET +- **我方服务地址**:http://[IP_ADDR]:[PORT]/AutoInventory/stop +- **第三方调用**:RFID设备需调用此接口停止扫描 + +#### 3.5.4 断开连接接口(/AutoInventory/disconnect) +- **功能说明**:断开RFID设备连接 +- **请求方式**:GET +- **我方服务地址**:http://[IP_ADDR]:[PORT]/AutoInventory/disconnect +- **第三方调用**:RFID设备需调用此接口断开连接 + +#### 3.5.5 设备状态查询接口(/AutoInventory/status) +- **功能说明**:查询RFID设备连接状态 +- **请求方式**:GET +- **我方服务地址**:http://[IP_ADDR]:[PORT]/AutoInventory/status +- **第三方调用**:RFID设备需调用此接口查询状态 + +#### 3.5.6 开始匹配接口(/AutoInventory/match) +- **功能说明**:将扫描数据与系统库存数据进行匹配 +- **请求方式**:POST +- **我方服务地址**:http://[IP_ADDR]:[PORT]/AutoInventory/match +- **第三方调用**:系统内部调用 + +#### 3.5.7 盘点任务管理接口(/Inventory/task) +- **功能说明**:管理盘点任务的增删改查 +- **请求方式**:POST/GET/PUT/DELETE +- **我方服务地址**:http://[IP_ADDR]:[PORT]/Inventory/task +- **第三方调用**:系统内部调用 + +### 3.6 对接流程 + +#### 3.6.1 RFID设备对接流程 +1. **连接建立**:设备通过TCP/IP连接到我方系统 +2. **设备注册**:设备向我方系统注册,获取设备ID +3. **任务获取**:设备从我方系统获取当前盘点任务 +4. **数据采集**:设备开始扫描,实时传输标签数据 +5. **状态同步**:设备定期同步工作状态 +6. **任务完成**:设备完成任务后报告完成状态 + +#### 3.6.2 WebSocket通信 +- **连接地址**:ws://[IP_ADDR]:[PORT]/websocket +- **数据格式**:JSON格式的标签数据 +- **心跳机制**:定期发送心跳包保持连接 + +### 3.7 配置信息 + +#### 3.7.1 RFID设备配置 +```yaml +rfid: + device: + conn-id: [RFID_IP_ADDR]:[RFID_PORT] +``` + +## 4. 部署说明 + +### 4.1 环境要求 +- Java 8 或更高版本 +- Maven 3.6.0 或更高版本 +- MySQL 5.7 或更高版本 +- Redis 5.0 或更高版本 + +### 4.2 部署步骤 +1. 配置数据库连接信息 +2. 配置第三方系统接口地址 +3. 启动应用服务 +4. 验证接口连通性 + +### 4.3 配置文件 +- application.yml:主配置文件 +- application-druid.yml:数据库配置文件 + +## 5. 我方开发工作汇总 + +### 5.1 调度系统开发工作 + +#### 5.1.1 接口开发 +- **入库/上架接口开发**:实现与WCS系统的入库任务下发,预计16小时 +- **出库/下架接口开发**:实现与WCS系统的出库任务下发,预计16小时 +- **任务状态回调接口开发**:实现任务状态反馈机制,预计24小时 + +#### 5.1.2 业务逻辑开发 +- **货物上架逻辑实现**:实现完整的货物上架业务流程,预计32小时 +- **货物下架逻辑实现**:实现完整的货物下架业务流程,预计32小时 +- **任务调度与排队机制**:实现多任务排队调度算法,预计24小时 + +#### 5.1.3 系统集成开发 +- **与WMS系统接口对接**:确保调度系统与WMS系统稳定通信,预计20小时 +- **与AGV系统协调机制**:实现调度系统与AGV系统的任务协调,预计16小时 + +**调度系统总计:180小时** + +### 5.2 盘点系统开发工作 + +#### 5.2.1 设备接口开发 +- **RFID设备连接接口开发**:开发RFID设备连接、断开、状态查询接口,预计24小时 +- **盘点控制接口开发**:开发开始盘点、停止盘点等控制接口,预计16小时 + +#### 5.2.2 数据处理开发 +- **扫描数据处理开发**:处理RFID设备扫描的标签数据,预计28小时 +- **数据匹配算法开发**:开发扫描数据与库存数据的匹配算法,预计32小时 + +#### 5.2.3 任务管理开发 +- **盘点任务管理开发**:开发盘点任务的增删改查功能,预计24小时 +- **报告生成开发**:开发盘点报告生成和统计功能,预计20小时 + +#### 5.2.4 系统集成开发 +- **WebSocket通信开发**:实现实时数据传输功能,预计20小时 + +**盘点系统总计:164小时** + +### 5.3 项目总计 +- **调度系统开发**:180小时 +- **盘点系统开发**:164小时 +- **项目总计**:344小时 \ No newline at end of file