You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
yanzong/app/timer/service/groupon/Task.php

180 lines
6.7 KiB

<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\timer\service\groupon;
use app\common\library\helper;
use app\timer\library\Tools;
use app\timer\model\Order as OrderModel;
use app\timer\model\groupon\Task as TaskModel;
use app\timer\model\groupon\Setting as SettingModel;
use app\common\service\Order as OrderService;
use app\common\service\order\Refund as RefundService;
use app\common\enum\order\OrderStatus as OrderStatusEnum;
use app\common\service\BaseService;
/**
* 服务类:拼团拼单任务
* Class Task
* @package app\timer\service\groupon
*/
class Task extends BaseService
{
/**
* 拼单失败事件
* @param int $storeId
* @return bool
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function taskFailEvent(int $storeId): bool
{
// 获取已失效的拼单ID集
$model = new TaskModel;
$taskIds = $model->getFailTaskIds($storeId);
// 记录日志
Tools::taskLogs('GrouponTask', 'taskFailEvent', [
'title' => '拼单失败事件',
'storeId' => $storeId,
'taskIds' => helper::jsonEncode($taskIds),
]);
// 将拼团失败的订单退款处理
$this->refundFailOrder($storeId, $taskIds);
// 标记拼单失效状态
return empty($taskIds) || $model->setStatusFail($taskIds);
}
/**
* 拼单模拟成团事件
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function taskMockEvent(int $storeId)
{
// 获取模拟成团的拼单
$model = new TaskModel;
$taskList = $model->getMockTaskList($storeId);
// 拼单任务ID集
$taskIds = helper::getArrayColumn($taskList, 'task_id');
// 批量将拼单模拟成团
if (!empty($taskIds)) {
foreach ($taskList as $task) {
$model->mockTask($task, $storeId);
}
}
// 记录日志
Tools::taskLogs('GrouponTask', 'taskMockEvent', [
'title' => '拼单模拟成团事件',
'robotIds' => helper::jsonEncode($taskIds),
]);
}
/**
* 拼单完成事件
* @param int $storeId
* @return bool
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function taskCompleteEvent(int $storeId): bool
{
// 获取已完成的拼单ID集
$model = new TaskModel;
$taskIds = $model->getCompleteTaskIds($storeId);
// 记录日志
Tools::taskLogs('GrouponTask', 'taskCompleteEvent', [
'title' => '拼单完成事件',
'storeId' => $storeId,
'taskIds' => helper::jsonEncode($taskIds),
]);
// 将已完成拼单的未付款订单取消
$this->cancelCompleteOrder($storeId, $taskIds);
return true;
}
/**
* 将拼团失败的订单退款处理
* @param int $storeId
* @param array $taskIds
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
private function refundFailOrder(int $storeId, array $taskIds)
{
// 是否开启拼单失败自动退款
if (!SettingModel::taskFailAutoRefund($storeId)) {
return;
}
// 查询拼团拼单失败的已付款订单
$model = new OrderModel;
$list = $model->getListByGrouponTaskFail($storeId, $taskIds);
// 订单ID集
$orderIds = helper::getArrayColumn($list, 'order_id');
// 用于记录退款失败的订单ID
$invalidOrderIds = [];
if (!empty($orderIds)) {
foreach ($list as $order) {
try {
// 执行订单退款并关闭
(new RefundService)->handle($order) && OrderService::cancelEvent($order);
} catch (\Throwable $e) {
$invalidOrderIds[] = $order['order_id'];
}
}
// 批量更新订单状态为已取消
$result = array_diff($orderIds, $invalidOrderIds);
!empty($result) && $model->onBatchUpdate($result, ['order_status' => OrderStatusEnum::CANCELLED]);
}
// 记录日志
Tools::taskLogs('GrouponTask', 'refundFailOrder', [
'title' => '将到期的拼团订单退款处理',
'storeId' => $storeId,
'orderIds' => helper::jsonEncode($orderIds),
'invalidOrderIds' => helper::jsonEncode($invalidOrderIds),
]);
}
/**
* 将已完成拼单的未付款订单取消
* @param int $storeId
* @param array $taskIds
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
private function cancelCompleteOrder(int $storeId, array $taskIds)
{
// 查询拼团拼单已完成的未付款订单
$model = new OrderModel;
$list = $model->getListByGrouponTaskComplete($storeId, $taskIds);
// 订单ID集
$orderIds = helper::getArrayColumn($list, 'order_id');
// 用于记录退款失败的订单ID
if (!empty($orderIds)) {
foreach ($list as $order) {
OrderService::cancelEvent($order);
}
// 批量更新订单状态为已取消
$model->onBatchUpdate($orderIds, ['order_status' => OrderStatusEnum::CANCELLED]);
}
// 记录日志
Tools::taskLogs('GrouponTask', 'cancelCompleteOrder', [
'title' => '将已完成拼单的未付款订单取消',
'storeId' => $storeId,
'orderIds' => helper::jsonEncode($orderIds),
]);
}
}