web: 审计页时间按浏览器本地时区显示
Some checks failed
Secrets MCP — Build & Release / 检查 / 构建 / 发版 (push) Failing after 25s
Secrets MCP — Build & Release / 部署 secrets-mcp (push) Has been skipped

Made-with: Cursor
This commit is contained in:
voson
2026-03-21 12:03:44 +08:00
parent 259fbe10a6
commit 17f8ac0dbc
2 changed files with 20 additions and 4 deletions

View File

@@ -1,4 +1,5 @@
use askama::Template; use askama::Template;
use chrono::SecondsFormat;
use std::net::SocketAddr; use std::net::SocketAddr;
use axum::{ use axum::{
@@ -61,7 +62,8 @@ struct AuditPageTemplate {
} }
struct AuditEntryView { struct AuditEntryView {
created_at: String, /// RFC3339 UTC for `<time datetime>`; rendered as browser-local in audit.html.
created_at_iso: String,
action: String, action: String,
target: String, target: String,
detail: String, detail: String,
@@ -408,7 +410,9 @@ async fn audit_page(
let entries = rows let entries = rows
.into_iter() .into_iter()
.map(|row| AuditEntryView { .map(|row| AuditEntryView {
created_at: row.created_at.format("%Y-%m-%d %H:%M:%S UTC").to_string(), created_at_iso: row
.created_at
.to_rfc3339_opts(SecondsFormat::Secs, true),
action: row.action, action: row.action,
target: format_audit_target(&row.namespace, &row.kind, &row.name), target: format_audit_target(&row.namespace, &row.kind, &row.name),
detail: serde_json::to_string_pretty(&row.detail).unwrap_or_else(|_| "{}".to_string()), detail: serde_json::to_string_pretty(&row.detail).unwrap_or_else(|_| "{}".to_string()),

View File

@@ -108,7 +108,7 @@
<main class="main"> <main class="main">
<section class="card"> <section class="card">
<div class="card-title">我的审计</div> <div class="card-title">我的审计</div>
<div class="card-subtitle">展示最近 100 条与当前用户相关的新审计记录。</div> <div class="card-subtitle">展示最近 100 条与当前用户相关的新审计记录。时间为浏览器本地时区。</div>
{% if entries.is_empty() %} {% if entries.is_empty() %}
<div class="empty">暂无审计记录。</div> <div class="empty">暂无审计记录。</div>
@@ -125,7 +125,7 @@
<tbody> <tbody>
{% for entry in entries %} {% for entry in entries %}
<tr> <tr>
<td class="col-time mono">{{ entry.created_at }}</td> <td class="col-time mono"><time class="audit-local-time" datetime="{{ entry.created_at_iso }}">{{ entry.created_at_iso }}</time></td>
<td class="col-action mono">{{ entry.action }}</td> <td class="col-action mono">{{ entry.action }}</td>
<td class="col-target mono">{{ entry.target }}</td> <td class="col-target mono">{{ entry.target }}</td>
<td class="col-detail"><pre class="detail">{{ entry.detail }}</pre></td> <td class="col-detail"><pre class="detail">{{ entry.detail }}</pre></td>
@@ -138,5 +138,17 @@
</main> </main>
</div> </div>
</div> </div>
<script>
(function () {
document.querySelectorAll('time.audit-local-time[datetime]').forEach(function (el) {
var raw = el.getAttribute('datetime');
var d = raw ? new Date(raw) : null;
if (d && !isNaN(d.getTime())) {
el.textContent = d.toLocaleString(undefined, { dateStyle: 'medium', timeStyle: 'medium' });
el.title = raw + ' (UTC)';
}
});
})();
</script>
</body> </body>
</html> </html>