Your Name 9 mēneši atpakaļ
vecāks
revīzija
b8f85a6cf7

+ 20 - 0
app/Module/GameItems/AdminControllers/TestController.php

@@ -0,0 +1,20 @@
+<?php
+
+namespace App\Module\Test\AdminControllers;
+
+use Dcat\Admin\Http\Controllers\AdminController;
+use Illuminate\Routing\Controller;
+use Illuminate\Support\Facades\Log;
+use Spatie\RouteAttributes\Attributes\Get;
+use Spatie\RouteAttributes\Attributes\Prefix;
+
+#[Prefix('test')]
+class TestController extends AdminController
+{
+    #[Get('/test')]
+    public function test()
+    {
+        Log::info(123);
+        echo 1;die;
+    }
+}

+ 35 - 0
app/Module/GameItems/Commands/TestCommands.php

@@ -0,0 +1,35 @@
+<?php
+
+namespace App\Module\Test\Commands;
+
+
+
+use App\Module\Test\Services\TestService;
+use Illuminate\Console\Command;
+
+class TestCommands extends Command
+{
+    /**
+     * 控制台命令的名称和签名
+     *
+     * @var string
+     */
+    protected $signature = 'test';
+
+    /**
+     * 命令描述
+     *
+     * @var string
+     */
+    protected $description = 'Test commands';
+
+    /**
+     * 执行命令
+     */
+    public function handle()
+    {
+        TestService::verify(1);
+        echo '完成';
+    }
+
+}

+ 17 - 0
app/Module/GameItems/Config/test.php

@@ -0,0 +1,17 @@
+<?php
+
+return [
+    /*
+    |--------------------------------------------------------------------------
+    | 测试模块配置
+    |--------------------------------------------------------------------------
+    */
+
+    // 测试配置项
+    'key' => 'value',
+
+    // 测试数组配置
+    'array' => [
+        'key' => 'value'
+    ]
+];

+ 39 - 0
app/Module/GameItems/Enums/TEST_TYPE.php

@@ -0,0 +1,39 @@
+<?php
+
+namespace App\Module\Test\Enums;
+
+enum TEST_TYPE: int
+{
+    /**
+     * 禁用
+     */
+    case DISABLED = 0;
+
+    /**
+     * 启用
+     */
+    case ENABLED = 1;
+
+    /**
+     * 获取枚举标签
+     *
+     * @return string
+     */
+    public function label(): string
+    {
+        return match($this) {
+            self::DISABLED => '禁用',
+            self::ENABLED => '启用',
+        };
+    }
+
+    /**
+     * 获取枚举值
+     *
+     * @return int
+     */
+    public function value(): int
+    {
+        return $this->value;
+    }
+}

+ 40 - 0
app/Module/GameItems/Events/TestEvent.php

@@ -0,0 +1,40 @@
+<?php
+
+namespace App\Module\Test\Events;
+
+use App\Module\Test\Models\Test;
+use Illuminate\Broadcasting\InteractsWithSockets;
+use Illuminate\Foundation\Events\Dispatchable;
+use Illuminate\Queue\SerializesModels;
+
+class TestEvent
+{
+    use Dispatchable, InteractsWithSockets, SerializesModels;
+
+    /**
+     * 测试数据
+     *
+     * @var Test
+     */
+    public Test $test;
+
+    /**
+     * 事件类型
+     *
+     * @var string
+     */
+    public string $type;
+
+    /**
+     * 创建事件实例
+     *
+     * @param Test $test
+     * @param string $type
+     * @return void
+     */
+    public function __construct(Test $test, string $type)
+    {
+        $this->test = $test;
+        $this->type = $type;
+    }
+}

+ 18 - 0
app/Module/GameItems/Exceptions/TestException.php

@@ -0,0 +1,18 @@
+<?php
+
+namespace App\Module\Test\Exceptions;
+
+class TestException extends \Exception
+{
+    /**
+     * 创建异常实例
+     *
+     * @param string $message
+     * @param int $code
+     * @return void
+     */
+    public function __construct(string $message = "", int $code = 0)
+    {
+        parent::__construct($message, $code);
+    }
+}

+ 34 - 0
app/Module/GameItems/Jobs/TestJob.php

