1. 维护代码健壮

2. 更新项目结构文档
This commit is contained in:
技术老胡
2026-04-27 16:20:41 +08:00
parent 9a16a88640
commit 0e5de50337
198 changed files with 21038 additions and 702 deletions

View File

@@ -3,6 +3,7 @@
namespace app\http\admin\controller\merchant;
use app\common\base\BaseController;
use app\http\admin\validation\MerchantApiCredentialValidator;
use app\http\admin\validation\MerchantValidator;
use app\service\merchant\MerchantService;
use support\Request;
@@ -136,8 +137,9 @@ class MerchantController extends BaseController
public function issueCredential(Request $request, string $id): Response
{
$merchantId = (int) $id;
$data = $this->validated($request->all(), MerchantApiCredentialValidator::class, 'issueCredential');
return $this->success($this->merchantService->issueCredential($merchantId));
return $this->success($this->merchantService->issueCredential($merchantId, $data));
}
/**

View File

@@ -0,0 +1,85 @@
<?php
namespace app\http\admin\controller\ops;
use app\common\base\BaseController;
use app\http\admin\validation\MerchantNotifyTaskValidator;
use app\service\ops\log\MerchantNotifyTaskService;
use support\Request;
use support\Response;
/**
* 商户通知任务控制器。
*
* @property MerchantNotifyTaskService $merchantNotifyTaskService 商户通知任务服务
*/
class MerchantNotifyTaskController extends BaseController
{
/**
* 构造方法。
*
* @param MerchantNotifyTaskService $merchantNotifyTaskService 商户通知任务服务
* @return void
*/
public function __construct(
protected MerchantNotifyTaskService $merchantNotifyTaskService
) {
}
/**
* 查询商户通知任务列表。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function index(Request $request): Response
{
$data = $this->validated($request->all(), MerchantNotifyTaskValidator::class, 'index');
return $this->page(
$this->merchantNotifyTaskService->paginate(
$data,
(int) ($data['page'] ?? 1),
(int) ($data['page_size'] ?? 10)
)
);
}
/**
* 查询商户通知任务详情。
*
* @param Request $request 请求对象
* @param string $notifyNo 通知号
* @return Response 响应对象
*/
public function show(Request $request, string $notifyNo): Response
{
$data = $this->validated(['notify_no' => $notifyNo], MerchantNotifyTaskValidator::class, 'show');
$task = $this->merchantNotifyTaskService->findByNotifyNo((string) $data['notify_no']);
if (!$task) {
return $this->fail('商户通知任务不存在', 404);
}
return $this->success($task);
}
/**
* 手动重试商户通知任务。
*
* @param Request $request 请求对象
* @param string $notifyNo 通知号
* @return Response 响应对象
*/
public function retry(Request $request, string $notifyNo): Response
{
$data = $this->validated(['notify_no' => $notifyNo], MerchantNotifyTaskValidator::class, 'retry');
$task = $this->merchantNotifyTaskService->retry((string) $data['notify_no']);
if (!$task) {
return $this->fail('商户通知任务不存在', 404);
}
return $this->success($task, '商户通知任务已执行重试');
}
}

View File

@@ -86,6 +86,24 @@ class AuthController extends BaseController
(string) $this->requestAttribute($request, 'auth.admin_username', '')
));
}
/**
* 修改当前登录管理员密码。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function changePassword(Request $request): Response
{
$adminId = $this->currentAdminId($request);
if ($adminId <= 0) {
return $this->fail('未获取到当前管理员信息', 401);
}
$data = $this->validated($request->all(), AuthValidator::class, 'changePassword');
return $this->success($this->adminUserService->changePassword($adminId, $data));
}
}

View File

@@ -11,7 +11,7 @@ use support\Response;
/**
* 支付订单管理控制器。
*
* 当前提供列表查询,后续可以继续扩展支付单详情、关闭、重试等管理操作
* 当前提供列表查询和详情查看,便于后台直接排查支付链路
*
* @property PayOrderService $payOrderService 支付订单服务
*/
@@ -42,6 +42,24 @@ class PayOrderController extends BaseController
return $this->success($this->payOrderService->paginate($data, $page, $pageSize));
}
/**
* 查询支付订单详情。
*
* @param Request $request 请求对象
* @param string $payNo 支付单号
* @return Response 响应对象
*/
public function show(Request $request, string $payNo): Response
{
$this->validated(
array_merge($request->all(), ['pay_no' => $payNo]),
PayOrderValidator::class,
'show'
);
return $this->success($this->payOrderService->detail($payNo));
}
}

View File

