fix: gitignore 排除了 PNG 资源导致构建失败
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 2m12s
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 2m12s
- .gitignore 中 *.png 规则误忽略了 web/src/assets/ 和 web/public/ 下的 logo/favicon - 添加例外规则允许 web 资源目录的 PNG 文件 - 补提交 logo_32/128/512.png + favicon.png - 审计日志变更详情优化:字段名中文化 + 布尔值显示优化 + 空值兜底 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
e5273540e9
commit
b78a220082
3
.gitignore
vendored
3
.gitignore
vendored
@ -31,6 +31,9 @@ test-screenshots/
|
|||||||
|
|
||||||
# === Screenshots & prototype images ===
|
# === Screenshots & prototype images ===
|
||||||
*.png
|
*.png
|
||||||
|
# Allow web assets and public PNGs
|
||||||
|
!web/src/assets/*.png
|
||||||
|
!web/public/*.png
|
||||||
|
|
||||||
# === Environment ===
|
# === Environment ===
|
||||||
.env
|
.env
|
||||||
|
|||||||
BIN
web/public/favicon.png
Normal file
BIN
web/public/favicon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.3 KiB |
BIN
web/src/assets/logo_128.png
Normal file
BIN
web/src/assets/logo_128.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 19 KiB |
BIN
web/src/assets/logo_32.png
Normal file
BIN
web/src/assets/logo_32.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.3 KiB |
BIN
web/src/assets/logo_512.png
Normal file
BIN
web/src/assets/logo_512.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 181 KiB |
@ -22,48 +22,62 @@ const ACTION_OPTIONS = [
|
|||||||
{ label: '切换成员状态', value: 'member_status_toggle' },
|
{ label: '切换成员状态', value: 'member_status_toggle' },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const FIELD_LABELS: Record<string, string> = {
|
||||||
|
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<string, unknown> | null, after: Record<string, unknown> | null) {
|
function renderChanges(before: Record<string, unknown> | null, after: Record<string, unknown> | null) {
|
||||||
if (!before && !after) return '-';
|
if (!before && !after) return '-';
|
||||||
const fields = new Set([...Object.keys(before || {}), ...Object.keys(after || {})]);
|
const fields = new Set([...Object.keys(before || {}), ...Object.keys(after || {})]);
|
||||||
if (fields.size === 0) return '-';
|
if (fields.size === 0) return '-';
|
||||||
|
|
||||||
return (
|
const items: JSX.Element[] = [];
|
||||||
<div className={styles.changeDetail}>
|
|
||||||
{[...fields].map((field) => {
|
for (const field of fields) {
|
||||||
const oldVal = before?.[field];
|
const oldVal = before?.[field];
|
||||||
const newVal = after?.[field];
|
const newVal = after?.[field];
|
||||||
if (oldVal === undefined && newVal !== undefined) {
|
const label = FIELD_LABELS[field] || field;
|
||||||
return (
|
|
||||||
<div key={field} className={styles.changeItem}>
|
if (oldVal === undefined && newVal !== undefined) {
|
||||||
<span className={styles.changeField}>{field}:</span>
|
items.push(
|
||||||
<span className={styles.changeNew}>{String(newVal)}</span>
|
<div key={field} className={styles.changeItem}>
|
||||||
</div>
|
<span className={styles.changeField}>{label}:</span>
|
||||||
);
|
<span className={styles.changeNew}>{formatVal(newVal)}</span>
|
||||||
}
|
</div>
|
||||||
if (oldVal !== undefined && newVal !== undefined && String(oldVal) !== String(newVal)) {
|
);
|
||||||
return (
|
} else if (oldVal !== undefined && newVal !== undefined && formatVal(oldVal) !== formatVal(newVal)) {
|
||||||
<div key={field} className={styles.changeItem}>
|
items.push(
|
||||||
<span className={styles.changeField}>{field}:</span>
|
<div key={field} className={styles.changeItem}>
|
||||||
<span className={styles.changeOld}>{String(oldVal)}</span>
|
<span className={styles.changeField}>{label}:</span>
|
||||||
<span className={styles.changeArrow}>→</span>
|
<span className={styles.changeOld}>{formatVal(oldVal)}</span>
|
||||||
<span className={styles.changeNew}>{String(newVal)}</span>
|
<span className={styles.changeArrow}>→</span>
|
||||||
</div>
|
<span className={styles.changeNew}>{formatVal(newVal)}</span>
|
||||||
);
|
</div>
|
||||||
}
|
);
|
||||||
if (oldVal === undefined && newVal === undefined) return null;
|
}
|
||||||
// Same value, show as-is for create actions
|
}
|
||||||
if (oldVal === undefined) {
|
|
||||||
return (
|
return items.length > 0
|
||||||
<div key={field} className={styles.changeItem}>
|
? <div className={styles.changeDetail}>{items}</div>
|
||||||
<span className={styles.changeField}>{field}:</span>
|
: <span style={{ color: '#8b8ea8' }}>无变更</span>;
|
||||||
<span className={styles.changeNew}>{String(newVal)}</span>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function AuditLogsPage() {
|
export function AuditLogsPage() {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user