@@ -0,0 +1,34 @@
+<?php
+
+namespace App\Module\Test\Jobs;
+
+use App\Module\Test\Models\Test;
+use Illuminate\Bus\Queueable;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Foundation\Bus\Dispatchable;
+use Illuminate\Queue\InteractsWithQueue;
+use Illuminate\Queue\SerializesModels;
+
+class TestJob implements ShouldQueue
+{
+    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
+
+    /**
+     * 创建任务实例
+     *
+     * @param Test $test
+     */
+    public function __construct(protected Test $test)
+    {
+    }
+
+    /**
+     * 执行任务
+     *
+     * @return void
+     */
+    public function handle(): void
+    {
+        // 任务处理逻辑
+    }
+}

+ 31 - 0
app/Module/GameItems/Listeners/TestEventListener.php

@@ -0,0 +1,31 @@
+<?php
+
+namespace App\Module\Test\Listeners;
+
+use App\Module\Test\Events\TestEvent;
+use Illuminate\Contracts\Queue\ShouldQueue;
+
+class TestEventListener implements ShouldQueue
+{
+    /**
+     * 处理事件
+     *
+     * @param TestEvent $event
+     * @return void
+     */
+    public function handle(TestEvent $event): void
+    {
+        // 根据事件类型处理不同的逻辑
+        switch ($event->type) {
+            case 'created':
+                // 处理创建事件
+                break;
+            case 'updated':
+                // 处理更新事件
+                break;
+            case 'deleted':
+                // 处理删除事件
+                break;
+        }
+    }
+}

+ 20 - 0
app/Module/GameItems/Listeners/TestListener.php

@@ -0,0 +1,20 @@
+<?php
+
+namespace App\Module\Test\Listeners;
+
+use App\Module\Test\Events\TestEvent;
+use Illuminate\Contracts\Queue\ShouldQueue;
+
+class TestListener implements ShouldQueue
+{
+    /**
+     * 处理事件
+     *
+     * @param TestEvent $event
+     * @return void
+     */
+    public function handle(TestEvent $event): void
+    {
+        // 处理事件逻辑
+    }
+}

+ 0 - 0
app/Module/GameItems/Models/README.md


+ 29 - 0
app/Module/GameItems/Providers/TestServiceProvider.php

@@ -0,0 +1,29 @@
+<?php
+
+namespace App\Module\Test\Providers;
+
+use App\Module\Test\Events\TestEvent;
+use App\Module\Test\Listeners\TestEventListener;
+use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
+
+class TestServiceProvider extends ServiceProvider
+{
+    /**
+     * 事件到监听器的映射
+     *
+     * @var array<class-string, array<int, class-string>>
+     */
+    protected $listen = [
+        TestEvent::class => [
+            TestEventListener::class,
+        ],
+    ];
+
+    /**
+     * 注册任何事件监听器
+     */
+    public function boot(): void
+    {
+        parent::boot();
+    }
+}

+ 8 - 0
app/Module/GameItems/Queues/TestQueue.php

@@ -0,0 +1,8 @@
+<?php
+
+namespace App\Module\Test\Queues;
+
+class TestQueue
+{
+
+}

+ 28 - 0
app/Module/GameItems/README.md

@@ -0,0 +1,28 @@
+# Test 模块
+
+## 模块说明
+Test 模块是一个示例模块,用于展示模块化开发的最佳实践。
+
+## 目录结构
+```
+├── AdminControllers/    # 后台控制器
+├── Commands/            # 命令目录
+├── Config/              # 配置目录
+├── Database/            # 数据库目录
+│   └── create.sql       # 创建数据表的SQL
+└── Enums/               # 枚举(枚举的名和Case全大写)
+├── Models/              # 模型目录
+├── Providers/           # Providers
+├── Events/              # 事件目录
+├── Logic/               # Logic目录/逻辑目录
+├── Listeners/           # 监听器目录 
+├── Queues/              # 事件目录
+├── Repositorys/         # 仓库目录(后台控制器专用,其他场景不要用)
+├── Services/            # 服务目录(供其他模块使用)
+│   └──  TestService.php       # 服务之一
+├── Validations/         # Validation 目录(不是Laravel的Validation规则)
+├── Validators/          # Validator目录
+└── Tests/               # 测试目录
+```
+
+

