forked from github/cool-admin-java
feat: 商品行为管理 + 属性编码 + ActionHandler机制
- ProductActionEntity: 行为管理实体(name/code/description/status) - ProductAttributeEntity: 新增code(属性编码)和action(关联行为)字段 - ActionHandler接口: validate校验 + afterPurchase购买后处理 - StockCheckHandler: 库存校验+扣减 - DatePickHandler: 服务日期校验 - DeliveryRouteHandler: 发货方式校验 - ActionHandlerRegistry: 自动注册所有handler
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
package com.cool.modules.product.action;
|
||||
|
||||
import cn.hutool.json.JSONObject;
|
||||
|
||||
/**
|
||||
* 商品行为处理器接口
|
||||
*/
|
||||
public interface ActionHandler {
|
||||
|
||||
/**
|
||||
* 获取行为编码
|
||||
*/
|
||||
String getCode();
|
||||
|
||||
/**
|
||||
* 购买时校验
|
||||
*
|
||||
* @param attrCode 属性编码
|
||||
* @param attrValue 属性值
|
||||
* @param quantity 购买数量
|
||||
*/
|
||||
void validate(String attrCode, String attrValue, int quantity);
|
||||
|
||||
/**
|
||||
* 购买成功后执行(如扣减库存)
|
||||
*
|
||||
* @param attrCode 属性编码
|
||||
* @param attrValue 属性值
|
||||
* @param quantity 购买数量
|
||||
* @return 更新后的属性值
|
||||
*/
|
||||
default String afterPurchase(String attrCode, String attrValue, int quantity) {
|
||||
return attrValue;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.cool.modules.product.action;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 行为处理器注册中心
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class ActionHandlerRegistry {
|
||||
|
||||
private final List<ActionHandler> handlers;
|
||||
|
||||
private Map<String, ActionHandler> handlerMap;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
handlerMap = handlers.stream()
|
||||
.collect(Collectors.toMap(ActionHandler::getCode, Function.identity()));
|
||||
}
|
||||
|
||||
public ActionHandler getHandler(String actionCode) {
|
||||
return handlerMap.get(actionCode);
|
||||
}
|
||||
|
||||
public boolean hasHandler(String actionCode) {
|
||||
return handlerMap.containsKey(actionCode);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.cool.modules.product.action;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 日期选择处理器(服务类商品预约时间)
|
||||
*/
|
||||
@Component
|
||||
public class DatePickHandler implements ActionHandler {
|
||||
|
||||
@Override
|
||||
public String getCode() {
|
||||
return "date_pick";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate(String attrCode, String attrValue, int quantity) {
|
||||
if (attrValue == null || attrValue.isEmpty()) {
|
||||
throw new RuntimeException("请选择服务时间");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.cool.modules.product.action;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 发货路由处理器(判断物流/线上交付)
|
||||
*/
|
||||
@Component
|
||||
public class DeliveryRouteHandler implements ActionHandler {
|
||||
|
||||
@Override
|
||||
public String getCode() {
|
||||
return "delivery_route";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate(String attrCode, String attrValue, int quantity) {
|
||||
if (attrValue == null || attrValue.isEmpty()) {
|
||||
throw new RuntimeException("请选择发货方式");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.cool.modules.product.action;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 库存校验处理器
|
||||
*/
|
||||
@Component
|
||||
public class StockCheckHandler implements ActionHandler {
|
||||
|
||||
@Override
|
||||
public String getCode() {
|
||||
return "stock_check";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate(String attrCode, String attrValue, int quantity) {
|
||||
if (attrValue == null || attrValue.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
int stock = Integer.parseInt(attrValue);
|
||||
if (stock < quantity) {
|
||||
throw new RuntimeException("库存不足,当前库存:" + stock);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String afterPurchase(String attrCode, String attrValue, int quantity) {
|
||||
if (attrValue == null || attrValue.isEmpty()) {
|
||||
return attrValue;
|
||||
}
|
||||
int stock = Integer.parseInt(attrValue);
|
||||
return String.valueOf(stock - quantity);
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
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.modules.product.entity.ProductActionEntity;
|
||||
import com.cool.modules.product.service.ProductActionService;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@Tag(name = "商品行为管理", description = "商品行为管理")
|
||||
@CoolRestController(api = {"add", "delete", "update", "page", "info"})
|
||||
public class AdminProductActionController extends BaseController<ProductActionService, ProductActionEntity> {
|
||||
|
||||
@Override
|
||||
protected void init(HttpServletRequest request, JSONObject requestParams) {
|
||||
setPageOption(createOp());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.cool.modules.product.controller.app;
|
||||
|
||||
import cn.hutool.json.JSONObject;
|
||||
import com.cool.core.annotation.CoolRestController;
|
||||
import com.cool.core.request.R;
|
||||
import com.cool.modules.product.entity.ProductActionEntity;
|
||||
import com.cool.modules.product.service.ProductActionService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestAttribute;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@Tag(name = "商品行为", description = "App端商品行为")
|
||||
@CoolRestController
|
||||
public class AppProductActionController {
|
||||
|
||||
private final ProductActionService productActionService;
|
||||
|
||||
@Operation(summary = "行为列表")
|
||||
@GetMapping("/list")
|
||||
public R list(@RequestAttribute JSONObject requestParams) {
|
||||
return R.ok(productActionService.list(requestParams, null));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.cool.modules.product.entity;
|
||||
|
||||
import com.cool.core.base.TenantEntity;
|
||||
import com.mybatisflex.annotation.Table;
|
||||
import com.cool.core.annotation.ColumnDefine;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Table(value = "product_action", comment = "商品行为表")
|
||||
public class ProductActionEntity extends TenantEntity<ProductActionEntity> {
|
||||
|
||||
@ColumnDefine(comment = "行为名称", notNull = true)
|
||||
private String name;
|
||||
|
||||
@ColumnDefine(comment = "行为编码", notNull = true)
|
||||
private String code;
|
||||
|
||||
@ColumnDefine(comment = "说明", type = "text")
|
||||
private String description;
|
||||
|
||||
@ColumnDefine(comment = "状态 0:禁用 1:启用", defaultValue = "1")
|
||||
private Integer status;
|
||||
}
|
||||
@@ -14,12 +14,18 @@ public class ProductAttributeEntity extends TenantEntity<ProductAttributeEntity>
|
||||
@ColumnDefine(comment = "属性名称", notNull = true)
|
||||
private String name;
|
||||
|
||||
@ColumnDefine(comment = "属性编码", notNull = true)
|
||||
private String code;
|
||||
|
||||
@ColumnDefine(comment = "值类型 0:文本 1:数字 2:选择 3:日期", defaultValue = "0")
|
||||
private Integer type;
|
||||
|
||||
@ColumnDefine(comment = "选项值(type=2时存JSON)", type = "text")
|
||||
private String options;
|
||||
|
||||
@ColumnDefine(comment = "关联行为编码")
|
||||
private String action;
|
||||
|
||||
@ColumnDefine(comment = "状态 0:禁用 1:启用", defaultValue = "1")
|
||||
private Integer status;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.cool.modules.product.mapper;
|
||||
|
||||
import com.mybatisflex.core.BaseMapper;
|
||||
import com.cool.modules.product.entity.ProductActionEntity;
|
||||
|
||||
public interface ProductActionMapper extends BaseMapper<ProductActionEntity> {
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.cool.modules.product.service;
|
||||
|
||||
import com.cool.core.base.BaseService;
|
||||
import com.cool.modules.product.entity.ProductActionEntity;
|
||||
|
||||
public interface ProductActionService extends BaseService<ProductActionEntity> {
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.cool.modules.product.service.impl;
|
||||
|
||||
import com.cool.core.base.BaseServiceImpl;
|
||||
import com.cool.modules.product.entity.ProductActionEntity;
|
||||
import com.cool.modules.product.mapper.ProductActionMapper;
|
||||
import com.cool.modules.product.service.ProductActionService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class ProductActionServiceImpl extends BaseServiceImpl<ProductActionMapper, ProductActionEntity> implements
|
||||
ProductActionService {
|
||||
}
|
||||
Reference in New Issue
Block a user