fix(activity): 修正使用者更新時產生雙重紀錄的問題

- 使用 saveQuietly 避免原生 update 事件觸發紀錄

- 手動合併屬性變更 (Attributes) 與角色變更 (Roles) 為單一操作紀錄
This commit is contained in:
2026-01-19 16:10:59 +08:00
parent cdcc0f4ce3
commit 632dee13a5

View File

@@ -117,7 +117,6 @@ class UserController extends Controller
public function update(Request $request, string $id) public function update(Request $request, string $id)
{ {
$user = User::findOrFail($id); $user = User::findOrFail($id);
$oldRoles = $user->roles()->pluck('display_name')->join(', ');
$validated = $request->validate([ $validated = $request->validate([
'name' => ['required', 'string', 'max:255'], 'name' => ['required', 'string', 'max:255'],
@@ -130,6 +129,7 @@ class UserController extends Controller
'password.confirmed' => '密碼確認不符', 'password.confirmed' => '密碼確認不符',
]); ]);
// 1. Prepare data and detect changes
$userData = [ $userData = [
'name' => $validated['name'], 'name' => $validated['name'],
'email' => $validated['email'], 'email' => $validated['email'],
@@ -140,25 +140,55 @@ class UserController extends Controller
$userData['password'] = Hash::make($validated['password']); $userData['password'] = Hash::make($validated['password']);
} }
$user->update($userData); $user->fill($userData);
// Capture dirty attributes for manual logging
$dirty = $user->getDirty();
$oldAttributes = [];
$newAttributes = [];
foreach ($dirty as $key => $value) {
$oldAttributes[$key] = $user->getOriginal($key);
$newAttributes[$key] = $value;
}
// Save without triggering events (prevents duplicate log)
$user->saveQuietly();
// 2. Handle Roles
$roleChanges = null;
if (isset($validated['roles'])) { if (isset($validated['roles'])) {
$oldRoles = $user->roles()->pluck('display_name')->join(', ');
$user->syncRoles($validated['roles']); $user->syncRoles($validated['roles']);
$newRoles = $user->roles()->pluck('display_name')->join(', '); $newRoles = $user->roles()->pluck('display_name')->join(', ');
if ($oldRoles !== $newRoles) { if ($oldRoles !== $newRoles) {
$roleChanges = [
'old' => $oldRoles,
'new' => $newRoles
];
}
}
// 3. Manually Log activity (Single Consolidated Log)
if (!empty($newAttributes) || $roleChanges) {
$properties = [
'attributes' => $newAttributes,
'old' => $oldAttributes,
];
if ($roleChanges) {
$properties['attributes']['role_id'] = $roleChanges['new'];
$properties['old']['role_id'] = $roleChanges['old'];
}
activity() activity()
->performedOn($user) ->performedOn($user)
->causedBy(auth()->user()) ->causedBy(auth()->user())
->event('updated') ->event('updated')
->withProperties([ ->withProperties($properties)
'attributes' => ['role_id' => $newRoles],
'old' => ['role_id' => $oldRoles],
])
->log('updated'); ->log('updated');
} }
}
return redirect()->route('users.index')->with('success', '使用者更新成功'); return redirect()->route('users.index')->with('success', '使用者更新成功');
} }