From c4dd04ccb6a358cec3ba7c4e0a97ddb89dbb47d9 Mon Sep 17 00:00:00 2001 From: kuaifan Date: Thu, 22 Jan 2026 05:30:32 +0000 Subject: [PATCH] =?UTF-8?q?fix(task):=20=E4=BF=AE=E5=A4=8D=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E5=AE=8C=E6=88=90/=E5=8F=96=E6=B6=88=E5=AE=8C?= =?UTF-8?q?=E6=88=90=E6=97=B6=E5=B7=A5=E4=BD=9C=E6=B5=81=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E5=88=87=E6=8D=A2=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 重构 flow_item_id 变更时的完成状态处理,使用 completeTask 方法替代直接赋值 - 新增 checkAndAutoSetFlowItem 方法,支持自动设置唯一的开始/结束状态 - 存在多个开始/结束状态时抛出带状态列表的错误(-4005/-4006),由前端引导用户选择 - 修复 complete_at 与 flow_item_id 同时存在时的重复处理问题 Co-Authored-By: Claude Opus 4.5 --- app/Models/ProjectTask.php | 53 +++++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/app/Models/ProjectTask.php b/app/Models/ProjectTask.php index dd8d6e0d7..879bae36b 100644 --- a/app/Models/ProjectTask.php +++ b/app/Models/ProjectTask.php @@ -684,13 +684,13 @@ class ProjectTask extends AbstractModel // 判断自动完成 if (!$this->complete_at) { $flowData['complete_at'] = $this->complete_at; - $data['complete_at'] = date("Y-m-d H:i"); + $this->completeTask(Carbon::now(), $newFlowItem->name); } } else { // 判断自动打开 if ($this->complete_at) { $flowData['complete_at'] = $this->complete_at; - $data['complete_at'] = false; + $this->completeTask(null); } } $flowUserids = $newFlowItem->userids; @@ -740,7 +740,7 @@ class ProjectTask extends AbstractModel ])->save(); } // 状态 - if (Arr::exists($data, 'complete_at')) { + if (Arr::exists($data, 'complete_at') && !Arr::exists($data, 'flow_item_id')) { // 子任务:主任务已完成时无法修改 if ($mainTask?->complete_at) { throw new ApiException('主任务已完成,无法修改子任务状态'); @@ -750,12 +750,14 @@ class ProjectTask extends AbstractModel if ($this->complete_at) { throw new ApiException('任务已完成'); } - $this->completeTask(Carbon::now(), isset($newFlowItem) ? $newFlowItem->name : null); + $flowItemName = $this->checkAndAutoSetFlowItem('end', -4005); + $this->completeTask(Carbon::now(), $flowItemName); } else { // 标记未完成 if (!$this->complete_at) { throw new ApiException('未完成任务'); } + $this->checkAndAutoSetFlowItem('start', -4006); $this->completeTask(null); } $updateMarking['is_update_project'] = true; @@ -1539,6 +1541,49 @@ class ProjectTask extends AbstractModel return $this->appendattrs['has_owner']; } + /** + * 检查并自动设置工作流状态 + * @param string $status 目标状态类型 ('start' 或 'end') + * @param int $errorCode 多状态时的错误码 (-4005 或 -4006) + * @return string|null 自动设置的状态名称,无状态时返回 null + */ + private function checkAndAutoSetFlowItem(string $status, int $errorCode): ?string + { + $flowItems = ProjectFlowItem::whereProjectId($this->project_id) + ->whereStatus($status) + ->get(['id', 'name', 'status', 'color']); + + if ($flowItems->count() > 1) { + $msg = $status === 'end' ? '存在多个结束状态,请选择要使用的状态' : '存在多个开始状态,请选择要使用的状态'; + throw new ApiException($msg, [ + 'task_id' => $this->id, + 'flow_items' => $flowItems->toArray(), + ], $errorCode); + } + + if ($flowItems->count() == 1) { + $autoFlowItem = $flowItems->first(); + $oldFlowItemId = $this->flow_item_id; + $oldFlowItemName = $this->flow_item_name; + $this->flow_item_id = $autoFlowItem->id; + $this->flow_item_name = $autoFlowItem->status . "|" . $autoFlowItem->name . "|" . $autoFlowItem->color; + + if ($oldFlowItemId != $this->flow_item_id) { + ProjectTaskFlowChange::createInstance([ + 'task_id' => $this->id, + 'userid' => User::userid(), + 'before_flow_item_id' => $oldFlowItemId, + 'before_flow_item_name' => $oldFlowItemName, + 'after_flow_item_id' => $this->flow_item_id, + 'after_flow_item_name' => $this->flow_item_name, + ])->save(); + } + return $autoFlowItem->name; + } + + return null; + } + /** * 标记已完成、未完成 * @param Carbon|null $complete_at 完成时间