+ 0 - 0
app/Module/GameItems/Repositorys/README.md


+ 204 - 0
app/Module/GameItems/Services/TestService.php

@@ -0,0 +1,204 @@
+<?php
+
+namespace App\Module\Test\Services;
+
+use App\Module\Test\Events\TestEvent;
+use App\Module\Test\Exceptions\TestException;
+use App\Module\Test\Models\Test as TestModel;
+use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Event;
+use Illuminate\Support\Facades\Validator;
+
+class TestService implements TestServiceInterface
+{
+    /**
+     * 创建测试数据
+     *
+     * @param array $data
+     * @return TestModel
+     * @throws TestException
+     */
+    public function create(array $data): TestModel
+    {
+        try {
+            $this->validate($data);
+            $test = TestModel::create($data);
+            Event::dispatch(new TestEvent($test, 'created'));
+            return $test;
+        } catch (\Exception $e) {
+            throw new TestException('创建测试数据失败:' . $e->getMessage());
+        }
+    }
+
+    /**
+     * 更新测试数据
+     *
+     * @param TestModel $test
+     * @param array $data
+     * @return bool
+     * @throws TestException
+     */
+    public function update(TestModel $test, array $data): bool
+    {
+        try {
+            $this->validate($data);
+            $result = $test->update($data);
+            if ($result) {
+                Event::dispatch(new TestEvent($test, 'updated'));
+            }
+            return $result;
+        } catch (\Exception $e) {
+            throw new TestException('更新测试数据失败:' . $e->getMessage());
+        }
+    }
+
+    /**
+     * 删除测试数据
+     *
+     * @param TestModel $test
+     * @return bool
+     * @throws TestException
+     */
+    public function delete(TestModel $test): bool
+    {
+        try {
+            $result = $test->delete();
+            if ($result) {
+                Event::dispatch(new TestEvent($test, 'deleted'));
+            }
+            return $result;
+        } catch (\Exception $e) {
+            throw new TestException('删除测试数据失败:' . $e->getMessage());
+        }
+    }
+
+    /**
+     * 恢复测试数据
+     *
+     * @param TestModel $test
+     * @return bool
+     * @throws TestException
+     */
+    public function restore(TestModel $test): bool
+    {
+        try {
+            $result = $test->restore();
+            if ($result) {
+                Event::dispatch(new TestEvent($test, 'restored'));
+            }
+            return $result;
+        } catch (\Exception $e) {
+            throw new TestException('恢复测试数据失败:' . $e->getMessage());
+        }
+    }
+
+    /**
+     * 强制删除测试数据
+     *
+     * @param TestModel $test
+     * @return bool
+     * @throws TestException
+     */
+    public function forceDelete(TestModel $test): bool
+    {
+        try {
+            $result = $test->forceDelete();
+            if ($result) {
+                Event::dispatch(new TestEvent($test, 'force_deleted'));
+            }
+            return $result;
+        } catch (\Exception $e) {
+            throw new TestException('强制删除测试数据失败:' . $e->getMessage());
+        }
+    }
+
+    /**
+     * 验证数据
+     *
+     * @param array $data
+     * @return void
+     * @throws TestException
+     */
+    protected function validate(array $data): void
+    {
+        $validator = Validator::make($data, [
+            'name' => 'required|string|max:255',
+            'code' => 'required|string|max:50|unique:test,code',
+            'description' => 'nullable|string',
+            'data' => 'nullable|array',
+            'status' => 'required|integer|in:0,1'
+        ]);
+
+        if ($validator->fails()) {
+            throw new TestException('数据验证失败:' . $validator->errors()->first());
+        }
+    }
+
+    public static function insertHash()
+    {
+        // 初始化salt
+        $salt = 'uraus';
+        // 初始化hash
+        $hashInit = 'uraus';
+
+        for ($i = 0; $i < 10000; $i++) {
+            // 获取hash
+            $lashHash = DB::table('lan_hash_test')
+                ->where(['user_id' => 1])
+                ->orderBy('id', 'desc')
+                ->limit(1)
+                ->value('hash');
+            $lastHash = $lashHash ?? $hashInit;
+
+
+            // 验证哈希链
+            $isTrue = self::verify(1);
+            if (!$isTrue) {
+                echo '错误';
+                return;
+            }
+            $num = 1;
+            $time = time();
+            $hashStr = "$time|$num|$lastHash|$salt";
+            $hashValue = hash('sha256', $hashStr);
+            $insert = [
+                'user_id' => 1,
+                'num' => $num,
+                'time' => $time,
+                'hash' => $hashValue
+            ];
+            DB::table('lan_hash_test')->insert($insert);
+            echo $i . PHP_EOL;
+        }
+        return;
+    }
+
+    public static function verify($userId)
+    {
+        // 初始化salt
+        $salt = 'uraus';
+        // 初始化hash
+        $hashInit = 'uraus';
+        $logs = DB::table('lan_hash_test')->where(['user_id' => 1])->orderBy('id')->get()->toArray();
+        foreach ($logs as $key => $value) {
+            if (isset($logs[$key - 1])) {
+                $lastHash = $logs[$key - 1]->hash;
+            } else {
+                $lastHash = $hashInit;
+            }
+
+            $hashStr = "$value->time|$value->num|$lastHash|$salt";
+            $hashValue = hash('sha256', $hashStr);
+            if ($hashValue === $value->hash) {
+                echo $value->hash . PHP_EOL;
+                echo $hashValue . PHP_EOL;
+                echo '第'.$key.'次比对成功' . PHP_EOL;
+                continue;
+            }
+            echo $value->hash . PHP_EOL;
+            echo $hashValue . PHP_EOL;
+            echo '比对失败' . PHP_EOL;
+            return false;
+        }
+    }
+}

