新增每日签到与补签卡功能
This commit is contained in:
@@ -0,0 +1,185 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* 文件功能:创建每日签到奖励规则表。
|
||||
*
|
||||
* 规则按连续签到天数配置奖励,签到服务会匹配小于等于当前连续天数的最高启用规则。
|
||||
*/
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
/**
|
||||
* 类功能:维护 sign_in_reward_rules 表结构与回滚逻辑。
|
||||
*/
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* 创建每日签到奖励规则表。
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('sign_in_reward_rules', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedInteger('streak_days')->unique()->comment('连续签到天数门槛');
|
||||
$table->unsignedInteger('gold_reward')->default(0)->comment('金币奖励');
|
||||
$table->unsignedInteger('exp_reward')->default(0)->comment('经验奖励');
|
||||
$table->unsignedInteger('charm_reward')->default(0)->comment('魅力奖励');
|
||||
$table->string('identity_badge_code', 50)->nullable()->comment('身份徽章编码');
|
||||
$table->string('identity_badge_name', 50)->nullable()->comment('身份徽章名称');
|
||||
$table->string('identity_badge_icon', 120)->nullable()->comment('身份徽章图标');
|
||||
$table->string('identity_badge_color', 20)->nullable()->comment('身份徽章文字颜色');
|
||||
$table->unsignedSmallInteger('identity_duration_days')->default(0)->comment('身份有效天数,0表示永久');
|
||||
$table->boolean('is_enabled')->default(true)->index()->comment('是否启用');
|
||||
$table->unsignedInteger('sort_order')->default(0)->index()->comment('后台排序值');
|
||||
$table->timestamps();
|
||||
|
||||
$table->index(['is_enabled', 'streak_days'], 'idx_sign_in_rules_enabled_streak');
|
||||
});
|
||||
|
||||
DB::table('sign_in_reward_rules')->insert($this->defaultRules());
|
||||
}
|
||||
|
||||
/**
|
||||
* 回滚:删除每日签到奖励规则表。
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('sign_in_reward_rules');
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认连续签到奖励规则。
|
||||
*
|
||||
* @return array<int, array<string, mixed>>
|
||||
*/
|
||||
private function defaultRules(): array
|
||||
{
|
||||
$now = now();
|
||||
|
||||
return [
|
||||
[
|
||||
'streak_days' => 1,
|
||||
'gold_reward' => 100,
|
||||
'exp_reward' => 10,
|
||||
'charm_reward' => 0,
|
||||
'identity_badge_code' => 'sign_in_new_star',
|
||||
'identity_badge_name' => '签到新星',
|
||||
'identity_badge_icon' => '✅',
|
||||
'identity_badge_color' => '#0f766e',
|
||||
'identity_duration_days' => 7,
|
||||
'is_enabled' => true,
|
||||
'sort_order' => 1,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
],
|
||||
[
|
||||
'streak_days' => 3,
|
||||
'gold_reward' => 180,
|
||||
'exp_reward' => 18,
|
||||
'charm_reward' => 1,
|
||||
'identity_badge_code' => 'sign_in_spark',
|
||||
'identity_badge_name' => '三日星火',
|
||||
'identity_badge_icon' => '✨',
|
||||
'identity_badge_color' => '#2563eb',
|
||||
'identity_duration_days' => 10,
|
||||
'is_enabled' => true,
|
||||
'sort_order' => 3,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
],
|
||||
[
|
||||
'streak_days' => 7,
|
||||
'gold_reward' => 350,
|
||||
'exp_reward' => 35,
|
||||
'charm_reward' => 3,
|
||||
'identity_badge_code' => 'sign_in_flame',
|
||||
'identity_badge_name' => '七日恒星',
|
||||
'identity_badge_icon' => '🔥',
|
||||
'identity_badge_color' => '#dc2626',
|
||||
'identity_duration_days' => 30,
|
||||
'is_enabled' => true,
|
||||
'sort_order' => 7,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
],
|
||||
[
|
||||
'streak_days' => 14,
|
||||
'gold_reward' => 600,
|
||||
'exp_reward' => 60,
|
||||
'charm_reward' => 5,
|
||||
'identity_badge_code' => 'sign_in_moon_guard',
|
||||
'identity_badge_name' => '半月守望',
|
||||
'identity_badge_icon' => '🌙',
|
||||
'identity_badge_color' => '#7c3aed',
|
||||
'identity_duration_days' => 45,
|
||||
'is_enabled' => true,
|
||||
'sort_order' => 14,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
],
|
||||
[
|
||||
'streak_days' => 30,
|
||||
'gold_reward' => 1200,
|
||||
'exp_reward' => 120,
|
||||
'charm_reward' => 8,
|
||||
'identity_badge_code' => 'sign_in_month_master',
|
||||
'identity_badge_name' => '月签达人',
|
||||
'identity_badge_icon' => '🏆',
|
||||
'identity_badge_color' => '#ca8a04',
|
||||
'identity_duration_days' => 60,
|
||||
'is_enabled' => true,
|
||||
'sort_order' => 30,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
],
|
||||
[
|
||||
'streak_days' => 60,
|
||||
'gold_reward' => 2200,
|
||||
'exp_reward' => 220,
|
||||
'charm_reward' => 14,
|
||||
'identity_badge_code' => 'sign_in_diamond',
|
||||
'identity_badge_name' => '双月钻冕',
|
||||
'identity_badge_icon' => '💎',
|
||||
'identity_badge_color' => '#0891b2',
|
||||
'identity_duration_days' => 90,
|
||||
'is_enabled' => true,
|
||||
'sort_order' => 60,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
],
|
||||
[
|
||||
'streak_days' => 100,
|
||||
'gold_reward' => 4000,
|
||||
'exp_reward' => 400,
|
||||
'charm_reward' => 25,
|
||||
'identity_badge_code' => 'sign_in_legend',
|
||||
'identity_badge_name' => '百日传奇',
|
||||
'identity_badge_icon' => '👑',
|
||||
'identity_badge_color' => '#9333ea',
|
||||
'identity_duration_days' => 180,
|
||||
'is_enabled' => true,
|
||||
'sort_order' => 100,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
],
|
||||
[
|
||||
'streak_days' => 365,
|
||||
'gold_reward' => 12000,
|
||||
'exp_reward' => 1200,
|
||||
'charm_reward' => 100,
|
||||
'identity_badge_code' => 'sign_in_year_guardian',
|
||||
'identity_badge_name' => '周年守护者',
|
||||
'identity_badge_icon' => '🌟',
|
||||
'identity_badge_color' => '#e11d48',
|
||||
'identity_duration_days' => 0,
|
||||
'is_enabled' => true,
|
||||
'sort_order' => 365,
|
||||
'created_at' => $now,
|
||||
'updated_at' => $now,
|
||||
],
|
||||
];
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* 文件功能:创建用户身份徽章表。
|
||||
*
|
||||
* 用于记录用户通过签到等来源获得的身份展示信息,当前阶段只由签到服务刷新 sign_in 来源。
|
||||
*/
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
/**
|
||||
* 类功能:维护 user_identity_badges 表结构与回滚逻辑。
|
||||
*/
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* 创建用户身份徽章表。
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('user_identity_badges', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('user_id')->constrained()->cascadeOnDelete()->comment('用户ID');
|
||||
$table->string('source', 30)->default('sign_in')->comment('徽章来源');
|
||||
$table->string('badge_code', 50)->comment('徽章编码');
|
||||
$table->string('badge_name', 50)->comment('徽章名称');
|
||||
$table->string('badge_icon', 120)->nullable()->comment('徽章图标');
|
||||
$table->string('badge_color', 20)->nullable()->comment('徽章文字颜色');
|
||||
$table->timestamp('acquired_at')->nullable()->comment('获得时间');
|
||||
$table->timestamp('expires_at')->nullable()->index()->comment('过期时间,空表示长期有效');
|
||||
$table->boolean('is_active')->default(true)->index()->comment('是否当前启用');
|
||||
$table->json('metadata')->nullable()->comment('扩展信息');
|
||||
$table->timestamps();
|
||||
|
||||
$table->unique(['user_id', 'source', 'badge_code'], 'uniq_user_identity_badge');
|
||||
$table->index(['user_id', 'source', 'is_active'], 'idx_user_identity_badges_current');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 回滚:删除用户身份徽章表。
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('user_identity_badges');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* 文件功能:创建每日签到记录表。
|
||||
*
|
||||
* 每个用户每天只能签到一次,并保存当次连续天数与实际发放奖励快照。
|
||||
*/
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
/**
|
||||
* 类功能:维护 daily_sign_ins 表结构与回滚逻辑。
|
||||
*/
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* 创建每日签到记录表。
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('daily_sign_ins', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('user_id')->constrained()->cascadeOnDelete()->comment('用户ID');
|
||||
$table->unsignedBigInteger('room_id')->nullable()->index()->comment('签到所在房间ID');
|
||||
$table->date('sign_in_date')->comment('签到日期');
|
||||
$table->unsignedInteger('streak_days')->comment('连续签到天数');
|
||||
$table->foreignId('reward_rule_id')->nullable()->constrained('sign_in_reward_rules')->nullOnDelete()->comment('命中奖励规则ID');
|
||||
$table->unsignedInteger('gold_reward')->default(0)->comment('实际发放金币');
|
||||
$table->unsignedInteger('exp_reward')->default(0)->comment('实际发放经验');
|
||||
$table->unsignedInteger('charm_reward')->default(0)->comment('实际发放魅力');
|
||||
$table->string('identity_badge_code', 50)->nullable()->comment('本次刷新身份徽章编码');
|
||||
$table->string('identity_badge_name', 50)->nullable()->comment('本次刷新身份徽章名称');
|
||||
$table->string('identity_badge_icon', 120)->nullable()->comment('本次刷新身份徽章图标');
|
||||
$table->string('identity_badge_color', 20)->nullable()->comment('本次刷新身份徽章颜色');
|
||||
$table->timestamps();
|
||||
|
||||
$table->unique(['user_id', 'sign_in_date'], 'uniq_user_daily_sign_in');
|
||||
$table->index(['sign_in_date', 'streak_days'], 'idx_daily_sign_ins_date_streak');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 回滚:删除每日签到记录表。
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('daily_sign_ins');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* 文件功能:为每日签到记录补充补签来源字段。
|
||||
*
|
||||
* 记录补签卡消耗的购买记录与补签时间,便于日历区分正常签到和补签。
|
||||
*/
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* 方法功能:新增补签标记、补签卡购买记录和补签完成时间。
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('daily_sign_ins', function (Blueprint $table): void {
|
||||
$table->boolean('is_makeup')->default(false)->after('room_id')->comment('是否通过补签卡补签');
|
||||
$table->foreignId('makeup_purchase_id')->nullable()->after('is_makeup')->constrained('user_purchases')->nullOnDelete()->comment('消耗的补签卡购买记录ID');
|
||||
$table->timestamp('makeup_at')->nullable()->after('makeup_purchase_id')->comment('补签完成时间');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 方法功能:回滚补签字段。
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('daily_sign_ins', function (Blueprint $table): void {
|
||||
$table->dropConstrainedForeignId('makeup_purchase_id');
|
||||
$table->dropColumn(['is_makeup', 'makeup_at']);
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* 文件功能:为商店商品类型加入签到补签卡。
|
||||
*
|
||||
* 允许后台商店配置补签卡,并提供一条默认上架商品。
|
||||
*/
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* 方法功能:扩展商品类型枚举并写入默认补签卡。
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
if (DB::getDriverName() === 'mysql') {
|
||||
DB::statement("ALTER TABLE `shop_items` MODIFY `type` ENUM('instant','duration','one_time','ring','auto_fishing','sign_repair') NOT NULL COMMENT '道具类型'");
|
||||
}
|
||||
|
||||
DB::table('shop_items')->updateOrInsert(
|
||||
['slug' => 'sign_repair_card'],
|
||||
[
|
||||
'name' => '补签卡',
|
||||
'description' => '用于补签本月漏掉的未签到日期,每张可补签 1 天;不能补签上月或更早日期。',
|
||||
'icon' => '🗓️',
|
||||
'price' => 10000,
|
||||
'type' => 'sign_repair',
|
||||
'duration_days' => 0,
|
||||
'duration_minutes' => 0,
|
||||
'intimacy_bonus' => 0,
|
||||
'charm_bonus' => 0,
|
||||
'sort_order' => 35,
|
||||
'is_active' => true,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 方法功能:回滚补签卡商品类型。
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
DB::table('shop_items')->where('slug', 'sign_repair_card')->delete();
|
||||
|
||||
if (DB::getDriverName() === 'mysql') {
|
||||
DB::statement("UPDATE `shop_items` SET `type` = 'one_time' WHERE `type` = 'sign_repair'");
|
||||
DB::statement("ALTER TABLE `shop_items` MODIFY `type` ENUM('instant','duration','one_time','ring','auto_fishing') NOT NULL COMMENT '道具类型'");
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* 文件功能:更新补签卡默认价格和购买说明。
|
||||
*
|
||||
* 确保已经运行过旧迁移的环境,也能同步补签卡 10000 金币与本月补签限制说明。
|
||||
*/
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* 方法功能:把补签卡默认价格和说明更新为当前业务规则。
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
DB::table('shop_items')
|
||||
->where('slug', 'sign_repair_card')
|
||||
->update([
|
||||
'price' => 10000,
|
||||
'description' => '用于补签本月漏掉的未签到日期,每张可补签 1 天;不能补签上月或更早日期。',
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 方法功能:回滚补签卡默认价格和旧说明,方便本地调试回退。
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
DB::table('shop_items')
|
||||
->where('slug', 'sign_repair_card')
|
||||
->update([
|
||||
'price' => 1200,
|
||||
'description' => '用于补签漏掉的历史日期,每张可补签 1 天。',
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user