codex基础代码更新

This commit is contained in:
技术老胡
2026-03-20 10:31:13 +08:00
parent 7e545f0621
commit f3919c9899
36 changed files with 5060 additions and 1459 deletions

View File

@@ -0,0 +1,43 @@
<?php
namespace app\repositories;
use app\common\base\BaseRepository;
use app\models\CallbackInbox;
use Illuminate\Database\QueryException;
/**
* 回调幂等收件箱仓储
*/
class CallbackInboxRepository extends BaseRepository
{
public function __construct()
{
parent::__construct(new CallbackInbox());
}
public function findByEventKey(string $eventKey): ?CallbackInbox
{
return $this->model->newQuery()
->where('event_key', $eventKey)
->first();
}
/**
* 尝试创建幂等事件,重复时返回 false。
*/
public function createIfAbsent(array $data): bool
{
try {
$this->model->newQuery()->create($data);
return true;
} catch (QueryException $e) {
// 1062: duplicate entry
if ((int)($e->errorInfo[1] ?? 0) === 1062) {
return false;
}
throw $e;
}
}
}

View File

@@ -5,9 +5,6 @@ namespace app\repositories;
use app\common\base\BaseRepository;
use app\models\PaymentChannel;
/**
* 支付通道仓储
*/
class PaymentChannelRepository extends BaseRepository
{
public function __construct()
@@ -15,9 +12,6 @@ class PaymentChannelRepository extends BaseRepository
parent::__construct(new PaymentChannel());
}
/**
* 根据商户、应用、支付方式查找可用通道
*/
public function findAvailableChannel(int $merchantId, int $merchantAppId, int $methodId): ?PaymentChannel
{
return $this->model->newQuery()
@@ -35,4 +29,49 @@ class PaymentChannelRepository extends BaseRepository
->where('chan_code', $chanCode)
->first();
}
public function searchPaginate(array $filters = [], int $page = 1, int $pageSize = 10)
{
$query = $this->buildSearchQuery($filters);
$query->orderBy('sort', 'asc')->orderByDesc('id');
return $query->paginate($pageSize, ['*'], 'page', $page);
}
public function searchList(array $filters = [])
{
return $this->buildSearchQuery($filters)
->orderBy('sort', 'asc')
->orderByDesc('id')
->get();
}
private function buildSearchQuery(array $filters = [])
{
$query = $this->model->newQuery();
if (!empty($filters['merchant_id'])) {
$query->where('merchant_id', (int)$filters['merchant_id']);
}
if (!empty($filters['merchant_app_id'])) {
$query->where('merchant_app_id', (int)$filters['merchant_app_id']);
}
if (!empty($filters['method_id'])) {
$query->where('method_id', (int)$filters['method_id']);
}
if (($filters['status'] ?? '') !== '' && $filters['status'] !== null) {
$query->where('status', (int)$filters['status']);
}
if (!empty($filters['plugin_code'])) {
$query->where('plugin_code', (string)$filters['plugin_code']);
}
if (!empty($filters['chan_code'])) {
$query->where('chan_code', 'like', '%' . $filters['chan_code'] . '%');
}
if (!empty($filters['chan_name'])) {
$query->where('chan_name', 'like', '%' . $filters['chan_name'] . '%');
}
return $query;
}
}

View File