+ 0 - 0
app/Module/Test/Services/TestServiceInterface.php → app/Module/GameItems/Services/TestServiceInterface.php


+ 0 - 0
app/Module/Test/Services/TestStatisticsService.php → app/Module/GameItems/Services/TestStatisticsService.php


+ 0 - 0
app/Module/Test/Services/TestStatisticsServiceInterface.php → app/Module/GameItems/Services/TestStatisticsServiceInterface.php


+ 167 - 0
app/Module/GameItems/Tests/TestEventTest.php

@@ -0,0 +1,167 @@
+<?php
+
+namespace App\Module\Test\Tests;
+
+use App\Module\Test\Events\TestEvent;
+use App\Module\Test\Models\Test;
+use App\Module\Test\Test as TestService;
+use Illuminate\Foundation\Testing\DatabaseTransactions;
+use Illuminate\Support\Facades\Event;
+use Tests\TestCase;
+
+class TestEventTest extends TestCase
+{
+    use DatabaseTransactions;
+
+    protected TestService $service;
+
+    protected function setUp(): void
+    {
+        parent::setUp();
+        $this->service = new TestService();
+    }
+
+    /**
+     * 测试创建事件
+     */
+    public function test_created_event(): void
+    {
+        Event::fake();
+
+        // 创建测试数据
+        $test = $this->service->create([
+            'name' => '测试数据1',
+            'code' => 'TEST001',
+            'description' => '这是一个测试数据',
+            'data' => ['key' => 'value'],
+            'status' => 1
+        ]);
+
+        // 断言事件被触发
+        Event::assertDispatched(TestEvent::class, function ($event) use ($test) {
+            return $event->test->id === $test->id
+                && $event->type === 'created'
+                && $event->test->name === '测试数据1'
+                && $event->test->code === 'TEST001'
+                && $event->test->status === 1;
+        });
+    }
+
+    /**
+     * 测试更新事件
+     */
+    public function test_updated_event(): void
+    {
+        Event::fake();
+
+        // 创建测试数据
+        $test = $this->service->create([
+            'name' => '原始数据',
+            'code' => 'TEST002',
+            'status' => 1
+        ]);
+
+        // 更新数据
+        $this->service->update($test, [
+            'name' => '更新后的数据',
+            'status' => 2
+        ]);
+
+        // 断言事件被触发
+        Event::assertDispatched(TestEvent::class, function ($event) use ($test) {
+            return $event->test->id === $test->id
+                && $event->type === 'updated'
+                && $event->test->name === '更新后的数据'
+                && $event->test->status === 2;
+        });
+    }
+
+    /**
+     * 测试软删除事件
+     */
+    public function test_deleted_event(): void
+    {
+        Event::fake();
+
+        // 创建测试数据
+        $test = $this->service->create([
+            'name' => '待删除数据',
+            'code' => 'TEST003',
+            'status' => 1
+        ]);
+
+        // 软删除数据
+        $this->service->delete($test);
+
+        // 断言事件被触发
+        Event::assertDispatched(TestEvent::class, function ($event) use ($test) {
+            return $event->test->id === $test->id
+                && $event->type === 'deleted'
+                && $event->test->name === '待删除数据'
+                && $event->test->trashed();
+        });
+    }
+
+    /**
+     * 测试恢复事件
+     */
+    public function test_restored_event(): void
+    {
+        Event::fake();
+
+        // 创建并软删除测试数据
+        $test = $this->service->create([
+            'name' => '待恢复数据',
+            'code' => 'TEST004',
+            'status' => 1
+        ]);
+        $this->service->delete($test);
+
+        // 恢复数据
+        $this->service->restore($test);
+
+        // 断言事件被触发
+        Event::assertDispatched(TestEvent::class, function ($event) use ($test) {
+            return $event->test->id === $test->id
+                && $event->type === 'restored'
+                && $event->test->name === '待恢复数据'
+                && !$event->test->trashed();
+        });
+    }
+
+    /**
+     * 测试强制删除事件
+     */
+    public function test_force_deleted_event(): void
+    {
+        Event::fake();
+
+        // 创建测试数据
+        $test = $this->service->create([
+            'name' => '待强制删除数据',
+            'code' => 'TEST005',
+            'status' => 1
+        ]);
+
+        // 强制删除数据
+        $this->service->forceDelete($test);
+
+        // 断言事件被触发
+        Event::assertDispatched(TestEvent::class, function ($event) use ($test) {
+            return $event->test->id === $test->id
+                && $event->type === 'force_deleted'
+                && $event->test->name === '待强制删除数据';
+        });
+    }
+
+    /**
+     * 测试事件未被触发
+     */
+    public function test_event_not_dispatched(): void
+    {
+        Event::fake();
+
+        // 断言事件未被触发
+        Event::assertNotDispatched(TestEvent::class);
+    }
+}

