mirror of https://github.com/certd/certd
chore:
parent
6aa487269c
commit
2aefca3813
|
@ -11,6 +11,10 @@ import { ICnameProxyService, IEmailService, IPluginConfigService, IUrlService }
|
||||||
import { FileStore } from "./file-store.js";
|
import { FileStore } from "./file-store.js";
|
||||||
import { cloneDeep, forEach, merge } from "lodash-es";
|
import { cloneDeep, forEach, merge } from "lodash-es";
|
||||||
import { INotificationService, NotificationBody, NotificationContext, notificationRegistry } from "../notification/index.js";
|
import { INotificationService, NotificationBody, NotificationContext, notificationRegistry } from "../notification/index.js";
|
||||||
|
export type SysInfo = {
|
||||||
|
//系统标题
|
||||||
|
title?: string;
|
||||||
|
};
|
||||||
|
|
||||||
export type ExecutorOptions = {
|
export type ExecutorOptions = {
|
||||||
pipeline: Pipeline;
|
pipeline: Pipeline;
|
||||||
|
@ -25,6 +29,7 @@ export type ExecutorOptions = {
|
||||||
fileRootDir?: string;
|
fileRootDir?: string;
|
||||||
user: UserInfo;
|
user: UserInfo;
|
||||||
baseURL?: string;
|
baseURL?: string;
|
||||||
|
sysInfo?: SysInfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
export class Executor {
|
export class Executor {
|
||||||
|
@ -368,17 +373,18 @@ export class Executor {
|
||||||
let subject = "";
|
let subject = "";
|
||||||
let content = "";
|
let content = "";
|
||||||
const errorMessage = error?.message;
|
const errorMessage = error?.message;
|
||||||
|
const sysTitle = this.options.sysInfo?.title || "Certd";
|
||||||
if (when === "start") {
|
if (when === "start") {
|
||||||
subject = `【Certd】开始执行,${this.pipeline.title}【${this.pipeline.id}】`;
|
subject = `【${sysTitle}】开始执行,${this.pipeline.title}【${this.pipeline.id}】`;
|
||||||
content = `流水线ID:${this.pipeline.id},运行ID:${this.runtime.id}`;
|
content = `流水线ID:${this.pipeline.id},运行ID:${this.runtime.id}`;
|
||||||
} else if (when === "success") {
|
} else if (when === "success") {
|
||||||
subject = `【Certd】执行成功,${this.pipeline.title}【${this.pipeline.id}】`;
|
subject = `【${sysTitle}】执行成功,${this.pipeline.title}【${this.pipeline.id}】`;
|
||||||
content = `流水线ID:${this.pipeline.id},运行ID:${this.runtime.id}`;
|
content = `流水线ID:${this.pipeline.id},运行ID:${this.runtime.id}`;
|
||||||
} else if (when === "turnToSuccess") {
|
} else if (when === "turnToSuccess") {
|
||||||
subject = `【Certd】执行成功(失败转成功),${this.pipeline.title}【${this.pipeline.id}】`;
|
subject = `【${sysTitle}】执行成功(失败转成功),${this.pipeline.title}【${this.pipeline.id}】`;
|
||||||
content = `流水线ID:${this.pipeline.id},运行ID:${this.runtime.id}`;
|
content = `流水线ID:${this.pipeline.id},运行ID:${this.runtime.id}`;
|
||||||
} else if (when === "error") {
|
} else if (when === "error") {
|
||||||
subject = `【Certd】执行失败,${this.pipeline.title}【${this.pipeline.id}】`;
|
subject = `【${sysTitle}】执行失败,${this.pipeline.title}【${this.pipeline.id}】`;
|
||||||
content = `流水线ID:${this.pipeline.id},运行ID:${this.runtime.id}\n错误详情:${error.message}`;
|
content = `流水线ID:${this.pipeline.id},运行ID:${this.runtime.id}\n错误详情:${error.message}`;
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { request } from "/src/api/service";
|
import { request } from "/src/api/service";
|
||||||
|
|
||||||
export function createApi() {
|
export function createNotificationApi() {
|
||||||
const apiPrefix = "/pi/notification";
|
const apiPrefix = "/pi/notification";
|
||||||
return {
|
return {
|
||||||
async GetList(query: any) {
|
async GetList(query: any) {
|
||||||
|
@ -94,6 +94,13 @@ export function createApi() {
|
||||||
method: "post",
|
method: "post",
|
||||||
params: { type }
|
params: { type }
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
async GetOrCreateDefault(param: { email: any }) {
|
||||||
|
return await request({
|
||||||
|
url: apiPrefix + "/getOrCreateDefault",
|
||||||
|
method: "post",
|
||||||
|
data: param
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
import { getCommonColumnDefine } from "./common";
|
import { getCommonColumnDefine } from "./common";
|
||||||
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
||||||
import { createApi } from "/@/views/certd/notification/api";
|
import { createNotificationApi } from "/@/views/certd/notification/api";
|
||||||
const api = createApi();
|
const api = createNotificationApi();
|
||||||
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||||
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
|
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
|
||||||
return await api.GetList(query);
|
return await api.GetList(query);
|
||||||
|
|
|
@ -14,12 +14,12 @@
|
||||||
import { defineComponent, onActivated, onMounted } from "vue";
|
import { defineComponent, onActivated, onMounted } from "vue";
|
||||||
import { useFs } from "@fast-crud/fast-crud";
|
import { useFs } from "@fast-crud/fast-crud";
|
||||||
import createCrudOptions from "./crud";
|
import createCrudOptions from "./crud";
|
||||||
import { createApi } from "./api";
|
import { createNotificationApi } from "./api";
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: "NotificationManager",
|
name: "NotificationManager",
|
||||||
setup() {
|
setup() {
|
||||||
const api = createApi();
|
const api = createNotificationApi();
|
||||||
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: { api } });
|
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: { api } });
|
||||||
|
|
||||||
// 页面打开后获取列表数据
|
// 页面打开后获取列表数据
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
|
|
||||||
<script lang="tsx" setup>
|
<script lang="tsx" setup>
|
||||||
import { inject, ref, Ref, watch } from "vue";
|
import { inject, ref, Ref, watch } from "vue";
|
||||||
import { createApi } from "../api";
|
import { createNotificationApi } from "../api";
|
||||||
import { message } from "ant-design-vue";
|
import { message } from "ant-design-vue";
|
||||||
import { dict } from "@fast-crud/fast-crud";
|
import { dict } from "@fast-crud/fast-crud";
|
||||||
import createCrudOptions from "../crud";
|
import createCrudOptions from "../crud";
|
||||||
|
@ -64,7 +64,7 @@ const onChange = async (value: number) => {
|
||||||
|
|
||||||
const emit = defineEmits(["update:modelValue", "selectedChange", "change"]);
|
const emit = defineEmits(["update:modelValue", "selectedChange", "change"]);
|
||||||
|
|
||||||
const api = createApi();
|
const api = createNotificationApi();
|
||||||
|
|
||||||
// const types = ref({});
|
// const types = ref({});
|
||||||
// async function loadNotificationTypes() {
|
// async function loadNotificationTypes() {
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
import { defineComponent, onMounted, watch } from "vue";
|
import { defineComponent, onMounted, watch } from "vue";
|
||||||
import { useFs } from "@fast-crud/fast-crud";
|
import { useFs } from "@fast-crud/fast-crud";
|
||||||
import createCrudOptions from "./crud";
|
import createCrudOptions from "./crud";
|
||||||
import { createApi } from "../../api";
|
import { createNotificationApi } from "../../api";
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: "CertNotificationModal",
|
name: "CertNotificationModal",
|
||||||
|
@ -17,7 +17,7 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
emits: ["update:modelValue"],
|
emits: ["update:modelValue"],
|
||||||
setup(props, ctx) {
|
setup(props, ctx) {
|
||||||
const api = createApi();
|
const api = createNotificationApi();
|
||||||
const context: any = { props, ctx, api };
|
const context: any = { props, ctx, api };
|
||||||
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context });
|
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context });
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
|
|
@ -1,16 +1,15 @@
|
||||||
import { compute, CreateCrudOptionsRet, dict } from "@fast-crud/fast-crud";
|
import { compute, CreateCrudOptionsRet, dict } from "@fast-crud/fast-crud";
|
||||||
import { PluginGroup } from "@certd/pipeline";
|
|
||||||
import { useReference } from "/@/use/use-refrence";
|
import { useReference } from "/@/use/use-refrence";
|
||||||
import _, { merge } from "lodash-es";
|
import _, { merge } from "lodash-es";
|
||||||
import { useUserStore } from "/@/store/modules/user";
|
import { useUserStore } from "/@/store/modules/user";
|
||||||
import { useSettingStore } from "/@/store/modules/settings";
|
import { useSettingStore } from "/@/store/modules/settings";
|
||||||
import * as api from "../api.plugin";
|
import * as api from "../api.plugin";
|
||||||
import NotificationSelector from "/@/views/certd/notification/notification-selector/index.vue";
|
|
||||||
export default function (certPluginGroup: PluginGroup, formWrapperRef: any): CreateCrudOptionsRet {
|
export default function (certPlugins: any[], formWrapperRef: any): CreateCrudOptionsRet {
|
||||||
const inputs: any = {};
|
const inputs: any = {};
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
const settingStore = useSettingStore();
|
const settingStore = useSettingStore();
|
||||||
for (const plugin of certPluginGroup.plugins) {
|
for (const plugin of certPlugins) {
|
||||||
for (const inputKey in plugin.input) {
|
for (const inputKey in plugin.input) {
|
||||||
if (inputs[inputKey]) {
|
if (inputs[inputKey]) {
|
||||||
inputs[inputKey].form.show = true;
|
inputs[inputKey].form.show = true;
|
||||||
|
|
|
@ -9,6 +9,8 @@ import { ref } from "vue";
|
||||||
import * as _ from "lodash-es";
|
import * as _ from "lodash-es";
|
||||||
import * as api from "../api.plugin";
|
import * as api from "../api.plugin";
|
||||||
import { PluginGroup, PluginGroups } from "/@/views/certd/pipeline/pipeline/type";
|
import { PluginGroup, PluginGroups } from "/@/views/certd/pipeline/pipeline/type";
|
||||||
|
import { GetPluginDefine } from "../api.plugin";
|
||||||
|
import { createNotificationApi } from "/@/views/certd/notification/api";
|
||||||
export default {
|
export default {
|
||||||
name: "PiCertdForm",
|
name: "PiCertdForm",
|
||||||
setup(props: any, ctx: any) {
|
setup(props: any, ctx: any) {
|
||||||
|
@ -19,17 +21,28 @@ export default {
|
||||||
const pluginGroups: { [key: string]: PluginGroup } = await api.GetGroups({});
|
const pluginGroups: { [key: string]: PluginGroup } = await api.GetGroups({});
|
||||||
const certPluginGroup = pluginGroups.cert;
|
const certPluginGroup = pluginGroups.cert;
|
||||||
|
|
||||||
|
const certPlugins = [];
|
||||||
|
for (const plugin of certPluginGroup.plugins) {
|
||||||
|
const detail: any = await api.GetPluginDefine(plugin.name);
|
||||||
|
certPlugins.push(detail);
|
||||||
|
}
|
||||||
|
|
||||||
// 自定义表单配置
|
// 自定义表单配置
|
||||||
const { buildFormOptions } = useColumns();
|
const { buildFormOptions } = useColumns();
|
||||||
//使用crudOptions结构来构建自定义表单配置
|
//使用crudOptions结构来构建自定义表单配置
|
||||||
let { crudOptions } = createCrudOptions(certPluginGroup, formWrapperRef);
|
let { crudOptions } = createCrudOptions(certPlugins, formWrapperRef);
|
||||||
|
|
||||||
const formOptions = buildFormOptions(
|
const formOptions = buildFormOptions(
|
||||||
_.merge(crudOptions, {
|
_.merge(crudOptions, {
|
||||||
form: {
|
form: {
|
||||||
doSubmit({ form }: any) {
|
async doSubmit({ form }: any) {
|
||||||
// 创建certd 的pipeline
|
// 创建certd 的pipeline
|
||||||
doSubmitRef.value({ form });
|
await doSubmitRef.value({ form });
|
||||||
|
|
||||||
|
if (form.email) {
|
||||||
|
const notificationApi = createNotificationApi();
|
||||||
|
await notificationApi.GetOrCreateDefault({ email: form.email });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}) as any
|
}) as any
|
||||||
|
|
|
@ -14,7 +14,7 @@ import * as _ from "lodash-es";
|
||||||
import { useModal } from "/@/use/use-modal";
|
import { useModal } from "/@/use/use-modal";
|
||||||
import CertView from "./cert-view.vue";
|
import CertView from "./cert-view.vue";
|
||||||
import { eachStages } from "./utils";
|
import { eachStages } from "./utils";
|
||||||
import { createApi as createNotificationApi } from "../notification/api";
|
import { createNotificationApi as createNotificationApi } from "../notification/api";
|
||||||
export default function ({ crudExpose, context: { certdFormRef, groupDictRef, selectedRowKeys } }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
export default function ({ crudExpose, context: { certdFormRef, groupDictRef, selectedRowKeys } }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
@ -173,9 +173,9 @@ export default function ({ crudExpose, context: { certdFormRef, groupDictRef, se
|
||||||
const downloadCert = async (row: any) => {
|
const downloadCert = async (row: any) => {
|
||||||
const files = await api.GetFiles(row.id);
|
const files = await api.GetFiles(row.id);
|
||||||
model.success({
|
model.success({
|
||||||
title: "文件下载",
|
title: "点击链接下载",
|
||||||
maskClosable: true,
|
maskClosable: true,
|
||||||
okText: "↑↑↑ 点击上面链接下载",
|
okText: "关闭",
|
||||||
content: () => {
|
content: () => {
|
||||||
const children = [];
|
const children = [];
|
||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
|
@ -191,7 +191,16 @@ export default function ({ crudExpose, context: { certdFormRef, groupDictRef, se
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return <div class={"mt-3"}>{children}</div>;
|
if (children.length === 0) {
|
||||||
|
return <div>暂无文件下载</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div class={"mt-3"}>
|
||||||
|
<h3>点击链接下载</h3>
|
||||||
|
<div> {children}</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -141,6 +141,12 @@ export class NotificationController extends CrudController<NotificationService>
|
||||||
return this.ok(res);
|
return this.ok(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Post('/getOrCreateDefault', { summary: Constants.per.authOnly })
|
||||||
|
async getOrCreateDefault(@Body('email') email: string) {
|
||||||
|
const res = await this.service.getOrCreateDefault(email, this.getUserId());
|
||||||
|
return this.ok(res);
|
||||||
|
}
|
||||||
|
|
||||||
@Post('/options', { summary: Constants.per.authOnly })
|
@Post('/options', { summary: Constants.per.authOnly })
|
||||||
async options() {
|
async options() {
|
||||||
const res = await this.service.list({
|
const res = await this.service.list({
|
||||||
|
|
|
@ -106,4 +106,22 @@ export class NotificationService extends BaseService<NotificationEntity> {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getOrCreateDefault(email: string, userId: any) {
|
||||||
|
const defaultConfig = await this.getDefault(userId);
|
||||||
|
if (defaultConfig) {
|
||||||
|
return defaultConfig;
|
||||||
|
}
|
||||||
|
const setting = {
|
||||||
|
receivers: [email],
|
||||||
|
};
|
||||||
|
const res = await this.repository.save({
|
||||||
|
userId,
|
||||||
|
type: 'email',
|
||||||
|
name: '邮件通知',
|
||||||
|
setting: JSON.stringify(setting),
|
||||||
|
isDefault: true,
|
||||||
|
});
|
||||||
|
return this.buildNotificationInstanceConfig(res);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { Config, Inject, Provide, Scope, ScopeEnum, sleep } from '@midwayjs/core';
|
import { Config, Inject, Provide, Scope, ScopeEnum, sleep } from '@midwayjs/core';
|
||||||
import { InjectEntityModel } from '@midwayjs/typeorm';
|
import { InjectEntityModel } from '@midwayjs/typeorm';
|
||||||
import { In, MoreThan, Repository } from 'typeorm';
|
import { In, MoreThan, Repository } from 'typeorm';
|
||||||
import { BaseService, NeedVIPException, PageReq, SysPublicSettings, SysSettingsService } from '@certd/lib-server';
|
import { BaseService, NeedVIPException, PageReq, SysPublicSettings, SysSettingsService, SysSiteInfo } from '@certd/lib-server';
|
||||||
import { PipelineEntity } from '../entity/pipeline.js';
|
import { PipelineEntity } from '../entity/pipeline.js';
|
||||||
import { PipelineDetail } from '../entity/vo/pipeline-detail.js';
|
import { PipelineDetail } from '../entity/vo/pipeline-detail.js';
|
||||||
import { Executor, Pipeline, ResultType, RunHistory, UserInfo } from '@certd/pipeline';
|
import { Executor, Pipeline, ResultType, RunHistory, SysInfo, UserInfo } from '@certd/pipeline';
|
||||||
import { AccessService } from './access-service.js';
|
import { AccessService } from './access-service.js';
|
||||||
import { DbStorage } from './db-storage.js';
|
import { DbStorage } from './db-storage.js';
|
||||||
import { StorageService } from './storage-service.js';
|
import { StorageService } from './storage-service.js';
|
||||||
|
@ -21,7 +21,7 @@ import { CnameProxyService } from './cname-proxy-service.js';
|
||||||
import { PluginConfigGetter } from '../../plugin/service/plugin-config-getter.js';
|
import { PluginConfigGetter } from '../../plugin/service/plugin-config-getter.js';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import { DbAdapter } from '../../db/index.js';
|
import { DbAdapter } from '../../db/index.js';
|
||||||
import { isPlus } from '@certd/plus-core';
|
import { isComm, isPlus } from '@certd/plus-core';
|
||||||
import { logger } from '@certd/basic';
|
import { logger } from '@certd/basic';
|
||||||
import { UrlService } from './url-service.js';
|
import { UrlService } from './url-service.js';
|
||||||
import { NotificationService } from './notification-service.js';
|
import { NotificationService } from './notification-service.js';
|
||||||
|
@ -391,9 +391,15 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||||
id: userId,
|
id: userId,
|
||||||
role: userIsAdmin ? 'admin' : 'user',
|
role: userIsAdmin ? 'admin' : 'user',
|
||||||
};
|
};
|
||||||
|
|
||||||
const accessGetter = new AccessGetter(userId, this.accessService.getById.bind(this.accessService));
|
const accessGetter = new AccessGetter(userId, this.accessService.getById.bind(this.accessService));
|
||||||
const cnameProxyService = new CnameProxyService(userId, this.cnameRecordService.getWithAccessByDomain.bind(this.cnameRecordService));
|
const cnameProxyService = new CnameProxyService(userId, this.cnameRecordService.getWithAccessByDomain.bind(this.cnameRecordService));
|
||||||
const notificationGetter = new NotificationGetter(userId, this.notificationService);
|
const notificationGetter = new NotificationGetter(userId, this.notificationService);
|
||||||
|
const sysInfo: SysInfo = {};
|
||||||
|
if (isComm()) {
|
||||||
|
const siteInfo = await this.sysSettingsService.getSetting<SysSiteInfo>(SysSiteInfo);
|
||||||
|
sysInfo.title = siteInfo.title;
|
||||||
|
}
|
||||||
const executor = new Executor({
|
const executor = new Executor({
|
||||||
user,
|
user,
|
||||||
pipeline,
|
pipeline,
|
||||||
|
@ -406,6 +412,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||||
urlService: this.urlService,
|
urlService: this.urlService,
|
||||||
notificationService: notificationGetter,
|
notificationService: notificationGetter,
|
||||||
fileRootDir: this.certdConfig.fileRootDir,
|
fileRootDir: this.certdConfig.fileRootDir,
|
||||||
|
sysInfo,
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
runningTasks.set(historyId, executor);
|
runningTasks.set(historyId, executor);
|
||||||
|
|
Loading…
Reference in New Issue