mirror of https://github.com/certd/certd
chore: 模版创建流水线
parent
821c6d807d
commit
9296ba7492
|
@ -84,6 +84,7 @@ export abstract class BaseService<T> {
|
||||||
...where,
|
...where,
|
||||||
});
|
});
|
||||||
await this.modifyAfter(idArr);
|
await this.modifyAfter(idArr);
|
||||||
|
return ids
|
||||||
}
|
}
|
||||||
|
|
||||||
resolveIdArr(ids: string | any[]) {
|
resolveIdArr(ids: string | any[]) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: "LayoutFooter"
|
name: "LayoutFooter",
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,11 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
editRequest,
|
editRequest,
|
||||||
delRequest,
|
delRequest,
|
||||||
},
|
},
|
||||||
|
addForm: {
|
||||||
|
onSuccess: ({ res }) => {
|
||||||
|
router.push({ path: "/certd/pipeline/template/edit", query: { templateId: res.id, editMode: "true" } });
|
||||||
|
},
|
||||||
|
},
|
||||||
form: {
|
form: {
|
||||||
labelCol: {
|
labelCol: {
|
||||||
//固定label宽度
|
//固定label宽度
|
||||||
|
@ -95,7 +100,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
show: true,
|
show: true,
|
||||||
},
|
},
|
||||||
column: {
|
column: {
|
||||||
width: 200,
|
width: 400,
|
||||||
sorter: true,
|
sorter: true,
|
||||||
cellRender({ row, value }) {
|
cellRender({ row, value }) {
|
||||||
return <router-link to={{ path: "/certd/pipeline/template/edit", query: { templateId: row.id } }}>{value}</router-link>;
|
return <router-link to={{ path: "/certd/pipeline/template/edit", query: { templateId: row.id } }}>{value}</router-link>;
|
||||||
|
@ -117,8 +122,12 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
editForm: {
|
editForm: {
|
||||||
show: false,
|
show: false,
|
||||||
},
|
},
|
||||||
form: {
|
column: {
|
||||||
show: false,
|
show: false,
|
||||||
|
},
|
||||||
|
form: {
|
||||||
|
show: true,
|
||||||
|
helper: "复制该流水线配置作为模版来源",
|
||||||
component: {
|
component: {
|
||||||
valuesFormat: {
|
valuesFormat: {
|
||||||
labelFormatter: (item: any) => {
|
labelFormatter: (item: any) => {
|
||||||
|
|
|
@ -7,18 +7,33 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="more flex items-center flex-1 justify-end">
|
<div class="more flex items-center flex-1 justify-end">
|
||||||
<loading-button type="primary" @click="doSave">保存</loading-button>
|
<loading-button type="primary" @click="doSave">保存模版</loading-button>
|
||||||
|
<loading-button class="ml-10" type="primary" @click="useTemplateCreate">使用模版</loading-button>
|
||||||
|
<loading-button class="ml-10" type="primary" danger @click="doDelete">删除模版</loading-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div class="page-template-edit">
|
<div class="page-template-edit">
|
||||||
<div class="base"></div>
|
<div class="base"></div>
|
||||||
<div class="props flex p-10">
|
<div class="props flex p-10">
|
||||||
<div class="task-list w-50%">
|
<div class="task-list w-50%">
|
||||||
<div class="block-title">
|
<div class="block-title flex flex-between">
|
||||||
原始任务参数
|
<div>
|
||||||
<div class="helper">点击加号,将字段作为模版变量</div>
|
模版流水线参数
|
||||||
|
<div class="helper">点击加号,将字段作为模版变量</div>
|
||||||
|
</div>
|
||||||
|
<div class="more">
|
||||||
|
<router-link
|
||||||
|
v-if="detail?.template?.pipelineId > 0"
|
||||||
|
:to="{
|
||||||
|
path: '/certd/pipeline/detail',
|
||||||
|
query: { id: detail?.template?.pipelineId, editMode: true },
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
修改模版流水线
|
||||||
|
</router-link>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<a-collapse v-model:active-key="activeKey">
|
<a-collapse v-if="detail?.template?.pipelineId > 0" v-model:active-key="activeKey">
|
||||||
<a-collapse-panel v-for="(step, stepId) in steps" :key="stepId" class="step-item" :header="step.title">
|
<a-collapse-panel v-for="(step, stepId) in steps" :key="stepId" class="step-item" :header="step.title">
|
||||||
<div class="step-inputs flex flex-wrap">
|
<div class="step-inputs flex flex-wrap">
|
||||||
<div v-for="(input, key) of step.input" :key="key" class="hover:bg-gray-100 p-5 w-full xl:w-[50%]">
|
<div v-for="(input, key) of step.input" :key="key" class="hover:bg-gray-100 p-5 w-full xl:w-[50%]">
|
||||||
|
@ -36,6 +51,17 @@
|
||||||
</div>
|
</div>
|
||||||
</a-collapse-panel>
|
</a-collapse-panel>
|
||||||
</a-collapse>
|
</a-collapse>
|
||||||
|
|
||||||
|
<div v-else-if="detail?.template?.pipelineId === 0">
|
||||||
|
<div class="p-20 flex flex-col flex-center text-sm">
|
||||||
|
<div class="mb-10">还未绑定模版流水线</div>
|
||||||
|
<div>
|
||||||
|
<a-button type="primary" @click="bindPipelineByCreate">创建新流水线作为模版</a-button>
|
||||||
|
或
|
||||||
|
<a-button type="primary" @click="bindPipelineByCopy">从已有流水线复制</a-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="template-props w-50%">
|
<div class="template-props w-50%">
|
||||||
|
@ -60,7 +86,9 @@ import { templateApi } from "./api";
|
||||||
import { usePluginStore } from "/@/store/plugin";
|
import { usePluginStore } from "/@/store/plugin";
|
||||||
import { useStepHelper } from "./utils";
|
import { useStepHelper } from "./utils";
|
||||||
import TemplateForm from "./form.vue";
|
import TemplateForm from "./form.vue";
|
||||||
|
import { Modal, notification } from "ant-design-vue";
|
||||||
|
import { useTabbarStore } from "/@/vben/stores";
|
||||||
|
import { useTemplate } from "./use";
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const templateId = route.query.templateId as string;
|
const templateId = route.query.templateId as string;
|
||||||
|
|
||||||
|
@ -79,6 +107,9 @@ const templateProps: Ref = ref({
|
||||||
});
|
});
|
||||||
const detail: Ref<TemplateDetail> = ref();
|
const detail: Ref<TemplateDetail> = ref();
|
||||||
async function getTemplateDetail() {
|
async function getTemplateDetail() {
|
||||||
|
if (!templateId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const res = await templateApi.GetDetail(parseInt(templateId));
|
const res = await templateApi.GetDetail(parseInt(templateId));
|
||||||
detail.value = res;
|
detail.value = res;
|
||||||
templateProps.value = JSON.parse(res.template.content ?? "{input:{}}");
|
templateProps.value = JSON.parse(res.template.content ?? "{input:{}}");
|
||||||
|
@ -100,7 +131,7 @@ onMounted(async () => {
|
||||||
|
|
||||||
const { getStepsMap } = useStepHelper(pluginStore);
|
const { getStepsMap } = useStepHelper(pluginStore);
|
||||||
const steps = computed(() => {
|
const steps = computed(() => {
|
||||||
if (!detail.value) {
|
if (!detail.value || !detail.value.pipeline) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,5 +157,36 @@ async function doSave() {
|
||||||
title: detail.value.template.title,
|
title: detail.value.template.title,
|
||||||
content: JSON.stringify(templateProps.value),
|
content: JSON.stringify(templateProps.value),
|
||||||
});
|
});
|
||||||
|
notification.success({
|
||||||
|
message: "保存成功",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const tabbar = useTabbarStore();
|
||||||
|
async function doDelete() {
|
||||||
|
Modal.confirm({
|
||||||
|
title: "确定删除模版?",
|
||||||
|
content: "删除后,该模版流水线将不能再使用",
|
||||||
|
onOk() {
|
||||||
|
templateApi.DelObj(detail.value.template.id);
|
||||||
|
notification.success({
|
||||||
|
message: "删除成功",
|
||||||
|
});
|
||||||
|
tabbar.closeTab({ fullPath: route.fullPath } as any, router);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function bindPipelineByCreate() {
|
||||||
|
//
|
||||||
|
// openAddCertdPipelineDialog({ templateId: detail.value.template.id });
|
||||||
|
}
|
||||||
|
|
||||||
|
async function bindPipelineByCopy() {}
|
||||||
|
|
||||||
|
const { openCreateFromTemplateDialog } = useTemplate();
|
||||||
|
|
||||||
|
async function useTemplateCreate() {
|
||||||
|
openCreateFromTemplateDialog({ templateId: detail.value.template.id });
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<a-form ref="templateFormRef" class="template-form" :model="templateForm" :label-col="labelCol" :wrapper-col="wrapperCol">
|
<a-form ref="templateFormRef" class="template-form w-full" :model="templateForm" :label-col="labelCol" :wrapper-col="wrapperCol">
|
||||||
<template v-for="(item, key) in templateFormColumns" :key="key">
|
<template v-for="(item, key) in templateFormColumns" :key="key">
|
||||||
<fs-form-item v-if="item.show !== false" :model-value="get(templateForm, key)" :item="item" :get-context-fn="getScopeFunc(key)" @update:model-value="set(templateForm, key, $event)" />
|
<fs-form-item v-if="item.show !== false" :model-value="get(templateForm, key)" :item="item" :get-context-fn="getScopeFunc(key)" @update:model-value="set(templateForm, key, $event)" />
|
||||||
</template>
|
</template>
|
||||||
|
@ -28,7 +28,12 @@ const steps = computed(() => {
|
||||||
return getStepsMap(props.pipeline);
|
return getStepsMap(props.pipeline);
|
||||||
});
|
});
|
||||||
|
|
||||||
const labelCol = ref({ span: 6 });
|
const labelCol = ref({
|
||||||
|
span: null,
|
||||||
|
style: {
|
||||||
|
width: "145px",
|
||||||
|
},
|
||||||
|
});
|
||||||
const wrapperCol = ref({ span: 16 });
|
const wrapperCol = ref({ span: 16 });
|
||||||
const templateForm: any = reactive({});
|
const templateForm: any = reactive({});
|
||||||
const templateFormColumns = computed(() => {
|
const templateFormColumns = computed(() => {
|
||||||
|
|
|
@ -0,0 +1,112 @@
|
||||||
|
import { dict, useFormWrapper } from "@fast-crud/fast-crud";
|
||||||
|
import { checkPipelineLimit } from "/@/views/certd/pipeline/utils";
|
||||||
|
import { templateApi } from "/@/views/certd/pipeline/template/api";
|
||||||
|
import TemplateForm from "./form.vue";
|
||||||
|
import NotificationSelector from "/@/views/certd/notification/notification-selector/index.vue";
|
||||||
|
import GroupSelector from "/@/views/certd/pipeline/group/group-selector.vue";
|
||||||
|
import { ref } from "vue";
|
||||||
|
|
||||||
|
export function useTemplate() {
|
||||||
|
const { openCrudFormDialog } = useFormWrapper();
|
||||||
|
|
||||||
|
async function openCreateFromTemplateDialog(req: { templateId?: number }) {
|
||||||
|
//检查是否流水线数量超出限制
|
||||||
|
await checkPipelineLimit();
|
||||||
|
const detail = await templateApi.GetDetail(req.templateId);
|
||||||
|
if (!detail) {
|
||||||
|
throw new Error("模板不存在");
|
||||||
|
}
|
||||||
|
if (!detail.template?.pipelineId) {
|
||||||
|
throw new Error("还未绑定模版流水线");
|
||||||
|
}
|
||||||
|
const templateProps = JSON.parse(detail.template.content || "{}");
|
||||||
|
const pipeline = detail.pipeline;
|
||||||
|
|
||||||
|
const groupDictRef = dict({
|
||||||
|
url: "/pi/pipeline/group/all",
|
||||||
|
value: "id",
|
||||||
|
label: "name",
|
||||||
|
});
|
||||||
|
|
||||||
|
const wrapperRef = ref();
|
||||||
|
function getFormData() {
|
||||||
|
if (!wrapperRef.value) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return wrapperRef.value.getFormData();
|
||||||
|
}
|
||||||
|
|
||||||
|
const randomHour = Math.floor(Math.random() * 6);
|
||||||
|
const randomMin = Math.floor(Math.random() * 60);
|
||||||
|
const crudOptions = {
|
||||||
|
form: {
|
||||||
|
wrapper: {
|
||||||
|
title: `从模版<${detail.template.title}>创建流水线`,
|
||||||
|
width: 1100,
|
||||||
|
slots: {
|
||||||
|
"form-body-top": () => {
|
||||||
|
return (
|
||||||
|
<div class={"w-full flex"}>
|
||||||
|
<TemplateForm input={templateProps.input} pipeline={pipeline} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
columns: {
|
||||||
|
triggerCron: {
|
||||||
|
title: "定时触发",
|
||||||
|
type: "text",
|
||||||
|
form: {
|
||||||
|
value: `0 ${randomMin} ${randomHour} * * *`,
|
||||||
|
component: {
|
||||||
|
name: "cron-editor",
|
||||||
|
vModel: "modelValue",
|
||||||
|
placeholder: "0 0 4 * * *",
|
||||||
|
},
|
||||||
|
helper: "点击上面的按钮,选择每天几点定时执行。\n建议设置为每天触发一次,证书未到期之前任务会跳过,不会重复执行",
|
||||||
|
order: 100,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
notification: {
|
||||||
|
title: "失败通知",
|
||||||
|
type: "text",
|
||||||
|
form: {
|
||||||
|
value: 0,
|
||||||
|
component: {
|
||||||
|
name: NotificationSelector,
|
||||||
|
vModel: "modelValue",
|
||||||
|
on: {
|
||||||
|
selectedChange(opts: any) {
|
||||||
|
opts.form.notificationTarget = opts.$event;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
order: 101,
|
||||||
|
helper: "任务执行失败实时提醒",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
groupId: {
|
||||||
|
title: "流水线分组",
|
||||||
|
type: "dict-select",
|
||||||
|
dict: groupDictRef,
|
||||||
|
form: {
|
||||||
|
component: {
|
||||||
|
name: GroupSelector,
|
||||||
|
vModel: "modelValue",
|
||||||
|
},
|
||||||
|
order: 9999,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const wrapper = await openCrudFormDialog({ crudOptions });
|
||||||
|
wrapperRef.value = wrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
openCreateFromTemplateDialog,
|
||||||
|
};
|
||||||
|
}
|
|
@ -13,3 +13,6 @@ CREATE TABLE "pi_template"
|
||||||
|
|
||||||
CREATE INDEX "index_template_user_id" ON "pi_template" ("user_id");
|
CREATE INDEX "index_template_user_id" ON "pi_template" ("user_id");
|
||||||
CREATE INDEX "index_template_pipeline_id" ON "pi_template" ("pipeline_id");
|
CREATE INDEX "index_template_pipeline_id" ON "pi_template" ("pipeline_id");
|
||||||
|
|
||||||
|
ALTER TABLE pi_pipeline ADD COLUMN "template_id" integer DEFAULT 0;
|
||||||
|
CREATE INDEX "index_pipeline_template_id" ON "pi_pipeline" ("template_id");
|
||||||
|
|
|
@ -59,8 +59,8 @@ export class TemplateController extends CrudController<TemplateService> {
|
||||||
|
|
||||||
@Post('/delete', { summary: Constants.per.authOnly })
|
@Post('/delete', { summary: Constants.per.authOnly })
|
||||||
async delete(@Query('id') id: number) {
|
async delete(@Query('id') id: number) {
|
||||||
await this.service.checkUserId(id, this.getUserId());
|
await this.service.batchDelete([id], this.getUserId());
|
||||||
return super.delete(id);
|
return this.ok({});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post('/batchDelete', { summary: Constants.per.authOnly })
|
@Post('/batchDelete', { summary: Constants.per.authOnly })
|
||||||
|
|
|
@ -52,6 +52,7 @@ export class CnameProviderService extends BaseService<CnameProviderEntity> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//@ts-ignore
|
||||||
async delete(ids: any) {
|
async delete(ids: any) {
|
||||||
if (!ids) {
|
if (!ids) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -37,6 +37,9 @@ export class PipelineEntity {
|
||||||
@Column({ comment: '来源', nullable: true, default: '' })
|
@Column({ comment: '来源', nullable: true, default: '' })
|
||||||
from: string;
|
from: string;
|
||||||
|
|
||||||
|
@Column({ name:"template_id", comment: '是否模版', nullable: true, default: '' })
|
||||||
|
templateId: number;
|
||||||
|
|
||||||
@Column({
|
@Column({
|
||||||
name: 'last_history_time',
|
name: 'last_history_time',
|
||||||
comment: '最后一次执行时间',
|
comment: '最后一次执行时间',
|
||||||
|
|
|
@ -46,6 +46,7 @@ import {UserSuiteEntity, UserSuiteService} from "@certd/commercial-core";
|
||||||
import {CertInfoService} from "../../monitor/service/cert-info-service.js";
|
import {CertInfoService} from "../../monitor/service/cert-info-service.js";
|
||||||
import {TaskServiceBuilder} from "./task-service-getter.js";
|
import {TaskServiceBuilder} from "./task-service-getter.js";
|
||||||
import {nanoid} from "nanoid";
|
import {nanoid} from "nanoid";
|
||||||
|
import {set} from "lodash-es";
|
||||||
|
|
||||||
const runningTasks: Map<string | number, Executor> = new Map();
|
const runningTasks: Map<string | number, Executor> = new Map();
|
||||||
|
|
||||||
|
@ -117,6 +118,8 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||||
}
|
}
|
||||||
|
|
||||||
async page(pageReq: PageReq<PipelineEntity>) {
|
async page(pageReq: PageReq<PipelineEntity>) {
|
||||||
|
//模版流水线不要被查询出来
|
||||||
|
set(pageReq,"query.templateId",0)
|
||||||
const result = await super.page(pageReq);
|
const result = await super.page(pageReq);
|
||||||
await this.fillLastVars(result.records);
|
await this.fillLastVars(result.records);
|
||||||
|
|
||||||
|
@ -281,6 +284,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||||
},
|
},
|
||||||
where: {
|
where: {
|
||||||
disabled: false,
|
disabled: false,
|
||||||
|
templateId: 0,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const ids = idEntityList.map(item => {
|
const ids = idEntityList.map(item => {
|
||||||
|
@ -385,7 +389,8 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async delete(id: any) {
|
//@ts-ignore
|
||||||
|
async delete(id:any) {
|
||||||
await this.clearTriggers(id);
|
await this.clearTriggers(id);
|
||||||
//TODO 删除storage
|
//TODO 删除storage
|
||||||
// const storage = new DbStorage(pipeline.userId, this.storageService);
|
// const storage = new DbStorage(pipeline.userId, this.storageService);
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
import {Inject, Provide, Scope, ScopeEnum} from '@midwayjs/core';
|
import {Inject, Provide, Scope, ScopeEnum} from '@midwayjs/core';
|
||||||
import {BaseService, SysSettingsService} from '@certd/lib-server';
|
import {BaseService, SysSettingsService} from '@certd/lib-server';
|
||||||
import {InjectEntityModel} from '@midwayjs/typeorm';
|
import {InjectEntityModel} from '@midwayjs/typeorm';
|
||||||
import {Repository} from 'typeorm';
|
import {In, Repository} from 'typeorm';
|
||||||
import { TemplateEntity } from '../entity/template.js';
|
import {TemplateEntity} from '../entity/template.js';
|
||||||
import { PipelineService } from './pipeline-service.js';
|
import {PipelineService} from './pipeline-service.js';
|
||||||
|
import {cloneDeep} from "lodash-es";
|
||||||
|
import {PipelineEntity} from "../entity/pipeline.js";
|
||||||
|
import {Pipeline} from "@certd/pipeline";
|
||||||
|
|
||||||
@Provide()
|
@Provide()
|
||||||
@Scope(ScopeEnum.Request, { allowDowngrade: true })
|
@Scope(ScopeEnum.Request, {allowDowngrade: true})
|
||||||
export class TemplateService extends BaseService<TemplateEntity> {
|
export class TemplateService extends BaseService<TemplateEntity> {
|
||||||
@InjectEntityModel(TemplateEntity)
|
@InjectEntityModel(TemplateEntity)
|
||||||
repository: Repository<TemplateEntity>;
|
repository: Repository<TemplateEntity>;
|
||||||
|
@ -22,6 +25,47 @@ export class TemplateService extends BaseService<TemplateEntity> {
|
||||||
return this.repository;
|
return this.repository;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async add(param: any) {
|
||||||
|
const pipelineId = param.pipelineId;
|
||||||
|
delete param.pipelineId;
|
||||||
|
|
||||||
|
const pipelineEntity = await this.pipelineService.info(pipelineId);
|
||||||
|
if (!pipelineEntity) {
|
||||||
|
throw new Error('pipeline not found');
|
||||||
|
}
|
||||||
|
if (pipelineEntity.userId !== param.userId) {
|
||||||
|
throw new Error('permission denied');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
let template = null
|
||||||
|
await this.transaction(async (tx: any) => {
|
||||||
|
|
||||||
|
template = await tx.getRepository(TemplateEntity).save(param);
|
||||||
|
let newPipeline = cloneDeep(pipelineEntity)
|
||||||
|
//创建pipeline模版
|
||||||
|
newPipeline.id = undefined;
|
||||||
|
newPipeline.title = template.title+"模版流水线"
|
||||||
|
newPipeline.templateId = template.id
|
||||||
|
|
||||||
|
const pipelineJson:Pipeline = JSON.parse(newPipeline.content)
|
||||||
|
delete pipelineJson.triggers
|
||||||
|
pipelineJson.id = template.id
|
||||||
|
pipelineJson.userId = template.userId
|
||||||
|
pipelineJson.title = newPipeline.title
|
||||||
|
newPipeline.content = JSON.stringify(pipelineJson)
|
||||||
|
newPipeline = await tx.getRepository(PipelineEntity).save(newPipeline)
|
||||||
|
|
||||||
|
const update :any= {}
|
||||||
|
update.id = template.id
|
||||||
|
update.pipelineId = newPipeline.id
|
||||||
|
await tx.getRepository(TemplateEntity).save(update)
|
||||||
|
})
|
||||||
|
|
||||||
|
return template
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
async detail(id: number, userId: number) {
|
async detail(id: number, userId: number) {
|
||||||
const info = await this.info(id)
|
const info = await this.info(id)
|
||||||
if (!info) {
|
if (!info) {
|
||||||
|
@ -30,12 +74,31 @@ export class TemplateService extends BaseService<TemplateEntity> {
|
||||||
if (info.userId !== userId) {
|
if (info.userId !== userId) {
|
||||||
throw new Error('无权限');
|
throw new Error('无权限');
|
||||||
}
|
}
|
||||||
const pipeline = await this.pipelineService.info(info.pipelineId);
|
let pipeline = null
|
||||||
|
if (info.pipelineId) {
|
||||||
|
const pipelineEntity = await this.pipelineService.info(info.pipelineId);
|
||||||
|
pipeline = JSON.parse(pipelineEntity.content)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
template:info,
|
template: info,
|
||||||
pipeline: JSON.parse(pipeline.content),
|
pipeline,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
async batchDelete(ids: number[], userId: number) {
|
||||||
|
|
||||||
|
const where :any= {
|
||||||
|
id: In(ids),
|
||||||
|
}
|
||||||
|
if (userId > 0) {
|
||||||
|
where.userId = userId
|
||||||
|
}
|
||||||
|
const list = await this.getRepository().find({where })
|
||||||
|
ids = list.map(item => item.id)
|
||||||
|
const pipelineIds = list.map(item => item.pipelineId)
|
||||||
|
await this.delete(ids);
|
||||||
|
await this.pipelineService.batchDelete(pipelineIds,userId)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -129,6 +129,7 @@ export class RoleService extends BaseService<RoleEntity> {
|
||||||
return permissionSet;
|
return permissionSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//@ts-ignore
|
||||||
async delete(id: any) {
|
async delete(id: any) {
|
||||||
const idArr = this.resolveIdArr(id);
|
const idArr = this.resolveIdArr(id);
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
|
|
|
@ -253,6 +253,7 @@ export class UserService extends BaseService<UserEntity> {
|
||||||
await this.update(param);
|
await this.update(param);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//@ts-ignore
|
||||||
async delete(ids: any) {
|
async delete(ids: any) {
|
||||||
if (typeof ids === 'string') {
|
if (typeof ids === 'string') {
|
||||||
ids = ids.split(',');
|
ids = ids.split(',');
|
||||||
|
|
|
@ -7,6 +7,7 @@ import {
|
||||||
createCertDomainGetterInputDefine,
|
createCertDomainGetterInputDefine,
|
||||||
createRemoteSelectInputDefine
|
createRemoteSelectInputDefine
|
||||||
} from "@certd/plugin-lib";
|
} from "@certd/plugin-lib";
|
||||||
|
import {PageReq} from "@certd/lib-server";
|
||||||
|
|
||||||
@IsTaskPlugin({
|
@IsTaskPlugin({
|
||||||
name: 'AliyunDeployCertToWaf',
|
name: 'AliyunDeployCertToWaf',
|
||||||
|
@ -168,7 +169,7 @@ export class AliyunDeployCertToWaf extends AbstractTaskPlugin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async onGetCnameList(data: any) {
|
async onGetCnameList(data: PageReq) {
|
||||||
if (!this.accessId) {
|
if (!this.accessId) {
|
||||||
throw new Error('请选择Access授权');
|
throw new Error('请选择Access授权');
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue