feat: 实现操作日志管理界面
- ActivityLogResource: Filament 资源类 - 只读模式(禁用创建、编辑、删除) - 表格列:时间、用户、操作类型、对象、详情 - 按时间倒序排序 - 支持多维度筛选(时间范围、操作类型、用户、对象类型) - 集成导出功能(Excel/CSV) - ViewActivityLog: 日志详情页面 - 完整的变更信息展示 - JSON diff 对比视图 - 支持查看原始 JSON 数据 - activity-log-diff.blade.php: Diff 对比组件 - 字段级别的变更对比 - 使用颜色区分新旧值(绿色/红色) - 支持 JSON 数据格式化显示
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
<div class="space-y-4">
|
||||
@php
|
||||
$properties = $getState();
|
||||
$old = $properties['old'] ?? [];
|
||||
$attributes = $properties['attributes'] ?? [];
|
||||
|
||||
// 获取所有键
|
||||
$allKeys = array_unique(array_merge(array_keys($old), array_keys($attributes)));
|
||||
@endphp
|
||||
|
||||
@if(empty($allKeys))
|
||||
<div class="text-sm text-gray-500 dark:text-gray-400">
|
||||
无变更数据
|
||||
</div>
|
||||
@else
|
||||
<div class="overflow-hidden rounded-lg border border-gray-200 dark:border-gray-700">
|
||||
<table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
|
||||
<thead class="bg-gray-50 dark:bg-gray-800">
|
||||
<tr>
|
||||
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider w-1/4">
|
||||
字段
|
||||
</th>
|
||||
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider w-3/8">
|
||||
旧值
|
||||
</th>
|
||||
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider w-3/8">
|
||||
新值
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="bg-white dark:bg-gray-900 divide-y divide-gray-200 dark:divide-gray-700">
|
||||
@foreach($allKeys as $key)
|
||||
@php
|
||||
$oldValue = $old[$key] ?? null;
|
||||
$newValue = $attributes[$key] ?? null;
|
||||
$hasChanged = $oldValue !== $newValue;
|
||||
@endphp
|
||||
<tr class="{{ $hasChanged ? 'bg-yellow-50 dark:bg-yellow-900/10' : '' }}">
|
||||
<td class="px-4 py-3 text-sm font-medium text-gray-900 dark:text-gray-100">
|
||||
{{ $key }}
|
||||
@if($hasChanged)
|
||||
<span class="ml-2 inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200">
|
||||
已变更
|
||||
</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="px-4 py-3 text-sm text-gray-500 dark:text-gray-400">
|
||||
@if($oldValue !== null)
|
||||
<div class="font-mono text-xs bg-red-50 dark:bg-red-900/20 text-red-700 dark:text-red-300 p-2 rounded border border-red-200 dark:border-red-800">
|
||||
@if(is_array($oldValue) || is_object($oldValue))
|
||||
<pre class="whitespace-pre-wrap break-words">{{ json_encode($oldValue, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) }}</pre>
|
||||
@else
|
||||
{{ $oldValue }}
|
||||
@endif
|
||||
</div>
|
||||
@else
|
||||
<span class="text-gray-400 dark:text-gray-600 italic">-</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="px-4 py-3 text-sm text-gray-500 dark:text-gray-400">
|
||||
@if($newValue !== null)
|
||||
<div class="font-mono text-xs bg-green-50 dark:bg-green-900/20 text-green-700 dark:text-green-300 p-2 rounded border border-green-200 dark:border-green-800">
|
||||
@if(is_array($newValue) || is_object($newValue))
|
||||
<pre class="whitespace-pre-wrap break-words">{{ json_encode($newValue, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) }}</pre>
|
||||
@else
|
||||
{{ $newValue }}
|
||||
@endif
|
||||
</div>
|
||||
@else
|
||||
<span class="text-gray-400 dark:text-gray-600 italic">-</span>
|
||||
@endif
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@if(!empty($old) || !empty($attributes))
|
||||
<div class="mt-4 p-4 bg-gray-50 dark:bg-gray-800 rounded-lg">
|
||||
<details class="space-y-2">
|
||||
<summary class="cursor-pointer text-sm font-medium text-gray-700 dark:text-gray-300 hover:text-gray-900 dark:hover:text-gray-100">
|
||||
查看原始 JSON 数据
|
||||
</summary>
|
||||
<div class="mt-2 space-y-2">
|
||||
@if(!empty($old))
|
||||
<div>
|
||||
<div class="text-xs font-medium text-gray-600 dark:text-gray-400 mb-1">旧值 (JSON):</div>
|
||||
<pre class="text-xs bg-white dark:bg-gray-900 p-3 rounded border border-gray-200 dark:border-gray-700 overflow-x-auto">{{ json_encode($old, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) }}</pre>
|
||||
</div>
|
||||
@endif
|
||||
@if(!empty($attributes))
|
||||
<div>
|
||||
<div class="text-xs font-medium text-gray-600 dark:text-gray-400 mb-1">新值 (JSON):</div>
|
||||
<pre class="text-xs bg-white dark:bg-gray-900 p-3 rounded border border-gray-200 dark:border-gray-700 overflow-x-auto">{{ json_encode($attributes, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT) }}</pre>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
@endif
|
||||
@endif
|
||||
</div>
|
||||
Reference in New Issue
Block a user