diff --git a/app/Http/Controllers/Admin/UserController.php b/app/Http/Controllers/Admin/UserController.php index b29f2cb..c24e3a8 100644 --- a/app/Http/Controllers/Admin/UserController.php +++ b/app/Http/Controllers/Admin/UserController.php @@ -7,6 +7,7 @@ use App\Models\Host; use App\Models\Transaction; use App\Models\User; +use App\Models\UserGroup; use App\Models\WorkOrder\WorkOrder; use Carbon\Carbon; use Illuminate\Http\RedirectResponse; @@ -37,7 +38,7 @@ public function index(Request $request): View $users = $users->where('email', 'like', '%' . $request->email . '%'); } - $users = $users->paginate(100); + $users = $users->with('user_group')->paginate(100); return view('admin.users.index', compact('users')); } @@ -70,9 +71,9 @@ public function edit(User $user) $hosts = Host::where('user_id', $user->id)->latest()->paginate(50, ['*'], 'hosts_page'); $workOrders = WorkOrder::where('user_id', $user->id)->latest()->paginate(50, ['*'], 'workOrders_page'); $balances = Balance::where('user_id', $user->id)->latest()->paginate(50, ['*'], 'balances_page'); + $groups = UserGroup::all(); - - return view('admin.users.edit', compact('user', 'hosts', 'workOrders', 'balances')); + return view('admin.users.edit', compact('user', 'hosts', 'workOrders', 'balances', 'groups')); } /** @@ -118,7 +119,10 @@ public function update(Request $request, User $user) } } - $user->save(); + + if ($request->has('user_group_id')) { + $user->user_group_id = $request->user_group_id; + } if ($user->isDirty()) { $user->save(); diff --git a/app/Http/Controllers/Admin/UserGroupController.php b/app/Http/Controllers/Admin/UserGroupController.php new file mode 100644 index 0000000..9ada3ef --- /dev/null +++ b/app/Http/Controllers/Admin/UserGroupController.php @@ -0,0 +1,123 @@ +validate($this->rules()); + + $user_group = UserGroup::create($request->all()); + + return redirect()->route('admin.user-groups.edit', $user_group)->with('success', '用户组新建成功。'); + } + + /** + * Display the specified resource. + * + * @param UserGroup $user_group + * + * @return View + */ + public function show(UserGroup $user_group): View + { + $users = User::where('user_group_id', $user_group->id)->paginate(100); + + return view('admin.user-groups.show', compact('user_group', 'users')); + } + + /** + * Show the form for editing the specified resource. + * + * @param UserGroup $user_group + * + * @return View + */ + public function edit(UserGroup $user_group): View + { + // + + return view('admin.user-groups.edit', compact('user_group')); + } + + /** + * Update the specified resource in storage. + * + * @param Request $request + * @param UserGroup $user_group + * + * @return RedirectResponse + */ + public function update(Request $request, UserGroup $user_group): RedirectResponse + { + // + $request->validate($this->rules()); + + $user_group->update($request->all()); + + return back()->with('success', '用户组更新成功。'); + } + + /** + * Remove the specified resource from storage. + * + * @param UserGroup $user_group + * + * @return RedirectResponse + */ + public function destroy(UserGroup $user_group) + { + $user_group->delete(); + + return redirect()->route('admin.user-groups.index')->with('success', '用户组删除成功。'); + } + + private function rules(): array + { + return [ + 'name' => 'required|string', + 'color' => 'regex:/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/', + 'discount' => 'required|numeric|min:0|max:100', + 'exempt' => 'required|boolean', + ]; + } +} diff --git a/app/Jobs/HostCost.php b/app/Jobs/HostCost.php index acbf6fe..f34b1c8 100644 --- a/app/Jobs/HostCost.php +++ b/app/Jobs/HostCost.php @@ -34,7 +34,14 @@ public function __construct($minute) public function handle() { // chunk hosts and load user - Host::where('minute_at', $this->minute)->whereIn('status', ['running', 'stopped'])->with('user')->chunk(500, function ($hosts) { + $host = new Host(); + + // if env not local, then use minute_at + if (app()->environment() != 'local') { + $host = $host->where('minute_at', $this->minute); + } + + $host->whereIn('status', ['running', 'stopped'])->with('user')->chunk(500, function ($hosts) { foreach ($hosts as $host) { $host->cost(); } diff --git a/app/Models/Host.php b/app/Models/Host.php index e2cbc9e..a312ca4 100644 --- a/app/Models/Host.php +++ b/app/Models/Host.php @@ -218,6 +218,15 @@ public function safeDelete(): bool public function cost($amount = null, $auto = true): bool { $this->load('user'); + $user = $this->user; + $user->load('user_group'); + $user_group = $user->user_group; + + if ($user_group) { + if ($user_group->exempt) { + return true; + } + } $real_price = $amount ?? $this->price; @@ -227,6 +236,13 @@ public function cost($amount = null, $auto = true): bool } } + if ($user_group) { + if ($user_group->discount !== 100 && $user_group->discount !== null) { + $real_price = $real_price * ($user_group->discount / 100); + } + } + + if ($auto) { // 获取本月天数 $days = now()->daysInMonth; diff --git a/app/Models/User.php b/app/Models/User.php index 1fa9ca2..b7344d7 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -7,6 +7,7 @@ use App\Exceptions\User\BalanceNotEnoughException; use GeneaLabs\LaravelModelCaching\Traits\Cachable; use Illuminate\Database\Eloquent\Factories\HasFactory; +use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; @@ -144,6 +145,11 @@ public function hosts(): HasMany return $this->hasMany(Host::class); } + public function user_group(): BelongsTo + { + return $this->belongsTo(UserGroup::class); + } + /** * @throws CommonException * @throws BalanceNotEnoughException diff --git a/app/Models/UserGroup.php b/app/Models/UserGroup.php new file mode 100644 index 0000000..6e91c8b --- /dev/null +++ b/app/Models/UserGroup.php @@ -0,0 +1,30 @@ + 'integer', + 'exempt' => 'boolean', + ]; + + public function users(): HasMany + { + return $this->hasMany(User::class); + } + +} diff --git a/database/migrations/2022_11_26_202440_create_user_groups_table.php b/database/migrations/2022_11_26_202440_create_user_groups_table.php new file mode 100644 index 0000000..d9fda08 --- /dev/null +++ b/database/migrations/2022_11_26_202440_create_user_groups_table.php @@ -0,0 +1,73 @@ +id(); + + // 名称 + $table->string('name')->comment('名称')->index(); + + // 颜色 + $table->string('color')->comment('颜色')->nullable(); + + // 优惠百分比 + $table->integer('discount')->comment('优惠百分比')->default(100); + + // 暂停/终止豁免权 + $table->boolean('exempt')->comment('暂停/终止豁免权')->default(false); + + $table->timestamps(); + }); + + // Schema::table('users', function (Blueprint $table) { + // $table->unsignedBigInteger('user_group_id')->nullable()->comment('用户组')->index()->after('banned_reason'); + // $table->foreign('user_group_id')->references('id')->on('user_groups')->onDelete('set null'); + // }); + + Schema::table('users', function (Blueprint $table) { + $table->unsignedBigInteger('user_group_id')->nullable()->comment('用户组')->index()->after('banned_reason'); + $table->foreign('user_group_id')->references('id')->on('user_groups')->onDelete('set null'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + // Schema::table('users', function (Blueprint $table) { + // // drop column if exists + // if (Schema::hasColumn('users', 'user_group_id')) { + // $table->dropForeign('users_user_group_id_foreign'); + // + // $table->dropColumn('user_group_id'); + // } + // }); + // + + Schema::table('users', function (Blueprint $table) { + // drop column if exists + if (Schema::hasColumn('users', 'user_group_id')) { + $table->dropForeign('users_user_group_id_foreign'); + + $table->dropColumn('user_group_id'); + } + }); + + + Schema::dropIfExists('user_groups'); + } +}; diff --git a/resources/views/admin/user-groups/create.blade.php b/resources/views/admin/user-groups/create.blade.php new file mode 100644 index 0000000..4122780 --- /dev/null +++ b/resources/views/admin/user-groups/create.blade.php @@ -0,0 +1,43 @@ +@extends('layouts.admin') + +@section('title', '新建用户组') + +@section('content') +

新建用户组

+ + 返回 用户组列表 + +
+ @csrf + +
+ + +
+ +
+ + +
+ +
+ + + {{-- 提示 --}} + 折扣为 100% 时,不打折。 + +
+ +
+ + +
+ + +
+ +@endsection diff --git a/resources/views/admin/user-groups/edit.blade.php b/resources/views/admin/user-groups/edit.blade.php new file mode 100644 index 0000000..418c85c --- /dev/null +++ b/resources/views/admin/user-groups/edit.blade.php @@ -0,0 +1,53 @@ +@extends('layouts.admin') + +@section('title', '用户组: ' . $user_group->name) + +@section('content') +

{{ $user_group->name }}

+ + 查看此用户组 + +
+ @csrf + @method('PATCH') + +
+ + +
+ +
+ + +
+ +
+ + + {{-- 提示 --}} + 折扣为 100% 时,不打折。 + +
+ +
+ + +
+ + +
+ +
+
+ @csrf + @method('DELETE') + +
+ +@endsection diff --git a/resources/views/admin/user-groups/index.blade.php b/resources/views/admin/user-groups/index.blade.php new file mode 100644 index 0000000..1220b95 --- /dev/null +++ b/resources/views/admin/user-groups/index.blade.php @@ -0,0 +1,60 @@ +@extends('layouts.admin') + +@section('title', '用户组') + +@section('content') + +

用户组

+

将用户划分到一个组中,可让他们享受到特别待遇。

+ + 新用户组 +
+ + + + + + + + + + + @foreach ($user_groups as $user_group) + + + + + + + + @endforeach + +
ID名称折扣暂停 / 终止豁免权操作
+ + {{ $user_group->id }} + + +   +   + {{ $user_group->name }} + + @if ($user_group->discount == 100) + 不享受折扣 + @else + 享受 {{ $user_group->discount }}% 的折扣 + @endif + + {{ $user_group->exempt ? '是' : '否' }} + + 查看 + + 编辑 +
+
+ + {{-- 分页 --}} + {{ $user_groups->links() }} + +@endsection diff --git a/resources/views/admin/user-groups/show.blade.php b/resources/views/admin/user-groups/show.blade.php new file mode 100644 index 0000000..2251a3b --- /dev/null +++ b/resources/views/admin/user-groups/show.blade.php @@ -0,0 +1,70 @@ +@extends('layouts.admin') + +@section('title', '用户组: ' . $user_group->name) + +@section('content') +

{{ $user_group->name }}

+ 编辑此用户组 + +
+ + 此用户组的 ID 为 {{ $user_group->id }}。 + @if ($user_group->discount == 100) + 不享受折扣 + @else + 享受 {{ $user_group->discount }}% 的折扣 + @endif + , + @if ($user_group->exempt) + 并且有暂停 / 终止豁免权 + @else + 并且没有暂停 / 终止豁免权 + @endif + 。 + + + {{-- 用户列表 --}} +
+ + + + + + + + + + + + @foreach ($users as $user) + + + + + + + + + + @endforeach + +
ID用户名邮箱余额注册时间操作
+ + {{ $user->id }} + + + + {{ $user->name }} + + + {{ $user->email }} + + {{ $user->balance }} 元 + + {{ $user->created_at }} + + 编辑 +
+
+@endsection diff --git a/resources/views/admin/users/edit.blade.php b/resources/views/admin/users/edit.blade.php index b5f7b77..63c87f9 100644 --- a/resources/views/admin/users/edit.blade.php +++ b/resources/views/admin/users/edit.blade.php @@ -43,7 +43,7 @@ {{ $host->getPrice() }} 元 - + 查看 @@ -165,4 +165,25 @@ + + {{-- 用户组 --}} +

用户组

+
+ @csrf + @method('PATCH') + +
+ + +
+ + +
+ @endsection diff --git a/resources/views/admin/users/index.blade.php b/resources/views/admin/users/index.blade.php index 904a7cf..1c994df 100644 --- a/resources/views/admin/users/index.blade.php +++ b/resources/views/admin/users/index.blade.php @@ -37,6 +37,7 @@ 用户名 邮箱 余额 + 用户组 注册时间 操作 @@ -60,6 +61,15 @@ {{ $user->balance }} 元 + + @if ($user->group_id) + + {{ $user->user_group->name }} + + @else + 无 + @endif + {{ $user->created_at }} diff --git a/resources/views/layouts/admin.blade.php b/resources/views/layouts/admin.blade.php index f0acc21..d40064a 100644 --- a/resources/views/layouts/admin.blade.php +++ b/resources/views/layouts/admin.blade.php @@ -19,94 +19,97 @@ -
-
- +
@yield('content')
- +
diff --git a/routes/admin.php b/routes/admin.php index d69120e..b976a09 100644 --- a/routes/admin.php +++ b/routes/admin.php @@ -6,6 +6,7 @@ use App\Http\Controllers\Admin\HostController; use App\Http\Controllers\Admin\ModuleController; use App\Http\Controllers\Admin\UserController; +use App\Http\Controllers\Admin\UserGroupController; use App\Http\Controllers\Admin\WorkOrderController; use Illuminate\Support\Facades\Route; @@ -26,6 +27,9 @@ Route::resource('hosts', HostController::class)->only(['index', 'edit', 'update', 'destroy']); Route::resource('work-orders', WorkOrderController::class)->only(['index', 'show', 'edit', 'update', 'destroy']); + Route::resource('user-groups', UserGroupController::class); + + Route::view('commands', 'admin.commands')->name('commands'); Route::get('transactions', [HomeController::class, 'transactions'])->name('transactions');