feat: 完善运维控制台产品化体验

This commit is contained in:
湛兮
2026-06-12 16:36:20 +08:00
parent 0f92eb7b2b
commit 878125fe76
14 changed files with 2957 additions and 129 deletions
+61 -2
View File
@@ -21,6 +21,7 @@ import type {
IntegrationConfigStatus,
IntegrationVariableHelp,
IntegrationStatus,
JenkinsImportSummary,
JenkinsBuildLog,
JenkinsSyncSummary,
LoginPayload,
@@ -107,7 +108,7 @@ interface BackendDeployRun {
environment?: EnvironmentName
ref?: string
status?: BackendRunStatus
trigger?: 'manual' | 'gitea_webhook' | 'retry'
trigger?: 'manual' | 'gitea_webhook' | 'retry' | 'jenkins_external'
operator?: string
jenkinsQueueId?: string | number
jenkinsBuildNumber?: number
@@ -129,6 +130,26 @@ interface BackendJenkinsSyncSummary {
}>
}
interface BackendJenkinsImportSummary {
checkedAt: string
totalJobs: number
totalBuilds: number
importedRuns: BackendDeployRun[]
syncedRuns: BackendDeployRun[]
skippedBuilds: Array<{
projectKey: string
environment: EnvironmentName
buildNumber: number
reason: 'already_imported' | 'linked_platform_run' | 'parameter_mismatch'
}>
failedBuilds: Array<{
projectKey: string
environment: EnvironmentName
buildNumber?: number
message: string
}>
}
interface BackendProcessDefinition {
key: 'release'
version: string
@@ -205,6 +226,13 @@ const agentCards: AgentCard[] = [
inputScope: ['commit 列表', 'PR 信息', 'tag'],
outputPreview: ['变更摘要', '验证范围', '回滚提示'],
},
{
mode: 'incidentReview',
title: '事故复盘草稿',
description: '基于失败 run、流程耗时、Jenkins 摘要和 Runbook 生成复盘草稿。',
inputScope: ['失败 run', 'BPMN 节点', '脱敏日志片段', 'Runbook'],
outputPreview: ['时间线', '根因假设', '修复和预防项'],
},
]
const settings: SystemSetting[] = [
@@ -229,7 +257,7 @@ const settings: SystemSetting[] = [
name: 'Agent 边界',
status: 'warning',
owner: '后端 Agent proxy',
contract: '只支持发布风险、失败诊断、Runbook、发布说明类用途。',
contract: '只支持发布风险、失败诊断、Runbook、发布说明和事故复盘五类用途。',
boundary: '无泛聊天入口;模型 key/baseURL/model 仅后端保存。',
},
{
@@ -439,6 +467,14 @@ export const devopsApi = {
return toJenkinsSyncSummary(data, projectList)
},
async importJenkinsBuilds(projectList: ProjectConfig[] = []): Promise<JenkinsImportSummary> {
const { data } = await http.post<BackendJenkinsImportSummary>(
'/deploy-runs/import-jenkins',
)
lastDataSource = 'backend'
return toJenkinsImportSummary(data, projectList)
},
async getJenkinsLog(runId: string, start = 0): Promise<JenkinsBuildLog> {
const { data } = await http.get<JenkinsBuildLog>(`/deploy-runs/${runId}/jenkins-log`, {
params: { start },
@@ -1055,6 +1091,25 @@ function toJenkinsSyncSummary(
}
}
function toJenkinsImportSummary(
summary: BackendJenkinsImportSummary,
projectList: ProjectConfig[],
): JenkinsImportSummary {
return {
checkedAt: summary.checkedAt,
totalJobs: Number.isFinite(summary.totalJobs) ? summary.totalJobs : 0,
totalBuilds: Number.isFinite(summary.totalBuilds) ? summary.totalBuilds : 0,
importedRuns: (Array.isArray(summary.importedRuns) ? summary.importedRuns : []).map((run) =>
toReleaseRun(run, projectList),
),
syncedRuns: (Array.isArray(summary.syncedRuns) ? summary.syncedRuns : []).map((run) =>
toReleaseRun(run, projectList),
),
skippedBuilds: Array.isArray(summary.skippedBuilds) ? summary.skippedBuilds : [],
failedBuilds: Array.isArray(summary.failedBuilds) ? summary.failedBuilds : [],
}
}
function sanitizeAuditLogEntry(record: AuditLogEntry): AuditLogEntry {
return {
id: safeText(record.id, 'audit-unknown'),
@@ -1216,6 +1271,10 @@ function triggerLabel(trigger: BackendDeployRun['trigger']): string {
return '失败后重试'
}
if (trigger === 'jenkins_external') {
return 'Jenkins 直构导入'
}
return '人工触发'
}