mirror of
https://github.com/crmeb/CRMEB.git
synced 2026-10-28 21:40:50 +00:00
- 新增 OrderCenterListExtend 监听器:从 eb_pt_virtual_order 合并 product_id/status/complete_time 到列表行,修复商品ID与状态空白 - list() 搜索契约映射:order_no 走中台 keyword 前缀搜索、status 对应 status_code,修复搜索不生效 - 列表去掉发货时间/退款状态/商品ID(网盘自动发货、无退款流程), 新增商品名称/规格/金额
product/ — 产品类型扩展模块(商品域)
功能概述
产品类型(ProductType)决定卖什么,是与交易模式(modules/trade/,怎么卖)正交的维度。
每个产品类型是一个独立的插件包,包含商品的履约形态、库存管理方式、物流/配送规则、售后规则等。
产品类型 Handler 继承 crmeb/trade/product/BaseProductTypeHandler.php,通过 ProductTypeRegistry 注册。
目录结构
product/
├── cardkey/ 卡密商品 product_cardkey
├── normal/ 实物商品 product_normal
├── virtual/ 虚拟商品 product_virtual
├── App.php 骨架入口:创建 ProductTypeRegistry 容器单例(新增类型无需改动)
└── README.md 本文件
各类型说明
| 产品类型 | 目录 | source_type | 履约方式 | 售后支持 | 售后期限 | 需物流 | 兼容交易模式 | 用户端路由 |
|---|---|---|---|---|---|---|---|---|
| 实物 | normal/ |
normal_order(+遗留 store_order) |
物流发货 | 退款/退货退款/换货/维修 | 7天 | ✅ | normal/seckill/combination/bargain/integral | route/user.php |
| 虚拟 | virtual/ |
virtual_order |
自动发放 | 退款 | 24小时 | ❌ | normal/seckill | route/user.php |
| 卡密 | cardkey/ |
cardkey_order |
卡密派发 | 退款 | 1小时 | ❌ | normal | route/user.php |
注册机制:一个产品类型 = 三个注册维度
每个产品类型的 App.php 必须完成三项注册,缺一不可:
// modules/product/{type}/App.php
public static function register(ThinkApp $app): void
{
// ① 产品类型 Handler —— 库存/履约/详情扩展/选择契约
$registry = $app->make(ProductTypeRegistry::class);
$registry->register('{type}', \modules\product\{type}\Handler::class);
// ② 订单适配器 —— source_type → 状态树/按钮/进度推导(缺了会抛「未注册的源表类型」异常)
OrderTypeRegistry::register('{type}_order', __NAMESPACE__ . '\handler\{Type}OrderAdapter');
}
public static function boot(ThinkApp $app): void
{
// 加载事件监听器
$eventFile = __DIR__ . '/event.php';
if (is_file($eventFile)) {
$event = include $eventFile;
if (is_array($event)) {
$app->loadEvent($event);
}
}
// ③ 售后规则 —— 按 product_type 维度注册
AfterSaleRuleRegistry::register('product_type', '{type}', {Type}AfterSaleHandler::class);
}
| # | 注册中心 | 单例/实例化来源 | 漏注册的后果 |
|---|---|---|---|
| ① | ProductTypeRegistry |
本目录骨架 product/App.php 容器 instance() 单例 |
类型回退 normal,详情/库存逻辑错乱 |
| ② | OrderTypeRegistry |
纯静态类 | getAdapter() 抛 RuntimeException: 未注册的源表类型 |
| ③ | AfterSaleRuleRegistry |
纯静态注册 | 该类型售后规则缺失,走默认兜底 |
售后规则按两个维度聚合:
order_category(订单大类,goods 由crmeb/trade/order/aftersale/GoodsOrderCategoryProvider.php提供)∩product_type(各类型自声明),详见核心层crmeb/trade/order/aftersale/目录。
兼容性声明
每个产品类型通过 getCompatibility() 声明支持的交易模式:
public function getCompatibility(): array
{
return [
'supported_trade_modes' => ['normal', 'seckill', 'combination'],
'requires_shipping' => true,
'supports_pickup' => true,
'supports_after_sale' => true,
];
}
⚠️ 如实说明:该声明目前是声明性元数据,系统未在运行时强制校验(订单创建不会因组合不兼容而拦截)。新增产品类型/交易模式组合时,需自行在选品与下单校验中保证一致性,并同步维护声明值供人工对齐。
公共结构
{type}/
├── aftersale/ 售后规则处理器({Type}AfterSaleHandler)
├── controller/ 控制器(admin + user)
├── crontab/ 定时任务(normal 有取消/自动收货)
├── dao/ model/ service/ validate/
├── handler/ {Type}OrderAdapter 订单适配器
├── listener/ 事件监听器(详情扩展/支付回调/取消回库存等)
├── pipeline/ 订单创建管线扩展(OrderCreatePipeline)
├── route/ 路由(admin.php / user.php / manage.php,中间件自行引入)
├── App.php 模块注册入口(三项注册)
├── Handler.php 主处理器(继承 BaseProductTypeHandler)
├── Installer.php 安装/卸载
├── event.php 事件注册(key 用大驼峰业务名,禁止带 Listener 后缀)
└── plugin.json 插件元数据(key 如 product_cardkey)
新增产品类型清单(如火车票、网课)
- 建目录
modules/product/{type}/,按公共结构搭建;plugin.jsonkey 用product_{type} - 写 Handler.php:继承
BaseProductTypeHandler,实现getTypeKey()/getTypeName()/getOrderSourceType(),按需覆写getRequiredFields()/afterProductSave()/getSkuInfo()/getDetailExtend()/getSelectionSpec()/decStock()/createOrderExtend()/afterOrder()/afterPay()/onCancel()/getCompatibility() - 写 OrderAdapter:继承
BaseOrderTypeAdapter,实现getSourceType()/getModelClass()/defineStatusTree()/resolveStatusCode()/resolvePayStatus()/getStatusButtons()/getProgress() - 写售后处理器:
aftersale/{Type}AfterSaleHandler,声明可用售后类型/期限/退款标的 - App.php 三项注册(见上节),
boot()加载event.php+ 注册售后规则 - 建扩展表:
eb_pt_{type}/eb_pt_{type}_sku/eb_pt_{type}_order(source_type 全局唯一);表结构由当前模块Installer.php::runMigrate()幂等创建 - 详情页扩展:监听
ProductDetailExtend事件,向display_sections注入展示块(order 区间 10-99)、向extensions注入业态数据——前端核心零改动 - 订单扩展:监听
OrderCenterListExtend/OrderCenterDetailExtend注入列表/详情扩展数据(写回$event['detail']['extend']['{插件标识}']) - Installer:
runMigrate()(建表)→insertMenus()(菜单幂等,pid 动态查询)→seed() - 验证:安装启用 → 后台建商品 → 用户端详情/加购/下单/支付/取消/售后全链路
完整教程见 .trae/skills/crmeb-dev/references/03-系统商品说明/product-type.md。