+ 133 - 0
app/Module/GameItems/Tests/TestHookTest.php

@@ -0,0 +1,133 @@
+<?php
+
+namespace App\Module\Test\Tests;
+
+use App\Module\Test\Hooks\TestHook;
+use App\Module\Test\Models\Test;
+use Illuminate\Foundation\Testing\DatabaseTransactions;
+use Tests\TestCase;
+
+class TestHookTest extends TestCase
+{
+    use DatabaseTransactions;
+
+    protected TestHook $hook;
+
+    public function setUp(): void
+    {
+        parent::setUp();
+        $this->hook = app(TestHook::class);
+    }
+
+    /**
+     * 测试创建并通知
+     *
+     * @return void
+     */
+    public function test_create_and_notify(): void
+    {
+        $data = [
+            'name' => '测试数据',
+            'code' => 'TEST001',
+            'description' => '测试描述'
+        ];
+
+        $result = $this->hook->createAndNotify($data);
+
+        $this->assertIsArray($result);
+        $this->assertEquals('测试数据创建成功', $result['title']);
+        $this->assertStringContainsString($data['name'], $result['content']);
+        $this->assertStringContainsString($data['code'], $result['content']);
+        $this->assertArrayHasKey('test_id', $result['data']);
+        $this->assertEquals($data['name'], $result['data']['name']);
+        $this->assertEquals($data['code'], $result['data']['code']);
+
+        // 验证数据是否真的创建了
+        $test = Test::find($result['data']['test_id']);
+        $this->assertNotNull($test);
+        $this->assertEquals($data['name'], $test->name);
+        $this->assertEquals($data['code'], $test->code);
+    }
+
+    /**
+     * 测试更新并通知
+     *
+     * @return void
+     */
+    public function test_update_and_notify(): void
+    {
+        // 创建测试数据
+        $test = Test::factory()->create();
+
+        $data = [
+            'name' => '更新数据',
+            'code' => 'TEST002'
+        ];
+
+        $result = $this->hook->updateAndNotify($test->id, $data);
+
+        $this->assertIsArray($result);
+        $this->assertEquals('测试数据更新成功', $result['title']);
+        $this->assertStringContainsString($data['name'], $result['content']);
+        $this->assertStringContainsString($data['code'], $result['content']);
+        $this->assertEquals($test->id, $result['data']['test_id']);
+        $this->assertEquals($data['name'], $result['data']['name']);
+        $this->assertEquals($data['code'], $result['data']['code']);
+
+        // 验证数据是否真的更新了
+        $test->refresh();
+        $this->assertEquals($data['name'], $test->name);
+        $this->assertEquals($data['code'], $test->code);
+    }
+
+    /**
+     * 测试更新不存在的数据
+     *
+     * @return void
+     */
+    public function test_update_non_existent(): void
+    {
+        $result = $this->hook->updateAndNotify(999, [
+            'name' => '更新数据',
+            'code' => 'TEST002'
+        ]);
+
+        $this->assertNull($result);
+    }
+
+    /**
+     * 测试删除并通知
+     *
+     * @return void
+     */
+    public function test_delete_and_notify(): void
+    {
+        // 创建测试数据
+        $test = Test::factory()->create();
+
+        $result = $this->hook->deleteAndNotify($test->id);
+
+        $this->assertIsArray($result);
+        $this->assertEquals('测试数据删除成功', $result['title']);
+        $this->assertStringContainsString($test->name, $result['content']);
+        $this->assertStringContainsString($test->code, $result['content']);
+        $this->assertEquals($test->id, $result['data']['test_id']);
+        $this->assertEquals($test->name, $result['data']['name']);
+        $this->assertEquals($test->code, $result['data']['code']);
+
+        // 验证数据是否真的删除了
+        $this->assertNull(Test::find($test->id));
+    }
+
+    /**
+     * 测试删除不存在的数据
+     *
+     * @return void
+     */
+    public function test_delete_non_existent(): void
+    {
+        $result = $this->hook->deleteAndNotify(999);
+
+        $this->assertNull($result);
+    }
+}

