From 3c749969b48eba9395c4ba9ea180bcd659b3fb8e Mon Sep 17 00:00:00 2001 From: pllx Date: Mon, 27 Apr 2026 14:23:34 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=96=B0=E4=BA=BA=E7=AD=89?= =?UTF-8?q?=E7=BA=A7=E8=A2=AB=E9=99=8D=E4=B8=BA=E9=9B=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Models/SysParam.php | 6 ++++- tests/Feature/ChatControllerTest.php | 33 ++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/app/Models/SysParam.php b/app/Models/SysParam.php index 8f6b8ca..f6d7cbc 100644 --- a/app/Models/SysParam.php +++ b/app/Models/SysParam.php @@ -15,6 +15,9 @@ namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\Cache; +/** + * 类功能:读取和计算系统参数,提供等级经验阈值等全局配置能力。 + */ class Sysparam extends Model { /** @var string 表名 */ @@ -74,7 +77,8 @@ class Sysparam extends Model // 不超过最大等级 $maxLevel = (int) static::getValue('maxlevel', '99'); - return min($level, $maxLevel); + // 聊天室普通用户最低等级为 1,避免低经验新人被自动存点降成 0 后无法进入默认房间。 + return max(1, min($level, $maxLevel)); } /** diff --git a/tests/Feature/ChatControllerTest.php b/tests/Feature/ChatControllerTest.php index 3b0e363..ec4aac8 100644 --- a/tests/Feature/ChatControllerTest.php +++ b/tests/Feature/ChatControllerTest.php @@ -801,6 +801,39 @@ class ChatControllerTest extends TestCase $this->assertGreaterThanOrEqual(0, $user->exp_num); // Might be 1 depending on sysparam } + /** + * 测试低经验新人心跳后不会被降到 0 级,刷新后仍可进入默认房间。 + */ + public function test_low_exp_newbie_keeps_minimum_level_after_heartbeat(): void + { + Sysparam::updateOrCreate(['alias' => 'exp_per_heartbeat'], ['body' => '0']); + Sysparam::updateOrCreate(['alias' => 'jjb_per_heartbeat'], ['body' => '0']); + Sysparam::updateOrCreate(['alias' => 'auto_event_chance'], ['body' => '0']); + Cache::flush(); + + $room = Room::create([ + 'room_name' => 'newhb', + 'permit_level' => 1, + 'door_open' => true, + ]); + $user = User::factory()->create([ + 'user_level' => 1, + 'exp_num' => 0, + 'has_received_new_gift' => true, + ]); + + $this->actingAs($user)->get(route('chat.room', $room->id))->assertOk(); + + $heartbeatResponse = $this->actingAs($user)->postJson(route('chat.heartbeat', $room->id)); + + $heartbeatResponse->assertOk(); + $heartbeatResponse->assertJsonPath('data.user_level', 1); + $this->assertSame(1, $user->fresh()->user_level); + + Redis::del("room:{$room->id}:alive:{$user->username}"); + $this->actingAs($user)->get(route('chat.room', $room->id))->assertOk(); + } + /** * 测试显式退房会清理 Redis 在线状态。 */