feat: 行为管理改为自动注册模式 - handler自带name/description

- ActionHandler: 新增getName()/getDescription()方法
- StockCheckHandler/DatePickHandler/DeliveryRouteHandler: 补全name和description
- AdminProductActionController: 改为list(自动从handler生成)+toggle(启用禁用)
- product_action表仅存被禁用的行为记录,启用状态为默认
- RestInterceptor: 声明api={list,toggle}放行
This commit is contained in:
OpenCode
2026-07-28 13:10:11 +08:00
parent 8e87c94053
commit 3c339f7f43
5 changed files with 97 additions and 17 deletions
@@ -1,7 +1,5 @@
package com.cool.modules.product.action;
import cn.hutool.json.JSONObject;
/**
* 商品行为处理器接口
*/
@@ -12,6 +10,16 @@ public interface ActionHandler {
*/
String getCode();
/**
* 获取行为名称
*/
String getName();
/**
* 获取行为描述
*/
String getDescription();
/**
* 购买时校验
*
@@ -13,6 +13,16 @@ public class DatePickHandler implements ActionHandler {
return "date_pick";
}
@Override
public String getName() {
return "日期选择";
}
@Override
public String getDescription() {
return "服务类商品购买时必须选择服务日期";
}
@Override
public void validate(String attrCode, String attrValue, int quantity) {
if (attrValue == null || attrValue.isEmpty()) {
@@ -13,6 +13,16 @@ public class DeliveryRouteHandler implements ActionHandler {
return "delivery_route";
}
@Override
public String getName() {
return "发货路由";
}
@Override
public String getDescription() {
return "购买时校验发货方式,决定走物流配送还是线上交付";
}
@Override
public void validate(String attrCode, String attrValue, int quantity) {
if (attrValue == null || attrValue.isEmpty()) {
@@ -13,6 +13,16 @@ public class StockCheckHandler implements ActionHandler {
return "stock_check";
}
@Override
public String getName() {
return "库存校验";
}
@Override
public String getDescription() {
return "购买时校验库存是否充足,购买后自动扣减库存";
}
@Override
public void validate(String attrCode, String attrValue, int quantity) {
if (attrValue == null || attrValue.isEmpty()) {
@@ -1,40 +1,82 @@
package com.cool.modules.product.controller.admin;
import cn.hutool.json.JSONObject;
import com.cool.core.annotation.CoolRestController;
import com.cool.core.base.BaseController;
import com.cool.core.request.R;
import com.cool.modules.product.action.ActionHandler;
import com.cool.modules.product.action.ActionHandlerRegistry;
import com.cool.modules.product.entity.ProductActionEntity;
import com.cool.modules.product.service.ProductActionService;
import com.mybatisflex.core.query.QueryWrapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
@RequiredArgsConstructor
@Tag(name = "商品行为管理", description = "商品行为管理")
@CoolRestController(api = {"add", "delete", "update", "page", "info"})
public class AdminProductActionController extends BaseController<ProductActionService, ProductActionEntity> {
@CoolRestController(api = {"list", "toggle"})
public class AdminProductActionController {
private final ActionHandlerRegistry actionHandlerRegistry;
@Override
protected void init(HttpServletRequest request, JSONObject requestParams) {
setPageOption(createOp());
private final ProductActionService productActionService;
@Operation(summary = "行为列表(自动从handler生成)")
@GetMapping("/list")
public R list() {
List<ActionHandler> handlers = actionHandlerRegistry.getHandlers();
Set<String> disabledCodes = productActionService.list(
QueryWrapper.create().eq(ProductActionEntity::getStatus, 0)
).stream().map(ProductActionEntity::getCode).collect(Collectors.toSet());
List<Map<String, Object>> result = new ArrayList<>();
for (ActionHandler handler : handlers) {
Map<String, Object> item = new HashMap<>();
item.put("code", handler.getCode());
item.put("name", handler.getName());
item.put("description", handler.getDescription());
item.put("status", disabledCodes.contains(handler.getCode()) ? 0 : 1);
result.add(item);
}
return R.ok(result);
}
@Operation(summary = "获取已注册的行为处理器列表")
@GetMapping("/handlers")
public R handlers() {
List<Map<String, String>> handlers = actionHandlerRegistry.getHandlers().stream()
.map(h -> Map.of("code", h.getCode(), "name", h.getCode()))
.toList();
return R.ok(handlers);
@Operation(summary = "启用/禁用行为")
@PostMapping("/toggle")
public R toggle(@RequestBody Map<String, Object> body) {
String code = (String) body.get("code");
Integer status = (Integer) body.get("status");
ProductActionEntity existing = productActionService.getOne(
QueryWrapper.create().eq(ProductActionEntity::getCode, code)
);
if (status == 0) {
if (existing == null) {
ProductActionEntity entity = new ProductActionEntity();
entity.setCode(code);
entity.setName(code);
entity.setStatus(0);
productActionService.save(entity);
}
else {
existing.setStatus(0);
productActionService.update(existing);
}
}
else {
if (existing != null) {
productActionService.removeById(existing.getId());
}
}
return R.ok();
}
}