Commit f4139d0a authored by wangzhengwen's avatar wangzhengwen

订单超时

parent c57cddac
...@@ -63,7 +63,7 @@ class Project extends BaseController ...@@ -63,7 +63,7 @@ class Project extends BaseController
$token = $request->header('token'); $token = $request->header('token');
if ($token) if ($token)
{ {
$userId = UserService::getUserInfo($token)['id']; $userId = UserService::getUserInfo($token)['id'] ?? 0;
} }
......
<?php
namespace app\api\controller\task;
use app\api\service\PayService;
class order
{
public function run()
{
$res = PayService::orderTimeOut();;
return json(['code'=>1,'msg'=>$res]);
}
}
\ No newline at end of file
...@@ -10,15 +10,28 @@ class PayService ...@@ -10,15 +10,28 @@ class PayService
const PAY_METHOD_ALIPAY = 1; const PAY_METHOD_ALIPAY = 1;
const PAY_METHOD_WECHAT = 2; const PAY_METHOD_WECHAT = 2;
// 支付状态 // 支付状态 未支付
const PAY_STATUS_UNPAID = 0; const PAY_STATUS_UNPAID = 0;
//成功
const PAY_STATUS_SUCCESS = 1; const PAY_STATUS_SUCCESS = 1;
//失败
const PAY_STATUS_FAILED = 2; const PAY_STATUS_FAILED = 2;
//超时
const PAY_STATUS_TIMEOUT = 3;
// 订单类型 // 订单类型
const ORDER_TYPE_COURSE = 1; const ORDER_TYPE_COURSE = 1;
const ORDER_TYPE_CERT = 2; const ORDER_TYPE_CERT = 2;
// 订单超时时间(单位:秒)
const ORDER_TIMEOUT = 7200;
// 每次处理的订单数量限制
const BATCH_LIMIT = 100;
/** /**
* 创建支付订单 * 创建支付订单
* @param int $userId 用户ID * @param int $userId 用户ID
...@@ -61,7 +74,7 @@ class PayService ...@@ -61,7 +74,7 @@ class PayService
'req_info' => json_encode($reqInfo, JSON_UNESCAPED_UNICODE), 'req_info' => json_encode($reqInfo, JSON_UNESCAPED_UNICODE),
'createtime' => time(), 'createtime' => time(),
'updatetime' => time(), 'updatetime' => time(),
'expire_time' => time() + 7200 // 2小时过期 'expire_time' => time() + self::ORDER_TIMEOUT // 2小时过期
]; ];
// 写入数据库 // 写入数据库
$paymentId = Db::name('payment')->insertGetId($paymentData); $paymentId = Db::name('payment')->insertGetId($paymentData);
...@@ -120,6 +133,12 @@ class PayService ...@@ -120,6 +133,12 @@ class PayService
return true; return true;
} }
// 检查订单是否过期
if (isset($payment['expire_time']) && $payment['expire_time'] > 0
&& $payment['expire_time'] < time()) {
throw new \Exception("支付订单已过期: {$orderNo}");
}
// 验证金额 // 验证金额
$amount = $payment['pay_method'] == self::PAY_METHOD_ALIPAY ? $amount = $payment['pay_method'] == self::PAY_METHOD_ALIPAY ?
$notifyData['total_amount'] : ($notifyData['amount']['total'] / 100); $notifyData['total_amount'] : ($notifyData['amount']['total'] / 100);
...@@ -194,4 +213,130 @@ class PayService ...@@ -194,4 +213,130 @@ class PayService
return $payMethod == self::PAY_METHOD_ALIPAY ? return $payMethod == self::PAY_METHOD_ALIPAY ?
config('pay.alipay') : config('pay.wechat'); config('pay.alipay') : config('pay.wechat');
} }
/**订单过期
* @return array
*/
public static function orderTimeOut()
{
$startTime = time();
Log::info("开始执行支付超时订单检查任务");
try {
$expireTime = $startTime - self::ORDER_TIMEOUT;
// 查询未支付且已过期的订单
$orders = Db::name('payment')
->where('pay_status', '=', self::PAY_STATUS_UNPAID)
->where(function($query) use ($expireTime, $startTime) {
$query->where('expire_time', '<', $startTime)
->where('expire_time', '>', 0)
->whereOr('createtime', '<', $expireTime);
})
->limit(self::BATCH_LIMIT)
->select();
if (empty($orders)) {
$msg = "没有需要处理的超时订单";
Log::info($msg);
return [
'status' => true,
'code' => 200,
'message' => $msg,
'data' => [
'processed_count' => 0,
'success_count' => 0
]
];
}
$successCount = 0;
foreach ($orders as $order) {
Db::startTrans();
try {
// 再次检查状态防止并发处理
$currentStatus = Db::name('payment')
->where('id', $order['id'])
->lock(true)
->value('pay_status');
if ($currentStatus != self::PAY_STATUS_UNPAID) {
Db::commit();
continue;
}
// 更新为超时状态
$result = Db::name('payment')
->where('id', $order['id'])
->update([
'pay_status' => self::PAY_STATUS_TIMEOUT,
'updatetime' => time(),
'pay_info' => json_encode(['timeout_reason' => '系统自动取消'])
]);
if ($result) {
// 处理订单取消后的业务逻辑
// self::handleBusinessAfterTimeout($order);
$successCount++;
}
Db::commit();
} catch (\Exception $e) {
Db::rollback();
Log::error("处理超时订单失败: {$order['order_no']} - " . $e->getMessage());
}
}
$msg = "支付超时订单处理完成";
Log::info("{$msg},共处理: " . count($orders) . "条,成功: {$successCount}条");
return [
'status' => true,
'code' => 200,
'message' => $msg,
'data' => [
'total_count' => count($orders),
'processed_count' => count($orders),
'success_count' => $successCount,
'failed_count' => count($orders) - $successCount
]
];
} catch (\Exception $e) {
$errorMsg = "支付超时订单任务执行失败: " . $e->getMessage();
Log::error($errorMsg);
return [
'status' => false,
'code' => 500,
'message' => $errorMsg,
'data' => []
];
}
}
/**
* 订单超时后的业务处理
*/
protected static function handleBusinessAfterTimeout($order)
{
// 根据你的业务需求实现
// 例如:释放库存、通知用户等
// 示例代码:
try {
// 1. 记录日志
Log::info("订单超时处理: {$order['order_no']}");
// 2. 如果是商品订单,可以释放库存
// $this->releaseStock($order);
// 3. 发送通知给用户
// $this->sendTimeoutNotice($order);
} catch (\Exception $e) {
Log::error("订单超时后处理业务失败: {$order['order_no']} - " . $e->getMessage());
}
}
} }
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment