diff --git a/youchain-system/src/main/java/com/youchain/appupdate/inputJson/MissionStateCallback.java b/youchain-system/src/main/java/com/youchain/appupdate/inputJson/MissionStateCallback.java index 8853980..1ec0d6f 100644 --- a/youchain-system/src/main/java/com/youchain/appupdate/inputJson/MissionStateCallback.java +++ b/youchain-system/src/main/java/com/youchain/appupdate/inputJson/MissionStateCallback.java @@ -9,7 +9,7 @@ import lombok.Data; @Data public class MissionStateCallback { @ApiModelProperty(value = "任务ID") - int missionCode; + String missionCode; @ApiModelProperty(value = "容器编号") String containerCode; diff --git a/youchain-system/src/main/java/com/youchain/basicdata/service/PointService.java b/youchain-system/src/main/java/com/youchain/basicdata/service/PointService.java index 700b5d5..62f6fab 100644 --- a/youchain-system/src/main/java/com/youchain/basicdata/service/PointService.java +++ b/youchain-system/src/main/java/com/youchain/basicdata/service/PointService.java @@ -162,4 +162,6 @@ public interface PointService { * @return */ Point createPoint(String code,String type,Area area); -} \ No newline at end of file + + +} diff --git a/youchain-system/src/main/java/com/youchain/basicdata/service/StockService.java b/youchain-system/src/main/java/com/youchain/basicdata/service/StockService.java index aa27dcc..2bde62e 100644 --- a/youchain-system/src/main/java/com/youchain/basicdata/service/StockService.java +++ b/youchain-system/src/main/java/com/youchain/basicdata/service/StockService.java @@ -137,4 +137,9 @@ public interface StockService { */ String stockMsg(String msg); + /** + * 容器上架 + */ + void stockShangJia(); + } diff --git a/youchain-system/src/main/java/com/youchain/basicdata/service/impl/StockServiceImpl.java b/youchain-system/src/main/java/com/youchain/basicdata/service/impl/StockServiceImpl.java index 43da8ac..23e3f98 100644 --- a/youchain-system/src/main/java/com/youchain/basicdata/service/impl/StockServiceImpl.java +++ b/youchain-system/src/main/java/com/youchain/basicdata/service/impl/StockServiceImpl.java @@ -235,4 +235,9 @@ public class StockServiceImpl implements StockService { return "error"; } + + @Override + public void stockShangJia() { + + } } diff --git a/youchain-system/src/main/java/com/youchain/businessdata/domain/AgvTask.java b/youchain-system/src/main/java/com/youchain/businessdata/domain/AgvTask.java new file mode 100644 index 0000000..2bc0850 --- /dev/null +++ b/youchain-system/src/main/java/com/youchain/businessdata/domain/AgvTask.java @@ -0,0 +1,161 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.youchain.businessdata.domain; + +import com.youchain.base.BaseEntity; +import lombok.Data; +import cn.hutool.core.bean.BeanUtil; +import io.swagger.annotations.ApiModelProperty; +import cn.hutool.core.bean.copier.CopyOptions; +import javax.persistence.*; +import javax.validation.constraints.*; +import java.sql.Timestamp; +import java.io.Serializable; +import java.util.Date; + +/** + * @website https://eladmin.vip + * @description / + * @author baobinglin + * @date 2023-08-18 + **/ +@Entity +@Data +@Table(name="data_agv_task") +public class AgvTask extends BaseEntity implements Serializable { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "`id`") + @ApiModelProperty(value = "任务ID") + private Long id; + + @Column(name = "`stock_code`") + @NotBlank + @ApiModelProperty(value = "容器号") + private String stockCode; + + @Column(name = "`stock_type_code`") + @NotBlank + @ApiModelProperty(value = "") + private String stockTypeCode; + + @Column(name = "`start_slot_code`",nullable = false) + @NotBlank + @ApiModelProperty(value = "起点位置") + private String startSlotCode; + + @Column(name = "`end_slot_code`") + @ApiModelProperty(value = "终点位置") + private String endSlotCode; + + @Column(name = "`slot_code`") + @ApiModelProperty(value = "设备编号") + private String slotCode; + + @Column(name = "`status`",nullable = false) + @NotBlank + @ApiModelProperty(value = "任务状态") + private String status; + + @Column(name = "`type`") + @ApiModelProperty(value = "任务类型") + private String type; + + @Column(name = "`job_id`") + @ApiModelProperty(value = "") + private String jobId; + + @Column(name = "`job_type`",nullable = false) + @NotBlank + @ApiModelProperty(value = "工作类型") + /** + * 01:料箱 + */ + private String jobType="01"; + + @Column(name = "`job_priority`") + @ApiModelProperty(value = "优先级") + private Integer jobPriority=1; + + @Column(name = "`job_priority_type`") + @ApiModelProperty(value = "强制优先级") + private Integer jobPriorityType; + + @Column(name = "`job_force`") + @ApiModelProperty(value = "任务组") + private String jobForce; + + @Column(name = "`job_force_asc`") + @ApiModelProperty(value = "任务组执行顺序") + private Integer jobForceAsc; + + @Column(name = "`job_message`") + @ApiModelProperty(value = "返回报文") + private String jobMessage; + + @Column(name = "`req_message`") + @ApiModelProperty(value = "请求报文") + private String reqMessage; + + @Column(name = "`be_scan`") + @ApiModelProperty(value = "是否扫描") + private Integer beScan=0; + + @Column(name = "`line_slot_code`") + @ApiModelProperty(value = "出库单号") + private String lineSlotCode; + + @Column(name = "`job_message_time`") + @ApiModelProperty(value = "变动时间") + private Timestamp jobMessageTime; + + @Column(name = "`start_time`") + @ApiModelProperty(value = "开始时间") + private Timestamp startTime; + + @Column(name = "`end_time`") + @ApiModelProperty(value = "完成时间") + private Timestamp endTime; + + + public AgvTask() { + + } + + /** + * 添加搬运任务 + * @param type 任务类型-入库/出库 + * @param stockCode 料车号 + * @param startSlotCode 起始位置(取料箱点位;料箱当前放置的货位码;取料箱时之前是否需要 + * 确认)中间用 ; 隔开 例如 9;2-001;false + * @param endSlotCode 终点位置(放料箱点位;料箱放置的目标货位码;放料箱时之前是否需要 + * 确认)中间用 ; 隔开 例如 14;1-001;false + * @param status 任务状态,直接下发还是排队下发 + * @param jobType 任务类型-货 架 ( 托 盘 ) 移动:RACK_MOVE + * + */ + public AgvTask(String type,String stockCode,String startSlotCode,String endSlotCode,String status,String jobType){ + this.type=type; + this.stockCode=stockCode; + this.startSlotCode=startSlotCode; + this.endSlotCode=endSlotCode; + this.status=status; + this.jobType=jobType; + } + public void copy(AgvTask source){ + BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true)); + } +} diff --git a/youchain-system/src/main/java/com/youchain/businessdata/domain/Task.java b/youchain-system/src/main/java/com/youchain/businessdata/domain/Task.java index 4bcc958..8295e54 100644 --- a/youchain-system/src/main/java/com/youchain/businessdata/domain/Task.java +++ b/youchain-system/src/main/java/com/youchain/businessdata/domain/Task.java @@ -167,6 +167,11 @@ public class Task extends BaseEntity implements Serializable { @ApiModelProperty(value = "制造库位") private Point zzkw; + @OneToOne + @JoinColumn(name = "agv_task_id") + @ApiModelProperty(value = "AGV任务") + private AgvTask agvTask; + public void copy(Task source){ BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true)); } diff --git a/youchain-system/src/main/java/com/youchain/businessdata/repository/AgvTaskRepository.java b/youchain-system/src/main/java/com/youchain/businessdata/repository/AgvTaskRepository.java new file mode 100644 index 0000000..7a32b1a --- /dev/null +++ b/youchain-system/src/main/java/com/youchain/businessdata/repository/AgvTaskRepository.java @@ -0,0 +1,36 @@ +/* +* Copyright 2019-2020 Zheng Jie +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package com.youchain.businessdata.repository; + +import com.youchain.businessdata.domain.AgvTask; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Query; + +import java.util.List; + +/** +* @website https://eladmin.vip +* @author huojin +* @date 2024-09-25 +**/ +public interface AgvTaskRepository extends JpaRepository, JpaSpecificationExecutor { + /** + * 去重 + */ + @Query(value = " from AgvTask agv where agv.stockCode=:stockCode and agv.status not in ('CANCEL','FINISH') ") + List findRepeat(String stockCode); +} diff --git a/youchain-system/src/main/java/com/youchain/businessdata/repository/InventoryRepository.java b/youchain-system/src/main/java/com/youchain/businessdata/repository/InventoryRepository.java index bf28fa0..6a18b20 100644 --- a/youchain-system/src/main/java/com/youchain/businessdata/repository/InventoryRepository.java +++ b/youchain-system/src/main/java/com/youchain/businessdata/repository/InventoryRepository.java @@ -50,4 +50,13 @@ public interface InventoryRepository extends JpaRepository, Jpa "and (:deptId is null or inv.dept.id = :deptId)") List findByInventory(Long itemKeyId, Long pointId, Long stockId, Long deptId); + /** + * 查询待上架的容器库存 + * + * @param status + * @return + */ + @Query(value = " from Inventory inv where inv.quantity > 0 and inv.status =:status and inv.stock.id>0 ") + List queryInventoryForShangJia(String status); + } diff --git a/youchain-system/src/main/java/com/youchain/businessdata/repository/TaskRepository.java b/youchain-system/src/main/java/com/youchain/businessdata/repository/TaskRepository.java index ef32bab..56b6245 100644 --- a/youchain-system/src/main/java/com/youchain/businessdata/repository/TaskRepository.java +++ b/youchain-system/src/main/java/com/youchain/businessdata/repository/TaskRepository.java @@ -67,7 +67,7 @@ public interface TaskRepository extends JpaRepository, JpaSpecificat * @return */ @Query(value = "SELECT * FROM data_task t WHERE t.agv_task_id=?1 ", nativeQuery = true) - List getAgvTaskList(Integer id); + List getAgvTaskList(Long id); /** * 根据 收货明细序号 进行删除数据 @@ -80,4 +80,4 @@ public interface TaskRepository extends JpaRepository, JpaSpecificat */ @Query(value = "SELECT * FROM `data_task` dt where dt.bill_code = :billCode", nativeQuery = true) List queryByBillCode(@Param("billCode")String billCode); -} \ No newline at end of file +} diff --git a/youchain-system/src/main/java/com/youchain/businessdata/rest/AgvTaskController.java b/youchain-system/src/main/java/com/youchain/businessdata/rest/AgvTaskController.java new file mode 100644 index 0000000..af5180b --- /dev/null +++ b/youchain-system/src/main/java/com/youchain/businessdata/rest/AgvTaskController.java @@ -0,0 +1,87 @@ +/* +* Copyright 2019-2020 Zheng Jie +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package com.youchain.businessdata.rest; + +import com.youchain.annotation.Log; +import com.youchain.businessdata.domain.AgvTask; +import com.youchain.businessdata.service.AgvTaskService; +import com.youchain.businessdata.service.dto.AgvTaskQueryCriteria; +import org.springframework.data.domain.Pageable; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import io.swagger.annotations.*; +import java.io.IOException; +import javax.servlet.http.HttpServletResponse; + +/** +* @website https://eladmin.vip +* @author huojin +* @date 2024-09-25 +**/ +@RestController +@RequiredArgsConstructor +@Api(tags = "agvTask管理") +@RequestMapping("/api/agvTask") +public class AgvTaskController { + + private final AgvTaskService agvTaskService; + + @Log("导出数据") + @ApiOperation("导出数据") + @GetMapping(value = "/download") + @PreAuthorize("@el.check('agvTask:list')") + public void exportAgvTask(HttpServletResponse response, AgvTaskQueryCriteria criteria) throws Exception { + agvTaskService.download(agvTaskService.queryAll(criteria), response); + } + + @GetMapping + @Log("查询agvTask") + @ApiOperation("查询agvTask") + @PreAuthorize("@el.check('agvTask:list')") + public ResponseEntity queryAgvTask(AgvTaskQueryCriteria criteria, Pageable pageable){ + return new ResponseEntity<>(agvTaskService.queryAll(criteria,pageable),HttpStatus.OK); + } + + @PostMapping + @Log("新增agvTask") + @ApiOperation("新增agvTask") + @PreAuthorize("@el.check('agvTask:add')") + public ResponseEntity createAgvTask(@Validated @RequestBody AgvTask resources){ + return new ResponseEntity<>(agvTaskService.create(resources),HttpStatus.CREATED); + } + + @PutMapping + @Log("修改agvTask") + @ApiOperation("修改agvTask") + @PreAuthorize("@el.check('agvTask:edit')") + public ResponseEntity updateAgvTask(@Validated @RequestBody AgvTask resources){ + agvTaskService.update(resources); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @DeleteMapping + @Log("删除agvTask") + @ApiOperation("删除agvTask") + @PreAuthorize("@el.check('agvTask:del')") + public ResponseEntity deleteAgvTask(@RequestBody Long[] ids) { + agvTaskService.deleteAll(ids); + return new ResponseEntity<>(HttpStatus.OK); + } +} diff --git a/youchain-system/src/main/java/com/youchain/businessdata/rest/InventoryController.java b/youchain-system/src/main/java/com/youchain/businessdata/rest/InventoryController.java index 92290fb..8ebb010 100644 --- a/youchain-system/src/main/java/com/youchain/businessdata/rest/InventoryController.java +++ b/youchain-system/src/main/java/com/youchain/businessdata/rest/InventoryController.java @@ -76,6 +76,7 @@ public class InventoryController { public void downloadXb(HttpServletResponse response, InventoryQueryCriteria criteria) throws Exception { inventoryService.downloadXb(inventoryService.queryAll(criteria), response); } + @Log("导出协同数据") @ApiOperation("导出协同数据") @GetMapping(value = "/downloadXt") @@ -83,6 +84,7 @@ public class InventoryController { public void downloadXt(HttpServletResponse response, InventoryQueryCriteria criteria) throws Exception { inventoryService.downloadXt(inventoryService.queryAll(criteria), response); } + @Log("导出制造数据") @ApiOperation("导出制造数据") @GetMapping(value = "/downloadZz") @@ -117,12 +119,12 @@ public class InventoryController { public ResponseEntity updateInventory(@Validated @RequestBody Inventory resources) { //库存修改 Inventory byId = inventoryRepository.getById(resources.getId()); - if (byId.getQuantity()>resources.getQuantity()){//以前的大于现在的 + if (byId.getQuantity() > resources.getQuantity()) {//以前的大于现在的 invLogService.storeInventoryLog(BizStatus.INVENTORY_ADJUST, BizStatus.REDUCE, null, byId.getArea(), byId.getItemKey(), byId.getPoint(), byId.getPoint(), byId.getStock(), byId.getStock(), byId.getQuantity(), (byId.getQuantity() - resources.getQuantity()), - null,null,BizStatus.INVENTORY_ADJUST, byId.getId(), byId.getId(), resources.getDescription()); - }else { - invLogService.storeInventoryLog(BizStatus.INVENTORY_ADJUST, BizStatus.ADD, null, byId.getArea(), byId.getItemKey(), byId.getPoint(), byId.getPoint(), byId.getStock(), byId.getStock(), byId.getQuantity(), (resources.getQuantity()-byId.getQuantity()), - null,null,BizStatus.INVENTORY_ADJUST, byId.getId(), byId.getId(), resources.getDescription()); + null, null, BizStatus.INVENTORY_ADJUST, byId.getId(), byId.getId(), resources.getDescription()); + } else { + invLogService.storeInventoryLog(BizStatus.INVENTORY_ADJUST, BizStatus.ADD, null, byId.getArea(), byId.getItemKey(), byId.getPoint(), byId.getPoint(), byId.getStock(), byId.getStock(), byId.getQuantity(), (resources.getQuantity() - byId.getQuantity()), + null, null, BizStatus.INVENTORY_ADJUST, byId.getId(), byId.getId(), resources.getDescription()); } inventoryService.update(resources); return new ResponseEntity<>(HttpStatus.NO_CONTENT); @@ -160,11 +162,24 @@ public class InventoryController { @ApiOperation("APP查询库存") @AnonymousAccess public ApiResult queryInvApp(@RequestBody ScanItemCode scan) { - String code=scan.getItemCode(); - if(code!=null&&code.length()>=85){ - code=code.substring(3, 13); + String code = scan.getItemCode(); + if (code != null && code.length() >= 85) { + code = code.substring(3, 13); } - List qs=inventoryService.queryInvApp(code); + List qs = inventoryService.queryInvApp(code); return ApiResult.result(200, "", qs); } -} \ No newline at end of file + + @GetMapping("/queryStockShangJia") + @Log("待上架容器") + @ApiOperation("待上架容器") + @AnonymousAccess + public ResponseEntity queryStockShangJia(String status) { + try { + return new ResponseEntity<>(inventoryService.queryInventoryForShangJia(status), HttpStatus.OK); + } catch (Exception e) { + return new ResponseEntity<>(ApiResult.fail(HttpStatus.BAD_REQUEST.value(), e.getMessage(), null), HttpStatus.BAD_REQUEST); + } + + } +} diff --git a/youchain-system/src/main/java/com/youchain/businessdata/rest/KMReSController.java b/youchain-system/src/main/java/com/youchain/businessdata/rest/KMReSController.java new file mode 100644 index 0000000..6894f85 --- /dev/null +++ b/youchain-system/src/main/java/com/youchain/businessdata/rest/KMReSController.java @@ -0,0 +1,53 @@ +package com.youchain.businessdata.rest; + +import com.youchain.annotation.AnonymousAccess; +import com.youchain.annotation.Log; +import com.youchain.appupdate.inputJson.MissionStateCallback; +import com.youchain.businessdata.domain.AgvTask; +import com.youchain.businessdata.service.AgvTaskService; +import com.youchain.businessdata.service.dto.AgvTaskDto; +import com.youchain.exception.handler.ApiResult; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import static org.springframework.http.HttpStatus.BAD_REQUEST; +import static org.springframework.http.HttpStatus.OK; + +/** + * @author 92525 + */ +@RestController +@RequiredArgsConstructor +@Api(tags = "KMReS") +@RequestMapping("/interfaces/api/amr") +@Slf4j +public class KMReSController { + + private final AgvTaskService agvTaskService; + + @PostMapping("/missionStateCallback") + @Log("KMReS接口回调") + @ApiOperation("KMReS接口回调") + @AnonymousAccess + public ResponseEntity missionStateCallback(@RequestBody MissionStateCallback missionStateCallback) { + String id = missionStateCallback.getMissionCode();//作业 id + String containerCode = missionStateCallback.getContainerCode();//容器编号 + String missionStatus = missionStateCallback.getMissionStatus();//作业当前状态 + try { + //货架任务 + AgvTaskDto agvTaskDto = agvTaskService.findById(Long.parseLong(id)); + AgvTask agvTask = agvTaskService.toEntity(agvTaskDto);//转实体 + agvTaskService.agvTaskCallback(agvTask, missionStatus, containerCode); + return new ResponseEntity<>(ApiResult.success(OK.value(), "", ""), HttpStatus.OK); + } catch (Exception e) { + return new ResponseEntity<>(ApiResult.fail(BAD_REQUEST.value(), e.getMessage(), ""), HttpStatus.BAD_REQUEST); + } + } +} diff --git a/youchain-system/src/main/java/com/youchain/businessdata/service/AgvTaskService.java b/youchain-system/src/main/java/com/youchain/businessdata/service/AgvTaskService.java new file mode 100644 index 0000000..a96c075 --- /dev/null +++ b/youchain-system/src/main/java/com/youchain/businessdata/service/AgvTaskService.java @@ -0,0 +1,94 @@ +/* +* Copyright 2019-2020 Zheng Jie +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package com.youchain.businessdata.service; + +import com.youchain.businessdata.domain.AgvTask; +import com.youchain.businessdata.service.dto.AgvTaskDto; +import com.youchain.businessdata.service.dto.AgvTaskQueryCriteria; +import org.springframework.data.domain.Pageable; +import java.util.Map; +import java.util.List; +import java.io.IOException; +import javax.servlet.http.HttpServletResponse; + +/** +* @website https://eladmin.vip +* @description 服务接口 +* @author huojin +* @date 2024-09-25 +**/ +public interface AgvTaskService { + + /** + * 查询数据分页 + * @param criteria 条件 + * @param pageable 分页参数 + * @return Map + */ + Map queryAll(AgvTaskQueryCriteria criteria, Pageable pageable); + + /** + * 查询所有数据不分页 + * @param criteria 条件参数 + * @return List + */ + List queryAll(AgvTaskQueryCriteria criteria); + + /** + * 根据ID查询 + * @param id ID + * @return AgvTaskDto + */ + AgvTaskDto findById(Long id); + + /** + * 创建 + * @param resources / + * @return AgvTaskDto + */ + AgvTaskDto create(AgvTask resources); + + /** + * 编辑 + * @param resources / + */ + void update(AgvTask resources); + + /** + * 多选删除 + * @param ids / + */ + void deleteAll(Long[] ids); + + /** + * 导出数据 + * @param all 待导出的数据 + * @param response / + * @throws Exception / + */ + void download(List all, HttpServletResponse response) throws Exception; + + AgvTask toEntity(AgvTaskDto agvTaskDto); + + /** + * 任务回报更新状态 + * + * @param agvTask + * @param status + * @param containerCode + */ + void agvTaskCallback(AgvTask agvTask, String status, String containerCode); +} diff --git a/youchain-system/src/main/java/com/youchain/businessdata/service/InventoryService.java b/youchain-system/src/main/java/com/youchain/businessdata/service/InventoryService.java index a8afe15..8be067f 100644 --- a/youchain-system/src/main/java/com/youchain/businessdata/service/InventoryService.java +++ b/youchain-system/src/main/java/com/youchain/businessdata/service/InventoryService.java @@ -144,4 +144,7 @@ public interface InventoryService { List queryInvApp(String code); Inventory getInventory(ItemKey itemKey, Point point, Stock stock, Dept dept, String type,Area area); + + List queryInventoryForShangJia(String status); + } diff --git a/youchain-system/src/main/java/com/youchain/businessdata/service/TaskService.java b/youchain-system/src/main/java/com/youchain/businessdata/service/TaskService.java index 210421d..684b870 100644 --- a/youchain-system/src/main/java/com/youchain/businessdata/service/TaskService.java +++ b/youchain-system/src/main/java/com/youchain/businessdata/service/TaskService.java @@ -134,7 +134,7 @@ public interface TaskService { */ List queryTaskApp(IPTask t); - List getAgvTaskList(Integer id); + List getAgvTaskList(Long id); List findbyPointCode(Long boxId); diff --git a/youchain-system/src/main/java/com/youchain/businessdata/service/dto/AgvTaskDto.java b/youchain-system/src/main/java/com/youchain/businessdata/service/dto/AgvTaskDto.java new file mode 100644 index 0000000..d7a5992 --- /dev/null +++ b/youchain-system/src/main/java/com/youchain/businessdata/service/dto/AgvTaskDto.java @@ -0,0 +1,105 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.youchain.businessdata.service.dto; + +import lombok.Data; +import java.sql.Timestamp; +import java.io.Serializable; + +/** + * @website https://eladmin.vip + * @description / + * @author baobinglin + * @date 2023-08-18 + **/ +@Data +public class AgvTaskDto implements Serializable { + + /** 任务ID */ + private Long id; + + /** 容器码 */ + private String stockCode; + + /** 容器类型 */ + private String stockTypeCode; + + /** 起点位置 */ + private String startSlotCode; + + /** 终点位置 */ + private String endSlotCode; + + /** 容器当前位置 */ + private String slotCode; + + /** 任务状态 */ + private String status; + + /** 任务类型 */ + private String type; + + /** 下游任务号 */ + private String jobId; + + /** 工作类型 */ + private String jobType; + + /** 优先级 */ + private Integer jobPriority; + + /** 强制优先级 */ + private Integer jobPriorityType; + + /** 任务组 */ + private String jobForce; + + /** 任务组执行顺序 */ + private Integer jobForceAsc; + + /** 返回报文 */ + private String jobMessage; + + /** 请求报文 */ + private String reqMessage; + + /** 是否扫描 */ + private Integer beScan=0; + + /** 出库单号 */ + private String lineSlotCode; + + /** 变动时间 */ + private Timestamp jobMessageTime; + + /** 创建时间 */ + private Timestamp createTime; + + /** 开始时间 */ + private Timestamp startTime; + + /** 完成时间 */ + private Timestamp endTime; + + /** 创建人 */ + private String createBy; + + /** 修改人 */ + private String updateBy; + + /** 修改时间 */ + private Timestamp updateTime; +} diff --git a/youchain-system/src/main/java/com/youchain/businessdata/service/dto/AgvTaskQueryCriteria.java b/youchain-system/src/main/java/com/youchain/businessdata/service/dto/AgvTaskQueryCriteria.java new file mode 100644 index 0000000..d86024e --- /dev/null +++ b/youchain-system/src/main/java/com/youchain/businessdata/service/dto/AgvTaskQueryCriteria.java @@ -0,0 +1,76 @@ +/* +* Copyright 2019-2020 Zheng Jie +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package com.youchain.businessdata.service.dto; + +import lombok.Data; +import java.sql.Timestamp; +import java.util.List; +import com.youchain.annotation.Query; + +/** +* @website https://eladmin.vip +* @author huojin +* @date 2024-09-25 +**/ +@Data +public class AgvTaskQueryCriteria{ + + /** 任务ID */ + @Query + private String id; + + /** 任务组号 */ + @Query + private String jobForce; + + /** 容器码 */ + @Query(type = Query.Type.LEFT_LIKE) + private String stockCode; + + /** 起点位置 */ + @Query(type = Query.Type.LEFT_LIKE) + private String startSlotCode; + + /** 终点位置 */ + @Query(type = Query.Type.LEFT_LIKE) + private String endSlotCode; + + /** 状态 */ + @Query(type = Query.Type.IN) + private List status; + + /** 任务类型 */ + @Query + private String type; + + //AGV类型 + @Query(type = Query.Type.RIGHT_LIKE) + private String jobType; + + + /** 返回报文 */ + @Query(type = Query.Type.INNER_LIKE) + private String jobMessage; + + + /** 创建日期 */ + @Query(type = Query.Type.BETWEEN) + private List createTime; + + /** 完成时间 */ + @Query(type = Query.Type.BETWEEN) + private List endTime; +} diff --git a/youchain-system/src/main/java/com/youchain/businessdata/service/dto/TaskDto.java b/youchain-system/src/main/java/com/youchain/businessdata/service/dto/TaskDto.java index 73a68b6..39c18f3 100644 --- a/youchain-system/src/main/java/com/youchain/businessdata/service/dto/TaskDto.java +++ b/youchain-system/src/main/java/com/youchain/businessdata/service/dto/TaskDto.java @@ -16,6 +16,7 @@ package com.youchain.businessdata.service.dto; import com.youchain.basicdata.service.dto.*; +import com.youchain.businessdata.domain.AgvTask; import com.youchain.modules.system.service.dto.DeptDto; import com.youchain.modules.system.service.dto.DeptSmallDto; import lombok.Data; @@ -106,6 +107,8 @@ public class TaskDto implements Serializable { /** 库存ID */ private Long invId; + private AgvTask agvTask; + /** 仓库ID */ private DeptDto dept; diff --git a/youchain-system/src/main/java/com/youchain/businessdata/service/impl/AgvTaskServiceImpl.java b/youchain-system/src/main/java/com/youchain/businessdata/service/impl/AgvTaskServiceImpl.java new file mode 100644 index 0000000..0b37a64 --- /dev/null +++ b/youchain-system/src/main/java/com/youchain/businessdata/service/impl/AgvTaskServiceImpl.java @@ -0,0 +1,298 @@ +/* + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.youchain.businessdata.service.impl; + +import com.youchain.basicdata.domain.Point; +import com.youchain.basicdata.domain.Stock; +import com.youchain.basicdata.repository.StockRepository; +import com.youchain.basicdata.service.PointService; +import com.youchain.businessdata.domain.AgvTask; +import com.youchain.businessdata.domain.AsnDetail; +import com.youchain.businessdata.domain.Inventory; +import com.youchain.businessdata.domain.Task; +import com.youchain.businessdata.repository.TaskRepository; +import com.youchain.businessdata.service.AsnDetailService; +import com.youchain.businessdata.service.TaskService; +import com.youchain.exception.BadRequestException; +import com.youchain.utils.*; +import lombok.RequiredArgsConstructor; +import com.youchain.businessdata.repository.AgvTaskRepository; +import com.youchain.businessdata.service.AgvTaskService; +import com.youchain.businessdata.service.dto.AgvTaskDto; +import com.youchain.businessdata.service.dto.AgvTaskQueryCriteria; +import com.youchain.businessdata.service.mapstruct.AgvTaskMapper; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + +import java.sql.Timestamp; +import java.util.*; +import java.io.IOException; +import javax.servlet.http.HttpServletResponse; + +/** + * @author huojin + * @website https://eladmin.vip + * @description 服务实现 + * @date 2024-09-25 + **/ +@Service +@RequiredArgsConstructor +public class AgvTaskServiceImpl implements AgvTaskService { + + private final AgvTaskRepository agvTaskRepository; + private final StockRepository stockRepository; + private final TaskRepository taskRepository; + private final AgvTaskMapper agvTaskMapper; + private final PointService pointService; + private final TaskService taskService; + private final AsnDetailService asnDetailService; + + @Override + public Map queryAll(AgvTaskQueryCriteria criteria, Pageable pageable) { + Page page = agvTaskRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable); + return PageUtil.toPage(page.map(agvTaskMapper::toDto)); + } + + @Override + public List queryAll(AgvTaskQueryCriteria criteria) { + return agvTaskMapper.toDto(agvTaskRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder))); + } + + @Override + @Transactional + public AgvTaskDto findById(Long id) { + AgvTask agvTask = agvTaskRepository.findById(id).orElseGet(AgvTask::new); + ValidationUtil.isNull(agvTask.getId(), "AgvTask", "id", id); + return agvTaskMapper.toDto(agvTask); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public AgvTaskDto create(AgvTask resources) { + return agvTaskMapper.toDto(agvTaskRepository.save(resources)); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void update(AgvTask resources) { + AgvTask agvTask = agvTaskRepository.findById(resources.getId()).orElseGet(AgvTask::new); + ValidationUtil.isNull(agvTask.getId(), "AgvTask", "id", resources.getId()); + agvTask.copy(resources); + agvTaskRepository.save(agvTask); + } + + @Override + public void deleteAll(Long[] ids) { + for (Long id : ids) { + agvTaskRepository.deleteById(id); + } + } + + @Override + public void download(List all, HttpServletResponse response) throws Exception { + List> list = new ArrayList<>(); + for (AgvTaskDto agvTask : all) { + Map map = new LinkedHashMap<>(); + map.put("容器码", agvTask.getStockCode()); + map.put("容器类型", agvTask.getStockTypeCode()); + map.put("起点位置", agvTask.getStartSlotCode()); + map.put("终点位置", agvTask.getEndSlotCode()); + map.put("容器当前位置", agvTask.getSlotCode()); + map.put("任务状态", agvTask.getStatus()); + map.put("任务类型", agvTask.getType()); + map.put("下游任务号", agvTask.getJobId()); + map.put("工作类型", agvTask.getJobType()); + map.put("优先级", agvTask.getJobPriority()); + map.put("强制优先级", agvTask.getJobPriorityType()); + map.put("任务组", agvTask.getJobForce()); + map.put("任务组执行顺序", agvTask.getJobForceAsc()); + map.put("返回报文", agvTask.getJobMessage()); + map.put("变动时间", agvTask.getJobMessageTime()); + map.put("创建时间", agvTask.getCreateTime()); + map.put("开始时间", agvTask.getStartTime()); + map.put("完成时间", agvTask.getEndTime()); + map.put("创建人", agvTask.getCreateBy()); + map.put("修改人", agvTask.getUpdateBy()); + map.put("修改时间", agvTask.getUpdateTime()); + list.add(map); + } + FileUtil.downloadExcel(list, response); + } + + @Override + public AgvTask toEntity(AgvTaskDto agvTaskDto) { + return agvTaskMapper.toEntity(agvTaskDto); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void agvTaskCallback(AgvTask agvTask, String status, String containerCode) { + switch (status) { + case "UP_CONTAINER": + case "FORK_UP": + handleUpContainer(agvTask, containerCode);//容器顶升 + break; + case "COMPLETED": + handleComContainer(agvTask, containerCode);//搬运任务完成 + break; + case "CANCELED": + handleCanceledTask(agvTask, containerCode);//容器取消 + break; + case "RESEND": + handleResendTask(agvTask);//重新发送 + break; + } + } + + + private void handleUpContainer(AgvTask agvTask, String containerCode) { + //顶升释放起点位置状态及容器绑定的起点位置 + Point startPoint = pointService.getPoint(agvTask.getStartSlotCode(), null, null, null); + startPoint.setStatus(BaseStatus.FREE); + pointService.update(startPoint); + + agvTask.setStockCode(containerCode); + agvTask.setStatus(BizStatus.UP_CONTAINER); + agvTask.setStartTime(new Timestamp(new Date().getTime())); + agvTaskRepository.save(agvTask); + } + + private void handleComContainer(AgvTask agvTask, String containerCode) { + //任务完成;根据AGV任务的目标点位走对应流程 + Point endPoint = pointService.getPoint(agvTask.getEndSlotCode(), null, null, null); + String endAreaName = endPoint.getArea().getCode(); + Stock stock = stockRepository.getStockByCode(containerCode); + if (stock == null) { + throw new BadRequestException(containerCode + "容器不存在! 请维护"); + } + List taskList = taskService.getAgvTaskList(agvTask.getId()); + switch (endAreaName) { + case "3#料箱区": + handleXJDJ(agvTask, taskList, stock);//入库完成 + break; + } + + agvTask.setStatus(BizStatus.FINISH); + agvTask.setStockCode(containerCode); + agvTask.setEndTime(new Timestamp(new Date().getTime())); + agvTaskRepository.save(agvTask); + } + + + /** + * 满车入库 + * + * @param taskList + * @param stock + */ + private void handleXJDJ(AgvTask agvTask, List taskList, Stock stock) { + if (BizStatus.ASN.equals(agvTask.getType())) { + //容器回存储区,新增库存、更新点位状态 + for (Task task : taskList) { + task.setTaskStatus(BizStatus.FINISH); + task.setMoveQty(task.getPlanQty()); + taskService.update(task); + //更新库存 + } + } + + } + + /** + * 任务取消完成 + * + * @param agvTask + * @param containerCode + */ + private void handleCanceledTask(AgvTask agvTask, String containerCode) { + //任务取消完成 + Point endPoint = pointService.getPoint(agvTask.getEndSlotCode(), null, null, null); + String endAreaName = endPoint.getArea().getCode(); + Stock stock = stockRepository.getStockByCode(containerCode); + if (stock == null) { + throw new BadRequestException(containerCode + "容器不存在! 请维护"); + } + switch (endAreaName) { + case "3#料箱区": + handleFBFCCancel(agvTask, endPoint, stock);//入库取消 + break; + } + agvTask.setStatus(BizStatus.CANCEL); + agvTask.setEndTime(new Timestamp(new Date().getTime())); + agvTaskRepository.save(agvTask); + + } + + private synchronized void handleResendTask(AgvTask agvTask) { + List repeatList = agvTaskRepository.findRepeat(agvTask.getStockCode()); + if (!repeatList.isEmpty()) { + throw new BadRequestException("任务已重新生成,请勿重复操作! "); + } + AgvTask newAgvTask = new AgvTask(); + newAgvTask.setStockCode(agvTask.getStockCode()); + newAgvTask.setStartSlotCode(agvTask.getStartSlotCode()); + newAgvTask.setEndSlotCode(agvTask.getEndSlotCode()); + newAgvTask.setSlotCode(agvTask.getSlotCode()); + newAgvTask.setStatus(BizStatus.OPEN); + newAgvTask.setType(agvTask.getType()); + newAgvTask.setJobType(agvTask.getJobType()); + newAgvTask.setJobPriority(1); + newAgvTask.setLineSlotCode(agvTask.getLineSlotCode()); + agvTaskRepository.save(newAgvTask); + + //重新发送任务 + List taskList = taskService.getAgvTaskList(agvTask.getId()); + for (Task task : taskList) { + task.setAgvTask(newAgvTask); + taskRepository.save(task); + } + } + + private void handleFBFCCancel(AgvTask agvTask, Point endPoint, Stock stock) { + //回存储区取消任务,不生成库存 入库任务取消即可 + List taskList = taskService.getAgvTaskList(agvTask.getId()); + for (Task task : taskList) { + AsnDetail ad = task.getAsnDetail(); + ad.setStatus(BizStatus.CANCEL); + asnDetailService.update(ad); + + task.setTaskStatus(BizStatus.CANCEL); + taskService.update(task); + } + //起点点位释放 + Point srcPoint = pointService.getPoint(agvTask.getStartSlotCode(), null, null, null); + releasePoint(srcPoint); + stock.setStatus(BaseStatus.FREE); + stockRepository.save(stock); + //线边点位释放 + releasePoint(endPoint); + } + + /** + * 释放点位 + * + * @param point + */ + private void releasePoint(Point point) { + if (point != null) { + point.setStatus(BaseStatus.FREE); + pointService.update(point); + } + } + +} diff --git a/youchain-system/src/main/java/com/youchain/businessdata/service/impl/AsnDetailServiceImpl.java b/youchain-system/src/main/java/com/youchain/businessdata/service/impl/AsnDetailServiceImpl.java index 6a12a46..0eec9be 100644 --- a/youchain-system/src/main/java/com/youchain/businessdata/service/impl/AsnDetailServiceImpl.java +++ b/youchain-system/src/main/java/com/youchain/businessdata/service/impl/AsnDetailServiceImpl.java @@ -243,18 +243,21 @@ public class AsnDetailServiceImpl implements AsnDetailService { //生成Itemkey ItemKey itemKey = itemKeyService.getItemKey(item, asnDetail.getPropC1(), asnDetail.getPropC3(), asnDetail.getPropC4(), asnDetail.getPropC5(), asnDetail.getPropC6(), asnDetail.getPropD1()); - //生成入库记录 - Task task = taskService.storeTask(asnDetail, null, zhengli.getArea(), itemKey, null, point, zhengli.getZlQty()); - task.setSrcStockCode(stock.getCode()); - task.setSrcStock(stock); - taskRepository.save(task); - //生成库存记录 Inventory inventory = inventoryService.getInventory(itemKey, point, stock, item.getDept(), BizStatus.ASN,area); inventory.setStatus("待入库"); inventory.setQuantity(inventory.getQuantity() + zhengli.getZlQty()); inventoryService.update(inventory); + //生成入库记录 + Task task = taskService.storeTask(asnDetail, null, zhengli.getArea(), itemKey, null, point, zhengli.getZlQty()); + task.setSrcStockCode(stock.getCode()); + task.setSrcStock(stock); + task.setInvId(inventory.getId()); + taskRepository.save(task); + + + //是序列号的商品,生成序列号记录 if (item.getIsSerial()) { XppRecord xppRecord = new XppRecord(); diff --git a/youchain-system/src/main/java/com/youchain/businessdata/service/impl/InventoryServiceImpl.java b/youchain-system/src/main/java/com/youchain/businessdata/service/impl/InventoryServiceImpl.java index c525130..f42becd 100644 --- a/youchain-system/src/main/java/com/youchain/businessdata/service/impl/InventoryServiceImpl.java +++ b/youchain-system/src/main/java/com/youchain/businessdata/service/impl/InventoryServiceImpl.java @@ -416,4 +416,9 @@ public class InventoryServiceImpl implements InventoryService { } return inventory; } + + @Override + public List queryInventoryForShangJia(String status) { + return inventoryRepository.queryInventoryForShangJia(status); + } } diff --git a/youchain-system/src/main/java/com/youchain/businessdata/service/impl/TaskServiceImpl.java b/youchain-system/src/main/java/com/youchain/businessdata/service/impl/TaskServiceImpl.java index 050eeb6..c4f5be5 100644 --- a/youchain-system/src/main/java/com/youchain/businessdata/service/impl/TaskServiceImpl.java +++ b/youchain-system/src/main/java/com/youchain/businessdata/service/impl/TaskServiceImpl.java @@ -303,7 +303,7 @@ public class TaskServiceImpl implements TaskService { } @Override - public List getAgvTaskList(Integer id) { + public List getAgvTaskList(Long id) { return taskRepository.getAgvTaskList(id); } diff --git a/youchain-system/src/main/java/com/youchain/businessdata/service/mapstruct/AgvTaskMapper.java b/youchain-system/src/main/java/com/youchain/businessdata/service/mapstruct/AgvTaskMapper.java new file mode 100644 index 0000000..19dd3d0 --- /dev/null +++ b/youchain-system/src/main/java/com/youchain/businessdata/service/mapstruct/AgvTaskMapper.java @@ -0,0 +1,32 @@ +/* +* Copyright 2019-2020 Zheng Jie +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package com.youchain.businessdata.service.mapstruct; + +import com.youchain.base.BaseMapper; +import com.youchain.businessdata.domain.AgvTask; +import com.youchain.businessdata.service.dto.AgvTaskDto; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** +* @website https://eladmin.vip +* @author huojin +* @date 2024-09-25 +**/ +@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface AgvTaskMapper extends BaseMapper { + +} \ No newline at end of file diff --git a/youchain-system/src/main/resources/config/application-prod.yml b/youchain-system/src/main/resources/config/application-prod.yml index 4465439..7cb6c7e 100644 --- a/youchain-system/src/main/resources/config/application-prod.yml +++ b/youchain-system/src/main/resources/config/application-prod.yml @@ -4,7 +4,7 @@ spring: druid: db-type: com.alibaba.druid.pool.DruidDataSource driverClassName: net.sf.log4jdbc.sql.jdbcapi.DriverSpy - url: jdbc:log4jdbc:mysql://${DB_HOST:localhost}:${DB_PORT:53306}/${DB_NAME:kams4_prod}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false + url: jdbc:log4jdbc:mysql://${DB_HOST:47.103.100.52}:${DB_PORT:53306}/${DB_NAME:zw_kams4}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false username: ${DB_USER:root} password: ${DB_PWD:Youchain@56} # 初始连接数 diff --git a/youchain-system/src/main/resources/config/application.yml b/youchain-system/src/main/resources/config/application.yml index f79b943..49e72de 100644 --- a/youchain-system/src/main/resources/config/application.yml +++ b/youchain-system/src/main/resources/config/application.yml @@ -1,6 +1,6 @@ server: + #port: 8077 port: 8000 -# port: 8000 spring: main: allow-circular-references: true @@ -32,7 +32,7 @@ spring: redis: #数据库索引 - database: ${REDIS_DB:3} + database: ${REDIS_DB:4} # database: ${REDIS_DB:2} # host: ${REDIS_HOST:47.100.54.81} host: ${REDIS_HOST:localhost}