摘要
商城二开最怕的不是多写一个功能,而是订单、退款、库存、活动这些关键链路出问题以后,等用户投诉才发现。AI 在这里最适合做的不是"自动处理退款"或"自动改库存",而是把系统已经产生的事件、日志、统计数据整理成风险提醒,让运营和技术提前看到异常。
这篇做一个 AI 风控提醒思路:退款异常、库存异常、秒杀异常怎么从 CRMEB Pro 现有代码里找信号,怎么交给 AI 生成可读预警,以及哪些动作绝不能让 AI 自动执行。
1. 风控提醒应该先看哪些链路
推荐先从三条链路做:
text
退款链路:退款状态、拆单退款、赠品订单、优惠券回退、外部推送
库存链路:SKU 库存、商品总库存、库存流水、库存预警
活动链路:秒杀/直播/促销活动库存、限购、活动状态、订单扣减
对应核心文件:
text
app/listener/order/Refund.php
app/services/order/StoreOrderRefundServices.php
app/services/order/StoreOrderCreateServices.php
app/services/product/product/StoreProductServices.php
app/jobs/product/ProductLogJob.php
app/jobs/product/ProductStockTips.php
app/services/activity/seckill/StoreSeckillServices.php
app/services/statistic/TradeStatisticServices.php
AI 的定位是"读取信号、解释风险、给出建议",不是代替系统处理订单。
2. 退款事件里已经有很多风险信号
退款监听器在:
text
app/listener/order/Refund.php
它不是只把订单改成已退款,而是会牵动发票、供应商流水、资金流水、商品日志、优惠券、小程序同步、外部推送和直播统计。
关键逻辑如下:
php
public function handle($event): void
{
[$data, $order] = $event;
$order = is_array($order) ? $order : $order->toArray();
$orderInvoiceServices = app()->make(StoreOrderInvoiceServices::class);
$orderInvoiceServices->update(['order_id' => $order['id']], ['is_refund' => 1]);
SupplierFinanceJob::dispatch([$order['id'], 2]);
CapitalFlowJob::dispatch([array_merge($order, [
'refund_price' => $data['refund_price']
]), 'refund']);
if ($order['supplier_id']) {
SupplierFinanceJob::dispatchDo('takeDoJob', [$order, time()]);
}
ProductLogJob::dispatch(['refund', [
'uid' => $order['uid'],
'order_id' => $order['id']
]]);
event('notice.notice', [['data' => $data, 'order' => $order], 'order_refund']);
}
这些都是 AI 风控可以利用的信号:
text
某商品退款日志突然增多
供应商订单退款集中出现
退款金额和订单金额接近或异常
退款后资金流水、发票、小程序同步是否完整
AI 不需要知道用户隐私,只需要订单维度的脱敏统计。
3. 拆单退款和赠品订单是高风险点
退款监听器里对主子订单做了专门处理:
php
if ($order['pid']) {
$id = (int)$order['pid'];
$refund_data = ['refund_status' => 2, 'refund_type' => 6];
$change_type = 'refund_split';
$change_message = '已拆分退款';
$noRefundOrders = $orderServices->getList([
'pid' => $id,
'refund_status' => 0
]);
$normalOrderCount = 0;
$giftOrderIds = [];
foreach ($noRefundOrders as $noRefundOrder) {
$is_gift = $storeOrderCartInfoServices->value(
['oid' => $noRefundOrder['id']],
'is_gift'
);
if ($is_gift) {
$giftOrderIds[] = $noRefundOrder['id'];
} else {
$normalOrderCount++;
}
}
if ($normalOrderCount == 0) {
foreach ($giftOrderIds as $giftOrderId) {
$orderServices->update($giftOrderId, $refund_data);
OrderStatusJob::dispatch([$giftOrderId, $change_type, [
'change_message' => $change_message,
'change_manager_id' => request()->adminId(),
'change_manager_type' => 'admin'
]]);
}
} else {
$refund_data = ['refund_status' => '3', 'refund_type' => 4];
$change_type = 'refund_part_split';
$change_message = '已拆分部分退款';
}
$orderServices->update($id, $refund_data);
OrderStatusJob::dispatch([$id, $change_type, [
'change_message' => $change_message,
'change_manager_id' => request()->adminId(),
'change_manager_type' => 'admin'
]]);
}
这里最适合做 AI 风控提醒:
text
同一主订单下子订单连续退款
普通商品都退款后,赠品订单是否被正确处理
部分退款状态是否长期停留
订单状态记录是否缺失
AI 可以生成这样的提醒:
text
风险类型:拆单退款异常
影响对象:主订单维度
判断依据:近 30 分钟内同一主订单出现多笔子订单退款,且仍有赠品订单未同步退款状态
建议动作:运营复查售后单;技术检查退款监听器和状态 Job 是否执行成功
4. 退款完成后还有优惠券和外部同步
退款监听器后半段还有这些动作:
php
ProductCouponJob::dispatchSece(5, 'failureProductCoupon', [$order]);
$id = $order['pid'] ? $order['pid'] : $order['id'];
$orderInfo = $orderServices->get($id);
$orderInfo = $orderInfo->toArray();
if ($orderInfo['refund_status'] == 2) {
StorePromotionsJob::dispatchSece(10, 'failureCoupon', [$orderInfo]);
$storeOrderRefundfoServices->syncRefundToMiniProgram($orderInfo);
}
event('out.outPush', ['refund_create_push', [
'order_id' => (int)$order['id']
]]);
event('live.order.stats', [$order]);
这说明退款风控不能只看 refund_status,还要看后续动作是否完成:
text
赠品优惠券是否失效
营销活动赠券是否回退
小程序订单管理是否同步
对外接口是否推送
直播订单统计是否刷新
AI 可以把"退款状态已完成,但后续动作失败或延迟"的订单列成异常清单。
5. 库存异常从哪里抓信号
普通商品库存扣减在 StoreProductServices::decProductStock():
php
public function decProductStock(int $num, int $productId, string $unique = '')
{
$res = true;
if ($unique) {
$skuValueServices = app()->make(StoreProductAttrValueServices::class);
$res = $res && $skuValueServices->decProductAttrStock($productId, $unique, $num);
$skuValueServices->decMarketingProductStock($productId, $unique, $num);
}
$res = $res && $this->dao->decStockIncSales(['id' => $productId], $num);
if ($res) {
$this->workSendStock($productId);
}
$this->clearProductCache();
return $res;
}
这里有几个可用于风控的点:
text
SKU 库存扣减是否成功
营销活动库存是否同步扣减
商品主表销量和库存是否同步变化
库存预警 Job 是否触发
缓存是否清理
库存增加也要关注:
php
public function incProductStock(int $num, int $productId, string $unique = '')
{
$res = true;
if ($unique) {
$skuValueServices = app()->make(StoreProductAttrValueServices::class);
$res = $res && $skuValueServices->incProductAttrStock($productId, $unique, $num);
}
$res = $res && $this->dao->incStockDecSales(['id' => $productId], $num);
$this->clearProductCache();
return $res;
}
AI 风控可以做成每天或每小时扫描:
text
库存低于警戒线但仍在售
SKU 库存为 0 但商品主表未售罄
活动库存和普通库存差异异常
短时间扣库存失败集中出现
退款后库存回退异常
6. 秒杀异常要同时看活动库存和普通库存
秒杀下单不是只扣普通商品库存,订单创建时会根据活动类型扣不同库存:
php
if ($type == 1) {
$seckillServices = app()->make(StoreSeckillServices::class);
$res5 = $res5 && $seckillServices->decSeckillStock(
$cart_num,
$activity_id,
$unique,
$store_id
);
} else {
$productServices = app()->make(StoreProductServices::class);
$res5 = $res5 && $productServices->decProductStock(
$cart_num,
$product_id,
$unique
);
}
if (!$res5) {
throw new ValidateException('库存不足!');
}
AI 风控适合识别这些情况:
text
秒杀活动显示还有库存,但下单连续提示库存不足
普通商品库存充足,活动库存不足
同一 SKU 在活动库存和普通库存之间出现异常差异
活动结束后仍有扣减请求
这些问题不适合让 AI 自动修复,因为涉及订单和库存一致性;AI 只应该给出"风险提醒 + 需要人工检查的代码链路"。
7. 给 AI 的风控上下文应该脱敏
推荐传给 AI 的结构:
php
[
'window' => '最近30分钟',
'refund' => [
'total_refund_orders' => 18,
'split_refund_orders' => 5,
'gift_order_pending' => 2,
'mini_program_sync_failed' => 1,
],
'stock' => [
'low_stock_products' => 12,
'sku_zero_product_showing' => 3,
'stock_dec_failed' => 4,
],
'activity' => [
'seckill_stock_warning' => 2,
'activity_order_failed' => 3,
],
'rules' => [
'只输出风险等级、原因、建议动作',
'不要输出用户手机号、地址、昵称',
'不要自动修改订单、库存、退款状态',
],
]
推荐输出结构:
json
{
"level": "high",
"title": "秒杀库存扣减异常升高",
"reason": "最近30分钟同一活动出现多次库存不足失败,且普通商品库存仍充足",
"impact": "可能影响用户下单成功率,也可能说明活动库存和普通库存口径不一致",
"actions": [
"检查 StoreSeckillServices::checkSeckillStock",
"检查 StoreOrderCreateServices 扣库存分支",
"核对活动 SKU 和普通商品 SKU 库存"
]
}
8. 风控提醒可以做成三个等级
建议把 AI 输出分成三类,不要一上来就做复杂自动化:
text
低风险:数据波动,建议观察
中风险:需要运营复查,例如退款率、库存低、活动转化异常
高风险:需要技术介入,例如库存扣减失败、退款后续同步失败、活动下单失败集中出现
后台展示时可以按:
text
风险等级
影响模块
命中规则
项目源码链路
建议动作
是否已处理
处理备注
这样比"AI 给一段大作文"更好落地。
9. 注意事项
- AI 风控只做提醒,不自动退款、不自动改库存、不自动上下架。
- 订单、库存、退款属于高风险业务,必须保留人工确认。
- 传给 AI 的数据要脱敏,不传手机号、地址、客户备注、支付流水号。
- 风控规则要先用后端代码算出命中结果,再让 AI 解释和总结。
- 退款、库存、活动的口径要复用现有 Service/Dao,不要在 Controller 里临时拼 SQL。
- 风控提醒需要有"已读、处理中、已处理、忽略"状态,避免每天重复告警。
- 高风险提醒建议同步到后台消息或企业微信,但发送前要控制频率。
标签建议
text
CRMEB Pro
二次开发
AI风控
商城系统
订单退款
库存管理
秒杀活动
PHP
ThinkPHP