mirror of
https://github.com/certd/certd.git
synced 2026-04-27 23:37:29 +08:00
perf: 批量运行优化,支持普通运行和强制重新运行
This commit is contained in:
@@ -159,6 +159,7 @@ export default {
|
|||||||
selectedCount: "Selected {count} items",
|
selectedCount: "Selected {count} items",
|
||||||
batchDelete: "Batch Delete",
|
batchDelete: "Batch Delete",
|
||||||
batchForceRerun: "Force Rerun",
|
batchForceRerun: "Force Rerun",
|
||||||
|
batchRerun: "Rerun",
|
||||||
applyCertificate: "Apply for Certificate",
|
applyCertificate: "Apply for Certificate",
|
||||||
pipelineExecutionRecords: "Pipeline Execution Records",
|
pipelineExecutionRecords: "Pipeline Execution Records",
|
||||||
confirm: "Confirm",
|
confirm: "Confirm",
|
||||||
|
|||||||
@@ -165,6 +165,7 @@ export default {
|
|||||||
selectedCount: "已选择 {count} 项",
|
selectedCount: "已选择 {count} 项",
|
||||||
batchDelete: "批量删除",
|
batchDelete: "批量删除",
|
||||||
batchForceRerun: "强制重新运行",
|
batchForceRerun: "强制重新运行",
|
||||||
|
batchRerun: "重新运行",
|
||||||
applyCertificate: "申请证书",
|
applyCertificate: "申请证书",
|
||||||
pipelineExecutionRecords: "流水线执行记录",
|
pipelineExecutionRecords: "流水线执行记录",
|
||||||
confirm: "确认",
|
confirm: "确认",
|
||||||
|
|||||||
@@ -117,11 +117,11 @@ export async function BatchDelete(pipelineIds: number[]): Promise<void> {
|
|||||||
data: { ids: pipelineIds },
|
data: { ids: pipelineIds },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
export async function BatchRerun(pipelineIds: number[]): Promise<void> {
|
export async function BatchRerun(pipelineIds: number[], force: boolean): Promise<void> {
|
||||||
return await request({
|
return await request({
|
||||||
url: apiPrefix + "/batchRerun",
|
url: apiPrefix + "/batchRerun",
|
||||||
method: "post",
|
method: "post",
|
||||||
data: { ids: pipelineIds },
|
data: { ids: pipelineIds, force },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,86 @@
|
|||||||
|
<template>
|
||||||
|
<fs-button icon="icon-park-outline:replay-music" class="need-plus" type="link" :text="t('certd.batchRerun')" @click="openFormDialog"></fs-button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { compute, dict, useFormWrapper } from "@fast-crud/fast-crud";
|
||||||
|
import * as api from "../api";
|
||||||
|
import { useSettingStore } from "/@/store/settings";
|
||||||
|
import { useI18n } from "/src/locales";
|
||||||
|
import { computed } from "vue";
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
selectedRowKeys: any[];
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
change: any;
|
||||||
|
}>();
|
||||||
|
async function batchUpdateRequest(form: any) {
|
||||||
|
await api.BatchRerun(props.selectedRowKeys, form.force ?? false);
|
||||||
|
emit("change");
|
||||||
|
}
|
||||||
|
|
||||||
|
const { openCrudFormDialog } = useFormWrapper();
|
||||||
|
|
||||||
|
const settingStore = useSettingStore();
|
||||||
|
|
||||||
|
async function openFormDialog() {
|
||||||
|
settingStore.checkPlus();
|
||||||
|
const crudOptions: any = {
|
||||||
|
columns: {
|
||||||
|
force: {
|
||||||
|
title: "运行模式",
|
||||||
|
form: {
|
||||||
|
value: false,
|
||||||
|
required: true,
|
||||||
|
helper: "强制重新运行:清除流水线所有状态,全部重新执行\n普通运行:成功过的任务会跳过",
|
||||||
|
component: {
|
||||||
|
name: "fs-dict-radio",
|
||||||
|
vModel: "value",
|
||||||
|
style: {
|
||||||
|
marginTop: "5px",
|
||||||
|
},
|
||||||
|
dict: dict({
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
label: "普通运行",
|
||||||
|
value: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "强制重新运行",
|
||||||
|
value: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
form: {
|
||||||
|
mode: "edit",
|
||||||
|
initialForm: {
|
||||||
|
clear: false,
|
||||||
|
},
|
||||||
|
//@ts-ignore
|
||||||
|
async doSubmit({ form }) {
|
||||||
|
await batchUpdateRequest(form);
|
||||||
|
},
|
||||||
|
col: {
|
||||||
|
span: 22,
|
||||||
|
},
|
||||||
|
labelCol: {
|
||||||
|
style: {
|
||||||
|
width: "100px",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wrapper: {
|
||||||
|
title: t("certd.batchRerun"),
|
||||||
|
width: 600,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} as any;
|
||||||
|
await openCrudFormDialog({ crudOptions });
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
<div class="batch-actions-inner">
|
<div class="batch-actions-inner">
|
||||||
<span>{{ t("certd.selectedCount", { count: selectedRowKeys.length }) }}</span>
|
<span>{{ t("certd.selectedCount", { count: selectedRowKeys.length }) }}</span>
|
||||||
<fs-button icon="ion:trash-outline" class="color-red" type="link" :text="t('certd.batchDelete')" @click="batchDelete"></fs-button>
|
<fs-button icon="ion:trash-outline" class="color-red" type="link" :text="t('certd.batchDelete')" @click="batchDelete"></fs-button>
|
||||||
<fs-button icon="icon-park-outline:replay-music" class="need-plus" type="link" :text="t('certd.batchForceRerun')" @click="batchRerun"></fs-button>
|
<batch-rerun :selected-row-keys="selectedRowKeys" @change="batchFinished"></batch-rerun>
|
||||||
<change-group :selected-row-keys="selectedRowKeys" @change="batchFinished"></change-group>
|
<change-group :selected-row-keys="selectedRowKeys" @change="batchFinished"></change-group>
|
||||||
<change-notification :selected-row-keys="selectedRowKeys" @change="batchFinished"></change-notification>
|
<change-notification :selected-row-keys="selectedRowKeys" @change="batchFinished"></change-notification>
|
||||||
<change-trigger :selected-row-keys="selectedRowKeys" @change="batchFinished"></change-trigger>
|
<change-trigger :selected-row-keys="selectedRowKeys" @change="batchFinished"></change-trigger>
|
||||||
@@ -28,6 +28,7 @@ import { dict, useFs } from "@fast-crud/fast-crud";
|
|||||||
import createCrudOptions from "./crud";
|
import createCrudOptions from "./crud";
|
||||||
import ChangeGroup from "./components/change-group.vue";
|
import ChangeGroup from "./components/change-group.vue";
|
||||||
import ChangeTrigger from "./components/change-trigger.vue";
|
import ChangeTrigger from "./components/change-trigger.vue";
|
||||||
|
import BatchRerun from "./components/batch-rerun.vue";
|
||||||
import { Modal, notification } from "ant-design-vue";
|
import { Modal, notification } from "ant-design-vue";
|
||||||
import * as api from "./api";
|
import * as api from "./api";
|
||||||
import { useI18n } from "/src/locales";
|
import { useI18n } from "/src/locales";
|
||||||
@@ -75,20 +76,6 @@ function batchDelete() {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function batchRerun() {
|
|
||||||
settingStore.checkPlus();
|
|
||||||
Modal.confirm({
|
|
||||||
title: "确认强制重新运行吗",
|
|
||||||
content: "确定要强制重新运行选中流水线吗?(20条一批执行)",
|
|
||||||
async onOk() {
|
|
||||||
await api.BatchRerun(selectedRowKeys.value);
|
|
||||||
notification.success({ message: "任务已提交" });
|
|
||||||
await crudExpose.doRefresh();
|
|
||||||
selectedRowKeys.value = [];
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
.batch-actions {
|
.batch-actions {
|
||||||
|
|||||||
@@ -192,8 +192,8 @@ export class PipelineController extends CrudController<PipelineService> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Post('/batchRerun', { summary: Constants.per.authOnly })
|
@Post('/batchRerun', { summary: Constants.per.authOnly })
|
||||||
async batchRerun(@Body('ids') ids: number[]) {
|
async batchRerun(@Body('ids') ids: number[], @Body('force') force: boolean) {
|
||||||
await this.service.batchRerun(ids, this.getUserId());
|
await this.service.batchRerun(ids, this.getUserId(), force);
|
||||||
return this.ok({});
|
return this.ok({});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -898,7 +898,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async batchRerun(ids: number[], userId: any) {
|
async batchRerun(ids: number[], userId: any, force: boolean) {
|
||||||
if (!isPlus()) {
|
if (!isPlus()) {
|
||||||
throw new NeedVIPException("此功能需要升级专业版");
|
throw new NeedVIPException("此功能需要升级专业版");
|
||||||
}
|
}
|
||||||
@@ -919,18 +919,20 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
|||||||
ids = list.map(item => item.id);
|
ids = list.map(item => item.id);
|
||||||
|
|
||||||
//异步执行
|
//异步执行
|
||||||
this.startBatchRerun(ids);
|
this.startBatchRerun(userId,ids, force);
|
||||||
}
|
}
|
||||||
|
|
||||||
async startBatchRerun(ids: number[]) {
|
startBatchRerun(userId:number, ids: number[], force: boolean) {
|
||||||
//20条一批
|
for (const id of ids) {
|
||||||
const batchSize = 20;
|
executorQueue.addTask(userId,{
|
||||||
for (let i = 0; i < ids.length; i += batchSize) {
|
task: async () => {
|
||||||
const batchIds = ids.slice(i, i + batchSize);
|
if (force) {
|
||||||
const batchPromises = batchIds.map(async (id) => {
|
await this.run(id, null, "ALL");
|
||||||
await this.run(id, null, "ALL");
|
} else {
|
||||||
|
await this.run(id, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
await Promise.all(batchPromises);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user