diff --git a/src/components/RunExecutionDetails.vue b/src/components/RunExecutionDetails.vue
index e5db7b8..32a96ad 100644
--- a/src/components/RunExecutionDetails.vue
+++ b/src/components/RunExecutionDetails.vue
@@ -1,12 +1,23 @@
@@ -74,6 +136,18 @@ function buildText() {
{{ displayText(run.jenkinsQueueId) }}
Jenkins Build
{{ buildText() }}
+ Jenkins 日志
+
+
+ 查看日志
+
+
Jenkins 状态
{{ displayText(run.jenkinsSummary) }}
Build URL
@@ -122,6 +196,31 @@ function buildText() {
后端尚未返回异常摘要、执行提示或日志摘要。
+
+
+
+
+
{{ logText }}
+
Jenkins 暂无日志。
+
+
@@ -155,6 +254,10 @@ function buildText() {
color: #1d5fd0;
}
+.detail-grid :deep(.el-button) {
+ max-width: 100%;
+}
+
.failure-block {
border-top: 1px solid #edf1f7;
padding-top: 14px;
@@ -235,6 +338,44 @@ function buildText() {
font-size: 13px;
}
+.jenkins-log-drawer {
+ display: flex;
+ min-height: 100%;
+ flex-direction: column;
+ gap: 12px;
+}
+
+.jenkins-log-toolbar {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 12px;
+ color: #5f6b7a;
+ font-size: 12px;
+}
+
+.log-actions {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+ justify-content: flex-end;
+}
+
+.jenkins-log-output {
+ flex: 1;
+ min-height: 420px;
+ margin: 0;
+ padding: 12px;
+ overflow: auto;
+ border-radius: 6px;
+ background: #111827;
+ color: #e5edf8;
+ font-size: 12px;
+ line-height: 1.55;
+ white-space: pre-wrap;
+ overflow-wrap: anywhere;
+}
+
@media (max-width: 760px) {
.detail-grid {
grid-template-columns: 1fr;
@@ -244,5 +385,10 @@ function buildText() {
.detail-grid dd + dt {
margin-top: 8px;
}
+
+ .jenkins-log-toolbar {
+ align-items: flex-start;
+ flex-direction: column;
+ }
}
diff --git a/src/services/devopsApi.ts b/src/services/devopsApi.ts
index bf02f79..b42ce63 100644
--- a/src/services/devopsApi.ts
+++ b/src/services/devopsApi.ts
@@ -20,6 +20,7 @@ import type {
IntegrationConfigStatus,
IntegrationVariableHelp,
IntegrationStatus,
+ JenkinsBuildLog,
JenkinsSyncSummary,
LoginPayload,
LoginResult,
@@ -402,6 +403,14 @@ export const devopsApi = {
return toJenkinsSyncSummary(data, projectList)
},
+ async getJenkinsLog(runId: string, start = 0): Promise {
+ const { data } = await http.get(`/deploy-runs/${runId}/jenkins-log`, {
+ params: { start },
+ })
+ lastDataSource = 'backend'
+ return data
+ },
+
async getAuditLogs(): Promise {
const { data } = await http.get('/audit-logs')
lastDataSource = 'backend'
diff --git a/src/types/devops.ts b/src/types/devops.ts
index 35fd7e9..72e969c 100644
--- a/src/types/devops.ts
+++ b/src/types/devops.ts
@@ -277,6 +277,17 @@ export interface ReleaseRun {
steps: PipelineStep[]
}
+export interface JenkinsBuildLog {
+ runId: string
+ jobPath: string
+ buildNumber: number
+ start: number
+ nextStart: number
+ hasMore: boolean
+ text: string
+ fetchedAt: string
+}
+
export interface JenkinsSyncError {
id: string
projectKey: string