文件
xionggeshop/addons/shopro/job/OrderAutoOper.php
可乐加冰 c264a7d30c feat(order): 新增自动确认过期命令并优化确认收货队列逻辑
- 注册 AutoConfirmOverdue 命令行任务以处理过期订单。
- 优化 autoConfirm 方法,增强参数提取与数据查询的健壮性。
- 增加确认收货成功与跳过的详细日志,便于后续问题排查。
- 新增 autoConfirmSkipReason 方法,精准区分任务跳过原因。
- 完善异常捕获注释,明确失败时不删除任务以便回流重试。
2026-11-05 08:50:34 +08:00

171 行
6.9 KiB
PHP

此文件含有模棱两可的 Unicode 字符

此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。

<?php
namespace addons\shopro\job;
use addons\shopro\model\GoodsComment;
use addons\shopro\model\Order;
use addons\shopro\model\OrderAction;
use addons\shopro\model\OrderItem;
use addons\shopro\model\Config;
use think\queue\Job;
/**
* 订单自动操作
*/
class OrderAutoOper extends BaseJob
{
/**
* 订单自动关闭
*/
public function autoClose(Job $job, $data){
try {
$order = $data['order'];
// 重新查询订单
$order = Order::get($order['id']);
if ($order && $order['status'] == 0) {
\think\Db::transaction(function () use ($order, $data) {
// 订单关闭前
\think\Hook::listen('order_close_before', $data);
// 执行关闭
$order->status = Order::STATUS_INVALID;
$order->ext = json_encode($order->setExt($order, ['invalid_time' => time()])); // 取消时间
$order->save();
OrderAction::operAdd($order, null, null, 'system', '系统自动失效订单');
// 订单自动关闭之后 行为 返还用户优惠券,积分
$data = ['order' => $order];
\think\Hook::listen('order_close_after', $data);
});
}
// 删除 job
$job->delete();
} catch (\Exception $e) {
// 队列执行失败
\think\Log::write('queue-' . get_class() . '-autoClose' . ':执行失败,错误信息:' . $e->getMessage());
}
}
/**
* 订单自动确认
*/
public function autoConfirm(Job $job, $data) {
try {
$orderData = $data['order'] ?? null;
$itemData = $data['item'] ?? null;
$orderId = (is_array($orderData) || is_object($orderData)) ? (int) ($orderData['id'] ?? 0) : 0;
$itemId = (is_array($itemData) || is_object($itemData)) ? (int) ($itemData['id'] ?? 0) : 0;
// 重新查询订单
$order = $orderId ? Order::get($orderId) : null;
// 只要没有退款成功,所有队列正常执行
$item = $itemId ? OrderItem::where('id', $itemId)
->where('dispatch_status', OrderItem::DISPATCH_STATUS_SENDED)
->where('refund_status', 'not in', [OrderItem::REFUND_STATUS_OK, OrderItem::REFUND_STATUS_FINISH])
->find() : null;
if ($order && $item) {
\think\Db::transaction(function () use ($order, $item) {
(new Order())->getedItem($order, $item, ['oper_type' => 'system']);
});
\think\Log::write('queue-' . get_class() . '-autoConfirm:确认收货成功 order_id=' . $orderId . ' item_id=' . $itemId);
} else {
$reason = $this->autoConfirmSkipReason($orderId, $itemId, $order);
\think\Log::write('queue-' . get_class() . '-autoConfirm:跳过 ' . $reason);
}
// 删除 job
$job->delete();
} catch (\Exception $e) {
// 队列执行失败(不 delete,便于 reserved 回流重试)
\think\Log::write('queue-' . get_class() . '-autoConfirm' . ':执行失败,错误信息:' . $e->getMessage());
}
}
/**
* 自动确认跳过原因(便于区分丢任务 vs 空跑)
*/
protected function autoConfirmSkipReason($orderId, $itemId, $order)
{
if (!$orderId || !$itemId) {
return 'payload缺少order/item id';
}
if (!$order) {
return 'order_id=' . $orderId . ' 订单不存在';
}
$raw = OrderItem::where('id', $itemId)->find();
if (!$raw) {
return 'order_id=' . $orderId . ' item_id=' . $itemId . ' 明细不存在';
}
if ((int) $raw['dispatch_status'] !== OrderItem::DISPATCH_STATUS_SENDED) {
return 'order_id=' . $orderId . ' item_id=' . $itemId
. ' dispatch_status=' . $raw['dispatch_status'] . '(非已发货)';
}
if (in_array((int) $raw['refund_status'], [OrderItem::REFUND_STATUS_OK, OrderItem::REFUND_STATUS_FINISH], true)) {
return 'order_id=' . $orderId . ' item_id=' . $itemId
. ' refund_status=' . $raw['refund_status'] . '(已退款)';
}
return 'order_id=' . $orderId . ' item_id=' . $itemId . ' 未知原因';
}
public function autoComment(Job $job, $data) {
try {
$order = $data['order'];
$item = $data['item'];
// 重新查询订单
$order = Order::get($order['id']);
// 只要没有退款成功,所有队列正常执行
$item = OrderItem::where('id', $item['id'])
->where('dispatch_status', OrderItem::DISPATCH_STATUS_GETED)
->where('comment_status', OrderItem::COMMENT_STATUS_NO)
->where('refund_status', 'not in', [OrderItem::REFUND_STATUS_OK, OrderItem::REFUND_STATUS_FINISH])
->find();
if ($order && $item) {
\think\Db::transaction(function () use ($order, $item, $data) {
// 订单评价前
\think\Hook::listen('order_comment_before', $data);
// 获取自动好评内容
$config = Config::where('name', 'order')->cache(300)->find(); // 读取配置自动缓存 5 分钟
$config = isset($config) ? json_decode($config['value'], true) : [];
$comment_content = (isset($config['order_comment_content']) && $config['order_comment_content'])
? $config['order_comment_content'] : '用户默认好评'; // 单位天
GoodsComment::create([
'goods_id' => $item['goods_id'],
'order_id' => $order['id'],
'user_id' => $order['user_id'],
'level' => 5, // 自动好评
'content' => $comment_content,
'images' => '',
'status' => 'show'
]);
$item->comment_status = OrderItem::COMMENT_STATUS_OK; // 评价成功
$item->save();
OrderAction::operAdd($order, $item, null, 'system', '系统自动评价成功');
// 订单评价后
$data = ['order' => $order, 'item' => $item];
\think\Hook::listen('order_comment_after', $data);
});
}
// 删除 job
$job->delete();
} catch (\Exception $e) {
// 队列执行失败
\think\Log::write('queue-' . get_class() . '-autoComment' . $e->getMessage());
}
}
}