返回类型:货位/库存数据类型
+ * @param 入参类型:决策参数类型
* @Author: liyongde
* @Date: 2026/7/18 11:03
*/
diff --git a/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/manage/StrategyChainExecutor.java b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/manage/StrategyChainExecutor.java
new file mode 100644
index 00000000..fcc0d0c9
--- /dev/null
+++ b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/manage/StrategyChainExecutor.java
@@ -0,0 +1,91 @@
+package cn.code.nl.module.wms.manage;
+
+import cn.code.nl.framework.common.exception.ServiceException;
+import cn.code.nl.module.wms.dal.dataobject.warehousestrategy.WarehouseStrategyDO;
+import cn.code.nl.module.wms.dal.mysql.warehousestrategy.WarehouseStrategyMapper;
+import cn.hutool.core.collection.CollUtil;
+import com.alibaba.fastjson.JSON;
+import jakarta.annotation.Resource;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.context.ApplicationContext;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+/**
+ * 策略链执行器
+ *
+ * 根据库区编码和策略类型加载策略链配置,从 Spring 容器中按名称精确获取策略处理器,
+ * 按序执行,每个处理器的输出作为下一个处理器的输入。
+ *
+ * @Author: liyongde
+ * @Date: 2026/7/18
+ */
+@Slf4j
+@Component
+public class StrategyChainExecutor {
+
+ @Resource
+ private WarehouseStrategyMapper warehouseStrategyMapper;
+
+ @Resource
+ private ApplicationContext applicationContext;
+
+ /**
+ * 执行策略链
+ *
+ * @param sectionCode 库区编码
+ * @param strategyType 策略类型(1=入库,2=出库)
+ * @param candidates 初始候选列表,入库时为可用货位列表,出库时传空列表由首个策略自行查询
+ * @param param 决策参数,类型由调用方决定(入库通常传 JSONObject,出库通常传强类型实体)
+ * @param 货位/库存数据类型
+ * @param 决策参数类型,需与策略链中所有处理器的泛型参数一致
+ * @return 策略链执行后的结果列表
+ */
+ @SuppressWarnings("unchecked")
+ public List execute(String sectionCode, String strategyType, List candidates, P param) {
+ // 1. 查询库区策略链配置
+ WarehouseStrategyDO strategy = warehouseStrategyMapper.selectOne(
+ WarehouseStrategyDO::getSectionCode, sectionCode,
+ WarehouseStrategyDO::getStrategyType, strategyType);
+ if (strategy == null) {
+ throw new ServiceException(500, "当前库区 " + sectionCode + " 未配置策略链");
+ }
+
+ // 2. 解析策略编码列表
+ List strategyCodes = JSON.parseArray(strategy.getStrategy(), String.class);
+ if (CollUtil.isEmpty(strategyCodes)) {
+ throw new ServiceException(500, "当前库区 " + sectionCode + " 策略链为空");
+ }
+
+ // 3. 按序执行策略链
+ List result = candidates;
+ for (String strategyCode : strategyCodes) {
+ DecisionManage handler;
+ try {
+ handler = (DecisionManage) applicationContext.getBean(strategyCode);
+ } catch (Exception e) {
+ log.error("策略 [{}] 未找到对应的处理器 Bean", strategyCode, e);
+ throw new ServiceException(500, "策略 " + strategyCode + " 未注册");
+ }
+
+ String strategyName = handler.strategyConfig.getStrategyName();
+ int inputSize = result != null ? result.size() : 0;
+ log.info("执行策略 [{}]:{},输入候选数量:{}", strategyCode, strategyName, inputSize);
+
+ long startTime = System.currentTimeMillis();
+ result = handler.handler(result, param);
+ long cost = System.currentTimeMillis() - startTime;
+
+ int outputSize = result != null ? result.size() : 0;
+ log.info("策略 [{}] 执行完成,耗时:{}ms,输出数量:{}(过滤:{})",
+ strategyCode, cost, outputSize, inputSize - outputSize);
+
+ if (CollUtil.isEmpty(result)) {
+ throw new ServiceException(500, "策略 " + strategyName + " 执行后无可用货位");
+ }
+ }
+ return result;
+ }
+
+}
diff --git a/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/manage/dto/DemoDTO.java b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/manage/dto/AlleyAveHandleDTO.java
similarity index 68%
rename from nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/manage/dto/DemoDTO.java
rename to nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/manage/dto/AlleyAveHandleDTO.java
index 566a1807..bda64595 100644
--- a/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/manage/dto/DemoDTO.java
+++ b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/manage/dto/AlleyAveHandleDTO.java
@@ -5,9 +5,9 @@ import lombok.Data;
/**
*
* @Author: liyongde
- * @Date: 2026/7/18 13:41
+ * @Date: 2026/7/18 14:12
*/
@Data
-public class DemoDTO {
+public class AlleyAveHandleDTO {
private String id;
}
diff --git a/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/manage/dto/AlleyAveHandleParam.java b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/manage/dto/AlleyAveHandleParam.java
new file mode 100644
index 00000000..ce7ae23b
--- /dev/null
+++ b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/manage/dto/AlleyAveHandleParam.java
@@ -0,0 +1,12 @@
+package cn.code.nl.module.wms.manage.dto;
+
+import lombok.Data;
+
+/**
+ *
+ * @Author: liyongde
+ * @Date: 2026/7/18 14:12
+ */
+@Data
+public class AlleyAveHandleParam {
+}
diff --git a/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/manage/handle/AlleyAveRuleHandler.java b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/manage/handle/AlleyAveRuleHandler.java
deleted file mode 100644
index 18d9f2c3..00000000
--- a/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/manage/handle/AlleyAveRuleHandler.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package cn.code.nl.module.wms.manage.handle;
-
-import cn.code.nl.module.wms.manage.DecisionManage;
-import cn.code.nl.module.wms.manage.dto.DemoDTO;
-import com.alibaba.fastjson.JSONObject;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Service;
-
-import java.util.List;
-
-/**
- *
- * @Author: liyongde
- * @Date: 2026/7/18 13:39
- */
-@Slf4j
-@Service("alleyAve")
-public class AlleyAveRuleHandler extends DecisionManage {
- @Override
- public List handler(List list, JSONObject param) {
- return List.of();
- }
-}
diff --git a/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/manage/handle/base/AlleyAveRuleHandler.java b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/manage/handle/base/AlleyAveRuleHandler.java
new file mode 100644
index 00000000..550123cd
--- /dev/null
+++ b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/manage/handle/base/AlleyAveRuleHandler.java
@@ -0,0 +1,23 @@
+package cn.code.nl.module.wms.manage.handle.base;
+
+import cn.code.nl.module.wms.manage.DecisionManage;
+import cn.code.nl.module.wms.manage.dto.AlleyAveHandleDTO;
+import cn.code.nl.module.wms.manage.dto.AlleyAveHandleParam;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ *
+ * @Author: liyongde
+ * @Date: 2026/7/18 13:39
+ */
+@Slf4j
+@Service("alleyAve")
+public class AlleyAveRuleHandler extends DecisionManage {
+ @Override
+ public List handler(List list, AlleyAveHandleParam param) {
+ return List.of();
+ }
+}
diff --git a/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/manage/handle/package-info.java b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/manage/handle/package-info.java
new file mode 100644
index 00000000..44ddb5b7
--- /dev/null
+++ b/nl-module-wms/nl-module-wms-server/src/main/java/cn/code/nl/module/wms/manage/handle/package-info.java
@@ -0,0 +1,6 @@
+/**
+ * 所有出入库的处理器
+ * @Author: liyongde
+ * @Date: 2026/7/18 14:11
+ */
+package cn.code.nl.module.wms.manage.handle;
\ No newline at end of file
diff --git a/nl-ui/nl-ui-admin-vben/yudao-ui-admin-vben/apps/web-antdv-next/src/views/wms/warehousestrategy/data.ts b/nl-ui/nl-ui-admin-vben/yudao-ui-admin-vben/apps/web-antdv-next/src/views/wms/warehousestrategy/data.ts
index 95f4f18f..72d38c84 100644
--- a/nl-ui/nl-ui-admin-vben/yudao-ui-admin-vben/apps/web-antdv-next/src/views/wms/warehousestrategy/data.ts
+++ b/nl-ui/nl-ui-admin-vben/yudao-ui-admin-vben/apps/web-antdv-next/src/views/wms/warehousestrategy/data.ts
@@ -134,7 +134,7 @@ export function useGridColumns(): VxeTableGridOptions