@@ -2,6 +2,7 @@
namespace app\http\admin\middleware;
use app\exception\UnauthorizedException;
use app\service\system\access\AdminAuthService;
use support\Context;
use Webman\Http\Request;
@@ -34,6 +35,7 @@ class AdminAuthMiddleware implements MiddlewareInterface
* @param Request $request 请求对象
* @param callable $handler handler
* @return Response 响应对象
* @throws UnauthorizedException
*/
public function process(Request $request, callable $handler): Response
{
@@ -42,11 +44,7 @@ class AdminAuthMiddleware implements MiddlewareInterface
if ($token === '') {
if ((int) env('AUTH_MIDDLEWARE_STRICT', 1) === 1) {
return json([
'code' => 401,
'msg' => 'admin unauthorized',
'data' => null,
]);
throw new UnauthorizedException('管理员未授权');
}
} else {
$admin = $this->adminAuthService->authenticateToken(
@@ -55,11 +53,7 @@ class AdminAuthMiddleware implements MiddlewareInterface
$request->header('user-agent', '')
);
if (!$admin) {
return json([
'code' => 401,
'msg' => 'admin unauthorized',
'data' => null,
]);
throw new UnauthorizedException('管理员未授权');
}
Context::set('auth.admin_id', (int) $admin->id);

View File

@@ -19,6 +19,8 @@ class AuthValidator extends Validator
protected array $rules = [
'username' => 'required|string|min:1|max:32',
'password' => 'required|string|min:6|max:100',
'current_password' => 'required|string|min:6|max:100',
'password_confirm' => 'required|string|min:6|max:100|same:password',
];
/**
@@ -29,6 +31,8 @@ class AuthValidator extends Validator
protected array $attributes = [
'username' => '用户名',
'password' => '密码',
'current_password' => '旧密码',
'password_confirm' => '确认密码',
];
/**
@@ -38,6 +42,7 @@ class AuthValidator extends Validator
*/
protected array $scenes = [
'login' => ['username', 'password'],
'changePassword' => ['current_password', 'password', 'password_confirm'],
];
}

View File

@@ -18,8 +18,11 @@ class MerchantApiCredentialValidator extends Validator
'id' => 'sometimes|integer|min:1',
'keyword' => 'sometimes|string|max:128',
'merchant_id' => 'sometimes|integer|min:1|exists:ma_merchant,id',
'sign_type' => 'sometimes|integer|in:0',
'sign_type' => 'sometimes|integer|in:0,1',
'rotate_v1' => 'sometimes|integer|in:0,1',
'rotate_v2' => 'sometimes|integer|in:0,1',
'api_key' => 'nullable|string|max:128',
'merchant_public_key' => 'nullable|string|max:65535',
'status' => 'sometimes|integer|in:0,1',
'page' => 'sometimes|integer|min:1',
'page_size' => 'sometimes|integer|min:1|max:100',
@@ -35,7 +38,10 @@ class MerchantApiCredentialValidator extends Validator
'keyword' => '关键词',
'merchant_id' => '所属商户',
'sign_type' => '签名类型',
'rotate_v1' => '是否重置 V1',
'rotate_v2' => '是否重置 V2',
'api_key' => '接口凭证值',
'merchant_public_key' => '商户公钥',
'status' => '接口凭证状态',
'page' => '页码',
'page_size' => '每页条数',
@@ -48,10 +54,11 @@ class MerchantApiCredentialValidator extends Validator
*/
protected array $scenes = [
'index' => ['keyword', 'merchant_id', 'status', 'page', 'page_size'],
'store' => ['merchant_id', 'sign_type', 'api_key', 'status'],
'update' => ['id', 'sign_type', 'api_key', 'status'],
'store' => ['merchant_id', 'sign_type', 'api_key', 'merchant_public_key', 'status'],
'update' => ['id', 'sign_type', 'api_key', 'merchant_public_key', 'status'],
'show' => ['id'],
'destroy' => ['id'],
'issueCredential' => ['rotate_v1', 'rotate_v2', 'sign_type', 'status'],
];
/**
@@ -63,7 +70,8 @@ class MerchantApiCredentialValidator extends Validator
{
return $this->appendRules([
'merchant_id' => 'required|integer|min:1|exists:ma_merchant,id',
'sign_type' => 'required|integer|in:0',
'sign_type' => 'required|integer|in:0,1',
'merchant_public_key' => 'nullable|string|max:65535',
'status' => 'required|integer|in:0,1',
]);
}
@@ -77,8 +85,25 @@ class MerchantApiCredentialValidator extends Validator
{
return $this->appendRules([
'id' => 'required|integer|min:1',
'sign_type' => 'required|integer|in:0',
'status' => 'required|integer|in:0,1',
'sign_type' => 'sometimes|integer|in:0,1',
'api_key' => 'nullable|string|max:128',
'merchant_public_key' => 'nullable|string|max:65535',
'status' => 'sometimes|integer|in:0,1',
]);
}
/**
* 配置生成接口凭证场景规则。
*
* @return static 校验器实例
*/
public function sceneIssueCredential(): static
{
return $this->appendRules([
'rotate_v1' => 'sometimes|integer|in:0,1',
'rotate_v2' => 'sometimes|integer|in:0,1',
'sign_type' => 'sometimes|integer|in:0,1',
'status' => 'sometimes|integer|in:0,1',
]);
}

View File

@@ -0,0 +1,72 @@
<?php
namespace app\http\admin\validation;
use support\validation\Validator;
/**
* 商户通知任务参数校验器。
*/
class MerchantNotifyTaskValidator extends Validator
{
/**
* 校验规则。
*
* @var array
*/
protected array $rules = [
'notify_no' => 'sometimes|string|max:64',
'keyword' => 'sometimes|string|max:128',
'merchant_id' => 'sometimes|integer|min:1',
'status' => 'sometimes|integer|in:0,1,2',
'page' => 'sometimes|integer|min:1',
'page_size' => 'sometimes|integer|min:1|max:100',
];
/**
* 字段别名。
*
* @var array
*/
protected array $attributes = [
'notify_no' => '通知号',
'keyword' => '关键词',
'merchant_id' => '所属商户',
'status' => '任务状态',
'page' => '页码',
'page_size' => '每页条数',
];
/**
* 校验场景。
*
* @var array
*/
protected array $scenes = [
'index' => ['keyword', 'merchant_id', 'status', 'page', 'page_size'],
'show' => ['notify_no'],
'retry' => ['notify_no'],
];
/**
* 配置详情场景规则。
*
* @return static
*/
public function sceneShow(): static
{
return $this->appendRules([
'notify_no' => 'required|string|max:64',
]);
}
/**
* 配置重试场景规则。
*
* @return static
*/
public function sceneRetry(): static
{
return $this->sceneShow();
}
}

View File

@@ -17,6 +17,7 @@ class PayOrderValidator extends Validator
* @var array
*/
protected array $rules = [
'pay_no' => 'sometimes|string|max:32',
'keyword' => 'sometimes|string|max:128',
'merchant_id' => 'sometimes|integer|min:1',
'pay_type_id' => 'sometimes|integer|min:1',
@@ -33,6 +34,7 @@ class PayOrderValidator extends Validator
* @var array
*/
protected array $attributes = [
'pay_no' => '支付单号',
'keyword' => '关键字',
'merchant_id' => '商户ID',
'pay_type_id' => '支付方式',
@@ -50,6 +52,6 @@ class PayOrderValidator extends Validator
*/
protected array $scenes = [
'index' => ['keyword', 'merchant_id', 'pay_type_id', 'status', 'channel_mode', 'callback_status', 'page', 'page_size'],
'show' => ['pay_no'],
];
}

View File

@@ -19,6 +19,7 @@ class PaymentPluginConfValidator extends Validator
protected array $rules = [
'id' => 'sometimes|integer|min:1',
'keyword' => 'sometimes|string|max:128',
'merchant_id' => 'sometimes|integer|min:0',
'plugin_code' => 'sometimes|string|alpha_dash|min:2|max:32',
'config' => 'nullable|array',
'settlement_cycle_type' => 'sometimes|integer|in:0,1,2,3,4',
@@ -37,6 +38,7 @@ class PaymentPluginConfValidator extends Validator
protected array $attributes = [
'id' => '配置ID',
'keyword' => '关键字',
'merchant_id' => '所属商户',
'plugin_code' => '插件编码',
'config' => '插件配置',
'settlement_cycle_type' => '结算周期',
@@ -53,9 +55,9 @@ class PaymentPluginConfValidator extends Validator
* @var array
*/
protected array $scenes = [
'index' => ['keyword', 'plugin_code', 'page', 'page_size'],
'store' => ['plugin_code', 'config', 'settlement_cycle_type', 'settlement_cutoff_time', 'remark'],
'update' => ['id', 'plugin_code', 'config', 'settlement_cycle_type', 'settlement_cutoff_time', 'remark'],
'index' => ['keyword', 'merchant_id', 'plugin_code', 'page', 'page_size'],
'store' => ['merchant_id', 'plugin_code', 'config', 'settlement_cycle_type', 'settlement_cutoff_time', 'remark'],
'update' => ['id', 'merchant_id', 'plugin_code', 'config', 'settlement_cycle_type', 'settlement_cutoff_time', 'remark'],
'show' => ['id'],
'destroy' => ['id'],
'options' => ['plugin_code'],
@@ -87,4 +89,3 @@ class PaymentPluginConfValidator extends Validator
}
}

View File

@@ -19,6 +19,7 @@ class PaymentPluginValidator extends Validator
protected array $rules = [
'code' => 'sometimes|string|alpha_dash|min:2|max:32',
'status' => 'sometimes|integer|in:0,1',
'allow_merchant' => 'sometimes|integer|in:0,1',
'remark' => 'nullable|string|max:500',
'keyword' => 'sometimes|string|max:128',
'name' => 'sometimes|string|max:50',
@@ -37,6 +38,7 @@ class PaymentPluginValidator extends Validator
'code' => '插件编码',
'name' => '插件名称',
'status' => '插件状态',
'allow_merchant' => '商户端可用',
'remark' => '备注',
'keyword' => '关键字',
'page' => '页码',
@@ -52,10 +54,9 @@ class PaymentPluginValidator extends Validator
*/
protected array $scenes = [
'index' => ['keyword', 'code', 'name', 'status', 'page', 'page_size'],
'update' => ['code', 'status', 'remark'],
'update' => ['code', 'status', 'allow_merchant', 'remark'],
'updateStatus' => ['code', 'status'],
'show' => ['code'],
'selectOptions' => ['keyword', 'page', 'page_size', 'pay_type_code', 'ids'],
];
}