UX优化: 同步日志显示服务器名 + redis_url可编辑

- 同步日志API: JOIN Server表返回server_name字段
- 推送历史: 显示服务器名称替代操作人
- 仪表盘最近同步: 显示服务器名称替代server_id
- redis_url从SENSITIVE_KEYS移除(非密码,用户需可编辑)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Your Name
2026-05-22 11:10:20 +08:00
parent e9feaa6cdc
commit c03fe97d18
4 changed files with 11 additions and 9 deletions
+6 -4
View File
@@ -282,10 +282,11 @@ async def get_all_sync_logs(
):
"""Get recent sync logs across all servers (for dashboard charts)"""
result = await db.execute(
select(SyncLog).order_by(SyncLog.started_at.desc()).limit(limit)
select(SyncLog, Server.name).join(Server, SyncLog.server_id == Server.id, isouter=True)
.order_by(SyncLog.started_at.desc()).limit(limit)
)
logs = result.scalars().all()
return [_sync_log_to_dict(log) for log in logs]
rows = result.all()
return [_sync_log_to_dict(log, server_name=name) for log, name in rows]
@router.get("/{id}/logs", response_model=list)
@@ -330,11 +331,12 @@ def _server_to_dict(server: Server) -> dict:
}
def _sync_log_to_dict(log) -> dict:
def _sync_log_to_dict(log, server_name: str = None) -> dict:
"""Convert SyncLog model to API response dict"""
return {
"id": log.id,
"server_id": log.server_id,
"server_name": server_name,
"source_path": log.source_path,
"target_path": log.target_path,
"trigger_type": log.trigger_type,
+1 -1
View File
@@ -24,7 +24,7 @@ from sqlalchemy.ext.asyncio import AsyncSession
IMMUTABLE_KEYS = {"secret_key", "api_key", "encryption_key", "database_url"}
# Settings whose values are masked in GET responses
SENSITIVE_KEYS = {"secret_key", "api_key", "encryption_key", "redis_url"}
SENSITIVE_KEYS = {"secret_key", "api_key", "encryption_key"}
router = APIRouter(prefix="/api/settings", tags=["settings"])
+1 -1
View File
@@ -160,7 +160,7 @@
const sc = l.status==='success'?'text-green-400':l.status==='failed'?'text-red-400':'text-yellow-400';
const icon = l.status==='success'?'✅':l.status==='failed'?'❌':'⏳';
return `<div class="flex items-center justify-between py-2 border-b border-slate-800 last:border-0">
<div class="flex items-center gap-2"><span class="text-xs">${icon}</span><span class="text-slate-300 text-xs">${esc(l.sync_mode||'sync')} #${l.server_id||'?'}</span><span class="${sc} text-xs">${esc(l.status)}</span></div>
<div class="flex items-center gap-2"><span class="text-xs">${icon}</span><span class="text-slate-300 text-xs">${esc(l.server_name||'#'+l.server_id)}</span><span class="${sc} text-xs">${esc(l.status)}</span></div>
<span class="text-slate-600 text-xs">${fmtTime(l.started_at)}</span>
</div>`;
}).join('');
+3 -3
View File
@@ -213,11 +213,11 @@
<div class="flex items-center gap-3">
<span class="${l.status==='success'?'text-green-400':'text-red-400'} text-sm">${l.status==='success'?'✓':'✗'}</span>
<div>
<span class="text-sm text-slate-300">${esc(l.operator||'system')}</span>
<span class="text-sm text-slate-300">${esc(l.server_name||'#'+l.server_id)}</span>
<span class="text-slate-600 mx-1">·</span>
<span class="text-xs text-slate-500">${esc(l.operator||'system')}</span>
<span class="text-slate-600 mx-1">·</span>
<span class="text-xs text-slate-500">${esc(l.sync_mode||'file')}</span>
<span class="text-slate-600 mx-1">·</span>
<span class="text-xs text-slate-500">${esc(l.source_path||'')}</span>
</div>
</div>
<div class="text-xs text-slate-500">${fmtTime(l.started_at)}</div>