+ 83 - 0
app/Module/GameItems/Tests/TestSoftDeleteTest.php

@@ -0,0 +1,83 @@
+<?php
+
+namespace App\Module\Test\Tests;
+
+use App\Module\Test\Models\Test;
+use Illuminate\Foundation\Testing\DatabaseTransactions;
+use Tests\TestCase;
+
+class TestSoftDeleteTest extends TestCase
+{
+    use DatabaseTransactions;
+
+    /**
+     * 测试软删除功能
+     */
+    public function test_soft_delete(): void
+    {
+        // 创建测试数据
+        $test = Test::factory()->create([
+            'name' => '测试数据1',
+            'description' => '这是一个测试数据'
+        ]);
+
+        // 验证数据存在
+        $this->assertDatabaseHas('tests', [
+            'id' => $test->id,
+            'name' => '测试数据1',
+            'description' => '这是一个测试数据'
+        ]);
+
+        // 软删除数据
+        $test->delete();
+
+        // 验证数据在正常查询中不可见
+        $this->assertDatabaseMissing('tests', [
+            'id' => $test->id,
+            'name' => '测试数据1',
+            'description' => '这是一个测试数据'
+        ]);
+
+        // 验证数据在软删除表中可见
+        $this->assertSoftDeleted('tests', [
+            'id' => $test->id,
+            'name' => '测试数据1',
+            'description' => '这是一个测试数据'
+        ]);
+
+        // 恢复数据
+        $test->restore();
+
+        // 验证数据恢复后可见
+        $this->assertDatabaseHas('tests', [
+            'id' => $test->id,
+            'name' => '测试数据1',
+            'description' => '这是一个测试数据'
+        ]);
+    }
+
+    /**
+     * 测试强制删除功能
+     */
+    public function test_force_delete(): void
+    {
+        // 创建测试数据
+        $test = Test::factory()->create([
+            'name' => '测试数据2',
+            'description' => '这是另一个测试数据'
+        ]);
+
+        // 软删除数据
+        $test->delete();
+
+        // 强制删除数据
+        $test->forceDelete();
+
+        // 验证数据完全删除
+        $this->assertDatabaseMissing('tests', [
+            'id' => $test->id,
+            'name' => '测试数据2',
+            'description' => '这是另一个测试数据'
+        ]);
+    }
+}

