搭建轻舟一期门户、后台和统一登录。
让分类、会员和示例工具共用同一账号,本地即可跑通登录与授权。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api\V1\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\LoginLog;
|
||||
use App\Models\OauthClient;
|
||||
use App\Models\Order;
|
||||
use App\Models\ServiceTicket;
|
||||
use App\Models\Setting;
|
||||
use App\Models\Subscription;
|
||||
use App\Models\ToolOpenLog;
|
||||
use App\Models\User;
|
||||
use App\Support\Settings;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class SystemController extends Controller
|
||||
{
|
||||
public function dashboard()
|
||||
{
|
||||
return $this->ok([
|
||||
'users' => User::query()->count(),
|
||||
'members' => Subscription::query()->where('status', 'active')->where('ends_at', '>', now())->count(),
|
||||
'logins_today' => LoginLog::query()->where('success', true)->where('created_at', '>=', today())->count(),
|
||||
'opens_today' => ToolOpenLog::query()->where('created_at', '>=', today())->count(),
|
||||
'pending_orders' => Order::query()->where('status', 'pending')->count(),
|
||||
'open_tickets' => ServiceTicket::query()->whereIn('status', ['pending', 'quoted', 'doing', 'checking'])->count(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function clients()
|
||||
{
|
||||
return $this->ok(OauthClient::query()->with('tool:id,name')->latest()->get()->map(fn (OauthClient $client) => $this->clientPayload($client)));
|
||||
}
|
||||
|
||||
public function storeClient(Request $request)
|
||||
{
|
||||
$data = $this->clientData($request);
|
||||
$secret = Str::random(32);
|
||||
$client = OauthClient::query()->create($data + ['secret_hash' => hash('sha256', $secret)]);
|
||||
$this->audit($request->user(), 'client.create', $client, '新建客户端 '.$client->name);
|
||||
|
||||
return $this->ok($this->clientPayload($client) + ['secret' => $secret], '密钥只显示一次');
|
||||
}
|
||||
|
||||
public function updateClient(Request $request, OauthClient $client)
|
||||
{
|
||||
$client->update($this->clientData($request, $client->id));
|
||||
$this->audit($request->user(), 'client.update', $client, '更新客户端 '.$client->name);
|
||||
|
||||
return $this->ok($this->clientPayload($client));
|
||||
}
|
||||
|
||||
public function resetSecret(Request $request, OauthClient $client)
|
||||
{
|
||||
$secret = Str::random(32);
|
||||
$client->update(['secret_hash' => hash('sha256', $secret)]);
|
||||
$this->audit($request->user(), 'client.secret', $client, '重置客户端密钥 '.$client->name);
|
||||
|
||||
return $this->ok(['secret' => $secret], '新密钥只显示一次');
|
||||
}
|
||||
|
||||
public function settings()
|
||||
{
|
||||
return $this->ok(Setting::query()->orderBy('key')->get());
|
||||
}
|
||||
|
||||
public function updateSettings(Request $request)
|
||||
{
|
||||
$data = $request->validate([
|
||||
'items' => ['required', 'array'],
|
||||
'items.site_name' => ['nullable', 'string', 'max:40'],
|
||||
'items.site_description' => ['nullable', 'string', 'max:255'],
|
||||
'items.icp' => ['nullable', 'string', 'max:80'],
|
||||
'items.grace_days' => ['nullable', 'integer', 'min:0', 'max:30'],
|
||||
'items.sms_register_creates_user' => ['nullable', 'in:0,1'],
|
||||
'items.mail_enabled' => ['nullable', 'in:0,1'],
|
||||
]);
|
||||
foreach ($data['items'] as $key => $value) {
|
||||
Setting::query()->updateOrCreate(['key' => $key], ['value' => (string) $value]);
|
||||
}
|
||||
Settings::flush();
|
||||
$this->audit($request->user(), 'settings.update', null, '更新系统设置');
|
||||
|
||||
return $this->ok(Setting::query()->orderBy('key')->get(), '设置已保存');
|
||||
}
|
||||
|
||||
private function clientData(Request $request, ?int $id = null): array
|
||||
{
|
||||
$data = $request->validate([
|
||||
'name' => ['required', 'string', 'max:80'],
|
||||
'client_id' => ['required', 'regex:/^[a-z0-9_\-]+$/', Rule::unique('oauth_clients', 'client_id')->ignore($id)],
|
||||
'redirect_uris' => ['required', 'array', 'min:1'],
|
||||
'redirect_uris.*' => ['url', 'max:500'],
|
||||
'logout_uris' => ['nullable', 'array'],
|
||||
'logout_uris.*' => ['url', 'max:500'],
|
||||
'tool_id' => ['nullable', 'integer', 'exists:tools,id'],
|
||||
'is_first_party' => ['required', 'boolean'],
|
||||
'is_public' => ['required', 'boolean'],
|
||||
'status' => ['required', 'in:active,disabled'],
|
||||
]);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
private function clientPayload(OauthClient $client): array
|
||||
{
|
||||
return [
|
||||
'id' => $client->id,
|
||||
'name' => $client->name,
|
||||
'client_id' => $client->client_id,
|
||||
'redirect_uris' => $client->redirect_uris,
|
||||
'logout_uris' => $client->logout_uris ?? [],
|
||||
'tool_id' => $client->tool_id,
|
||||
'tool_name' => $client->tool?->name,
|
||||
'is_first_party' => $client->is_first_party,
|
||||
'is_public' => $client->is_public,
|
||||
'status' => $client->status,
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user