diff --git a/inventory-backend/app/utils/audit_events.py b/inventory-backend/app/utils/audit_events.py
index 6b033ea..0227587 100644
--- a/inventory-backend/app/utils/audit_events.py
+++ b/inventory-backend/app/utils/audit_events.py
@@ -118,7 +118,7 @@ def insert_audit_log(connection, action, target, details):
target_id = str(target.bom_no)
# 获取目标名称(用于展示)
- target_name = target_id
+ target_name = ''
for name_field in ['name', 'title', 'material_name', 'product_name', 'display_name', 'username']:
if hasattr(target, name_field):
val = getattr(target, name_field)
@@ -126,6 +126,27 @@ def insert_audit_log(connection, action, target, details):
target_name = str(val)
break
+ # 如果当前表没名字,但它有关联的物料对象 (比如 material.name)
+ if not target_name and hasattr(target, 'material') and target.material:
+ target_name = getattr(target.material, 'name', '')
+
+ # 如果当前表有 material_id,尝试从关联的 material 表查询名称
+ if not target_name and hasattr(target, 'material_id') and target.material_id:
+ try:
+ # 使用 connection 查询物料表获取名称
+ result = connection.execute(
+ text("SELECT name FROM material_base WHERE id = :id"),
+ {'id': target.material_id}
+ ).fetchone()
+ if result:
+ target_name = str(result[0])
+ except Exception:
+ pass
+
+ # 如果实在找不到名字,再用 表名 + ID 兜底
+ if not target_name:
+ target_name = f"{tablename} ID:{target_id}"
+
user_info = get_current_user_info()
# 推断模块名称
diff --git a/inventory-web/src/views/system/AuditLog.vue b/inventory-web/src/views/system/AuditLog.vue
index 5a931ce..266c1cf 100644
--- a/inventory-web/src/views/system/AuditLog.vue
+++ b/inventory-web/src/views/system/AuditLog.vue
@@ -55,12 +55,16 @@
- {{ scope.row.action }}
+ {{ actionMap[scope.row.action] || scope.row.action }}
-
+
+
+ {{ formatLocalTime(scope.row.created_at) }}
+
+
{{ currentLog.module }}
- {{ currentLog.action }}
+ {{ actionMap[currentLog.action] || currentLog.action }}
{{ currentLog.target_name || '-' }}
{{ currentLog.ip_address }}
{{ currentLog.method }}
- {{ currentLog.created_at }}
+ {{ formatLocalTime(currentLog.created_at) }}
@@ -118,9 +122,9 @@
字段变更详情(共 {{ changesList.length }} 处变更)
-
+
- {{ row.field }}
+ {{ fieldMap[row.field] || row.field }}
@@ -218,6 +222,50 @@ const dateRange = ref<[string, string] | null>(null)
const moduleOptions = ref([])
const actionOptions = ref(['create', 'update', 'delete', 'export', 'import'])
+// ============================================================
+// 中文化映射
+// ============================================================
+
+// 操作类型中文化映射
+const actionMap: Record = {
+ 'UPDATE': '修改',
+ 'CREATE': '新增',
+ 'DELETE': '删除',
+ 'LOGIN': '登录',
+ 'LOGOUT': '登出'
+};
+
+// 字段名中文化映射 (常见业务字段)
+const fieldMap: Record = {
+ 'available_quantity': '可用库存',
+ 'in_quantity': '入库数量',
+ 'stock_quantity': '总库存',
+ 'out_quantity': '出库数量',
+ 'name': '名称',
+ 'material_name': '物料名称',
+ 'spec_model': '规格型号',
+ 'category': '类别',
+ 'status': '状态',
+ 'remark': '备注',
+ 'is_active': '是否启用'
+};
+
+// 时间格式化:将后端的 UTC 时间字符串转换为本地时间 (UTC+8)
+const formatLocalTime = (timeStr: string) => {
+ if (!timeStr) return '-'
+ // 补全 'Z' 让浏览器识别为 UTC 时间,自动转为当前系统的时区
+ const date = new Date(timeStr.replace(' ', 'T') + 'Z')
+ if (isNaN(date.getTime())) return timeStr
+
+ const y = date.getFullYear()
+ const m = String(date.getMonth() + 1).padStart(2, '0')
+ const d = String(date.getDate()).padStart(2, '0')
+ const h = String(date.getHours()).padStart(2, '0')
+ const min = String(date.getMinutes()).padStart(2, '0')
+ const s = String(date.getSeconds()).padStart(2, '0')
+ return `${y}-${m}-${d} ${h}:${min}:${s}`
+}
+
// 详情弹窗
const detailDialogVisible = ref(false)
const currentLog = ref({})