醉梦人间三千年 8 hónapja
szülő
commit
57a64668b0

+ 1 - 1
app/Exceptions/ApiException.php

@@ -13,6 +13,6 @@ class ApiException extends Exception
 {
     public function __construct(array $apiErrorConst, \Throwable $previous = null)
     {
-        parent::__construct($apiErrorConst['message'], $apiErrorConst['status'], $previous);
+        parent::__construct($apiErrorConst['message'], $apiErrorConst['code'], $previous);
     }
 }

+ 4 - 9
app/Http/Controllers/Backend/Server/System/UserController.php → app/Http/Controllers/Backend/Server/Member/UserController.php

@@ -1,14 +1,13 @@
 <?php
 
-namespace App\Http\Controllers\Backend\Server\System;
+namespace App\Http\Controllers\Backend\Server\Member;
 
 use App\Http\Controllers\Backend\Server\Controller;
 use App\Http\Requests\Backend\Server\System\UserRequest;
+use App\Models\SystemUser;
 use App\Models\User;
-use Illuminate\Auth\Events\Registered;
-use Illuminate\Support\Facades\Hash;
-use Illuminate\Validation\Rules;
 use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Hash;
 
 class UserController extends Controller
 {
@@ -30,13 +29,9 @@ class UserController extends Controller
 
     public function store(UserRequest $request)
     {
+        return '创建会员';
         // 存储新创建的用户逻辑
-        User::query()->create([
-            'name' => $request->string('name'),
-            'password' => Hash::make($request->string('password')),
-        ]);
 
-        return response()->noContent();
 //        event(new Registered($user));
 //
 //        Auth::login($user);

+ 59 - 0
app/Http/Controllers/Backend/Server/System/MenuController.php

@@ -0,0 +1,59 @@
+<?php
+/**
+ * @Name
+ * @Description
+ * @Author 刘学玺
+ * @Date 2024/8/14 21:30
+ */
+
+namespace App\Http\Controllers\Backend\Server\System;
+
+use App\Exceptions\ApiException;
+use App\Http\Controllers\Controller;
+use App\Http\Services\Backend\Server\System\MenuService;
+use Illuminate\Http\Request;
+
+class MenuController extends Controller
+{
+    public function index()
+    {
+        // 处理首页逻辑
+        return 'index';
+    }
+
+    public function show($id)
+    {
+        // 处理显示单个用户的逻辑
+    }
+
+    public function create()
+    {
+        // 显示创建用户的表单
+    }
+
+    /**
+     * @throws ApiException
+     */
+    public function store(Request $request)
+    {
+        $params = $request->all();
+        $res = (new MenuService())->createMenu($params);
+
+        return self::success($res);
+    }
+
+    public function edit($id)
+    {
+        // 显示编辑用户的表单
+    }
+
+    public function update(Request $request, $id)
+    {
+        // 更新用户逻辑
+    }
+
+    public function destroy($id)
+    {
+        // 删除用户逻辑
+    }
+}

+ 21 - 1
app/Http/Controllers/Controller.php

@@ -2,7 +2,27 @@
 
 namespace App\Http\Controllers;
 
+use App\Exceptions\ApiException;
+use \Illuminate\Http\Response;
+use Illuminate\Http\JsonResponse;
+use Illuminate\Support\Arr;
+
 abstract class Controller
 {
-    //
+    public static function success($result = null, $message = null, $code = 0): Response|JsonResponse
+    {
+        if (is_null($result) && is_null($message)) return response()->noContent();
+        $data = ['code' => $code];
+        !is_null($result) && Arr::add($data, 'result', $result);
+        !is_null($message) && Arr::add($data, 'message', $message);
+        return response()->json($data);
+    }
+
+    public function fail($message = null, $code = -1): JsonResponse
+    {
+        $data = ['code' => $code];
+        !is_null($message) && Arr::add($data, 'message', $message);
+        return response()->json($data);
+    }
+
 }

+ 44 - 0
app/Http/Requests/Backend/Server/System/MenuRequest.php

@@ -0,0 +1,44 @@
+<?php
+/**
+ * @Name
+ * @Description
+ * @Author 刘学玺
+ * @Date 2024/3/20 14:54
+ */
+
+namespace App\Http\Requests\Backend\Server\System;
+
+use App\Http\Requests\Request;
+use App\Models\System\User;
+use Illuminate\Validation\Rules;
+
+class MenuRequest extends Request
+{
+    /**
+     * Get the validation rules that apply to the request.
+     *
+     * @return array<string, array|string>
+     */
+    public function rules(): array
+    {
+        return [
+            'name' => ['required', 'string', 'max:50'],
+            'permission' => ['string', 'max:100'],
+            'type' => ['required', 'max:100'],
+//            'email' => ['string', 'lowercase', 'email', 'max:255', 'unique:'.User::class],
+            'password' => ['required', 'confirmed', Rules\Password::defaults()],
+//            unique:table,column,except,idColumn
+//            Rule::unique('facilities', 'name')->ignoreModel(Facility::find($this->request->get('id')))
+        ];
+    }
+
+    public function messages(): array
+    {
+        return [
+            'name.required' => '请输入用户账号!',
+            'name.unique' => '用户账号已存在!',
+            'password.required' => '请输入用户密码!',
+            'password.confirmed' => '两次输入密码不一致!',
+        ];
+    }
+}

+ 1 - 1
app/Http/Requests/Backend/Server/System/UserRequest.php

@@ -9,7 +9,7 @@
 namespace App\Http\Requests\Backend\Server\System;
 
 use App\Http\Requests\Request;
-use App\Models\User;
+use App\Models\System\User;
 use Illuminate\Validation\Rules;
 
 class UserRequest extends Request

+ 84 - 0
app/Http/Services/Backend/Server/System/MenuService.php

@@ -0,0 +1,84 @@
+<?php
+/**
+ * @Name
+ * @Description
+ * @Author 刘学玺
+ * @Date 2024/8/15 14:30
+ */
+
+namespace App\Http\Services\Backend\Server\System;
+
+use App\Enums\System\MenuType;
+use App\Exceptions\ApiException;
+use App\Http\Services\Service;
+use App\Models\System\Menu;
+
+class MenuService extends Service
+{
+
+    /**
+     * @throws ApiException
+     */
+    public function createMenu($params)
+    {
+        // 校验父菜单存在
+        self::validateParentMenu($params['parent_id'], null);
+        // 校验菜单(自己)
+        self::validateMenu($params['parent_id'], $params['name'], null);
+        // 插入数据库
+        $menu = self::toModel($params, Menu::class);
+        self::initMenuProperty($menu);
+        $menu->save();
+        return $menu->id;
+    }
+
+    /**
+     * @throws ApiException
+     */
+    protected static function validateParentMenu($parentId, $childId): void
+    {
+        if (!$parentId) return;
+        // 不能设置自己为父菜单
+        $parentId === $childId && self::error('MENU_PARENT_ERROR');
+
+        $menu = Menu::query()->find($parentId);
+        // 父菜单不存在
+        !$menu && self::error('MENU_PARENT_NOT_EXISTS');
+
+        // 父菜单必须是目录或者菜单类型
+        $menu->type != MenuType::DIR && $menu->type != MenuType::MENU && self::error('MENU_PARENT_NOT_DIR_OR_MENU');
+    }
+
+    /**
+     * @throws ApiException
+     */
+    protected static function validateMenu($parentId, $name, $id): void
+    {
+        $where = ['parent_id' => $parentId, 'name' => $name];
+        $menu = Menu::query()->where($where)->first();
+        if (is_null($menu)) return;
+
+        // 如果 id 为空,说明不用比较是否为相同 id 的菜单
+        !$id && self::error('MENU_NAME_DUPLICATE');
+        $menu->id !== $id && self::error('MENU_NAME_DUPLICATE');
+    }
+
+    /**
+     * 初始化菜单的通用属性。
+     * <p>
+     * 例如说,只有目录或者菜单类型的菜单,才设置 icon
+     *
+     */
+    private static function initMenuProperty(&$menu): void
+    {
+        // 菜单为按钮类型时,无需 component、icon、path 属性,进行置空
+        if ($menu->type === MenuType::BUTTON) {
+            $menu->component = null;
+            $menu->componentName = null;
+            $menu->icon = null;
+            $menu->path = null;
+        }
+
+        isset($menu->permission) && ($menu->permission = $menu->permission ?: null);
+    }
+}

+ 34 - 0
app/Http/Services/Service.php

@@ -0,0 +1,34 @@
+<?php
+/**
+ * @Name
+ * @Description
+ * @Author 刘学玺
+ * @Date 2024/8/15 14:35
+ */
+
+namespace App\Http\Services;
+
+use App\Exceptions\ApiException;
+use Illuminate\Support\Arr;
+
+class Service
+{
+    protected static function toModel($attributes, $class)
+    {
+        $classInstance = app($class);
+        $oldAttributes = $classInstance->getAttributes();
+        $newAttributes = array_merge($oldAttributes, $attributes);
+        $classInstance->setRawAttributes($newAttributes);
+        return $classInstance;
+    }
+
+
+    /**
+     * @throws ApiException
+     */
+    protected static function error(string $message = '系统错误', int $code = 500)
+    {
+        $data = ['code' => $code, 'message' => $message];
+        throw new ApiException($data);
+    }
+}

+ 28 - 0
app/Models/System/Menu.php

@@ -0,0 +1,28 @@
+<?php
+
+namespace App\Models\System;
+
+use Illuminate\Database\Eloquent\Factories\HasFactory;
+use Illuminate\Database\Eloquent\Model;
+use Spatie\Permission\Exceptions\PermissionAlreadyExists;
+use Spatie\Permission\Guard;
+use Spatie\Permission\Models\Permission;
+
+class Menu extends Permission
+{
+    public static function create(array $attributes = [])
+    {
+        $attributes = [
+            'name' => '系统设置',
+            'type' => 1,
+        ];
+        $attributes['guard_name'] = $attributes['guard_name'] ?? Guard::getDefaultName(static::class);
+        if (isset($attributes['permission']) && $attributes['permission']) {
+            $permission = static::getPermission(['permission' => $attributes['permission'], 'guard_name' => $attributes['guard_name']]);
+            if ($permission) {
+                throw PermissionAlreadyExists::create($attributes['permission'], $attributes['guard_name']);
+            }
+        }
+        return static::query()->create($attributes);
+    }
+}

+ 7 - 7
config/auth.php

@@ -15,7 +15,7 @@ return [
 
     'defaults' => [
         'guard' => env('AUTH_GUARD', 'web'),
-        'passwords' => env('AUTH_PASSWORD_BROKER', 'users'),
+        'passwords' => env('AUTH_PASSWORD_BROKER', 'system_users'),
     ],
 
     /*
@@ -38,7 +38,7 @@ return [
     'guards' => [
         'web' => [
             'driver' => 'session',
-            'provider' => 'users',
+            'provider' => 'system_users',
         ],
     ],
 
@@ -60,9 +60,9 @@ return [
     */
 
     'providers' => [
-        'users' => [
+        'system_users' => [
             'driver' => 'eloquent',
-            'model' => env('AUTH_MODEL', App\Models\User::class),
+            'model' => env('AUTH_MODEL', App\Models\System\User::class),
         ],
 
         // 'users' => [
@@ -91,9 +91,9 @@ return [
     */
 
     'passwords' => [
-        'users' => [
-            'provider' => 'users',
-            'table' => env('AUTH_PASSWORD_RESET_TOKEN_TABLE', 'password_reset_tokens'),
+        'system_users' => [
+            'provider' => 'system_users',
+            'table' => env('AUTH_PASSWORD_RESET_TOKEN_TABLE', 'system_password_reset_tokens'),
             'expire' => 60,
             'throttle' => 60,
         ],

+ 1 - 1
config/session.php

@@ -86,7 +86,7 @@ return [
     |
     */
 
-    'table' => env('SESSION_TABLE', 'sessions'),
+    'table' => env('SESSION_TABLE', 'system_sessions'),
 
     /*
     |--------------------------------------------------------------------------

+ 8 - 7
database/migrations/0001_01_01_000000_create_users_table.php → database/migrations/0001_01_01_000000_create_system_users_table.php

@@ -11,7 +11,7 @@ return new class extends Migration
      */
     public function up(): void
     {
-        Schema::create('users', function (Blueprint $table) {
+        Schema::create('system_users', function (Blueprint $table) {
             $table->comment('用户信息表');
             $table->id()->comment('用户ID');
             $table->string('name')->unique()->comment('用户账号');
@@ -25,20 +25,21 @@ return new class extends Migration
             $table->string('ip_address', 45)->nullable()->comment('最后登录IP');
             $table->timestamp('last_activity_at')->nullable()->comment('最后登录时间');
             $table->text('remark')->nullable()->comment('备注');
-            $table->tinyInteger('status')->default(0)->comment('账户状态 (0正常 1停用)');
+            $table->tinyInteger('status')->default(1)->comment('账户状态 (1正常 0停用)');
             $table->bigInteger('creator')->nullable()->comment('创建者');
             $table->bigInteger('updater')->nullable()->comment('更新者');
             $table->rememberToken();
             $table->timestamps();
+            $table->softDeletes();
         });
 
-        Schema::create('password_reset_tokens', function (Blueprint $table) {
+        Schema::create('system_password_reset_tokens', function (Blueprint $table) {
             $table->string('name')->primary();
             $table->string('token');
             $table->timestamp('created_at')->nullable();
         });
 
-        Schema::create('sessions', function (Blueprint $table) {
+        Schema::create('system_sessions', function (Blueprint $table) {
             $table->string('id')->primary();
             $table->foreignId('user_id')->nullable()->index();
             $table->string('ip_address', 45)->nullable();
@@ -53,8 +54,8 @@ return new class extends Migration
      */
     public function down(): void
     {
-        Schema::dropIfExists('users');
-        Schema::dropIfExists('password_reset_tokens');
-        Schema::dropIfExists('sessions');
+        Schema::dropIfExists('system_users');
+        Schema::dropIfExists('system_password_reset_tokens');
+        Schema::dropIfExists('system_sessions');
     }
 };

+ 4 - 0
routes/web.php

@@ -1,5 +1,7 @@
 <?php
 
+use App\Http\Controllers\Backend\Server\System\MenuController;
+use App\Http\Controllers\Backend\Server\System\RoleController;
 use App\Http\Controllers\Backend\Server\System\UserController;
 use Illuminate\Support\Facades\Route;
 
@@ -25,6 +27,8 @@ Route::prefix('server')->group(function () {
 
     Route::prefix('system')->group(function () {
         Route::resource('users', UserController::class);
+        Route::resource('menus', MenuController::class);
+        Route::resource('roles', RoleController::class);
     });
 });
 

+ 0 - 24
tests/Feature/Auth/RegistrationTest.php

@@ -1,24 +0,0 @@
-<?php
-
-namespace Tests\Feature\Auth;
-
-use Illuminate\Foundation\Testing\RefreshDatabase;
-use Tests\TestCase;
-
-class RegistrationTest extends TestCase
-{
-    use RefreshDatabase;
-
-    public function test_new_users_can_register(): void
-    {
-        $response = $this->post('/register', [
-            'name' => 'Test User',
-            'email' => 'test@example.com',
-            'password' => 'password',
-            'password_confirmation' => 'password',
-        ]);
-
-        $this->assertAuthenticated();
-        $response->assertNoContent();
-    }
-}

+ 19 - 0
tests/Feature/Backend/Server/SystemTest.php

@@ -0,0 +1,19 @@
+<?php
+
+namespace Tests\Feature\Backend\Server;
+
+use App\Models\System\Menu;
+use App\Models\User;
+use Illuminate\Foundation\Testing\RefreshDatabase;
+use Tests\TestCase;
+
+class SystemTest extends TestCase
+{
+    use RefreshDatabase;
+
+    public function test_create_menu(): void
+    {
+        $menu = Menu::query()->create(['guard_name' => 'Web']);
+        $this->assertGuest();
+    }
+}

+ 0 - 1
tests/Feature/ExampleTest.php

@@ -13,7 +13,6 @@ class ExampleTest extends TestCase
     public function test_the_application_returns_a_successful_response(): void
     {
         $response = $this->get('/');
-
         $response->assertStatus(200);
     }
 }