fix: 修复权限级联同步缺口

修复 Manticore 搜索索引在特定场景下 allowed_users 权限未能正确同步的问题:

  Observer.updated 补充:
  - ProjectUserObserver: 处理项目成员移交时的权限级联
  - ProjectTaskUserObserver: 处理任务成员移交时的权限更新

  批量操作绕过 Observer 修复(delete → remove):
  - FileUser: deleteFileAll/deleteFileUser 方法
  - ProjectTask: 可见性设置时的批量删除
  - ProjectController: 子任务升级和任务复制时的批量删除

  文件批量更新封装:
  - File 新增 updateChildFilesUserid() 方法,统一处理子文件 userid
    更新及 Manticore 同步
This commit is contained in:
kuaifan 2026-01-13 11:55:45 +00:00
parent 3026cd698f
commit 42e4ddbd17
7 changed files with 50 additions and 9 deletions

View File

@ -418,7 +418,7 @@ class FileController extends AbstractController
throw new ApiException("{$file->name} 内含有共享文件,无法移动到另一个共享文件夹内"); throw new ApiException("{$file->name} 内含有共享文件,无法移动到另一个共享文件夹内");
} }
$file->userid = $toShareFile->userid; $file->userid = $toShareFile->userid;
File::where('pids', 'LIKE', "%,{$file->id},%")->update(['userid' => $toShareFile->userid]); $file->updateChildFilesUserid($toShareFile->userid);
} }
// //
$tmpId = $pid; $tmpId = $pid;
@ -430,7 +430,7 @@ class FileController extends AbstractController
} }
} else { } else {
$file->userid = $user->userid; $file->userid = $user->userid;
File::where('pids', 'LIKE', "%,{$file->id},%")->update(['userid' => $user->userid]); $file->updateChildFilesUserid($user->userid);
} }
// //
$file->pid = $pid; $file->pid = $pid;

View File

@ -2379,7 +2379,7 @@ class ProjectController extends AbstractController
$task->save(); $task->save();
ProjectTaskUser::whereTaskId($task->id)->update(['task_pid' => $task->id]); ProjectTaskUser::whereTaskId($task->id)->update(['task_pid' => $task->id]);
if ($task->visibility == 3 && !empty($visibilityUserids)) { if ($task->visibility == 3 && !empty($visibilityUserids)) {
ProjectTaskVisibilityUser::whereTaskId($task->id)->delete(); ProjectTaskVisibilityUser::whereTaskId($task->id)->remove();
foreach (array_unique($visibilityUserids) as $userid) { foreach (array_unique($visibilityUserids) as $userid) {
if (!$userid) { if (!$userid) {
continue; continue;
@ -3031,7 +3031,7 @@ class ProjectController extends AbstractController
$taskTag->project_id = $project->id; $taskTag->project_id = $project->id;
$taskTag->save(); $taskTag->save();
} }
ProjectTaskUser::whereTaskId($copy->id)->delete(); ProjectTaskUser::whereTaskId($copy->id)->remove();
$copy->setRelation('taskUser', collect()); $copy->setRelation('taskUser', collect());
$copy->setRelation('project', $project); $copy->setRelation('project', $project);
$updateData = [ $updateData = [

View File

@ -6,6 +6,8 @@ use Request;
use App\Module\Apps; use App\Module\Apps;
use App\Module\Base; use App\Module\Base;
use App\Tasks\PushTask; use App\Tasks\PushTask;
use App\Tasks\ManticoreSyncTask;
use App\Observers\AbstractObserver;
use App\Exceptions\ApiException; use App\Exceptions\ApiException;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Hhxsv5\LaravelS\Swoole\Task\Task; use Hhxsv5\LaravelS\Swoole\Task\Task;
@ -623,6 +625,26 @@ class File extends AbstractModel
return true; return true;
} }
/**
* 批量更新子文件的 userid 并同步到 Manticore
* @param int $userid 新的 userid
* @return int 更新的文件数量
*/
public function updateChildFilesUserid(int $userid): int
{
self::where('pids', 'like', "%,{$this->id},%")->update(['userid' => $userid]);
// 批量 update 绕过 Observer手动触发 Manticore 同步
$childFileIds = self::where('pids', 'like', "%,{$this->id},%")
->where('type', '!=', 'folder')
->pluck('id')
->toArray();
foreach ($childFileIds as $childFileId) {
AbstractObserver::taskDeliver(new ManticoreSyncTask('file_sync', ['id' => $childFileId]));
}
return count($childFileIds);
}
/** /**
* 获取文件分享链接 * 获取文件分享链接
* @param $userid * @param $userid

View File

@ -45,7 +45,7 @@ class FileUser extends AbstractModel
} else { } else {
FileLink::whereFileId($file_id)->delete(); FileLink::whereFileId($file_id)->delete();
} }
FileUser::whereFileId($file_id)->delete(); FileUser::whereFileId($file_id)->remove();
}); });
} }
/** /**
@ -58,7 +58,7 @@ class FileUser extends AbstractModel
{ {
return AbstractModel::transaction(function() use ($userid, $file_id) { return AbstractModel::transaction(function() use ($userid, $file_id) {
FileLink::whereFileId($file_id)->whereUserid($userid)->delete(); FileLink::whereFileId($file_id)->whereUserid($userid)->delete();
return self::whereFileId($file_id)->whereUserid($userid)->delete(); return self::whereFileId($file_id)->whereUserid($userid)->remove();
}); });
} }
} }

View File

@ -800,7 +800,7 @@ class ProjectTask extends AbstractModel
$this->visibility = $data["visibility"]; $this->visibility = $data["visibility"];
ProjectTask::whereParentId($data['task_id'])->change(['visibility' => $data["visibility"]]); ProjectTask::whereParentId($data['task_id'])->change(['visibility' => $data["visibility"]]);
} }
ProjectTaskVisibilityUser::whereTaskId($data['task_id'])->delete(); ProjectTaskVisibilityUser::whereTaskId($data['task_id'])->remove();
if (Arr::exists($data, 'visibility_appointor')) { if (Arr::exists($data, 'visibility_appointor')) {
foreach ($data['visibility_appointor'] as $uid) { foreach ($data['visibility_appointor'] as $uid) {
if ($uid) { if ($uid) {

View File

@ -42,7 +42,18 @@ class ProjectTaskUserObserver extends AbstractObserver
*/ */
public function updated(ProjectTaskUser $projectTaskUser) public function updated(ProjectTaskUser $projectTaskUser)
{ {
// // userid 变更时需要更新任务权限(移交场景)
if ($projectTaskUser->isDirty('userid')) {
self::taskDeliver(new ManticoreSyncTask('update_task_allowed_users', [
'task_id' => $projectTaskUser->task_id,
]));
// 如果是子任务,也更新父任务
if ($projectTaskUser->task_pid) {
self::taskDeliver(new ManticoreSyncTask('update_task_allowed_users', [
'task_id' => $projectTaskUser->task_pid,
]));
}
}
} }
/** /**

View File

@ -36,7 +36,15 @@ class ProjectUserObserver extends AbstractObserver
*/ */
public function updated(ProjectUser $projectUser) public function updated(ProjectUser $projectUser)
{ {
// // userid 变更时需要更新项目权限和级联任务权限(移交场景)
if ($projectUser->isDirty('userid')) {
self::taskDeliver(new ManticoreSyncTask('update_project_allowed_users', [
'project_id' => $projectUser->project_id,
]));
self::taskDeliver(new ManticoreSyncTask('cascade_project_users', [
'project_id' => $projectUser->project_id,
]));
}
} }
/** /**