diff --git a/.gitignore b/.gitignore index f551d8a..6c731b9 100644 --- a/.gitignore +++ b/.gitignore @@ -31,6 +31,9 @@ test-screenshots/ # === Screenshots & prototype images === *.png +# Allow web assets and public PNGs +!web/src/assets/*.png +!web/public/*.png # === Environment === .env diff --git a/web/public/favicon.png b/web/public/favicon.png new file mode 100644 index 0000000..95adced Binary files /dev/null and b/web/public/favicon.png differ diff --git a/web/src/assets/logo_128.png b/web/src/assets/logo_128.png new file mode 100644 index 0000000..35c37f1 Binary files /dev/null and b/web/src/assets/logo_128.png differ diff --git a/web/src/assets/logo_32.png b/web/src/assets/logo_32.png new file mode 100644 index 0000000..95adced Binary files /dev/null and b/web/src/assets/logo_32.png differ diff --git a/web/src/assets/logo_512.png b/web/src/assets/logo_512.png new file mode 100644 index 0000000..3d2bbc9 Binary files /dev/null and b/web/src/assets/logo_512.png differ diff --git a/web/src/pages/AuditLogsPage.tsx b/web/src/pages/AuditLogsPage.tsx index 72d53ef..13f2c6e 100644 --- a/web/src/pages/AuditLogsPage.tsx +++ b/web/src/pages/AuditLogsPage.tsx @@ -22,48 +22,62 @@ const ACTION_OPTIONS = [ { label: '切换成员状态', value: 'member_status_toggle' }, ]; +const FIELD_LABELS: Record = { + default_daily_seconds_limit: '每日限额', + default_monthly_seconds_limit: '每月限额', + announcement: '公告内容', + announcement_enabled: '公告开关', + name: '名称', + monthly_seconds_limit: '月额度', + total_seconds_pool: '秒数池', + is_active: '状态', + daily_seconds_limit: '每日限额', + username: '用户名', + email: '邮箱', + role: '角色', +}; + +function formatVal(val: unknown): string { + if (val === true) return '开启'; + if (val === false) return '关闭'; + if (val === '' || val === null || val === undefined) return '(空)'; + return String(val); +} + function renderChanges(before: Record | null, after: Record | null) { if (!before && !after) return '-'; const fields = new Set([...Object.keys(before || {}), ...Object.keys(after || {})]); if (fields.size === 0) return '-'; - return ( -
- {[...fields].map((field) => { - const oldVal = before?.[field]; - const newVal = after?.[field]; - if (oldVal === undefined && newVal !== undefined) { - return ( -
- {field}: - {String(newVal)} -
- ); - } - if (oldVal !== undefined && newVal !== undefined && String(oldVal) !== String(newVal)) { - return ( -
- {field}: - {String(oldVal)} - - {String(newVal)} -
- ); - } - if (oldVal === undefined && newVal === undefined) return null; - // Same value, show as-is for create actions - if (oldVal === undefined) { - return ( -
- {field}: - {String(newVal)} -
- ); - } - return null; - })} -
- ); + const items: JSX.Element[] = []; + + for (const field of fields) { + const oldVal = before?.[field]; + const newVal = after?.[field]; + const label = FIELD_LABELS[field] || field; + + if (oldVal === undefined && newVal !== undefined) { + items.push( +
+ {label}: + {formatVal(newVal)} +
+ ); + } else if (oldVal !== undefined && newVal !== undefined && formatVal(oldVal) !== formatVal(newVal)) { + items.push( +
+ {label}: + {formatVal(oldVal)} + + {formatVal(newVal)} +
+ ); + } + } + + return items.length > 0 + ?
{items}
+ : 无变更; } export function AuditLogsPage() {