#feature: improve Jira planning and release branch creation
This commit is contained in:
@@ -138,19 +138,18 @@ class JiraService
|
||||
throw new \InvalidArgumentException('用户名不能为空');
|
||||
}
|
||||
|
||||
// 定义已完成的状态列表(需要排除的状态)
|
||||
$completedStatuses = [
|
||||
'Done',
|
||||
'已上线',
|
||||
'已完成',
|
||||
// 未来任务只展示已进入评审、排期或开发阶段,且已归入 Sprint 的需求。
|
||||
$nextWeekStatuses = [
|
||||
'需求已评审',
|
||||
'需求已排期',
|
||||
'开发中',
|
||||
];
|
||||
$statusExclusion = implode('", "', $completedStatuses);
|
||||
|
||||
// 查询分配给用户且未完成的需求(Story/需求类型,不包括子任务)
|
||||
$jql = sprintf(
|
||||
'assignee = "%s" AND status NOT IN ("%s") AND issuetype in ("Story", "需求") ORDER BY created ASC',
|
||||
// 查询未来一周需要继续处理的需求(Story/需求类型,不包括子任务)。
|
||||
// 需求既可能分给当前用户,也可能通过研发 owner 归属当前用户。
|
||||
$jql = $this->buildNextWeekTasksJql(
|
||||
$username,
|
||||
$statusExclusion
|
||||
$nextWeekStatuses,
|
||||
$this->resolveDeveloperOwnerJqlField()
|
||||
);
|
||||
|
||||
try {
|
||||
@@ -172,7 +171,45 @@ class JiraService
|
||||
return collect();
|
||||
}
|
||||
|
||||
private function buildNextWeekTasksJql(string $username, array $allowedStatuses, ?string $developerOwnerField): string
|
||||
{
|
||||
$statusInclusion = implode('", "', $allowedStatuses);
|
||||
$ownerClause = sprintf('assignee = "%s"', $username);
|
||||
|
||||
if ($developerOwnerField) {
|
||||
$ownerClause = sprintf('(%s OR %s = "%s")', $ownerClause, $developerOwnerField, $username);
|
||||
}
|
||||
|
||||
return sprintf(
|
||||
'%s AND status IN ("%s") AND issuetype in ("Story", "需求") AND Sprint is not EMPTY ORDER BY created ASC',
|
||||
$ownerClause,
|
||||
$statusInclusion
|
||||
);
|
||||
}
|
||||
|
||||
private function resolveDeveloperOwnerJqlField(): ?string
|
||||
{
|
||||
try {
|
||||
foreach ($this->fieldService->getAllFields() as $field) {
|
||||
$name = $field->name ?? '';
|
||||
$id = $field->id ?? '';
|
||||
|
||||
if ($name === '' || ! $this->isDeveloperOwnerFieldName($name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (preg_match('/^customfield_(\d+)$/', $id, $matches)) {
|
||||
return 'cf['.$matches[1].']';
|
||||
}
|
||||
|
||||
return '"'.str_replace('"', '\"', $name).'"';
|
||||
}
|
||||
} catch (\Exception) {
|
||||
// 字段发现失败时退回 assignee 查询,避免周报生成整体失败。
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 Jira Sprint 下拉选项(从最近 Story 的 Sprint 字段中提取)
|
||||
@@ -245,6 +282,7 @@ class JiraService
|
||||
$startAt += $maxResults;
|
||||
$total = $result->total ?? $issues->count();
|
||||
} while ($issues->count() < $total && ! empty($pageIssues));
|
||||
|
||||
return $issues;
|
||||
} catch (JiraException $e) {
|
||||
throw new \RuntimeException('获取 Sprint 需求失败: '.$e->getMessage());
|
||||
@@ -597,6 +635,7 @@ class JiraService
|
||||
if (is_array($item)) {
|
||||
return $item['value'] ?? $item['name'] ?? $item['displayName'] ?? '';
|
||||
}
|
||||
|
||||
return '';
|
||||
})->filter()->implode(', ');
|
||||
}
|
||||
@@ -618,6 +657,7 @@ class JiraService
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成 Markdown 格式的周报
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user