perf: 批量设置定时,支持清除定时

This commit is contained in:
xiaojunnuo
2025-12-16 00:21:31 +08:00
parent e4e16bc6a6
commit 63d8bcf882
5 changed files with 72 additions and 27 deletions
@@ -3,10 +3,11 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { useFormWrapper } from "@fast-crud/fast-crud"; import { compute, dict, useFormWrapper } from "@fast-crud/fast-crud";
import * as api from "../api"; import * as api from "../api";
import { useSettingStore } from "/@/store/settings"; import { useSettingStore } from "/@/store/settings";
import { useI18n } from "/src/locales"; import { useI18n } from "/src/locales";
import { computed } from "vue";
const { t } = useI18n(); const { t } = useI18n();
const props = defineProps<{ const props = defineProps<{
@@ -20,7 +21,7 @@ async function batchUpdateRequest(form: any) {
await api.BatchUpdateTrigger(props.selectedRowKeys, { await api.BatchUpdateTrigger(props.selectedRowKeys, {
title: "定时触发", title: "定时触发",
type: "timer", type: "timer",
props: form.props, props: form.clear ? false : form.props,
}); });
emit("change"); emit("change");
} }
@@ -33,6 +34,28 @@ async function openFormDialog() {
settingStore.checkPlus(); settingStore.checkPlus();
const crudOptions: any = { const crudOptions: any = {
columns: { columns: {
clear: {
title: "设置/清空",
form: {
value: false,
component: {
name: "fs-dict-switch",
vModel: "checked",
dict: dict({
data: [
{
label: "设置定时",
value: false,
},
{
label: "清空定时",
value: true,
},
],
}),
},
},
},
"props.cron": { "props.cron": {
title: t("certd.schedule"), title: t("certd.schedule"),
form: { form: {
@@ -40,12 +63,18 @@ async function openFormDialog() {
name: "cron-editor", name: "cron-editor",
vModel: "modelValue", vModel: "modelValue",
}, },
show: compute(({ form }) => {
return form.clear !== true;
}),
rules: [{ required: true, message: t("certd.selectCron") }], rules: [{ required: true, message: t("certd.selectCron") }],
}, },
}, },
}, },
form: { form: {
mode: "edit", mode: "edit",
initialForm: {
clear: false,
},
//@ts-ignore //@ts-ignore
async doSubmit({ form }) { async doSubmit({ form }) {
await batchUpdateRequest(form); await batchUpdateRequest(form);
@@ -121,6 +121,7 @@ export class EmailService implements IEmailService {
data: { data: {
title: '测试邮件,from certd', title: '测试邮件,from certd',
content: '测试邮件,from certd', content: '测试邮件,from certd',
url:"https://certd.handfree.work",
}, },
email: { email: {
receivers: [receiver], receivers: [receiver],
@@ -128,7 +128,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
} }
const pipeline = JSON.parse(item.content); const pipeline = JSON.parse(item.content);
let stepCount = 0; let stepCount = 0;
if(pipeline.stages){ if (pipeline.stages) {
RunnableCollection.each(pipeline.stages, (runnable: any) => { RunnableCollection.each(pipeline.stages, (runnable: any) => {
stepCount++; stepCount++;
}); });
@@ -237,7 +237,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
let fromType = "pipeline"; let fromType = "pipeline";
if (bean.type === "cert_upload") { if (bean.type === "cert_upload") {
fromType = "upload"; fromType = "upload";
}else if (bean.type === "cert_auto") { } else if (bean.type === "cert_auto") {
fromType = "auto"; fromType = "auto";
} }
await this.certInfoService.updateDomains(pipeline.id, pipeline.userId || bean.userId, domains, fromType); await this.certInfoService.updateDomains(pipeline.id, pipeline.userId || bean.userId, domains, fromType);
@@ -376,17 +376,17 @@ export class PipelineService extends BaseService<PipelineEntity> {
} }
if (immediateTriggerOnce) { if (immediateTriggerOnce) {
try{ try {
await this.trigger(pipeline.id); await this.trigger(pipeline.id);
await sleep(200); await sleep(200);
}catch(e){ } catch (e) {
logger.error(e); logger.error(e);
} }
} }
} }
async trigger(id: any, stepId?: string , doCheck = false) { async trigger(id: any, stepId?: string, doCheck = false) {
const entity: PipelineEntity = await this.info(id); const entity: PipelineEntity = await this.info(id);
if (doCheck) { if (doCheck) {
await this.beforeCheck(entity); await this.beforeCheck(entity);
@@ -500,8 +500,8 @@ export class PipelineService extends BaseService<PipelineEntity> {
async isPipelineValidTimeEnabled(entity: PipelineEntity) { async isPipelineValidTimeEnabled(entity: PipelineEntity) {
const settings = await this.sysSettingsService.getPublicSettings(); const settings = await this.sysSettingsService.getPublicSettings();
if (isPlus() && settings.pipelineValidTimeEnabled){ if (isPlus() && settings.pipelineValidTimeEnabled) {
if (entity.validTime > 0 && entity.validTime < Date.now()){ if (entity.validTime > 0 && entity.validTime < Date.now()) {
return false return false
} }
} }
@@ -524,7 +524,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
if (!validTimeEnabled) { if (!validTimeEnabled) {
throw new Error(`流水线${entity.id}已过期,不予执行`); throw new Error(`流水线${entity.id}已过期,不予执行`);
} }
let suite: UserSuiteEntity = null; let suite: UserSuiteEntity = null;
if (isComm()) { if (isComm()) {
suite = await this.checkHasDeployCount(entity.id, entity.userId); suite = await this.checkHasDeployCount(entity.id, entity.userId);
@@ -538,8 +538,8 @@ export class PipelineService extends BaseService<PipelineEntity> {
async doRun(entity: PipelineEntity, triggerId: string, stepId?: string) { async doRun(entity: PipelineEntity, triggerId: string, stepId?: string) {
let suite:any = null let suite: any = null
try{ try {
const res = await this.beforeCheck(entity); const res = await this.beforeCheck(entity);
suite = res.suite suite = res.suite
} catch (e) { } catch (e) {
@@ -803,11 +803,17 @@ export class PipelineService extends BaseService<PipelineEntity> {
for (const item of list) { for (const item of list) {
const pipeline = JSON.parse(item.content); const pipeline = JSON.parse(item.content);
pipeline.triggers = [{ if (trigger.props === false) {
id: nanoid(), //清除trigger
title: "定时触发", pipeline.triggers = []
...trigger } else {
}]; pipeline.triggers = [{
id: nanoid(),
title: "定时触发",
...trigger
}];
}
await this.doUpdatePipelineJson(item, pipeline); await this.doUpdatePipelineJson(item, pipeline);
} }
@@ -919,20 +925,20 @@ export class PipelineService extends BaseService<PipelineEntity> {
} }
} }
async createAutoPipeline(req: { domains: string[]; email: string; userId: number ,from:string}) { async createAutoPipeline(req: { domains: string[]; email: string; userId: 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);
const randomCron = `0 ${randomMin} ${randomHour} * * *`; const randomCron = `0 ${randomMin} ${randomHour} * * *`;
let pipeline: any = { let pipeline: any = {
title: req.domains[0] + `证书自动申请【${req.from??"OpenAPI"}`, title: req.domains[0] + `证书自动申请【${req.from ?? "OpenAPI"}`,
runnableType: "pipeline", runnableType: "pipeline",
triggers: [ triggers: [
{ {
id: nanoid(), id: nanoid(),
title: "定时触发", title: "定时触发",
props:{ props: {
cron: randomCron, cron: randomCron,
}, },
type: "timer" type: "timer"
@@ -25,13 +25,16 @@ export class EmailNotification extends BaseNotification {
const templateData = { const templateData = {
...body, ...body,
} }
const emailSend:any = {
receivers: this.receivers,
}
if (body.attachments && body.attachments.length > 0) {
emailSend.attachments = body.attachments;
}
await this.ctx.emailService.sendByTemplate({ await this.ctx.emailService.sendByTemplate({
type: body.notificationType, type: body.notificationType,
data: templateData, data: templateData,
email: { email: emailSend
receivers: this.receivers,
attachments: body.attachments,
}
}) })
// await this.ctx.emailService.send({ // await this.ctx.emailService.send({
@@ -61,8 +61,14 @@ export class BaseEmailTemplateProvider extends BaseAddon implements ITemplatePro
async buildContent(params: BuildContentReq): Promise<EmailContent> { async buildContent(params: BuildContentReq): Promise<EmailContent> {
const title = this.compile(this.titleTemplate)(params.data) const data = {
const content = this.compile(this.contentTemplate)(params.data) title:"",
content:"",
url:"",
...params.data,
}
const title = this.compile(this.titleTemplate)(data)
const content = this.compile(this.contentTemplate)(data)
const body: any = { const body: any = {
subject: title, subject: title,