#feature: update AI log analysis

This commit is contained in:
2026-02-11 11:00:32 +08:00
parent ddd0f531fd
commit 53bca7d609
18 changed files with 688 additions and 262 deletions

View File

@@ -132,10 +132,19 @@ class JiraService
throw new \InvalidArgumentException('用户名不能为空');
}
// 定义已完成的状态列表(需要排除的状态)
$completedStatuses = [
'Done',
'已上线',
'已完成',
];
$statusExclusion = implode('", "', $completedStatuses);
// 查询分配给用户且未完成的需求Story/需求类型,不包括子任务)
$jql = sprintf(
'assignee = "%s" AND status != "Done" AND issuetype in ("Story", "需求") ORDER BY created ASC',
$username
'assignee = "%s" AND status NOT IN ("%s") AND issuetype in ("Story", "需求") ORDER BY created ASC',
$username,
$statusExclusion
);
try {
@@ -203,6 +212,25 @@ class JiraService
}
}
// 没有Sprint的需求
if ($organizedTasks->has('stories') && $organizedTasks['stories']->isNotEmpty()) {
$markdown .= "### 需求\n";
foreach ($organizedTasks['stories'] as $task) {
$checkbox = $this->isTaskCompleted($task['status']) ? '[x]' : '[ ]';
$markdown .= "- {$checkbox} [{$task['key']}]({$task['url']}) {$task['summary']}\n";
if ($task['subtasks']->isNotEmpty()) {
// 按创建时间排序子任务
$sortedSubtasks = $task['subtasks']->sortBy('created');
foreach ($sortedSubtasks as $subtask) {
$subtaskCheckbox = $this->isTaskCompleted($subtask['status']) ? '[x]' : '[ ]';
$markdown .= " - {$subtaskCheckbox} [{$subtask['key']}]({$subtask['url']}) {$subtask['summary']}\n";
}
}
}
$markdown .= "\n";
}
// 单独列出的任务
if ($organizedTasks->has('tasks') && $organizedTasks['tasks']->isNotEmpty()) {
$markdown .= "### 任务\n";
@@ -675,9 +703,10 @@ class JiraService
*/
private function isTaskCompleted(string $status): bool
{
// 定义"进行中"的状态列表
// 定义"未完成"的状态列表(包括未开始和进行中)
// 如果状态不在这个列表中,则认为任务已完成
$inProgressStatuses = [
$incompleteStatuses = [
'未开始',
'需求已确认',
'开发中',
'需求调研中',
@@ -688,8 +717,8 @@ class JiraService
'需求设计中',
];
// 如果状态不在"进行中"列表中,则标记为已完成
return !in_array($status, $inProgressStatuses, true);
// 如果状态不在"未完成"列表中,则标记为已完成
return !in_array($status, $incompleteStatuses, true);
}
/**
@@ -699,6 +728,7 @@ class JiraService
{
$organized = collect([
'sprints' => collect(),
'stories' => collect(), // 没有Sprint的需求
'tasks' => collect(),
'bugs' => collect(),
]);
@@ -779,8 +809,25 @@ class JiraService
}
$this->addTaskToSprintOrTaskList($organized['sprints'][$sprintName], $workLog);
} elseif ($isStory && !$workLog['sprint']) {
// Story类型但没有Sprint的放入需求分类
$this->addTaskToSprintOrTaskList($organized['stories'], $workLog);
} elseif ($isSubtask && !$workLog['sprint'] && $workLog['parent_task']) {
// 子任务没有Sprint检查父任务类型来决定分类
$parentKey = $workLog['parent_task']['key'];
$parentDetails = $this->getIssueDetails($parentKey);
$parentType = $parentDetails ? ($parentDetails->fields->issuetype->name ?? '') : '';
$isParentStory = in_array($parentType, ['Story', 'story', '需求']);
if ($isParentStory) {
// 父任务是Story放入需求分类
$this->addTaskToSprintOrTaskList($organized['stories'], $workLog);
} else {
// 父任务不是Story放入任务分类
$this->addTaskToSprintOrTaskList($organized['tasks'], $workLog);
}
} else {
// 其他任务单独列出非Story/子任务类型或没有Sprint的
// 其他任务单独列出非Story/子任务类型)
$this->addTaskToSprintOrTaskList($organized['tasks'], $workLog);
}
}