|
|
@@ -83,50 +83,59 @@
|
|
|
label="构建状态"
|
|
|
>
|
|
|
<template slot-scope="scope">
|
|
|
- <el-button
|
|
|
- v-if="scope.row.buildResult === '构建成功'"
|
|
|
- type="text"
|
|
|
- >
|
|
|
- <span style="color: green">{{ scope.row.buildResult }}</span>
|
|
|
- </el-button>
|
|
|
- <el-button
|
|
|
- v-else-if="scope.row.buildResult === '构建失败'"
|
|
|
- type="text"
|
|
|
- @click="handleBuildResult(scope.$index, scope.row)"
|
|
|
+ <el-popover
|
|
|
+ v-if="scope.row.buildResult.code === 2"
|
|
|
+ placement="bottom"
|
|
|
+ title="构建进度"
|
|
|
+ width="300"
|
|
|
+ trigger="hover"
|
|
|
>
|
|
|
- <span style="color: red">{{ scope.row.buildResult }}</span>
|
|
|
- </el-button>
|
|
|
- <el-button
|
|
|
- v-else-if="scope.row.buildResult === '正在构建'"
|
|
|
- type="text"
|
|
|
- >
|
|
|
- <span style="color: blue">{{ scope.row.buildResult }}</span>
|
|
|
- </el-button>
|
|
|
- <el-button
|
|
|
- v-else
|
|
|
- type="text"
|
|
|
- >
|
|
|
- <span>{{ scope.row.buildResult }}</span>
|
|
|
- </el-button>
|
|
|
+ <el-steps
|
|
|
+ :active="getCurrentStepIndex(scope.row.steps)"
|
|
|
+ finish-status="success"
|
|
|
+ direction="vertical"
|
|
|
+ space="50px"
|
|
|
+ >
|
|
|
+ <el-step
|
|
|
+ v-for="step in scope.row.steps"
|
|
|
+ :key="step.stepName"
|
|
|
+ :title="step.stepName"
|
|
|
+ :description="getStepDesc(step)"
|
|
|
+ :status="getStepStatus(step.status)"
|
|
|
+ />
|
|
|
+ </el-steps>
|
|
|
+ <el-button
|
|
|
+ slot="reference"
|
|
|
+ type="text"
|
|
|
+ :style="{ color: scope.row.buildResult.color, fontWeight: 'bold' }"
|
|
|
+ >
|
|
|
+ <i class="el-icon-loading" />
|
|
|
+ {{ scope.row.buildResult.desc }}
|
|
|
+ </el-button>
|
|
|
+ </el-popover>
|
|
|
+ <div v-else-if="scope.row.buildResult.code === 4">
|
|
|
+ <el-button
|
|
|
+ type="text"
|
|
|
+ :style="{ color: scope.row.buildResult.color, fontWeight: 'bold' }"
|
|
|
+ @click="handleBuildResult(scope.row)"
|
|
|
+ >
|
|
|
+ {{ scope.row.buildResult.desc }}
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+ <div v-else>
|
|
|
+ <el-button
|
|
|
+ type="text"
|
|
|
+ :style="{ color: scope.row.buildResult.color, fontWeight: 'bold' }"
|
|
|
+ >
|
|
|
+ {{ scope.row.buildResult.desc }}
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
<el-table-column
|
|
|
prop="buildBy"
|
|
|
label="用户"
|
|
|
/>
|
|
|
- <el-table-column
|
|
|
- prop="totalNode"
|
|
|
- label="节点数/已运行"
|
|
|
- >
|
|
|
- <template slot-scope="scope">
|
|
|
- <el-tag style="margin-top: 5px; margin-left: 5px" disable-transitions>
|
|
|
- <span>{{ scope.row.totalNode }}</span>
|
|
|
- </el-tag>
|
|
|
- <el-tag style="margin-top: 5px; margin-left: 5px" disable-transitions>
|
|
|
- <span>{{ scope.row.totalRunning }}</span>
|
|
|
- </el-tag>
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
<el-table-column
|
|
|
fixed="right"
|
|
|
label="操作"
|
|
|
@@ -307,7 +316,7 @@
|
|
|
<el-button
|
|
|
style="margin-top: 5px; margin-left: 5px"
|
|
|
size="mini"
|
|
|
- @click="handleDeployApp(scope.$index, scope.row)"
|
|
|
+ @click="handleDeployApp(scope.row)"
|
|
|
>部署</el-button>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
@@ -348,7 +357,7 @@
|
|
|
<el-button
|
|
|
size="mini"
|
|
|
type="success"
|
|
|
- @click="handleBuildResult(scope.$index, scope.row)"
|
|
|
+ @click="handleBuildResult(scope.row)"
|
|
|
>查看</el-button>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
@@ -529,43 +538,22 @@
|
|
|
center
|
|
|
>
|
|
|
<template>
|
|
|
- <el-descriptions v-if="buildConsumed !== null" direction="vertical" :column="5" border>
|
|
|
- <el-descriptions-item>
|
|
|
- <template slot="label">
|
|
|
- <i class="el-icon-mobile-phone" />
|
|
|
- 构建总耗时(second)
|
|
|
- </template>
|
|
|
- {{ buildConsumed.total }}
|
|
|
- </el-descriptions-item>
|
|
|
- <el-descriptions-item>
|
|
|
- <template slot="label">
|
|
|
- <i class="el-icon-location-outline" />
|
|
|
- 更新耗时(ms)
|
|
|
- </template>
|
|
|
- {{ buildConsumed.pullConsumed }}
|
|
|
- </el-descriptions-item>
|
|
|
- <el-descriptions-item>
|
|
|
- <template slot="label">
|
|
|
- <i class="el-icon-tickets" />
|
|
|
- 编译耗时(ms)
|
|
|
- </template>
|
|
|
- {{ buildConsumed.compileConsumed }}
|
|
|
- </el-descriptions-item>
|
|
|
- <el-descriptions-item>
|
|
|
- <template slot="label">
|
|
|
- <i class="el-icon-office-building" />
|
|
|
- 打包耗时(ms)
|
|
|
- </template>
|
|
|
- {{ buildConsumed.packConsumed }}
|
|
|
- </el-descriptions-item>
|
|
|
- <el-descriptions-item>
|
|
|
- <template slot="label">
|
|
|
- <i class="el-icon-office-building" />
|
|
|
- 推送耗时(ms)
|
|
|
- </template>
|
|
|
- {{ buildConsumed.pushConsumed }}
|
|
|
- </el-descriptions-item>
|
|
|
- </el-descriptions>
|
|
|
+ <div v-if="buildConsumed !== null" style="margin-bottom: 20px;">
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <el-col :span="6">
|
|
|
+ <el-statistic title="总构建耗时" :value="buildConsumed.totalDurationSeconds" suffix="秒" />
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="18">
|
|
|
+ <el-tag
|
|
|
+ v-for="(time, name) in buildConsumed.stepDurations"
|
|
|
+ :key="name"
|
|
|
+ style="margin-right: 10px"
|
|
|
+ >
|
|
|
+ {{ name }}: {{ time }}s
|
|
|
+ </el-tag>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </div>
|
|
|
</template>
|
|
|
</el-dialog>
|
|
|
</el-container>
|
|
|
@@ -748,7 +736,7 @@ export default {
|
|
|
this.$message.error(error.message)
|
|
|
})
|
|
|
},
|
|
|
- handleBuildResult(index, row) {
|
|
|
+ handleBuildResult(row) {
|
|
|
const queryInfo = {}
|
|
|
queryInfo.buildLogId = row.buildLogId
|
|
|
getBuildResult(queryInfo).then(resp => {
|
|
|
@@ -782,6 +770,7 @@ export default {
|
|
|
getBuildConsumed(queryInfo).then(resp => {
|
|
|
if (resp.code === 0) {
|
|
|
this.buildConsumed = resp.data
|
|
|
+ console.log(this.buildConsumed)
|
|
|
this.showConsumedDialog = true
|
|
|
} else {
|
|
|
this.$message.error(resp.msg)
|
|
|
@@ -843,6 +832,11 @@ export default {
|
|
|
})
|
|
|
},
|
|
|
handleDeployList(index, row) {
|
|
|
+ if (row.buildLogId === undefined) {
|
|
|
+ this.$message.error("应用尚未构建")
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
const queryInfo = {}
|
|
|
queryInfo.appId = row.appId
|
|
|
this.deployForm.appId = row.appId
|
|
|
@@ -859,7 +853,7 @@ export default {
|
|
|
this.$message.error(error.message)
|
|
|
})
|
|
|
},
|
|
|
- handleDeployApp(index, row) {
|
|
|
+ handleDeployApp(row) {
|
|
|
const formData = new FormData()
|
|
|
formData.append('buildLogId', this.deployForm.buildLogId)
|
|
|
formData.append('machineId', row.machineId)
|
|
|
@@ -895,6 +889,56 @@ export default {
|
|
|
query: this.queryInfo
|
|
|
})
|
|
|
this.getData()
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * 获取当前激活步骤的索引
|
|
|
+ * @param {Array} steps 步骤列表
|
|
|
+ * @returns {Number} 索引值
|
|
|
+ */
|
|
|
+ getCurrentStepIndex(steps) {
|
|
|
+ if (!steps || steps.length === 0) return 0;
|
|
|
+ // 找到第一个状态不是 SUCCESS 的步骤索引
|
|
|
+ const index = steps.findIndex(step => step.status !== 'SUCCESS');
|
|
|
+ // 如果全部都成功了,返回 steps.length 使进度条全绿
|
|
|
+ return index === -1 ? steps.length : index;
|
|
|
+ },
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取步骤描述信息
|
|
|
+ * @param {Object} step 步骤对象
|
|
|
+ */
|
|
|
+ getStepDesc(step) {
|
|
|
+ if (step.status === 'RUNNING') {
|
|
|
+ return '正在执行...';
|
|
|
+ }
|
|
|
+ if (step.status === 'FAILED' && step.errorMsg) {
|
|
|
+ // 如果报错,显示错误摘要(截取前30个字符防止气泡框撑爆)
|
|
|
+ return step.errorMsg.length > 30
|
|
|
+ ? step.errorMsg.substring(0, 30) + '...'
|
|
|
+ : step.errorMsg;
|
|
|
+ }
|
|
|
+ if (step.status === 'SUCCESS' && step.endTime && step.startTime) {
|
|
|
+ // 计算耗时(可选)
|
|
|
+ const duration = (new Date(step.endTime) - new Date(step.startTime)) / 1000;
|
|
|
+ return `耗时: ${duration.toFixed(1)}s`;
|
|
|
+ }
|
|
|
+ return '';
|
|
|
+ },
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 映射后端状态到 el-step 的 status 属性
|
|
|
+ * el-step status 可选值: wait / process / finish / error / success
|
|
|
+ * @param {String} backendStatus 后端传来的状态串
|
|
|
+ */
|
|
|
+ getStepStatus(backendStatus) {
|
|
|
+ const statusMap = {
|
|
|
+ 'PENDING': 'wait',
|
|
|
+ 'RUNNING': 'process',
|
|
|
+ 'SUCCESS': 'success',
|
|
|
+ 'FAILED': 'error',
|
|
|
+ 'SKIPPED': 'wait'
|
|
|
+ };
|
|
|
+ return statusMap[backendStatus] || 'wait';
|
|
|
}
|
|
|
}
|
|
|
}
|