fix 构建详情页面布局(构建触发器、查看构建历史)

This commit is contained in:
bwcx_jzy 2023-03-29 10:55:53 +08:00
parent 3a3547966d
commit fecb477caf
No known key found for this signature in database
GPG Key ID: 5E48E9372088B9E5
11 changed files with 1764 additions and 1441 deletions

View File

@ -1,6 +1,6 @@
# 🚀 版本日志 # 🚀 版本日志
### 2.10.38.5 ### 2.10.38.5-beta
### 🐣 新增功能 ### 🐣 新增功能
@ -9,6 +9,10 @@
1. 【server】优化 证书管理支持使用文件管理部署 1. 【server】优化 证书管理支持使用文件管理部署
2. 【server】优化 节点管理中项目管理和脚本管理菜单合并为一个菜单 2. 【server】优化 节点管理中项目管理和脚本管理菜单合并为一个菜单
3. 【server】修复 节点分发构建确认弹窗筛选项目不生效问题
4. 【server】修复 无法使用添加构建功能
5. 【server】修复 资产管理 ssh 分组不生效问题(感谢@A
6. 【server】优化 构建详情页面布局(构建触发器、查看构建历史)
------ ------

View File

@ -141,11 +141,11 @@ public class BuildInfoController extends BaseServerController {
* *
* @return json * @return json
*/ */
@GetMapping(value = "/build/list_all", produces = MediaType.APPLICATION_JSON_VALUE) @GetMapping(value = "/build/get", produces = MediaType.APPLICATION_JSON_VALUE)
@Feature(method = MethodFeature.LIST) @Feature(method = MethodFeature.LIST)
public JsonMessage<List<BuildInfoModel>> getBuildListAll(HttpServletRequest request) { public JsonMessage<BuildInfoModel> getBuildListAll(String id, HttpServletRequest request) {
// load list with page // load list with page
List<BuildInfoModel> modelList = buildInfoService.listByWorkspace(request); BuildInfoModel modelList = buildInfoService.getByKey(id, request);
return JsonMessage.success("", modelList); return JsonMessage.success("", modelList);
} }
@ -424,7 +424,7 @@ public class BuildInfoController extends BaseServerController {
@RequestMapping(value = "/build/branch-list", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) @RequestMapping(value = "/build/branch-list", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
@Feature(method = MethodFeature.LIST) @Feature(method = MethodFeature.LIST)
public JsonMessage<JSONObject> branchList( public JsonMessage<JSONObject> branchList(
@ValidatorItem(value = ValidatorRule.NOT_BLANK, msg = "仓库ID不能为空") String repositoryId) throws Exception { @ValidatorItem(value = ValidatorRule.NOT_BLANK, msg = "仓库ID不能为空") String repositoryId) throws Exception {
// 根据 repositoryId 查询仓库信息 // 根据 repositoryId 查询仓库信息
RepositoryModel repositoryModel = repositoryService.getByKey(repositoryId, false); RepositoryModel repositoryModel = repositoryService.getByKey(repositoryId, false);
Assert.notNull(repositoryModel, "无效的仓库信息"); Assert.notNull(repositoryModel, "无效的仓库信息");

View File

@ -141,7 +141,8 @@ public class MachineSshController extends BaseGroupNameController {
String charset, String charset,
String id, String id,
Integer timeout, Integer timeout,
String allowEditSuffix) { String allowEditSuffix,
String groupName) {
boolean add = StrUtil.isEmpty(id); boolean add = StrUtil.isEmpty(id);
if (add) { if (add) {
// 优先判断参数 如果是 password 在修改时可以不填写 // 优先判断参数 如果是 password 在修改时可以不填写
@ -156,6 +157,7 @@ public class MachineSshController extends BaseGroupNameController {
} }
MachineSshModel sshModel = new MachineSshModel(); MachineSshModel sshModel = new MachineSshModel();
sshModel.setId(id); sshModel.setId(id);
sshModel.setGroupName(groupName);
sshModel.setHost(host); sshModel.setHost(host);
// 如果密码传递不为空就设置值 因为上面已经判断了只有修改的情况下 password 才可能为空 // 如果密码传递不为空就设置值 因为上面已经判断了只有修改的情况下 password 才可能为空
if (StrUtil.isNotEmpty(password)) { if (StrUtil.isNotEmpty(password)) {
@ -256,10 +258,10 @@ public class MachineSshController extends BaseGroupNameController {
@PostMapping(value = "save-workspace-config", produces = MediaType.APPLICATION_JSON_VALUE) @PostMapping(value = "save-workspace-config", produces = MediaType.APPLICATION_JSON_VALUE)
@Feature(method = MethodFeature.EDIT) @Feature(method = MethodFeature.EDIT)
public JsonMessage<String> saveWorkspaceConfig( public JsonMessage<String> saveWorkspaceConfig(
String fileDirs, String fileDirs,
@ValidatorItem String id, @ValidatorItem String id,
String notAllowedCommand, String notAllowedCommand,
String allowEditSuffix) { String allowEditSuffix) {
SshModel sshModel = new SshModel(id); SshModel sshModel = new SshModel(id);
// 目录 // 目录
if (StrUtil.isEmpty(fileDirs)) { if (StrUtil.isEmpty(fileDirs)) {
@ -364,21 +366,21 @@ public class MachineSshController extends BaseGroupNameController {
break; break;
} }
listPage.getResult() listPage.getResult()
.stream() .stream()
.map((Function<MachineSshModel, List<Object>>) machineSshModel -> CollUtil.newArrayList( .map((Function<MachineSshModel, List<Object>>) machineSshModel -> CollUtil.newArrayList(
machineSshModel.getName(), machineSshModel.getName(),
machineSshModel.getGroupName(), machineSshModel.getGroupName(),
machineSshModel.getHost(), machineSshModel.getHost(),
machineSshModel.getPort(), machineSshModel.getPort(),
machineSshModel.getUser(), machineSshModel.getUser(),
machineSshModel.getPassword(), machineSshModel.getPassword(),
machineSshModel.getCharset(), machineSshModel.getCharset(),
machineSshModel.getConnectType(), machineSshModel.getConnectType(),
machineSshModel.getPrivateKey(), machineSshModel.getPrivateKey(),
machineSshModel.getTimeout() machineSshModel.getTimeout()
)) ))
.map(objects -> objects.stream().map(StrUtil::toStringOrNull).toArray(String[]::new)) .map(objects -> objects.stream().map(StrUtil::toStringOrNull).toArray(String[]::new))
.forEach(writer::writeLine); .forEach(writer::writeLine);
if (ObjectUtil.equal(listPage.getPage(), listPage.getTotalPage())) { if (ObjectUtil.equal(listPage.getPage(), listPage.getTotalPage())) {
// 最后一页 // 最后一页
break; break;

View File

@ -67,10 +67,7 @@ import java.security.KeyStore;
import java.security.PrivateKey; import java.security.PrivateKey;
import java.security.PublicKey; import java.security.PublicKey;
import java.security.cert.Certificate; import java.security.cert.Certificate;
import java.util.Enumeration; import java.util.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/** /**
* @author bwcx_jzy * @author bwcx_jzy
@ -372,7 +369,8 @@ public class CertificateInfoController extends BaseServerController {
String absolutePath = FileUtil.file(tempSave, model.getSerialNumberStr() + ".zip").getAbsolutePath(); String absolutePath = FileUtil.file(tempSave, model.getSerialNumberStr() + ".zip").getAbsolutePath();
File zip = ZipUtil.zip(file.getAbsolutePath(), absolutePath, false); File zip = ZipUtil.zip(file.getAbsolutePath(), absolutePath, false);
// 添加到文件中心 // 添加到文件中心
String fileId = fileStorageService.addFile(zip, 3, certificateInfoService.getCheckUserWorkspace(request), model.getSerialNumberStr() + model.getDescription(), null, 1); String description = model.getSerialNumberStr() + Optional.ofNullable(model.getDescription()).map(s -> "," + s).orElse(StrUtil.EMPTY);
String fileId = fileStorageService.addFile(zip, 3, certificateInfoService.getCheckUserWorkspace(request), description, null, 1);
String releasePath = FileUtil.normalize(releasePathParent + StrUtil.SLASH + releasePathSecondary); String releasePath = FileUtil.normalize(releasePathParent + StrUtil.SLASH + releasePathSecondary);
// 创建发布任务 // 创建发布任务
Map<String, String> env = new HashMap<>(); Map<String, String> env = new HashMap<>();

View File

@ -0,0 +1,155 @@
<template>
<div>
<a-descriptions bordered>
<a-descriptions-item label="构建名称"> {{ data.name }}</a-descriptions-item>
<a-descriptions-item label="最新构建ID">
<a-tag color="#108ee9">#{{ data.buildId }}</a-tag>
</a-descriptions-item>
<a-descriptions-item label="分组"> {{ data.group }} </a-descriptions-item>
<a-descriptions-item label="分组/标签"> {{ data.branchName }} </a-descriptions-item>
<a-descriptions-item label="构建方式">
<template v-if="data.bubuildMode === 1">
<a-icon type="cloud" />
容器构建
</template>
<template v-else>
<a-icon type="code" />
本地构建
</template>
</a-descriptions-item>
<a-descriptions-item label="产物目录"> {{ data.resultDirFile }} </a-descriptions-item>
<a-descriptions-item label="构建状态">
<a-tag :color="statusColor[data.status]">{{ statusMap[data.status] || "未知" }}</a-tag>
</a-descriptions-item>
<a-descriptions-item label="发布方式">{{ releaseMethodMap[data.releaseMethod] }} </a-descriptions-item>
<a-descriptions-item label="定时构建"> {{ data.autoBuildCron }} </a-descriptions-item>
<a-descriptions-item label="创建时间"> {{ parseTime(data.createTimeMillis) }} </a-descriptions-item>
<a-descriptions-item label="最后修改时间"> {{ parseTime(data.modifyTimeMillis) }}</a-descriptions-item>
<a-descriptions-item label="最后修改人">{{ data.modifyUser }}</a-descriptions-item>
</a-descriptions>
<a-row type="flex" justify="center">
<a-divider v-if="listQuery.total > 1" dashed>构建历史</a-divider>
<a-timeline mode="alternate" style="width: 100%">
<a-timeline-item v-for="item in this.historyList" :key="item.id" :color="statusColor[item.status]">
<template slot="dot"> #{{ item.buildNumberId }}</template>
<a-space direction="vertical" :size="1">
<div v-if="item.buildRemark">构建备注{{ item.buildRemark }}</div>
<div>
状态<a-tag :color="statusColor[item.status]">{{ statusMap[item.status] || "未知" }}</a-tag>
</div>
<div>时间{{ parseTime(item.startTime) }} ~ {{ parseTime(item.endTime) }}</div>
<div>触发类型{{ triggerBuildTypeMap[item.triggerBuildType] || "未知" }}</div>
<div>占用空间{{ renderSize(item.resultFileSize) }}(产物)/{{ renderSize(item.buildLogFileSize) }}(日志)</div>
<div>构建耗时{{ formatDuration((item.endTime || 0) - (item.startTime || 0), "", 2) }}</div>
<div>
发布方式
<a-tag> {{ releaseMethodMap[item.releaseMethod] || "未知" }}</a-tag>
</div>
<div>
操作
<a-space>
<a-tooltip title="下载构建日志,如果按钮不可用表示日志文件不存在,一般是构建历史相关文件被删除">
<a-button size="small" icon="download" type="primary" :disabled="!item.hasLog" @click="handleDownload(item)">日志</a-button>
</a-tooltip>
<a-tooltip title="下载构建产物,如果按钮不可用表示产物文件不存在,一般是构建没有产生对应的文件或者构建历史相关文件被删除">
<a-button size="small" icon="download" type="primary" :disabled="!item.hasFile" @click="handleFile(item)"> 产物 </a-button>
</a-tooltip>
</a-space>
</div>
</a-space>
</a-timeline-item>
</a-timeline>
<a-divider v-if="listQuery.total / listQuery.limit > 1" dashed />
<a-col>
<a-pagination
v-model="listQuery.page"
:showTotal="
(total) => {
return PAGE_DEFAULT_SHOW_TOTAL(total, listQuery);
}
"
:showSizeChanger="true"
:pageSizeOptions="PAGE_DEFAULT_SIZW_OPTIONS"
:pageSize="listQuery.limit"
:total="listQuery.total"
:hideOnSinglePage="true"
@showSizeChange="
(current, size) => {
this.listQuery.limit = size;
this.listHistory();
}
"
@change="this.listHistory"
show-less-items
/>
</a-col>
</a-row>
</div>
</template>
<script>
import { getBuildGet, releaseMethodMap, statusMap, geteBuildHistory, statusColor, triggerBuildTypeMap, downloadBuildFile, downloadBuildLog } from "@/api/build-info";
import { parseTime, PAGE_DEFAULT_LIST_QUERY, PAGE_DEFAULT_SIZW_OPTIONS, PAGE_DEFAULT_SHOW_TOTAL, renderSize, formatDuration } from "@/utils/const";
export default {
props: {
id: {
type: String,
},
},
data() {
return {
PAGE_DEFAULT_SIZW_OPTIONS,
triggerBuildTypeMap,
releaseMethodMap,
statusColor,
statusMap,
data: {},
listQuery: Object.assign({ buildDataId: this.id }, PAGE_DEFAULT_LIST_QUERY),
historyList: [],
};
},
created() {
this.getData();
this.listHistory();
},
methods: {
parseTime,
formatDuration,
PAGE_DEFAULT_SHOW_TOTAL,
renderSize,
//
getData() {
//
getBuildGet({
id: this.id,
}).then((res) => {
if (res.data) {
this.data = res.data;
}
});
},
listHistory() {
//
geteBuildHistory(this.listQuery).then((res) => {
if (res.code === 200) {
this.historyList = res.data.result;
this.listQuery.total = res.data.total;
}
});
},
//
handleDownload(record) {
window.open(downloadBuildLog(record.id), "_blank");
},
//
handleFile(record) {
window.open(downloadBuildFile(record.id), "_blank");
},
},
};
</script>
<style scoped></style>

File diff suppressed because it is too large Load Diff

View File

@ -1,16 +1,9 @@
<template> <template>
<div class="full-content"> <div class="full-content">
<!-- <div ref="filter" class="filter">
<a-button type="primary" @click="handleFilter">刷新</a-button>
</div> -->
<!-- 数据表格 --> <!-- 数据表格 -->
<a-table :data-source="list" size="middle" :columns="columns" :pagination="pagination" bordered rowKey="id" @change="change" :row-selection="rowSelection"> <a-table :data-source="list" size="middle" :columns="columns" :pagination="pagination" bordered rowKey="id" @change="change" :row-selection="rowSelection">
<template slot="title"> <template slot="title">
<a-space> <a-space>
<a-select show-search option-filter-prop="children" v-model="listQuery.buildDataId" allowClear placeholder="请选择构建名称" class="search-input-item">
<a-select-option v-for="build in buildList" :key="build.id" :title="build.name">{{ build.name }}</a-select-option>
</a-select>
<a-select show-search option-filter-prop="children" v-model="listQuery.status" allowClear placeholder="请选择状态" class="search-input-item"> <a-select show-search option-filter-prop="children" v-model="listQuery.status" allowClear placeholder="请选择状态" class="search-input-item">
<a-select-option v-for="(val, key) in statusMap" :key="key">{{ val }}</a-select-option> <a-select-option v-for="(val, key) in statusMap" :key="key">{{ val }}</a-select-option>
</a-select> </a-select>
@ -52,9 +45,6 @@
<span>{{ triggerBuildTypeMap[text] }}</span> <span>{{ triggerBuildTypeMap[text] }}</span>
</a-tooltip> </a-tooltip>
<a-tooltip slot="startTime" slot-scope="text, record" :title="`开始时间:${parseTime(record.startTime)}${record.endTime ? '结束时间:' + parseTime(record.endTime) : ''}`">
<span>{{ parseTime(record.startTime) }}</span>
</a-tooltip>
<a-tooltip slot="resultFileSize" slot-scope="text, record" :title="`产物文件大小:${renderSize(record.resultFileSize)} 日志文件: ${renderSize(record.buildLogFileSize)}`"> <a-tooltip slot="resultFileSize" slot-scope="text, record" :title="`产物文件大小:${renderSize(record.resultFileSize)} 日志文件: ${renderSize(record.buildLogFileSize)}`">
<span>{{ renderSize(record.resultFileSize) }}</span> <span>{{ renderSize(record.resultFileSize) }}</span>
<!-- <div>{{ parseTime(record.endTime) }}</div> --> <!-- <div>{{ parseTime(record.endTime) }}</div> -->
@ -107,7 +97,7 @@
</template> </template>
<script> <script>
import BuildLog from "./log"; import BuildLog from "./log";
import { deleteBuildHistory, downloadBuildFile, downloadBuildLog, getBuildListAll, geteBuildHistory, releaseMethodMap, rollback, statusMap, triggerBuildTypeMap } from "@/api/build-info"; import { deleteBuildHistory, downloadBuildFile, downloadBuildLog, geteBuildHistory, releaseMethodMap, rollback, statusMap, triggerBuildTypeMap } from "@/api/build-info";
import { CHANGE_PAGE, COMPUTED_PAGINATION, PAGE_DEFAULT_LIST_QUERY, formatDuration, parseTime, renderSize } from "@/utils/const"; import { CHANGE_PAGE, COMPUTED_PAGINATION, PAGE_DEFAULT_LIST_QUERY, formatDuration, parseTime, renderSize } from "@/utils/const";
export default { export default {
@ -120,7 +110,7 @@ export default {
triggerBuildTypeMap: triggerBuildTypeMap, triggerBuildTypeMap: triggerBuildTypeMap,
loading: false, loading: false,
list: [], list: [],
buildList: [],
total: 0, total: 0,
listQuery: Object.assign({}, PAGE_DEFAULT_LIST_QUERY), listQuery: Object.assign({}, PAGE_DEFAULT_LIST_QUERY),
statusMap: statusMap, statusMap: statusMap,
@ -139,16 +129,23 @@ export default {
title: "开始时间", title: "开始时间",
dataIndex: "startTime", dataIndex: "startTime",
sorter: true, sorter: true,
scopedSlots: { customRender: "startTime" }, customRender: (text) => parseTime(text),
width: "170px", width: "170px",
}, },
{ {
title: "耗时", title: "耗时",
dataIndex: "endTime", dataIndex: "endTime",
sorter: true, // sorter: true,
scopedSlots: { customRender: "endTime" }, scopedSlots: { customRender: "endTime" },
width: "120px", width: "120px",
}, },
{
title: "数据更新时间",
dataIndex: "modifyTimeMillis",
sorter: true,
customRender: (text) => parseTime(text),
width: "170px",
},
{ title: "发布方式", dataIndex: "releaseMethod", width: "100px", ellipsis: true, scopedSlots: { customRender: "releaseMethod" } }, { title: "发布方式", dataIndex: "releaseMethod", width: "100px", ellipsis: true, scopedSlots: { customRender: "releaseMethod" } },
{ title: "构建人", dataIndex: "modifyUser", width: "130px", ellipsis: true, scopedSlots: { customRender: "modifyUser" } }, { title: "构建人", dataIndex: "modifyUser", width: "130px", ellipsis: true, scopedSlots: { customRender: "modifyUser" } },
{ title: "操作", dataIndex: "operation", scopedSlots: { customRender: "operation" }, width: "200px", align: "center", fixed: "right" }, { title: "操作", dataIndex: "operation", scopedSlots: { customRender: "operation" }, width: "200px", align: "center", fixed: "right" },
@ -167,21 +164,14 @@ export default {
}, },
}, },
created() { created() {
this.loadBuildList(); // this.loadBuildList();
this.loadData(); this.loadData();
}, },
methods: { methods: {
parseTime, parseTime,
renderSize, renderSize,
formatDuration, formatDuration,
//
loadBuildList() {
getBuildListAll().then((res) => {
if (res.code === 200) {
this.buildList = res.data;
}
});
},
// //
loadData(pointerEvent) { loadData(pointerEvent) {
this.listQuery.page = pointerEvent?.altKey || pointerEvent?.ctrlKey ? 1 : this.listQuery.page; this.listQuery.page = pointerEvent?.altKey || pointerEvent?.ctrlKey ? 1 : this.listQuery.page;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,236 @@
<template>
<div>
<div v-if="this.triggerToken || this.triggerVisible">
<a-form-model ref="editTriggerForm" :model="temp" :label-col="{ span: 6 }" :wrapper-col="{ span: 16 }">
<a-tabs default-active-key="1" type="card">
<template slot="tabBarExtraContent">
<a-tooltip title="重置触发器 token 信息,重置后之前的触发器 token 将失效">
<a-button type="primary" size="small" @click="resetTrigger">重置</a-button>
</a-tooltip>
</template>
<a-tab-pane key="1" tab="执行构建">
<a-space style="display: block" direction="vertical" align="baseline">
<a-alert message="温馨提示" type="warning">
<template slot="description">
<ul>
<li>单个触发器地址中第一个随机字符串为构建ID第二个随机字符串为 token</li>
<li>重置为重新生成触发地址,重置成功后之前的触发器地址将失效,构建触发器绑定到生成触发器到操作人上,如果将对应的账号删除触发器将失效</li>
<li>批量构建参数 BODY json [ { "id":"1", "token":"a", "delay":"0" } ]</li>
<li>批量构建参数还支持指定参数,delay延迟执行构建,单位秒 branchName分支名branchTagName标签script构建脚本resultDirFile构建产物webhook通知 webhook</li>
<li>
批量构建全部参数举例 BODY json [ { "id":"1", "token":"a", "delay":"0","branchName":"test","branchTagName":"1.*","script":"mvn clean
package","resultDirFile":"/target/","webhook":"http://test.com/webhook" } ]
</li>
<li>批量构建传入其他参数将同步执行修改</li>
</ul>
</template>
</a-alert>
<a-alert
v-clipboard:copy="temp.triggerBuildUrl"
v-clipboard:success="
() => {
tempVue.prototype.$notification.success({ message: '复制成功' });
}
"
v-clipboard:error="
() => {
tempVue.prototype.$notification.error({ message: '复制失败' });
}
"
type="info"
:message="`单个触发器地址(点击可以复制)`"
>
<template slot="description">
<a-tag>GET</a-tag> <span>{{ temp.triggerBuildUrl }} </span>
<a-icon type="copy" />
</template>
</a-alert>
<a-alert
v-clipboard:copy="temp.batchTriggerBuildUrl"
v-clipboard:success="
() => {
tempVue.prototype.$notification.success({ message: '复制成功' });
}
"
v-clipboard:error="
() => {
tempVue.prototype.$notification.error({ message: '复制失败' });
}
"
type="info"
:message="`批量触发器地址(点击可以复制)`"
>
<template slot="description">
<a-tag>POST</a-tag> <span>{{ temp.batchTriggerBuildUrl }} </span>
<a-icon type="copy" />
</template>
</a-alert>
</a-space>
</a-tab-pane>
<a-tab-pane key="2" tab="查看当前状态">
<a-space style="display: block" direction="vertical" align="baseline">
<a-alert message="温馨提示" type="warning">
<template slot="description">
<ul>
<li>批量构建参数 BODY json [ { "id":"1", "token":"a" } ]</li>
<li>参数中的 id token 和触发构建一致</li>
<li>
<a-tag>No(0, "未构建")</a-tag>, <a-tag>Ing(1, "")</a-tag>, <a-tag>Success(2, "")</a-tag>, <a-tag>Error(3, "")</a-tag>, <a-tag>PubIng(4, "")</a-tag>,
<a-tag>PubSuccess(5, "发布成功")</a-tag>, <a-tag>PubError(6, "")</a-tag>, <a-tag>Cancel(7, "")</a-tag>,
</li>
</ul>
</template>
</a-alert>
<a-alert
v-clipboard:copy="temp.batchBuildStatusUrl2"
v-clipboard:success="
() => {
tempVue.prototype.$notification.success({ message: '复制成功' });
}
"
v-clipboard:error="
() => {
tempVue.prototype.$notification.error({ message: '复制失败' });
}
"
type="info"
:message="`获取单个构建状态地址(点击可以复制)`"
>
<template slot="description">
<a-tag>GET</a-tag> <span>{{ temp.batchBuildStatusUrl2 }} </span>
<a-icon type="copy" />
</template>
</a-alert>
<a-alert
v-clipboard:copy="temp.batchBuildStatusUrl"
v-clipboard:success="
() => {
tempVue.prototype.$notification.success({ message: '复制成功' });
}
"
v-clipboard:error="
() => {
tempVue.prototype.$notification.error({ message: '复制失败' });
}
"
type="info"
:message="`批量获取构建状态地址(点击可以复制)`"
>
<template slot="description">
<a-tag>POST</a-tag> <span>{{ temp.batchBuildStatusUrl }} </span>
<a-icon type="copy" />
</template>
</a-alert>
</a-space>
</a-tab-pane>
<a-tab-pane key="3" tab="查看构建日志">
<a-space style="display: block" direction="vertical" align="baseline">
<a-alert message="温馨提示" type="warning">
<template slot="description">
<ul>
<li>参数中的 id token 和触发构建一致buildNumId 构建序号id</li>
<li>构建序号id需要跟进实际情况替换</li>
</ul>
</template>
</a-alert>
<a-alert
v-clipboard:copy="temp.buildLogUrl"
v-clipboard:success="
() => {
tempVue.prototype.$notification.success({ message: '复制成功' });
}
"
v-clipboard:error="
() => {
tempVue.prototype.$notification.error({ message: '复制失败' });
}
"
type="info"
:message="`获取单个构建日志地址(点击可以复制)`"
>
<template slot="description">
<a-tag>GET</a-tag> <span>{{ temp.buildLogUrl }} </span>
<a-icon type="copy" />
</template>
</a-alert>
</a-space>
</a-tab-pane>
</a-tabs>
</a-form-model>
</div>
<template v-else>
<a-result title="当前构建还没有生成触发器">
<template #extra>
<a-button key="console" type="primary" @click="handleTrigger"> 现成生成 </a-button>
</template>
</a-result>
</template>
</div>
</template>
<script>
import Vue from "vue";
import { getTriggerUrl } from "@/api/build-info";
export default {
props: {
id: {
type: String,
},
triggerToken: {
type: String,
default: "",
},
},
data() {
return {
temp: {},
tempVue: null,
triggerVisible: false,
};
},
created() {
if (this.triggerToken) {
this.handleTrigger();
}
},
methods: {
//
handleTrigger() {
this.temp = {};
this.tempVue = Vue;
getTriggerUrl({
id: this.id,
}).then((res) => {
if (res.code === 200) {
this.fillTriggerResult(res);
this.triggerVisible = true;
}
});
},
//
resetTrigger() {
getTriggerUrl({
id: this.id,
rest: "rest",
}).then((res) => {
if (res.code === 200) {
this.$notification.success({
message: res.msg,
});
this.fillTriggerResult(res);
}
});
},
fillTriggerResult(res) {
this.temp.triggerBuildUrl = `${location.protocol}//${location.host}${res.data.triggerBuildUrl}`;
this.temp.batchTriggerBuildUrl = `${location.protocol}//${location.host}${res.data.batchTriggerBuildUrl}`;
this.temp.batchBuildStatusUrl = `${location.protocol}//${location.host}${res.data.batchBuildStatusUrl}`;
this.temp.buildLogUrl = `${location.protocol}//${location.host}${res.data.buildLogUrl}`;
// this.temp.id = res.data.id;
// this.temp.token = res.data.token;
this.temp.batchBuildStatusUrl2 = `${this.temp.batchBuildStatusUrl}?id=${res.data.id}&token=${res.data.token}`;
this.temp.buildLogUrl = `${this.temp.buildLogUrl}?id=${res.data.id}&token=${res.data.token}&buildNumId=0`;
this.temp = { ...this.temp };
},
},
};
</script>

View File

@ -19,6 +19,8 @@
<template slot="title"> <template slot="title">
<a-space> <a-space>
<a-input v-model="listQuery['%name%']" @pressEnter="loadData" placeholder="文件名称" class="search-input-item" /> <a-input v-model="listQuery['%name%']" @pressEnter="loadData" placeholder="文件名称" class="search-input-item" />
<a-input v-model="listQuery['%aliasCode%']" @pressEnter="loadData" placeholder="别名码" class="search-input-item" />
<a-input v-model="listQuery['extName']" @pressEnter="loadData" placeholder="后缀,精准搜索" class="search-input-item" />
<a-input v-model="listQuery['id']" @pressEnter="loadData" placeholder="文件id,精准搜索" class="search-input-item" /> <a-input v-model="listQuery['id']" @pressEnter="loadData" placeholder="文件id,精准搜索" class="search-input-item" />
<a-tooltip title="按住 Ctr 或者 Alt/Option 键点击按钮快速回到第一页"> <a-tooltip title="按住 Ctr 或者 Alt/Option 键点击按钮快速回到第一页">
<a-button type="primary" :loading="loading" @click="loadData">搜索</a-button> <a-button type="primary" :loading="loading" @click="loadData">搜索</a-button>

View File

@ -70,7 +70,12 @@
size="middle" size="middle"
rowKey="id" rowKey="id"
:pagination="pagination" :pagination="pagination"
@change="changePage" @change="
(pagination, filters, sorter) => {
this.listQuery = CHANGE_PAGE(this.listQuery, { pagination, sorter });
this.loadData();
}
"
:row-selection="rowSelection" :row-selection="rowSelection"
> >
<a-tooltip slot="url" slot-scope="text, record" placement="topLeft" :title="text"> <a-tooltip slot="url" slot-scope="text, record" placement="topLeft" :title="text">
@ -573,7 +578,7 @@ export default {
renderSize, renderSize,
PAGE_DEFAULT_SHOW_TOTAL, PAGE_DEFAULT_SHOW_TOTAL,
parseTime, parseTime,
CHANGE_PAGE,
introGuideList() { introGuideList() {
this.$store.dispatch("tryOpenGuide", { this.$store.dispatch("tryOpenGuide", {
key: "node-list-manage", key: "node-list-manage",
@ -771,11 +776,7 @@ export default {
query: query, query: query,
}); });
}, },
//
changePage(pagination, filters, sorter) {
this.listQuery = CHANGE_PAGE(this.listQuery, { pagination, sorter });
this.loadData();
},
// //
loadWorkSpaceListAll() { loadWorkSpaceListAll() {
getWorkSpaceListAll().then((res) => { getWorkSpaceListAll().then((res) => {