chore(admin-ui): system settings page uses page header and list card

This commit is contained in:
萝卜
2026-03-16 03:51:05 +08:00
parent 0d4cca42b1
commit 2930e8cd22
2 changed files with 121 additions and 67 deletions

View File

@@ -4,80 +4,93 @@
@section('page_title', '系统配置')
@section('content')
<div class="card mb-20">
<p class="mt-0">系统配置已经从静态骨架切到数据库读取,当前已支持基础编辑、保存和缓存刷新。</p>
<div class="muted">当前系统配置列表已接入缓存读取。</div>
<div class="muted">当前配置分组数:{{ $groupedCount }}</div>
<div class="page-header mb-20" data-page="admin.settings.system">
<div class="page-header-main">
<div>
<div class="page-header-title">系统配置</div>
<div class="page-header-subtitle">当前系统配置已从静态骨架切到数据库读取;支持基础编辑、保存与缓存刷新(用于“总台可治理/可配置”的运营闭环)。</div>
</div>
<div class="page-header-actions">
<a class="btn btn-secondary" href="/admin/settings/channels">渠道与支付配置</a>
</div>
</div>
<div class="actions mt-12">
<a class="btn btn-secondary" href="/admin/settings/channels">渠道与支付配置</a>
<div class="page-header-meta">
<div>当前系统配置列表已接入缓存读取</div>
<div>当前配置分组数:{{ $groupedCount }}</div>
</div>
</div>
@foreach($systemSettings->groupBy('group') as $group => $items)
<div class="card mb-20">
<h3 class="mt-0">配置分组:{{ $group }}</h3>
<table>
<thead>
<tr>
<th>配置键</th>
<th>名称</th>
<th>配置值</th>
<th>类型</th>
<th>自动加载</th>
<th>备注</th>
<th>操作</th>
</tr>
</thead>
<tbody>
@foreach($items as $item)
@php
$isEditing = $editingConfigId === $item->id;
$configName = $isEditing ? old('config_name', $item->config_name) : $item->config_name;
$configValue = $isEditing ? old('config_value', $item->config_value) : $item->config_value;
$valueType = $isEditing ? old('value_type', $item->value_type) : $item->value_type;
$autoload = $isEditing ? old('autoload', $item->autoload) : $item->autoload;
$remark = $isEditing ? old('remark', $item->remark) : $item->remark;
@endphp
<div class="card list-card mb-20">
<div class="list-card-header">
<div>
<h3 class="list-card-title">配置分组:{{ $group }}</h3>
</div>
</div>
<div class="list-card-body">
<table class="list-card-table">
<thead>
<tr>
<form method="post" action="/admin/settings/system/{{ $item->id }}">
@csrf
<td>{{ $item->config_key }}<input type="hidden" name="group" value="{{ $item->group }}"></td>
<td><input name="config_name" value="{{ $configName }}"></td>
<td>
@if($valueType === 'json')
<textarea name="config_value" rows="4" class="w-full">{{ $configValue }}</textarea>
@if($isEditing && $errors->has('config_value'))
<div class="mt-6 muted" role="alert">{{ $errors->first('config_value') }}</div>
@endif
@elseif($valueType === 'boolean')
<select name="config_value">
<option value="1" @selected($configValue == '1')>true</option>
<option value="0" @selected($configValue == '0')>false</option>
</select>
@elseif($valueType === 'number')
<input type="number" step="any" name="config_value" value="{{ $configValue }}">
@else
<input name="config_value" value="{{ $configValue }}">
@endif
</td>
<td>
<select name="value_type">
@foreach($valueTypeOptions as $type)
<option value="{{ $type }}" @selected($valueType === $type)>{{ $type }}</option>
@endforeach
</select>
</td>
<td>
<label><input type="checkbox" name="autoload" value="1" @checked((bool) $autoload)> yes</label>
</td>
<td><input name="remark" value="{{ $remark }}"></td>
<td><button type="submit">保存</button></td>
</form>
<th>配置键</th>
<th>名称</th>
<th>配置值</th>
<th>类型</th>
<th>自动加载</th>
<th>备注</th>
<th>操作</th>
</tr>
@endforeach
</tbody>
</table>
</thead>
<tbody>
@foreach($items as $item)
@php
$isEditing = $editingConfigId === $item->id;
$configName = $isEditing ? old('config_name', $item->config_name) : $item->config_name;
$configValue = $isEditing ? old('config_value', $item->config_value) : $item->config_value;
$valueType = $isEditing ? old('value_type', $item->value_type) : $item->value_type;
$autoload = $isEditing ? old('autoload', $item->autoload) : $item->autoload;
$remark = $isEditing ? old('remark', $item->remark) : $item->remark;
@endphp
<tr>
<form method="post" action="/admin/settings/system/{{ $item->id }}">
@csrf
<td>{{ $item->config_key }}<input type="hidden" name="group" value="{{ $item->group }}"></td>
<td><input name="config_name" value="{{ $configName }}"></td>
<td>
@if($valueType === 'json')
<textarea name="config_value" rows="4" class="w-full">{{ $configValue }}</textarea>
@if($isEditing && $errors->has('config_value'))
<div class="mt-6 muted" role="alert">{{ $errors->first('config_value') }}</div>
@endif
@elseif($valueType === 'boolean')
<select name="config_value">
<option value="1" @selected($configValue == '1')>true</option>
<option value="0" @selected($configValue == '0')>false</option>
</select>
@elseif($valueType === 'number')
<input type="number" step="any" name="config_value" value="{{ $configValue }}">
@else
<input name="config_value" value="{{ $configValue }}">
@endif
</td>
<td>
<select name="value_type">
@foreach($valueTypeOptions as $type)
<option value="{{ $type }}" @selected($valueType === $type)>{{ $type }}</option>
@endforeach
</select>
</td>
<td>
<label><input type="checkbox" name="autoload" value="1" @checked((bool) $autoload)> yes</label>
</td>
<td><input name="remark" value="{{ $remark }}"></td>
<td><button type="submit" class="btn btn-sm">保存</button></td>
</form>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
@endforeach
@endsection

View File

@@ -0,0 +1,41 @@
<?php
namespace Tests\Feature;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class AdminSettingsSystemPageShouldUsePageHeaderAndListCardTest extends TestCase
{
use RefreshDatabase;
protected function loginAsPlatformAdmin(): void
{
$this->seed();
$this->post('/admin/login', [
'email' => 'platform.admin@demo.local',
'password' => 'Platform@123456',
])->assertRedirect('/admin');
}
public function test_admin_settings_system_page_should_use_page_header_and_list_card(): void
{
$this->loginAsPlatformAdmin();
$res = $this->get('/admin/settings/system');
$res->assertOk();
// 护栏:系统配置页应使用 PageHeader 与 ListCard保持总台管理风格统一。
$res->assertSee('page-header', false);
$res->assertSee('page-header-title', false);
$res->assertSee('page-header-subtitle', false);
$res->assertSee('page-header-actions', false);
$res->assertSee('page-header-meta', false);
$res->assertSee('list-card', false);
$res->assertSee('list-card-header', false);
$res->assertSee('list-card-body', false);
$res->assertSee('list-card-table', false);
}
}