From 5ce39a8dc472a263ddd408bb2d28e4dd96b78af3 Mon Sep 17 00:00:00 2001 From: kuaifan Date: Sat, 10 Oct 2026 02:41:15 +0000 Subject: [PATCH] =?UTF-8?q?feat(task):=20=E5=BB=BA=E7=AB=8B=E4=B8=8E?= =?UTF-8?q?=E8=A7=A3=E9=99=A4=E4=BB=BB=E5=8A=A1=E5=85=B3=E8=81=94=E6=97=B6?= =?UTF-8?q?=E8=AE=B0=E5=BD=95=E5=8F=8C=E6=96=B9=E4=BB=BB=E5=8A=A1=E5=8A=A8?= =?UTF-8?q?=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/Api/ProjectController.php | 2 +- app/Models/ProjectTaskRelation.php | 33 ++++++++++++++++++- language/original-api.txt | 2 ++ resources/ai-kb/zh/concept/task/related.md | 7 +++- 4 files changed, 41 insertions(+), 3 deletions(-) diff --git a/app/Http/Controllers/Api/ProjectController.php b/app/Http/Controllers/Api/ProjectController.php index 36707df7a..b5c0ccc3b 100755 --- a/app/Http/Controllers/Api/ProjectController.php +++ b/app/Http/Controllers/Api/ProjectController.php @@ -2449,7 +2449,7 @@ class ProjectController extends AbstractController $project = Project::userProject($task->project_id); ProjectPermission::userTaskPermission($project, ProjectPermission::TASK_UPDATE, $task); // - $success = ProjectTaskRelation::deleteRelation($task_id, $related_task_id); + $success = ProjectTaskRelation::deleteRelation($task_id, $related_task_id, User::userid()); if (!$success) { return Base::retError('关联不存在'); } diff --git a/app/Models/ProjectTaskRelation.php b/app/Models/ProjectTaskRelation.php index 74f301b33..52751fabc 100644 --- a/app/Models/ProjectTaskRelation.php +++ b/app/Models/ProjectTaskRelation.php @@ -97,6 +97,10 @@ class ProjectTaskRelation extends AbstractModel return false; } + $existed = static::whereTaskId($sourceTaskId) + ->whereRelatedTaskId($targetTaskId) + ->exists(); + // 创建正向关联:源任务提及目标任务 $mentionRelation = static::updateOrCreate( [ @@ -125,6 +129,12 @@ class ProjectTaskRelation extends AbstractModel ] ); + // 记录任务动态(仅首次建立关联时) + if (!$existed) { + self::addRelationLog($sourceTask, $targetTask, '关联任务', $userid); + self::addRelationLog($targetTask, $sourceTask, '关联任务', $userid); + } + // 推送关联更新 if ($push) { $needPush = $mentionRelation->wasRecentlyCreated || $mentionRelation->wasChanged() @@ -148,9 +158,10 @@ class ProjectTaskRelation extends AbstractModel * * @param int $taskId 任务ID * @param int $relatedTaskId 关联任务ID + * @param int|null $userid 操作人 * @return bool 是否删除成功 */ - public static function deleteRelation(int $taskId, int $relatedTaskId): bool + public static function deleteRelation(int $taskId, int $relatedTaskId, ?int $userid = null): bool { // 删除正向关联 $deleted1 = static::whereTaskId($taskId) @@ -166,6 +177,11 @@ class ProjectTaskRelation extends AbstractModel // 推送关联更新 $sourceTask = ProjectTask::with('project')->find($taskId); $targetTask = ProjectTask::with('project')->find($relatedTaskId); + // 记录任务动态 + if ($sourceTask && $targetTask) { + self::addRelationLog($sourceTask, $targetTask, '解除关联任务', $userid); + self::addRelationLog($targetTask, $sourceTask, '解除关联任务', $userid); + } if ($sourceTask?->project) { $sourceTask->pushMsg('relation', null, null, false); } @@ -178,6 +194,21 @@ class ProjectTaskRelation extends AbstractModel return false; } + /** + * 记录任务关联变更动态 + * + * @param ProjectTask $task 记录动态的任务 + * @param ProjectTask $relatedTask 关联的任务 + * @param string $detail 动态内容 + * @param int|null $userid 操作人 + */ + private static function addRelationLog(ProjectTask $task, ProjectTask $relatedTask, string $detail, ?int $userid): void + { + $task->addLog($detail, [ + 'change' => ['#' . $relatedTask->id . ' ' . $relatedTask->name], + ], $userid ?: 0); + } + public static function recordMentionsFromMessage(WebSocketDialogMsg $msg): void { if ($msg->type !== 'text') { diff --git a/language/original-api.txt b/language/original-api.txt index d0882eff2..871be07ca 100644 --- a/language/original-api.txt +++ b/language/original-api.txt @@ -1090,3 +1090,5 @@ WebDAV 未启用或你没有使用权限 最新版本已变化,请重新检查更新 发起系统更新失败 已开始更新系统 +关联任务 +解除关联任务 diff --git a/resources/ai-kb/zh/concept/task/related.md b/resources/ai-kb/zh/concept/task/related.md index 6ea9cf77a..3028a3f7d 100644 --- a/resources/ai-kb/zh/concept/task/related.md +++ b/resources/ai-kb/zh/concept/task/related.md @@ -18,7 +18,7 @@ negative: - 关联是平级的,不会形成父子层级(要拆层级用 [[task.subtask.concept]]) - 删除任意一方任务不会自动删除关联记录 - 关联不带过去字段数据(不是软链接,只是关系记录) -last_verified: v1.7.90 +last_verified: v1.9.59 --- # 任务关联(消息提及 / 任务 ↔ 任务) @@ -48,6 +48,11 @@ DooTask 用 `ProjectTaskRelation` 表记录两类关联: - 任务详情页底部「相关消息」区(来自 dialog mention) - 任务详情页「关联任务」区(来自任务详情页直接关联) - 关联任务双向显示:A 关联 B 后,B 那边也看到 A +- 任务动态:首次建立关联、解除关联时,双方任务的动态里都会记录「关联任务 / 解除关联任务: #任务ID 任务名称」 + +## 解除关联 +- 任务详情页「关联任务」区,对某条关联点击移除并确认,即同时解除双向关联 +- 需要对当前任务有修改权限(项目负责人、任务负责人或协助人员) ## 不支持 - 关联不产生权限继承