Files
klp-oa/klp-wms/src/main/java/com/klp/controller/WmsBatchController.java
Joshi 59bd751cd7 feat(wms): 优化批次分配策略以解决死锁和进程冲突问题
- 新增 checkDeadlock 方法检测任务执行是否会产生死锁
- 改进 generateNonDeadlockBatches 方法,增加对死锁和进程冲突的处理
- 实现增强版 DFS 检测环,并收集环中的节点- 添加进程依赖图构建和冲突进程对查找功能
- 优化批次分组算法,确保所有任务都被合理分配
2025-08-15 11:25:48 +08:00

158 lines
5.5 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.klp.controller;
import java.util.ArrayList;
import java.util.List;
import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import com.klp.domain.vo.BatchGroupVo;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.klp.common.annotation.RepeatSubmit;
import com.klp.common.annotation.Log;
import com.klp.common.core.controller.BaseController;
import com.klp.common.core.domain.PageQuery;
import com.klp.common.core.domain.R;
import com.klp.common.core.validate.AddGroup;
import com.klp.common.core.validate.EditGroup;
import com.klp.common.enums.BusinessType;
import com.klp.common.utils.poi.ExcelUtil;
import com.klp.domain.vo.WmsBatchVo;
import com.klp.domain.bo.WmsBatchBo;
import com.klp.service.IWmsBatchService;
import com.klp.common.core.page.TableDataInfo;
/**
* 批次(合并相同工艺的任务)
*
* @author klp
* @date 2025-08-14
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/klp/batch")
public class WmsBatchController extends BaseController {
private final IWmsBatchService iWmsBatchService;
/**
* 查询批次(合并相同工艺的任务)列表
*/
@GetMapping("/list")
public TableDataInfo<WmsBatchVo> list(WmsBatchBo bo, PageQuery pageQuery) {
return iWmsBatchService.queryPageList(bo, pageQuery);
}
/**
* 导出批次(合并相同工艺的任务)列表
*/
@Log(title = "批次(合并相同工艺的任务)", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(WmsBatchBo bo, HttpServletResponse response) {
List<WmsBatchVo> list = iWmsBatchService.queryList(bo);
ExcelUtil.exportExcel(list, "批次(合并相同工艺的任务)", WmsBatchVo.class, response);
}
/**
* 获取批次(合并相同工艺的任务)详细信息
*
* @param batchId 主键
*/
@GetMapping("/{batchId}")
public R<WmsBatchVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long batchId) {
return R.ok(iWmsBatchService.queryById(batchId));
}
/**
* 新增批次(合并相同工艺的任务)
*/
@Log(title = "批次(合并相同工艺的任务)", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody WmsBatchBo bo) {
return toAjax(iWmsBatchService.insertByBo(bo));
}
/**
* 修改批次(合并相同工艺的任务)
*/
@Log(title = "批次(合并相同工艺的任务)", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody WmsBatchBo bo) {
return toAjax(iWmsBatchService.updateByBo(bo));
}
/**
* 删除批次(合并相同工艺的任务)
*
* @param batchIds 主键串
*/
@Log(title = "批次(合并相同工艺的任务)", businessType = BusinessType.DELETE)
@DeleteMapping("/{batchIds}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] batchIds) {
return toAjax(iWmsBatchService.deleteWithValidByIds(Arrays.asList(batchIds), true));
}
/**
* 生成不会产生死锁的批次分配方案
* 相同processId的任务会合并到一个批次组中
* 不同processId的任务会放在不同的批次组中
* 对于存在死锁的情况,会避免将冲突的进程合并到一起
*
* @param rows 任务执行顺序数组
* @return 批次分配方案
*/
@PostMapping("/generate")
public R<List<BatchGroupVo>> generateNonDeadlockBatches(@RequestBody List<List<Map<String, Object>>> rows) {
// 检查是否存在死锁
boolean hasDeadlock = iWmsBatchService.checkDeadlock(rows);
// 获取批次分配方案
List<BatchGroupVo> batches = iWmsBatchService.generateNonDeadlockBatches(rows);
// 如果不存在死锁,才进行进一步合并
if (!hasDeadlock) {
// 使用Java 8 Stream API按processId分组并合并任务
Map<String, List<BatchGroupVo>> groupedByProcessId = batches.stream()
.collect(Collectors.groupingBy(BatchGroupVo::getProcessId));
// 合并相同processId的批次组
List<BatchGroupVo> mergedBatches = new ArrayList<>();
AtomicInteger groupCounter = new AtomicInteger(1);
groupedByProcessId.forEach((processId, groups) -> {
// 创建一个新的合并后的批次组
BatchGroupVo mergedGroup = new BatchGroupVo();
mergedGroup.setGroupId("Merged-Group-" + groupCounter.getAndIncrement());
mergedGroup.setProcessId(processId);
// 合并所有taskIds
List<String> allTaskIds = groups.stream()
.flatMap(group -> group.getTaskIds().stream())
.collect(Collectors.toList());
mergedGroup.setTaskIds(allTaskIds);
mergedBatches.add(mergedGroup);
});
return R.ok(mergedBatches);
} else {
// 如果存在死锁直接返回Service层的结果不进行额外合并
return R.ok(batches);
}
}
}