feat: add vip payment and member center

This commit is contained in:
2026-04-11 12:01:52 +08:00
parent db26820544
commit 746116d325
23 changed files with 1781 additions and 2 deletions
+37
View File
@@ -0,0 +1,37 @@
<?php
/**
* 文件功能:VIP 等级测试工厂
* 用于在测试中快速生成可购买的 VIP 等级数据
*/
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\VipLevel>
*/
class VipLevelFactory extends Factory
{
/**
* 定义默认测试数据
*
* @return array<string, mixed>
*/
public function definition(): array
{
return [
'name' => '测试会员'.fake()->unique()->numberBetween(1, 9999),
'icon' => '👑',
'color' => '#f59e0b',
'exp_multiplier' => 1.5,
'jjb_multiplier' => 1.2,
'join_templates' => null,
'leave_templates' => null,
'sort_order' => fake()->numberBetween(1, 20),
'price' => fake()->numberBetween(10, 99),
'duration_days' => 30,
];
}
}
@@ -0,0 +1,46 @@
<?php
/**
* 文件功能:VIP 支付订单测试工厂
* 用于在测试中快速生成本地 VIP 支付订单与远端支付映射数据
*/
namespace Database\Factories;
use App\Models\User;
use App\Models\VipLevel;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\VipPaymentOrder>
*/
class VipPaymentOrderFactory extends Factory
{
/**
* 定义默认测试数据
*
* @return array<string, mixed>
*/
public function definition(): array
{
return [
'order_no' => 'VPO'.fake()->unique()->numerify('##########'),
'merchant_order_no' => 'VPO'.fake()->unique()->numerify('##########'),
'user_id' => User::factory(),
'vip_level_id' => VipLevel::factory(),
'status' => 'pending',
'amount' => 30.00,
'subject' => '购买 VIP 会员 - 测试套餐',
'payment_order_no' => 'PO'.fake()->unique()->numerify('############'),
'provider' => 'alipay',
'provider_trade_no' => null,
'vip_name' => '测试会员',
'vip_duration_days' => 30,
'sync_return_payload' => null,
'async_notify_payload' => null,
'paid_at' => null,
'opened_vip_at' => null,
'meta' => ['username' => fake()->userName()],
];
}
}
@@ -0,0 +1,50 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
/**
* 文件功能:创建 VIP 支付订单表迁移
* 为聊天室 VIP 在线支付提供本地订单存储能力
*/
return new class extends Migration
{
/**
* 运行迁移
* 创建 VIP 支付订单表,记录本地订单与远端支付单的映射关系
*/
public function up(): void
{
Schema::create('vip_payment_orders', function (Blueprint $table) {
$table->id();
$table->string('order_no', 32)->unique()->comment('本地 VIP 支付订单号');
$table->string('merchant_order_no', 32)->unique()->comment('提交给支付中心的业务订单号');
$table->foreignId('user_id')->constrained('users')->cascadeOnDelete()->comment('购买用户');
$table->foreignId('vip_level_id')->constrained('vip_levels')->restrictOnDelete()->comment('目标 VIP 等级');
$table->string('status', 20)->default('created')->index()->comment('订单状态:created|pending|paid|closed|failed');
$table->decimal('amount', 10, 2)->comment('支付金额');
$table->string('subject', 120)->comment('支付标题');
$table->string('payment_order_no', 32)->nullable()->index()->comment('NovaLink 平台支付单号');
$table->string('provider', 30)->nullable()->comment('支付渠道,例如 alipay');
$table->string('provider_trade_no', 80)->nullable()->comment('第三方支付流水号');
$table->string('vip_name', 60)->comment('下单时快照的 VIP 名称');
$table->unsignedInteger('vip_duration_days')->default(0)->comment('下单时快照的会员时长');
$table->json('sync_return_payload')->nullable()->comment('同步回调原始数据');
$table->json('async_notify_payload')->nullable()->comment('异步回调原始数据');
$table->timestamp('paid_at')->nullable()->comment('支付成功时间');
$table->timestamp('opened_vip_at')->nullable()->comment('实际开通会员时间');
$table->json('meta')->nullable()->comment('扩展信息');
$table->timestamps();
});
}
/**
* 回滚迁移
* 删除 VIP 支付订单表
*/
public function down(): void
{
Schema::dropIfExists('vip_payment_orders');
}
};