mirror of
https://gitee.com/technical-laohu/mpay_v2_webman.git
synced 2026-04-26 20:14:26 +08:00
重构初始化
This commit is contained in:
@@ -1,31 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\repositories;
|
||||
|
||||
use app\common\base\BaseRepository;
|
||||
use app\models\Admin;
|
||||
|
||||
/**
|
||||
* 管理员仓储
|
||||
*/
|
||||
class AdminRepository extends BaseRepository
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(new Admin());
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户名查询
|
||||
*/
|
||||
public function findByUserName(string $userName): ?Admin
|
||||
{
|
||||
/** @var Admin|null $admin */
|
||||
$admin = $this->model
|
||||
->newQuery()
|
||||
->where('user_name', $userName)
|
||||
->first();
|
||||
|
||||
return $admin;
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
<?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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\repositories;
|
||||
|
||||
use app\common\base\BaseRepository;
|
||||
use app\models\MerchantApp;
|
||||
|
||||
/**
|
||||
* 商户应用仓储
|
||||
*/
|
||||
class MerchantAppRepository extends BaseRepository
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(new MerchantApp());
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据AppId查询
|
||||
*/
|
||||
public function findByAppId(string $appId): ?MerchantApp
|
||||
{
|
||||
return $this->model->newQuery()
|
||||
->where('app_code', $appId)
|
||||
->where('status', 1)
|
||||
->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据商户ID和应用ID查询
|
||||
*/
|
||||
public function findByMerchantAndApp(int $merchantId, int $appId): ?MerchantApp
|
||||
{
|
||||
return $this->model->newQuery()
|
||||
->where('mer_id', $merchantId)
|
||||
->where('id', $appId)
|
||||
->where('status', 1)
|
||||
->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据商户ID和应用ID(app_id)查询
|
||||
*/
|
||||
public function findByMerchantAndAppId(int $merchantId, string $appId): ?MerchantApp
|
||||
{
|
||||
return $this->model->newQuery()
|
||||
->where('mer_id', $merchantId)
|
||||
->where('app_code', $appId)
|
||||
->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* 后台按 app_id 查询(不过滤状态)
|
||||
*/
|
||||
public function findAnyByAppId(string $appId): ?MerchantApp
|
||||
{
|
||||
return $this->model->newQuery()
|
||||
->where('app_code', $appId)
|
||||
->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* 后台列表:支持筛选与模糊搜索
|
||||
*/
|
||||
public function searchPaginate(array $filters = [], int $page = 1, int $pageSize = 10)
|
||||
{
|
||||
$query = $this->model->newQuery();
|
||||
|
||||
if (!empty($filters['merchant_id'])) {
|
||||
$query->where('mer_id', (int)$filters['merchant_id']);
|
||||
}
|
||||
if (($filters['status'] ?? '') !== '' && $filters['status'] !== null) {
|
||||
$query->where('status', (int)$filters['status']);
|
||||
}
|
||||
if (!empty($filters['app_id'])) {
|
||||
$query->where('app_code', 'like', '%' . $filters['app_id'] . '%');
|
||||
}
|
||||
if (!empty($filters['app_name'])) {
|
||||
$query->where('app_name', 'like', '%' . $filters['app_name'] . '%');
|
||||
}
|
||||
if (!empty($filters['api_type'])) {
|
||||
$query->where('api_type', (string)$filters['api_type']);
|
||||
}
|
||||
if (!empty($filters['package_code'])) {
|
||||
$query->where('package_code', (string)$filters['package_code']);
|
||||
}
|
||||
if (($filters['notify_enabled'] ?? '') !== '' && $filters['notify_enabled'] !== null) {
|
||||
$query->where('notify_enabled', (int)$filters['notify_enabled']);
|
||||
}
|
||||
if (!empty($filters['callback_mode'])) {
|
||||
$query->where('callback_mode', (string)$filters['callback_mode']);
|
||||
}
|
||||
|
||||
$query->orderByDesc('id');
|
||||
|
||||
return $query->paginate($pageSize, ['*'], 'page', $page);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\repositories;
|
||||
|
||||
use app\common\base\BaseRepository;
|
||||
use app\models\Merchant;
|
||||
|
||||
/**
|
||||
* 商户仓储
|
||||
*/
|
||||
class MerchantRepository extends BaseRepository
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(new Merchant());
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据商户号查询
|
||||
*/
|
||||
public function findByMerchantNo(string $merchantNo): ?Merchant
|
||||
{
|
||||
return $this->model->newQuery()
|
||||
->where('merchant_no', $merchantNo)
|
||||
->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* 后台列表:支持模糊搜索
|
||||
*/
|
||||
public function searchPaginate(array $filters = [], int $page = 1, int $pageSize = 10)
|
||||
{
|
||||
$query = $this->model->newQuery();
|
||||
|
||||
if (($filters['status'] ?? '') !== '' && $filters['status'] !== null) {
|
||||
$query->where('status', (int)$filters['status']);
|
||||
}
|
||||
if (!empty($filters['merchant_no'])) {
|
||||
$query->where('merchant_no', 'like', '%' . $filters['merchant_no'] . '%');
|
||||
}
|
||||
if (!empty($filters['merchant_name'])) {
|
||||
$query->where('merchant_name', 'like', '%' . $filters['merchant_name'] . '%');
|
||||
}
|
||||
if (!empty($filters['email'])) {
|
||||
$query->where('email', 'like', '%' . $filters['email'] . '%');
|
||||
}
|
||||
if (isset($filters['balance']) && $filters['balance'] !== '') {
|
||||
$query->where('balance', (string)$filters['balance']);
|
||||
}
|
||||
|
||||
$query->orderByDesc('id');
|
||||
|
||||
return $query->paginate($pageSize, ['*'], 'page', $page);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\repositories;
|
||||
|
||||
use app\common\base\BaseRepository;
|
||||
use app\models\PaymentCallbackLog;
|
||||
|
||||
/**
|
||||
* 支付回调日志仓储
|
||||
*/
|
||||
class PaymentCallbackLogRepository extends BaseRepository
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(new PaymentCallbackLog());
|
||||
}
|
||||
|
||||
public function createLog(array $data): PaymentCallbackLog
|
||||
{
|
||||
return $this->model->newQuery()->create($data);
|
||||
}
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\repositories;
|
||||
|
||||
use app\common\base\BaseRepository;
|
||||
use app\models\PaymentChannel;
|
||||
|
||||
class PaymentChannelRepository extends BaseRepository
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(new PaymentChannel());
|
||||
}
|
||||
|
||||
public function findAvailableChannel(int $merchantId, int $merchantAppId, int $methodId): ?PaymentChannel
|
||||
{
|
||||
return $this->model->newQuery()
|
||||
->where('mer_id', $merchantId)
|
||||
->where('app_id', $merchantAppId)
|
||||
->where('pay_type_id', $methodId)
|
||||
->where('status', 1)
|
||||
->orderBy('sort', 'asc')
|
||||
->first();
|
||||
}
|
||||
|
||||
public function findByChanCode(string $chanCode): ?PaymentChannel
|
||||
{
|
||||
return $this->model->newQuery()
|
||||
->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('mer_id', (int)$filters['merchant_id']);
|
||||
}
|
||||
if (!empty($filters['merchant_app_id'])) {
|
||||
$query->where('app_id', (int)$filters['merchant_app_id']);
|
||||
}
|
||||
if (!empty($filters['method_id'])) {
|
||||
$query->where('pay_type_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;
|
||||
}
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\repositories;
|
||||
|
||||
use app\common\base\BaseRepository;
|
||||
use app\models\PaymentMethod;
|
||||
|
||||
/**
|
||||
* 支付方式仓储
|
||||
*/
|
||||
class PaymentMethodRepository extends BaseRepository
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(new PaymentMethod());
|
||||
}
|
||||
|
||||
public function getAllEnabled(): array
|
||||
{
|
||||
return $this->model->newQuery()
|
||||
->where('status', 1)
|
||||
->orderBy('sort', 'asc')
|
||||
->get()
|
||||
->toArray();
|
||||
}
|
||||
|
||||
public function findByCode(string $methodCode): ?PaymentMethod
|
||||
{
|
||||
return $this->model->newQuery()
|
||||
->where('type', $methodCode)
|
||||
->where('status', 1)
|
||||
->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* 后台按 code 查询(不过滤状态)
|
||||
*/
|
||||
public function findAnyByCode(string $methodCode): ?PaymentMethod
|
||||
{
|
||||
return $this->model->newQuery()
|
||||
->where('type', $methodCode)
|
||||
->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* 后台列表:支持筛选与排序
|
||||
*/
|
||||
public function searchPaginate(array $filters = [], int $page = 1, int $pageSize = 10)
|
||||
{
|
||||
$query = $this->model->newQuery();
|
||||
|
||||
if (($filters['status'] ?? '') !== '' && $filters['status'] !== null) {
|
||||
$query->where('status', (int)$filters['status']);
|
||||
}
|
||||
if (!empty($filters['method_code'])) {
|
||||
$query->where('type', 'like', '%' . $filters['method_code'] . '%');
|
||||
}
|
||||
if (!empty($filters['method_name'])) {
|
||||
$query->where('name', 'like', '%' . $filters['method_name'] . '%');
|
||||
}
|
||||
|
||||
$query->orderBy('sort', 'asc')->orderByDesc('id');
|
||||
|
||||
return $query->paginate($pageSize, ['*'], 'page', $page);
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\repositories;
|
||||
|
||||
use app\common\base\BaseRepository;
|
||||
use app\models\PaymentNotifyTask;
|
||||
|
||||
/**
|
||||
* 商户通知任务仓储
|
||||
*/
|
||||
class PaymentNotifyTaskRepository extends BaseRepository
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(new PaymentNotifyTask());
|
||||
}
|
||||
|
||||
public function findByOrderId(string $orderId): ?PaymentNotifyTask
|
||||
{
|
||||
return $this->model->newQuery()
|
||||
->where('order_id', $orderId)
|
||||
->first();
|
||||
}
|
||||
|
||||
public function getPendingRetryTasks(int $limit = 100): array
|
||||
{
|
||||
return $this->model->newQuery()
|
||||
->where('status', PaymentNotifyTask::STATUS_PENDING)
|
||||
->where('next_retry_at', '<=', date('Y-m-d H:i:s'))
|
||||
->limit($limit)
|
||||
->get()
|
||||
->toArray();
|
||||
}
|
||||
}
|
||||
@@ -1,197 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\repositories;
|
||||
|
||||
use app\common\base\BaseRepository;
|
||||
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());
|
||||
}
|
||||
|
||||
public function findByOrderId(string $orderId): ?PaymentOrder
|
||||
{
|
||||
return $this->model->newQuery()
|
||||
->where('order_id', $orderId)
|
||||
->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据商户订单号查询(幂等校验)
|
||||
*/
|
||||
public function findByMchNo(int $merchantId, int $merchantAppId, string $mchOrderNo): ?PaymentOrder
|
||||
{
|
||||
return $this->model->newQuery()
|
||||
->where('merchant_id', $merchantId)
|
||||
->where('merchant_app_id', $merchantAppId)
|
||||
->where('mch_order_no', $mchOrderNo)
|
||||
->first();
|
||||
}
|
||||
|
||||
public function updateStatus(string $orderId, int $status, array $extra = []): bool
|
||||
{
|
||||
$data = array_merge(['status' => $status], $extra);
|
||||
$order = $this->findByOrderId($orderId);
|
||||
return $order ? $this->updateById($order->id, $data) : false;
|
||||
}
|
||||
|
||||
public function updateChannelInfo(string $orderId, string $chanOrderNo, string $chanTradeNo = ''): bool
|
||||
{
|
||||
$order = $this->findByOrderId($orderId);
|
||||
if (!$order) {
|
||||
return false;
|
||||
}
|
||||
$data = ['chan_order_no' => $chanOrderNo];
|
||||
if ($chanTradeNo !== '') {
|
||||
$data['chan_trade_no'] = $chanTradeNo;
|
||||
}
|
||||
return $this->updateById($order->id, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 后台订单列表:支持筛选与模糊搜索
|
||||
*/
|
||||
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();
|
||||
|
||||
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['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']);
|
||||
}
|
||||
if (!empty($filters['order_id'])) {
|
||||
$query->where('order_id', 'like', '%' . $filters['order_id'] . '%');
|
||||
}
|
||||
if (!empty($filters['mch_order_no'])) {
|
||||
$query->where('mch_order_no', 'like', '%' . $filters['mch_order_no'] . '%');
|
||||
}
|
||||
if (!empty($filters['created_from'])) {
|
||||
$query->where('created_at', '>=', $filters['created_from']);
|
||||
}
|
||||
if (!empty($filters['created_to'])) {
|
||||
$query->where('created_at', '<=', $filters['created_to']);
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\repositories;
|
||||
|
||||
use app\common\base\BaseRepository;
|
||||
use app\models\PaymentPlugin;
|
||||
|
||||
/**
|
||||
* 支付插件仓储
|
||||
*/
|
||||
class PaymentPluginRepository extends BaseRepository
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(new PaymentPlugin());
|
||||
}
|
||||
|
||||
public function getActivePlugins()
|
||||
{
|
||||
return $this->model->newQuery()
|
||||
->where('status', 1)
|
||||
->get([
|
||||
'code',
|
||||
'name',
|
||||
'class_name',
|
||||
'pay_types',
|
||||
'transfer_types',
|
||||
'config_schema',
|
||||
]);
|
||||
}
|
||||
|
||||
public function findActiveByCode(string $pluginCode): ?PaymentPlugin
|
||||
{
|
||||
return $this->model->newQuery()
|
||||
->where('code', $pluginCode)
|
||||
->where('status', 1)
|
||||
->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* 后台按编码查询(不过滤状态)
|
||||
*/
|
||||
public function findByCode(string $pluginCode): ?PaymentPlugin
|
||||
{
|
||||
return $this->model->newQuery()
|
||||
->where('code', $pluginCode)
|
||||
->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* 后台列表:支持筛选与模糊搜索
|
||||
*/
|
||||
public function searchPaginate(array $filters = [], int $page = 1, int $pageSize = 10)
|
||||
{
|
||||
$query = $this->model->newQuery();
|
||||
|
||||
if (($filters['status'] ?? '') !== '' && $filters['status'] !== null) {
|
||||
$query->where('status', (int)$filters['status']);
|
||||
}
|
||||
if (!empty($filters['plugin_code'])) {
|
||||
$query->where('code', 'like', '%' . $filters['plugin_code'] . '%');
|
||||
}
|
||||
if (!empty($filters['plugin_name'])) {
|
||||
$query->where('name', 'like', '%' . $filters['plugin_name'] . '%');
|
||||
}
|
||||
|
||||
$query->orderByDesc('created_at');
|
||||
return $query->paginate($pageSize, ['*'], 'page', $page);
|
||||
}
|
||||
|
||||
/**
|
||||
* 后台保存:存在则更新,不存在则创建
|
||||
*/
|
||||
public function upsertByCode(string $pluginCode, array $data): PaymentPlugin
|
||||
{
|
||||
$row = $this->findByCode($pluginCode);
|
||||
if ($row) {
|
||||
$this->model->newQuery()
|
||||
->where('code', $pluginCode)
|
||||
->update($data);
|
||||
return $this->findByCode($pluginCode) ?: $row;
|
||||
}
|
||||
|
||||
$data['code'] = $pluginCode;
|
||||
/** @var PaymentPlugin $created */
|
||||
$created = $this->create($data);
|
||||
return $created;
|
||||
}
|
||||
|
||||
public function updateStatus(string $pluginCode, int $status): bool
|
||||
{
|
||||
return (bool)$this->model->newQuery()
|
||||
->where('code', $pluginCode)
|
||||
->update(['status' => $status]);
|
||||
}
|
||||
}
|
||||
@@ -1,157 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\repositories;
|
||||
|
||||
use app\common\base\BaseRepository;
|
||||
use app\models\SystemConfig;
|
||||
use support\Cache;
|
||||
use Webman\Event\Event;
|
||||
|
||||
/**
|
||||
* 系统配置仓储
|
||||
*/
|
||||
class SystemConfigRepository extends BaseRepository
|
||||
{
|
||||
/**
|
||||
* 缓存键:全部系统配置
|
||||
*/
|
||||
private const CACHE_KEY_ALL_CONFIG = 'system_config_all';
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(new SystemConfig());
|
||||
}
|
||||
|
||||
/**
|
||||
* 从数据库加载所有配置到缓存
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function loadAllToCache(): array
|
||||
{
|
||||
// 优先从 webman/cache 获取
|
||||
$cached = Cache::get(self::CACHE_KEY_ALL_CONFIG);
|
||||
if (is_array($cached)) {
|
||||
return $cached;
|
||||
}
|
||||
|
||||
// 缓存不存在时从数据库加载
|
||||
$configs = $this->model
|
||||
->newQuery()
|
||||
->get(['config_key', 'config_value']);
|
||||
|
||||
$result = [];
|
||||
foreach ($configs as $config) {
|
||||
$result[$config->config_key] = $config->config_value;
|
||||
}
|
||||
|
||||
// 写入缓存(不过期,除非显式清理)
|
||||
Cache::set(self::CACHE_KEY_ALL_CONFIG, $result);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空缓存(供事件调用)
|
||||
*/
|
||||
public static function clearCache(): void
|
||||
{
|
||||
Cache::delete(self::CACHE_KEY_ALL_CONFIG);
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新从数据库加载缓存(供事件调用)
|
||||
*/
|
||||
public function reloadCache(): void
|
||||
{
|
||||
Cache::delete(self::CACHE_KEY_ALL_CONFIG);
|
||||
$this->loadAllToCache();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据配置键名查询配置值
|
||||
*
|
||||
* @param string $configKey
|
||||
* @return string|null
|
||||
*/
|
||||
public function getValueByKey(string $configKey): ?string
|
||||
{
|
||||
$all = $this->loadAllToCache();
|
||||
|
||||
return $all[$configKey] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据配置键名数组批量查询配置
|
||||
*
|
||||
* @param array $configKeys
|
||||
* @return array 返回 ['config_key' => 'config_value'] 格式的数组
|
||||
*/
|
||||
public function getValuesByKeys(array $configKeys): array
|
||||
{
|
||||
if (empty($configKeys)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$all = $this->loadAllToCache();
|
||||
|
||||
$result = [];
|
||||
foreach ($configKeys as $key) {
|
||||
if (array_key_exists($key, $all)) {
|
||||
$result[$key] = $all[$key];
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据配置键名更新或创建配置
|
||||
*
|
||||
* @param string $configKey
|
||||
* @param string $configValue
|
||||
* @return bool
|
||||
*/
|
||||
public function updateOrCreate(string $configKey, string $configValue): bool
|
||||
{
|
||||
$this->model
|
||||
->newQuery()
|
||||
->updateOrCreate(
|
||||
['config_key' => $configKey],
|
||||
['config_value' => $configValue]
|
||||
);
|
||||
|
||||
// 通过事件通知重新加载缓存
|
||||
Event::emit('system.config.updated', null);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量更新或创建配置
|
||||
*
|
||||
* @param array $configs 格式:['config_key' => 'config_value']
|
||||
* @return bool
|
||||
*/
|
||||
public function batchUpdateOrCreate(array $configs): bool
|
||||
{
|
||||
if (empty($configs)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
foreach ($configs as $configKey => $configValue) {
|
||||
$this->model
|
||||
->newQuery()
|
||||
->updateOrCreate(
|
||||
['config_key' => $configKey],
|
||||
['config_value' => $configValue]
|
||||
);
|
||||
}
|
||||
|
||||
// 批量更新后只触发一次事件,通知重新加载缓存
|
||||
Event::emit('system.config.updated', null);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user