+ 92 - 0
app/Module/GameItems/Tests/TestTest.php

@@ -0,0 +1,92 @@
+<?php
+
+namespace App\Module\Test\Tests;
+
+use App\Module\Test\Models\Test;
+use App\Module\Test\Services\TestService;
+use Illuminate\Foundation\Testing\DatabaseTransactions;
+use Tests\TestCase;
+
+class TestTest extends TestCase
+{
+    use DatabaseTransactions;
+
+    protected TestService $service;
+
+    protected function setUp(): void
+    {
+        parent::setUp();
+        $this->service = app(TestService::class);
+    }
+
+    /**
+     * 测试创建数据
+     *
+     * @return void
+     */
+    public function test_create(): void
+    {
+        $data = [
+            'name' => '测试数据',
+            'code' => 'TEST001',
+            'description' => '测试描述'
+        ];
+
+        $test = $this->service->create($data);
+
+        $this->assertInstanceOf(Test::class, $test);
+        $this->assertEquals($data['name'], $test->name);
+        $this->assertEquals($data['code'], $test->code);
+        $this->assertEquals($data['description'], $test->description);
+    }
+
+    /**
+     * 测试获取数据
+     *
+     * @return void
+     */
+    public function test_get(): void
+    {
+        $test = Test::factory()->create();
+
+        $result = $this->service->get($test->id);
+
+        $this->assertInstanceOf(Test::class, $result);
+        $this->assertEquals($test->id, $result->id);
+    }
+
+    /**
+     * 测试更新数据
+     *
+     * @return void
+     */
+    public function test_update(): void
+    {
+        $test = Test::factory()->create();
+        $data = [
+            'name' => '更新数据',
+            'code' => 'TEST002'
+        ];
+
+        $result = $this->service->update($test->id, $data);
+
+        $this->assertTrue($result);
+        $this->assertEquals($data['name'], $test->fresh()->name);
+        $this->assertEquals($data['code'], $test->fresh()->code);
+    }
+
+    /**
+     * 测试删除数据
+     *
+     * @return void
+     */
+    public function test_delete(): void
+    {
+        $test = Test::factory()->create();
+
+        $result = $this->service->delete($test->id);
+
+        $this->assertTrue($result);
+        $this->assertNull(Test::find($test->id));
+    }
+}

+ 32 - 0
app/Module/GameItems/Validations/TestValidation.php

@@ -0,0 +1,32 @@
+<?php
+
+namespace App\Module\Test\Validations;
+
+use UCore\ValidationCore;
+
+
+/**
+ * Test请求 的 验证器
+ * TestValidation
+ *
+ */
+class TestValidation extends ValidationCore
+{
+
+    public function rules(array $rules = []): array
+    {
+        // times 是必填的
+        $rules[] = [
+            'times', 'required'
+        ];
+        $rules[] = [
+            'msg', 'required'
+        ];
+        $rules[] = [
+            'times', 'integer', 'min' => 10
+        ];
+
+        return parent::rules($rules); // TODO: Change the autogenerated stub
+    }
+
+}

+ 38 - 0
app/Module/GameItems/Validators/TestValidator.php

@@ -0,0 +1,38 @@
+<?php
+
+namespace App\Module\Test\Validators;
+
+use Inhere\Validate\Validation;
+use UCore\Validator;
+
+
+/**
+ * TestValidator
+ * Validator独立逻辑验证器,应区分与Validation的区别
+ *
+ */
+class TestValidator extends Validator
+{
+
+    /**
+     * 验证逻辑
+     * @param mixed $value
+     * @param array $data
+     * @return bool
+     */
+    public function validate(mixed $value, array $data): bool
+    {
+        if ($value > 3) {
+            // > 3
+            return false;
+        }
+        if ($value < -10) {
+            // < -10 增加一个错误消息
+            return $this->addError("这是一个极小的数字,不允许的!");
+        }
+
+        // 验证成功返回True
+        return true;
+    }
+
+}