@@ -10,6 +10,11 @@ use app\models\PaymentOrder;
*/
class PaymentOrderRepository extends BaseRepository
{
public const STATUS_PENDING = 0;
public const STATUS_SUCCESS = 1;
public const STATUS_FAIL = 2;
public const STATUS_CLOSED = 3;
public function __construct()
{
parent::__construct(new PaymentOrder());
@@ -58,6 +63,82 @@ class PaymentOrderRepository extends BaseRepository
* 后台订单列表:支持筛选与模糊搜索
*/
public function searchPaginate(array $filters = [], int $page = 1, int $pageSize = 10)
{
$query = $this->buildSearchQuery($filters);
$query->orderByDesc('id');
return $query->paginate($pageSize, ['*'], 'page', $page);
}
public function searchList(array $filters = [], int $limit = 5000)
{
return $this->buildSearchQuery($filters)
->orderByDesc('id')
->limit($limit)
->get();
}
public function aggregateByChannel(array $channelIds = [], array $filters = []): array
{
if (empty($channelIds)) {
return [];
}
$query = $this->model->newQuery()
->selectRaw(
'channel_id,
COUNT(*) AS total_orders,
SUM(CASE WHEN status = ? THEN 1 ELSE 0 END) AS success_orders,
SUM(CASE WHEN status = ? THEN 1 ELSE 0 END) AS pending_orders,
SUM(CASE WHEN status = ? THEN 1 ELSE 0 END) AS fail_orders,
SUM(CASE WHEN status = ? THEN 1 ELSE 0 END) AS closed_orders,
COALESCE(SUM(amount), 0) AS total_amount,
COALESCE(SUM(CASE WHEN status = ? THEN amount ELSE 0 END), 0) AS success_amount,
SUM(CASE WHEN DATE(created_at) = CURDATE() THEN 1 ELSE 0 END) AS today_orders,
COALESCE(SUM(CASE WHEN DATE(created_at) = CURDATE() THEN amount ELSE 0 END), 0) AS today_amount,
SUM(CASE WHEN DATE(created_at) = CURDATE() AND status = ? THEN 1 ELSE 0 END) AS today_success_orders,
COALESCE(SUM(CASE WHEN DATE(created_at) = CURDATE() AND status = ? THEN amount ELSE 0 END), 0) AS today_success_amount,
MAX(created_at) AS last_order_at,
MAX(CASE WHEN status = ? THEN pay_at ELSE NULL END) AS last_success_at',
[
self::STATUS_SUCCESS,
self::STATUS_PENDING,
self::STATUS_FAIL,
self::STATUS_CLOSED,
self::STATUS_SUCCESS,
self::STATUS_SUCCESS,
self::STATUS_SUCCESS,
self::STATUS_SUCCESS,
]
)
->whereIn('channel_id', $channelIds);
if (!empty($filters['merchant_id'])) {
$query->where('merchant_id', (int)$filters['merchant_id']);
}
if (!empty($filters['merchant_app_id'])) {
$query->where('merchant_app_id', (int)$filters['merchant_app_id']);
}
if (!empty($filters['method_id'])) {
$query->where('method_id', (int)$filters['method_id']);
}
if (!empty($filters['created_from'])) {
$query->where('created_at', '>=', $filters['created_from']);
}
if (!empty($filters['created_to'])) {
$query->where('created_at', '<=', $filters['created_to']);
}
$rows = $query->groupBy('channel_id')->get();
$result = [];
foreach ($rows as $row) {
$result[(int)$row->channel_id] = $row->toArray();
}
return $result;
}
private function buildSearchQuery(array $filters = [])
{
$query = $this->model->newQuery();
@@ -73,6 +154,28 @@ class PaymentOrderRepository extends BaseRepository
if (!empty($filters['channel_id'])) {
$query->where('channel_id', (int)$filters['channel_id']);
}
if (!empty($filters['route_policy_name'])) {
$query->whereRaw(
"JSON_UNQUOTE(JSON_EXTRACT(extra, '$.routing.policy.policy_name')) like ?",
['%' . $filters['route_policy_name'] . '%']
);
}
if (($filters['route_state'] ?? '') !== '' && $filters['route_state'] !== null) {
$routeState = (string)$filters['route_state'];
if ($routeState === 'error') {
$query->whereRaw("JSON_EXTRACT(extra, '$.route_error') IS NOT NULL");
} elseif ($routeState === 'none') {
$query->whereRaw("JSON_EXTRACT(extra, '$.route_error') IS NULL");
$query->whereRaw(
"(JSON_UNQUOTE(JSON_EXTRACT(extra, '$.routing.source')) IS NULL OR JSON_UNQUOTE(JSON_EXTRACT(extra, '$.routing.source')) = '')"
);
} else {
$query->whereRaw(
"JSON_EXTRACT(extra, '$.route_error') IS NULL AND JSON_UNQUOTE(JSON_EXTRACT(extra, '$.routing.source')) = ?",
[$routeState]
);
}
}
if (($filters['status'] ?? '') !== '' && $filters['status'] !== null) {
$query->where('status', (int)$filters['status']);
}
@@ -89,7 +192,6 @@ class PaymentOrderRepository extends BaseRepository
$query->where('created_at', '<=', $filters['created_to']);
}
$query->orderByDesc('id');
return $query->paginate($pageSize, ['*'], 'page', $page);
return $query;
}
}