feat(admin-frontend): 补齐活跃筛选与支付快照能力
新增用户管理“活跃状态”高级筛选,并在后端支持 activity_status 复合规则,支持按活跃与非活跃筛选用户。 补齐订单支付成功快照落库与后台展示,保存支付渠道、 支付方法、实付金额和支付 IP,并在订单详情中优先展示。 同时增强节点页在线/离线筛选与批量删除、仪表盘快捷入口, 并修复已关闭工单再次回复后自动重开的统一语义。 附带同步测试、迁移、CI 工作流命名及知识库记录
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Unit\Orders;
|
||||
|
||||
use App\Models\Order;
|
||||
use App\Models\Payment;
|
||||
use App\Services\OrderService;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use ReflectionMethod;
|
||||
|
||||
class OrderServicePaymentSnapshotTest extends TestCase
|
||||
{
|
||||
public function test_build_payment_snapshot_prefers_callback_metadata_over_payment_defaults(): void
|
||||
{
|
||||
$payment = new Payment([
|
||||
'name' => 'TokenPay 收银台',
|
||||
'payment' => 'TokenPay',
|
||||
'config' => ['token_pay_currency' => 'USDT_TRC20'],
|
||||
]);
|
||||
|
||||
$order = new Order();
|
||||
$order->setRelation('payment', $payment);
|
||||
|
||||
$payload = $this->invokeBuildPaymentSnapshot($order, [
|
||||
'payment_channel' => '链上收银台',
|
||||
'payment_method' => 'TRC20',
|
||||
'payment_amount' => '19.29',
|
||||
'payment_ip' => '117.132.7.238',
|
||||
]);
|
||||
|
||||
$this->assertSame('链上收银台', $payload['payment_channel']);
|
||||
$this->assertSame('TRC20', $payload['payment_method']);
|
||||
$this->assertSame(1929, $payload['payment_amount']);
|
||||
$this->assertSame('117.132.7.238', $payload['payment_ip']);
|
||||
}
|
||||
|
||||
public function test_build_payment_snapshot_falls_back_to_payment_config_when_callback_method_missing(): void
|
||||
{
|
||||
$payment = new Payment([
|
||||
'name' => 'TokenPay 收银台',
|
||||
'payment' => 'TokenPay',
|
||||
'config' => ['token_pay_currency' => 'USDT_TRC20'],
|
||||
]);
|
||||
|
||||
$order = new Order();
|
||||
$order->setRelation('payment', $payment);
|
||||
|
||||
$payload = $this->invokeBuildPaymentSnapshot($order, []);
|
||||
|
||||
$this->assertSame('TokenPay 收银台', $payload['payment_channel']);
|
||||
$this->assertSame('USDT_TRC20', $payload['payment_method']);
|
||||
$this->assertArrayNotHasKey('payment_amount', $payload);
|
||||
$this->assertArrayNotHasKey('payment_ip', $payload);
|
||||
}
|
||||
|
||||
public function test_build_payment_snapshot_ignores_invalid_amount_and_blank_ip(): void
|
||||
{
|
||||
$payment = new Payment([
|
||||
'payment' => 'TokenPay',
|
||||
'config' => [],
|
||||
]);
|
||||
|
||||
$order = new Order();
|
||||
$order->setRelation('payment', $payment);
|
||||
|
||||
$payload = $this->invokeBuildPaymentSnapshot($order, [
|
||||
'payment_amount' => 'invalid',
|
||||
'payment_ip' => ' ',
|
||||
]);
|
||||
|
||||
$this->assertSame('TokenPay', $payload['payment_channel']);
|
||||
$this->assertSame('TokenPay', $payload['payment_method']);
|
||||
$this->assertArrayNotHasKey('payment_amount', $payload);
|
||||
$this->assertArrayNotHasKey('payment_ip', $payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $paymentSnapshot
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
private function invokeBuildPaymentSnapshot(Order $order, array $paymentSnapshot): array
|
||||
{
|
||||
$service = new OrderService($order);
|
||||
$method = new ReflectionMethod(OrderService::class, 'buildPaymentSnapshot');
|
||||
$method->setAccessible(true);
|
||||
|
||||
/** @var array<string, mixed> $result */
|
||||
$result = $method->invoke($service, $paymentSnapshot);
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user