perf: 支持批量转移流水线到其他项目

This commit is contained in:
xiaojunnuo
2026-03-15 04:17:40 +08:00
parent f642e42eea
commit 8a3841f638
13 changed files with 283 additions and 36 deletions
@@ -7,8 +7,12 @@ import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
export class AccessEntity { export class AccessEntity {
@PrimaryGeneratedColumn() @PrimaryGeneratedColumn()
id: number; id: number;
@Column({ name: 'key_id', comment: 'key_id', length: 100 })
keyId: string;
@Column({ name: 'user_id', comment: '用户id' }) @Column({ name: 'user_id', comment: '用户id' })
userId: number; // 0为系统级别, -1为企业,大于1为用户 userId: number; // 0为系统级别, -1为企业,大于1为用户
@Column({ comment: '名称', length: 100 }) @Column({ comment: '名称', length: 100 })
name: string; name: string;
@@ -5,6 +5,7 @@ import {AccessGetter, BaseService, PageReq, PermissionException, ValidateExcepti
import {AccessEntity} from '../entity/access.js'; import {AccessEntity} from '../entity/access.js';
import {AccessDefine, accessRegistry, newAccess} from '@certd/pipeline'; import {AccessDefine, accessRegistry, newAccess} from '@certd/pipeline';
import {EncryptService} from './encrypt-service.js'; import {EncryptService} from './encrypt-service.js';
import { logger, utils } from '@certd/basic';
/** /**
* 授权 * 授权
@@ -46,6 +47,7 @@ export class AccessService extends BaseService<AccessEntity> {
} }
delete param._copyFrom delete param._copyFrom
this.encryptSetting(param, oldEntity); this.encryptSetting(param, oldEntity);
param.keyId = "ac_" + utils.id.simpleNanoId();
return await super.add(param); return await super.add(param);
} }
@@ -117,6 +119,7 @@ export class AccessService extends BaseService<AccessEntity> {
throw new ValidateException('该授权配置不存在,请确认是否已被删除'); throw new ValidateException('该授权配置不存在,请确认是否已被删除');
} }
this.encryptSetting(param, oldEntity); this.encryptSetting(param, oldEntity);
delete param.keyId
return await super.update(param); return await super.update(param);
} }
@@ -215,4 +218,36 @@ export class AccessService extends BaseService<AccessEntity> {
}); });
} }
/**
* 复制授权到其他项目
* @param accessId
* @param projectId
*/
async copyTo(accessId: number,projectId?: number) {
const access = await this.info(accessId);
if (access == null) {
throw new Error(`该授权配置不存在,请确认是否已被删除:id=${accessId}`);
}
const keyId = access.keyId;
//检查目标项目里是否已经有相同keyId的配置
const existAccess = await this.repository.findOne({
where: {
keyId,
projectId,
},
});
if (existAccess) {
logger.info(`目标项目已存在相同keyId的授权配置,跳过复制:keyId=${keyId}`);
return existAccess.id;
}
const newAccess = {
...access,
id: undefined,
projectId,
}
await this.add(newAccess);
return newAccess.id;
}
} }
@@ -6,6 +6,8 @@ import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
export class AddonEntity { export class AddonEntity {
@PrimaryGeneratedColumn() @PrimaryGeneratedColumn()
id: number; id: number;
@Column({ name: 'key_id', comment: 'key_id', length: 100 })
keyId: string;
@Column({ name: 'user_id', comment: '用户id' }) @Column({ name: 'user_id', comment: '用户id' })
userId: number; userId: number;
@Column({ comment: '名称', length: 100 }) @Column({ comment: '名称', length: 100 })
@@ -4,6 +4,7 @@ import { In, Repository } from "typeorm";
import { AddonDefine, BaseService, PageReq, ValidateException } from "../../../index.js"; import { AddonDefine, BaseService, PageReq, ValidateException } from "../../../index.js";
import { addonRegistry } from "../api/index.js"; import { addonRegistry } from "../api/index.js";
import { AddonEntity } from "../entity/addon.js"; import { AddonEntity } from "../entity/addon.js";
import { utils } from "@certd/basic";
/** /**
* Addon * Addon
@@ -43,6 +44,7 @@ export class AddonService extends BaseService<AddonEntity> {
} else { } else {
param.isSystem = false; param.isSystem = false;
} }
param.keyId = "ad_" + utils.id.simpleNanoId();
delete param._copyFrom; delete param._copyFrom;
return await super.add(param); return await super.add(param);
} }
@@ -57,6 +59,7 @@ export class AddonService extends BaseService<AddonEntity> {
if (oldEntity == null) { if (oldEntity == null) {
throw new ValidateException("该Addon配置不存在,请确认是否已被删除"); throw new ValidateException("该Addon配置不存在,请确认是否已被删除");
} }
delete param.keyId
return await super.update(param); return await super.update(param);
} }
@@ -67,6 +70,7 @@ export class AddonService extends BaseService<AddonEntity> {
} }
return { return {
id: entity.id, id: entity.id,
keyId: entity.keyId,
name: entity.name, name: entity.name,
userId: entity.userId, userId: entity.userId,
addonType: entity.addonType, addonType: entity.addonType,
@@ -100,6 +104,7 @@ export class AddonService extends BaseService<AddonEntity> {
}, },
select: { select: {
id: true, id: true,
keyId: true,
name: true, name: true,
addonType: true, addonType: true,
type: true, type: true,
@@ -132,6 +137,7 @@ export class AddonService extends BaseService<AddonEntity> {
const setting = JSON.parse(res.setting); const setting = JSON.parse(res.setting);
return { return {
id: res.id, id: res.id,
keyId: res.keyId,
addonType: res.addonType, addonType: res.addonType,
type: res.type, type: res.type,
name: res.name, name: res.name,
@@ -784,7 +784,7 @@ onMounted(async () => {
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
padding: 40px 20px; padding: 20px 10px;
color: #9ca3af; color: #9ca3af;
} }
@@ -110,6 +110,14 @@ export async function BatchUpdateNotificaiton(pipelineIds: number[], notificatio
}); });
} }
export async function BatchUpdateProject(pipelineIds: number[], toProjectId: number): Promise<void> {
return await request({
url: apiPrefix + "/batchTransfer",
method: "post",
data: { ids: pipelineIds, toProjectId: toProjectId },
});
}
export async function BatchDelete(pipelineIds: number[]): Promise<void> { export async function BatchDelete(pipelineIds: number[]): Promise<void> {
return await request({ return await request({
url: apiPrefix + "/batchDelete", url: apiPrefix + "/batchDelete",
@@ -0,0 +1,64 @@
<template>
<fs-button icon="mdi:format-list-group" class="need-plus" type="link" text="转到其他项目" @click="openProjectSelectDialog"></fs-button>
</template>
<script setup lang="ts">
import * as api from "../api";
import { notification } from "ant-design-vue";
import { dict, useFormWrapper } from "@fast-crud/fast-crud";
import { useSettingStore } from "/@/store/settings";
const props = defineProps<{
selectedRowKeys: any[];
}>();
const emit = defineEmits<{
change: any;
}>();
async function batchUpdateProjectRequest(toProjectId: number) {
await api.BatchUpdateProject(props.selectedRowKeys, toProjectId);
emit("change");
}
const pipelineProjectDictRef = dict({
url: "/enterprise/project/all",
value: "id",
label: "name",
});
const { openCrudFormDialog } = useFormWrapper();
const settingStore = useSettingStore();
async function openProjectSelectDialog() {
settingStore.checkPlus();
const crudOptions: any = {
columns: {
toProjectId: {
title: "转到项目",
type: "dict-select",
dict: pipelineProjectDictRef,
form: {
rules: [{ required: true, message: "请选择项目" }],
},
},
},
form: {
mode: "edit",
//@ts-ignore
async doSubmit({ form }) {
await batchUpdateProjectRequest(form.toProjectId);
},
col: {
span: 22,
},
labelCol: {
style: {
width: "100px",
},
},
wrapper: {
title: "批量转到其他项目",
width: 600,
},
},
} as any;
await openCrudFormDialog({ crudOptions });
}
</script>
@@ -42,6 +42,7 @@
<change-group v-if="hasActionPermission('write')" :selected-row-keys="selectedRowKeys" @change="batchFinished"></change-group> <change-group v-if="hasActionPermission('write')" :selected-row-keys="selectedRowKeys" @change="batchFinished"></change-group>
<change-notification v-if="hasActionPermission('write')" :selected-row-keys="selectedRowKeys" @change="batchFinished"></change-notification> <change-notification v-if="hasActionPermission('write')" :selected-row-keys="selectedRowKeys" @change="batchFinished"></change-notification>
<change-trigger v-if="hasActionPermission('write')" :selected-row-keys="selectedRowKeys" @change="batchFinished"></change-trigger> <change-trigger v-if="hasActionPermission('write')" :selected-row-keys="selectedRowKeys" @change="batchFinished"></change-trigger>
<change-project v-if="hasActionPermission('write')" :selected-row-keys="selectedRowKeys" @change="batchFinished"></change-project>
</div> </div>
</div> </div>
<template #form-bottom> <template #form-bottom>
@@ -57,6 +58,8 @@ 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 ChangeProject from "./components/change-project.vue";
import BatchRerun from "./components/batch-rerun.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";
@@ -0,0 +1,12 @@
ALTER TABLE cd_access ADD COLUMN key_id varchar(100) NULL;
CREATE INDEX "index_access_key_id" ON "cd_access" ("key_id");
update cd_access set key_id = id where key_id is null;
ALTER TABLE pi_notification ADD COLUMN key_id varchar(100) NULL;
CREATE INDEX "index_notification_key_id" ON "pi_notification" ("key_id");
update pi_notification set key_id = id where key_id is null;
ALTER TABLE cd_addon ADD COLUMN key_id varchar(100) NULL;
CREATE INDEX "index_addon_key_id" ON "cd_addon" ("key_id");
update cd_addon set key_id = id where key_id is null;
@@ -262,6 +262,14 @@ export class PipelineController extends CrudController<PipelineService> {
return this.ok({}); return this.ok({});
} }
@Post('/batchTransfer', { summary: Constants.per.authOnly })
async batchTransfer(@Body('ids') ids: number[], @Body('toProjectId') toProjectId: number) {
await this.checkPermissionCall(async ({})=>{
await this.service.batchTransfer(ids, toProjectId);
})
return this.ok({});
}
@Post('/refreshWebhookKey', { summary: Constants.per.authOnly }) @Post('/refreshWebhookKey', { summary: Constants.per.authOnly })
async refreshWebhookKey(@Body('id') id: number) { async refreshWebhookKey(@Body('id') id: number) {
await this.checkOwner(this.getService(), id,"write",true); await this.checkOwner(this.getService(), id,"write",true);
@@ -5,6 +5,9 @@ export class NotificationEntity {
@PrimaryGeneratedColumn() @PrimaryGeneratedColumn()
id: number; id: number;
@Column({ name: 'key_id', comment: 'key_id', length: 100 })
keyId: string;
@Column({ name: 'user_id', comment: 'UserId' }) @Column({ name: 'user_id', comment: 'UserId' })
userId: number; userId: number;
@@ -39,6 +39,7 @@ export class NotificationService extends BaseService<NotificationEntity> {
} }
return { return {
id: entity.id, id: entity.id,
keyId: entity.keyId,
name: entity.name, name: entity.name,
userId: entity.userId, userId: entity.userId,
}; };
@@ -58,6 +59,7 @@ export class NotificationService extends BaseService<NotificationEntity> {
if(bean.isDefault){ if(bean.isDefault){
await this.setDefault(res.id, bean.userId); await this.setDefault(res.id, bean.userId);
} }
bean.keyId = "nt_" + utils.id.simpleNanoId();
return res return res
} }
@@ -68,6 +70,7 @@ export class NotificationService extends BaseService<NotificationEntity> {
delete bean.userId; delete bean.userId;
delete bean.type delete bean.type
delete bean.keyId
const res = await super.update(bean); const res = await super.update(bean);
if(bean.isDefault){ if(bean.isDefault){
await this.setDefault(bean.id, old.userId); await this.setDefault(bean.id, old.userId);
@@ -20,6 +20,7 @@ import {
ICnameProxyService, ICnameProxyService,
INotificationService, Notification, INotificationService, Notification,
Pipeline, Pipeline,
pluginRegistry,
ResultType, ResultType,
RunHistory, RunHistory,
RunnableCollection, RunnableCollection,
@@ -163,8 +164,8 @@ export class PipelineService extends BaseService<PipelineEntity> {
nextTimes.push(...ret); nextTimes.push(...ret);
} }
item.nextRunTime = nextTimes[0] item.nextRunTime = nextTimes[0]
} }
} }
delete item.content; delete item.content;
@@ -304,8 +305,8 @@ export class PipelineService extends BaseService<PipelineEntity> {
fromType = "auto"; fromType = "auto";
} }
const userId = bean.userId; const userId = bean.userId;
const projectId = bean.projectId ??null; const projectId = bean.projectId ?? null;
await this.certInfoService.updateDomains(pipeline.id, userId, projectId , domains, fromType); await this.certInfoService.updateDomains(pipeline.id, userId, projectId, domains, fromType);
return { return {
...bean, ...bean,
version: pipeline.version, version: pipeline.version,
@@ -344,12 +345,12 @@ export class PipelineService extends BaseService<PipelineEntity> {
// throw new NeedVIPException(`基础版最多只能创建${freeCount}条流水线`); // throw new NeedVIPException(`基础版最多只能创建${freeCount}条流水线`);
// } // }
// } // }
if(isEnterprise()){ if (isEnterprise()) {
//企业模式不限制 //企业模式不限制
checkPlus() checkPlus()
return; return;
} }
if (isComm()) { if (isComm()) {
//校验pipelineCount //校验pipelineCount
const suiteSetting = await this.userSuiteService.getSuiteSetting(); const suiteSetting = await this.userSuiteService.getSuiteSetting();
@@ -377,7 +378,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
} }
} }
} }
} }
async foreachPipeline(callback: (pipeline: PipelineEntity) => void) { async foreachPipeline(callback: (pipeline: PipelineEntity) => void) {
@@ -610,7 +611,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
async beforeCheck(entity: PipelineEntity) { async beforeCheck(entity: PipelineEntity) {
if(isEnterprise()){ if (isEnterprise()) {
checkPlus() checkPlus()
return {} return {}
} }
@@ -683,9 +684,9 @@ export class PipelineService extends BaseService<PipelineEntity> {
const projectId = entity.projectId; const projectId = entity.projectId;
let userIsAdmin = false let userIsAdmin = false
if (projectId && projectId>0) { if (projectId && projectId > 0) {
userIsAdmin = await this.projectService.isAdmin(projectId); userIsAdmin = await this.projectService.isAdmin(projectId);
}else if(userId>0){ } else if (userId > 0) {
userIsAdmin = await this.userService.isAdmin(userId); userIsAdmin = await this.userService.isAdmin(userId);
} }
const user: UserInfo = { const user: UserInfo = {
@@ -693,7 +694,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
role: userIsAdmin ? "admin" : "user" role: userIsAdmin ? "admin" : "user"
}; };
const historyId = await this.historyService.start(entity, triggerType); const historyId = await this.historyService.start(entity, triggerType);
const sysInfo: SysInfo = {}; const sysInfo: SysInfo = {};
if (isComm()) { if (isComm()) {
const siteInfo = await this.sysSettingsService.getSetting<SysSiteInfo>(SysSiteInfo); const siteInfo = await this.sysSettingsService.getSetting<SysSiteInfo>(SysSiteInfo);
@@ -802,7 +803,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
id: pipelineId, id: pipelineId,
}, },
}); });
if(!pipelineEntity){ if (!pipelineEntity) {
return null return null
} }
return pipelineEntity.projectId; return pipelineEntity.projectId;
@@ -837,7 +838,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
await this.historyLogService.addOrUpdate(logEntity); await this.historyLogService.addOrUpdate(logEntity);
} }
async count(param: { userId?: any,projectId?:number }) { async count(param: { userId?: any, projectId?: number }) {
const count = await this.repository.count({ const count = await this.repository.count({
where: { where: {
userId: param.userId, userId: param.userId,
@@ -848,7 +849,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
return count; return count;
} }
async statusCount(param: { userId?: any,projectId?:number } = {}) { async statusCount(param: { userId?: any, projectId?: number } = {}) {
const statusCount = await this.repository const statusCount = await this.repository
.createQueryBuilder() .createQueryBuilder()
.select("status") .select("status")
@@ -863,7 +864,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
return statusCount; return statusCount;
} }
async enableCount(param: { userId?: any,projectId?:number } = {}) { async enableCount(param: { userId?: any, projectId?: number } = {}) {
const statusCount = await this.repository const statusCount = await this.repository
.createQueryBuilder() .createQueryBuilder()
.select("disabled") .select("disabled")
@@ -885,7 +886,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
return result; return result;
} }
async latestExpiringList({ userId,projectId }: any) { async latestExpiringList({ userId, projectId }: any) {
let list = await this.repository.find({ let list = await this.repository.find({
select: { select: {
id: true, id: true,
@@ -927,7 +928,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
return result; return result;
} }
async batchDelete(ids: number[], userId?: number,projectId?:number) { async batchDelete(ids: number[], userId?: number, projectId?: number) {
if (!isPlus()) { if (!isPlus()) {
throw new NeedVIPException("此功能需要升级专业版"); throw new NeedVIPException("此功能需要升级专业版");
} }
@@ -935,14 +936,14 @@ export class PipelineService extends BaseService<PipelineEntity> {
if (userId && userId > 0) { if (userId && userId > 0) {
await this.checkUserId(id, userId); await this.checkUserId(id, userId);
} }
if(projectId){ if (projectId) {
await this.checkUserId(id,projectId,"projectId") await this.checkUserId(id, projectId, "projectId")
} }
await this.delete(id); await this.delete(id);
} }
} }
async batchUpdateGroup(ids: number[], groupId: number, userId: any,projectId?:number) { async batchUpdateGroup(ids: number[], groupId: number, userId: any, projectId?: number) {
if (!isPlus()) { if (!isPlus()) {
throw new NeedVIPException("此功能需要升级专业版"); throw new NeedVIPException("此功能需要升级专业版");
} }
@@ -950,7 +951,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
if (userId && userId > 0) { if (userId && userId > 0) {
query.userId = userId; query.userId = userId;
} }
if(projectId){ if (projectId) {
query.projectId = projectId; query.projectId = projectId;
} }
await this.repository.update( await this.repository.update(
@@ -963,7 +964,105 @@ export class PipelineService extends BaseService<PipelineEntity> {
} }
async batchUpdateTrigger(ids: number[], trigger: any, userId: any,projectId?:number) {
/**
* 批量转移到其他项目
*/
async batchTransfer(ids: number[], projectId: number) {
if (!isPlus()) {
throw new NeedVIPException("此功能需要升级专业版");
}
if (!isEnterprise()) {
throw new Error("当前为非企业模式,不允许转移到其他项目");
}
if (!projectId || projectId <= 0) {
throw new Error("projectId不能为空");
}
const userId = -1 // 强制为-1
async function eachSteps(pipeline, callback) {
for (const stage of pipeline.stages) {
for (const task of stage.tasks) {
for (const step of task.steps) {
await callback(step);
}
}
}
}
for (const id of ids) {
const pipelineEntity = await this.info(id);
if (!pipelineEntity) {
logger.error(`转移流水线失败,pipeline:${id}不存在`);
continue;
}
if (pipelineEntity.projectId === projectId) {
logger.info(`流水线:${id}已在项目${projectId}中,跳过`);
continue;
}
const entity: any = {
...pipelineEntity,
id: pipelineEntity.id,
userId: userId,
projectId: projectId,
groupId: null,
}
const pipeline = JSON.parse(pipelineEntity.content);
pipeline.userId = userId;
pipeline.projectId = projectId;
//转移和修改access 和 Notification
await eachSteps(pipeline, async (step) => {
const type = step.type;
//plugin
const pluginDefine: any = pluginRegistry.getDefine(type);
if (pluginDefine) {
for (const key in step.input) {
const value = step.input[key];
if (!value || value <= 0) {
continue;
}
if (!pluginDefine.input[key]){
continue;
}
const componentName = pluginDefine.input[key].component?.name;
if (componentName === "access-selector" || componentName === "AccessSelector") {
//这是一个授权ID属性,检查是否需要转移授权
const newAccessId = await this.accessService.copyTo(value,projectId);
step.input[key] = newAccessId;
}
}
}
})
pipeline.notifications = [
{
"type": "custom",
"when": [
"error",
"turnToSuccess"
],
"notificationId": 0,
"title": "使用默认通知",
"id": nanoid()
}
],
entity.content = JSON.stringify(pipeline);
await this.unregisterTriggers(entity.id);
await this.repository.save(entity);
await this.save(entity)
}
}
async batchUpdateTrigger(ids: number[], trigger: any, userId: any, projectId?: number) {
if (!isPlus()) { if (!isPlus()) {
throw new NeedVIPException("此功能需要升级专业版"); throw new NeedVIPException("此功能需要升级专业版");
} }
@@ -971,7 +1070,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
if (userId && userId > 0) { if (userId && userId > 0) {
query.userId = userId; query.userId = userId;
} }
if(projectId){ if (projectId) {
query.projectId = projectId; query.projectId = projectId;
} }
const list = await this.find({ const list = await this.find({
@@ -1015,7 +1114,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
} }
async batchUpdateNotifications(ids: number[], notification: Notification, userId: any,projectId?:number) { async batchUpdateNotifications(ids: number[], notification: Notification, userId: any, projectId?: number) {
if (!isPlus()) { if (!isPlus()) {
throw new NeedVIPException("此功能需要升级专业版"); throw new NeedVIPException("此功能需要升级专业版");
} }
@@ -1023,7 +1122,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
if (userId && userId > 0) { if (userId && userId > 0) {
query.userId = userId; query.userId = userId;
} }
if(projectId){ if (projectId) {
query.projectId = projectId; query.projectId = projectId;
} }
const list = await this.find({ const list = await this.find({
@@ -1053,7 +1152,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
} }
} }
async batchRerun(ids: number[], force: boolean,userId: any, projectId?:number) { async batchRerun(ids: number[], force: boolean, userId: any, projectId?: number) {
if (!isPlus()) { if (!isPlus()) {
throw new NeedVIPException("此功能需要升级专业版"); throw new NeedVIPException("此功能需要升级专业版");
} }
@@ -1061,18 +1160,18 @@ export class PipelineService extends BaseService<PipelineEntity> {
if (userId == null || ids.length === 0) { if (userId == null || ids.length === 0) {
return; return;
} }
const where:any = { const where: any = {
id: In(ids), id: In(ids),
userId, userId,
} }
if(projectId){ if (projectId) {
where.projectId = projectId where.projectId = projectId
} }
const list = await this.repository.find({ const list = await this.repository.find({
select: { select: {
id: true id: true
}, },
where:where where: where
}); });
ids = list.map(item => item.id); ids = list.map(item => item.id);
@@ -1100,7 +1199,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
return await this.repository.count({ where: { userId } }); return await this.repository.count({ where: { userId } });
} }
async getSimplePipelines(pipelineIds: number[], userId?: number,projectId?:number) { async getSimplePipelines(pipelineIds: number[], userId?: number, projectId?: number) {
return await this.repository.find({ return await this.repository.find({
select: { select: {
id: true, id: true,
@@ -1116,9 +1215,9 @@ export class PipelineService extends BaseService<PipelineEntity> {
private async checkUserStatus(userId: number) { private async checkUserStatus(userId: number) {
if(isEnterprise()){ if (isEnterprise()) {
//企业模式不检查用户状态,都允许运行流水线 //企业模式不检查用户状态,都允许运行流水线
return return
} }
const userEntity = await this.userService.info(userId); const userEntity = await this.userService.info(userId);
if (userEntity == null) { if (userEntity == null) {
@@ -1141,7 +1240,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
} }
} }
async createAutoPipeline(req: { domains: string[]; email: string; userId: number,projectId?:number, from: string }) { async createAutoPipeline(req: { domains: string[]; email: string; userId: number, projectId?: number, from: string }) {
const randomHour = Math.floor(Math.random() * 6); const randomHour = Math.floor(Math.random() * 6);
const randomMin = Math.floor(Math.random() * 60); const randomMin = Math.floor(Math.random() * 60);