mirror of https://github.com/certd/certd
perf: 通知选择器优化
parent
68a503796c
commit
2c0cbdd29e
|
@ -98,10 +98,22 @@ export function createAxiosService({ logger }: { logger: Logger }) {
|
||||||
config.timeout = 15000;
|
config.timeout = 15000;
|
||||||
}
|
}
|
||||||
let agents = defaultAgents;
|
let agents = defaultAgents;
|
||||||
if (config.skipSslVerify) {
|
if (config.skipSslVerify || config.httpProxy) {
|
||||||
logger.info('跳过SSL验证');
|
let rejectUnauthorized = true;
|
||||||
agents = createAgent({ rejectUnauthorized: false } as any);
|
if (config.skipSslVerify) {
|
||||||
|
logger.info('跳过SSL验证');
|
||||||
|
rejectUnauthorized = false;
|
||||||
|
}
|
||||||
|
const proxy: any = {};
|
||||||
|
if (config.httpProxy) {
|
||||||
|
logger.info('使用自定义http代理:', config.httpProxy);
|
||||||
|
proxy.httpProxy = config.httpProxy;
|
||||||
|
proxy.httpsProxy = config.httpProxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
agents = createAgent({ rejectUnauthorized, ...proxy } as any);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete config.skipSslVerify;
|
delete config.skipSslVerify;
|
||||||
config.httpsAgent = agents.httpsAgent;
|
config.httpsAgent = agents.httpsAgent;
|
||||||
config.httpAgent = agents.httpAgent;
|
config.httpAgent = agents.httpAgent;
|
||||||
|
@ -200,6 +212,7 @@ export type HttpRequestConfig<D = any> = {
|
||||||
skipCheckRes?: boolean;
|
skipCheckRes?: boolean;
|
||||||
logParams?: boolean;
|
logParams?: boolean;
|
||||||
logRes?: boolean;
|
logRes?: boolean;
|
||||||
|
httpProxy?: string;
|
||||||
} & AxiosRequestConfig<D>;
|
} & AxiosRequestConfig<D>;
|
||||||
export type HttpClient = {
|
export type HttpClient = {
|
||||||
request<D = any, R = any>(config: HttpRequestConfig<D>): Promise<HttpClientResponse<R>>;
|
request<D = any, R = any>(config: HttpRequestConfig<D>): Promise<HttpClientResponse<R>>;
|
||||||
|
|
|
@ -388,6 +388,7 @@ export class Executor {
|
||||||
if (!notification.when.includes(when)) {
|
if (!notification.when.includes(when)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (notification.type === "email") {
|
if (notification.type === "email") {
|
||||||
try {
|
try {
|
||||||
await this.options.emailService?.send({
|
await this.options.emailService?.send({
|
||||||
|
@ -401,7 +402,16 @@ export class Executor {
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
//构建notification插件,发送通知
|
//构建notification插件,发送通知
|
||||||
const notifyConfig = await this.options.notificationService.getById(notification.notificationId);
|
let notifyConfig: any;
|
||||||
|
if (notification.notificationId === 0) {
|
||||||
|
notifyConfig = await this.options.notificationService.getDefault();
|
||||||
|
} else {
|
||||||
|
notifyConfig = await this.options.notificationService.getById(notification.notificationId);
|
||||||
|
}
|
||||||
|
if (notifyConfig == null) {
|
||||||
|
throw new Error(`通知配置<id:${notification.notificationId}>不存在`);
|
||||||
|
}
|
||||||
|
|
||||||
const notificationPlugin = notificationRegistry.get(notifyConfig.type);
|
const notificationPlugin = notificationRegistry.get(notifyConfig.type);
|
||||||
const notificationCls: any = notificationPlugin.target;
|
const notificationCls: any = notificationPlugin.target;
|
||||||
const notificationSender = new notificationCls();
|
const notificationSender = new notificationCls();
|
||||||
|
|
|
@ -77,6 +77,9 @@ h1, h2, h3, h4, h5, h6 {
|
||||||
.flex-1 {
|
.flex-1 {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
.flex-0 {
|
||||||
|
flex: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.flex-col {
|
.flex-col {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
|
@ -43,6 +43,13 @@ export function createApi() {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async GetOptions(id: number) {
|
||||||
|
return await request({
|
||||||
|
url: apiPrefix + "/options",
|
||||||
|
method: "post"
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
async SetDefault(id: number) {
|
async SetDefault(id: number) {
|
||||||
return await request({
|
return await request({
|
||||||
url: apiPrefix + "/setDefault",
|
url: apiPrefix + "/setDefault",
|
||||||
|
@ -66,6 +73,13 @@ export function createApi() {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async GetDefineTypes() {
|
||||||
|
return await request({
|
||||||
|
url: apiPrefix + "/getTypeDict",
|
||||||
|
method: "post"
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
async GetProviderDefine(type: string) {
|
async GetProviderDefine(type: string) {
|
||||||
return await request({
|
return await request({
|
||||||
url: apiPrefix + "/define",
|
url: apiPrefix + "/define",
|
||||||
|
|
|
@ -1,12 +1,9 @@
|
||||||
// @ts-ignore
|
|
||||||
import { useI18n } from "vue-i18n";
|
|
||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
import { getCommonColumnDefine } from "./common";
|
import { getCommonColumnDefine } from "./common";
|
||||||
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, 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";
|
||||||
|
const api = createApi();
|
||||||
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||||
const { t } = useI18n();
|
|
||||||
const api = context.api;
|
|
||||||
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
|
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
|
||||||
return await api.GetList(query);
|
return await api.GetList(query);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,162 +1,156 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="notification-selector">
|
<div class="notification-selector">
|
||||||
<span v-if="target?.name" class="mr-5 cd-flex-inline">
|
<div class="flex-o w-100">
|
||||||
<a-tag class="mr-5" color="green">{{ target.name }}</a-tag>
|
<fs-dict-select
|
||||||
<fs-icon class="cd-icon-button" icon="ion:close-circle-outline" @click="clear"></fs-icon>
|
class="flex-1"
|
||||||
</span>
|
:value="modelValue"
|
||||||
<span v-else class="mlr-5 text-gray">{{ placeholder }}</span>
|
:dict="optionsDictRef"
|
||||||
<a-button class="ml-5" :disabled="disabled" :size="size" @click="chooseForm.open">选择</a-button>
|
:disabled="disabled"
|
||||||
<a-form-item-rest v-if="chooseForm.show">
|
:render-label="renderLabel"
|
||||||
<a-modal v-model:open="chooseForm.show" title="选择通知渠道" width="905px" @ok="chooseForm.ok">
|
:slots="selectSlots"
|
||||||
<div style="height: 400px; position: relative">
|
:allow-clear="true"
|
||||||
<cert-notification-modal v-model="selectedId"></cert-notification-modal>
|
@update:value="onChange"
|
||||||
</div>
|
/>
|
||||||
</a-modal>
|
<fs-table-select
|
||||||
</a-form-item-rest>
|
ref="tableSelectRef"
|
||||||
|
class="flex-0"
|
||||||
|
:model-value="modelValue"
|
||||||
|
:dict="optionsDictRef"
|
||||||
|
:create-crud-options="createCrudOptions"
|
||||||
|
:crud-options-override="{
|
||||||
|
search: { show: false },
|
||||||
|
table: {
|
||||||
|
scroll: {
|
||||||
|
x: 540
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}"
|
||||||
|
:show-current="false"
|
||||||
|
:show-select="false"
|
||||||
|
:dialog="{ width: 960 }"
|
||||||
|
:destroy-on-close="false"
|
||||||
|
@update:model-value="onChange"
|
||||||
|
>
|
||||||
|
<template #default="scope">
|
||||||
|
<fs-button class="ml-5" :disabled="disabled" :size="size" type="primary" icon="ant-design:edit-outlined" @click="scope.open"></fs-button>
|
||||||
|
</template>
|
||||||
|
</fs-table-select>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script lang="tsx" setup>
|
||||||
import { defineComponent, reactive, ref, watch, inject } from "vue";
|
import { inject, ref, Ref, watch } from "vue";
|
||||||
import CertNotificationModal from "./modal/index.vue";
|
|
||||||
import { createApi } from "../api";
|
import { createApi } from "../api";
|
||||||
import { message } from "ant-design-vue";
|
import { message } from "ant-design-vue";
|
||||||
|
import { dict } from "@fast-crud/fast-crud";
|
||||||
|
import createCrudOptions from "../crud";
|
||||||
|
|
||||||
export default defineComponent({
|
defineOptions({
|
||||||
name: "NotificationSelector",
|
name: "NotificationSelector"
|
||||||
components: { CertNotificationModal },
|
});
|
||||||
props: {
|
|
||||||
modelValue: {
|
|
||||||
type: [Number, String],
|
|
||||||
default: null
|
|
||||||
},
|
|
||||||
type: {
|
|
||||||
type: String,
|
|
||||||
default: ""
|
|
||||||
},
|
|
||||||
placeholder: {
|
|
||||||
type: String,
|
|
||||||
default: "请选择"
|
|
||||||
},
|
|
||||||
size: {
|
|
||||||
type: String,
|
|
||||||
default: "middle"
|
|
||||||
},
|
|
||||||
disabled: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
useDefault: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
emits: ["update:modelValue", "selectedChange", "change"],
|
|
||||||
setup(props, ctx) {
|
|
||||||
const api = createApi();
|
|
||||||
|
|
||||||
const target = ref({});
|
const props = defineProps<{
|
||||||
const selectedId = ref();
|
modelValue?: number | string;
|
||||||
async function refreshTarget(value) {
|
type?: string;
|
||||||
selectedId.value = value;
|
placeholder?: string;
|
||||||
if (value > 0) {
|
size?: string;
|
||||||
target.value = await api.GetSimpleInfo(value);
|
disabled?: boolean;
|
||||||
}
|
}>();
|
||||||
}
|
|
||||||
|
|
||||||
async function loadDefault() {
|
const onChange = async (value: number) => {
|
||||||
const defId = await api.GetDefaultId();
|
await emitValue(value);
|
||||||
if (defId) {
|
};
|
||||||
await emitValue(defId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
loadDefault();
|
const emit = defineEmits(["update:modelValue", "selectedChange", "change"]);
|
||||||
|
|
||||||
function clear() {
|
const api = createApi();
|
||||||
if (props.disabled) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
emitValue(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function emitValue(value) {
|
// const types = ref({});
|
||||||
if (pipeline?.value && target?.value && pipeline.value.userId !== target.value.userId) {
|
// async function loadNotificationTypes() {
|
||||||
message.error("对不起,您不能修改他人流水线的通知");
|
// const types = await api.GetDefineTypes();
|
||||||
return;
|
// const map: any = {};
|
||||||
}
|
// for (const item of types) {
|
||||||
if (value == null) {
|
// map[item.type] = item;
|
||||||
selectedId.value = "";
|
// }
|
||||||
target.value = null;
|
// types.value = map;
|
||||||
} else {
|
// }
|
||||||
selectedId.value = value;
|
// loadNotificationTypes();
|
||||||
await refreshTarget(selectedId.value);
|
const tableSelectRef = ref();
|
||||||
}
|
const optionsDictRef = dict({
|
||||||
ctx.emit("change", selectedId.value);
|
url: "/pi/notification/options",
|
||||||
ctx.emit("update:modelValue", selectedId.value);
|
value: "id",
|
||||||
ctx.emit("selectedChange", target.value);
|
label: "name",
|
||||||
}
|
onReady: ({ dict }) => {
|
||||||
|
const data = [
|
||||||
watch(
|
|
||||||
() => {
|
|
||||||
return props.modelValue;
|
|
||||||
},
|
|
||||||
async (value) => {
|
|
||||||
selectedId.value = null;
|
|
||||||
target.value = null;
|
|
||||||
if (value == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
await refreshTarget(value);
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
immediate: true
|
id: 0,
|
||||||
}
|
name: "使用默认通知",
|
||||||
);
|
icon: "ion:notifications"
|
||||||
|
|
||||||
const providerDefine = ref({});
|
|
||||||
|
|
||||||
async function refreshProviderDefine(type) {
|
|
||||||
providerDefine.value = await api.GetProviderDefine(type);
|
|
||||||
}
|
|
||||||
// watch(
|
|
||||||
// () => {
|
|
||||||
// return props.type;
|
|
||||||
// },
|
|
||||||
// async (value) => {
|
|
||||||
// await refreshProviderDefine(value);
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// immediate: true
|
|
||||||
// }
|
|
||||||
// );
|
|
||||||
|
|
||||||
//当不在pipeline中编辑时,可能为空
|
|
||||||
const pipeline = inject("pipeline", null);
|
|
||||||
|
|
||||||
const chooseForm = reactive({
|
|
||||||
show: false,
|
|
||||||
open() {
|
|
||||||
chooseForm.show = true;
|
|
||||||
},
|
},
|
||||||
ok: () => {
|
...dict.data
|
||||||
console.log("choose ok:", selectedId.value);
|
];
|
||||||
emitValue(selectedId.value);
|
dict.setData(data);
|
||||||
chooseForm.show = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
clear,
|
|
||||||
target,
|
|
||||||
selectedId,
|
|
||||||
providerDefine,
|
|
||||||
chooseForm
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
const renderLabel = (option: any) => {
|
||||||
|
return <span>{option.name}</span>;
|
||||||
|
};
|
||||||
|
|
||||||
|
async function openTableSelectDialog(e: any) {
|
||||||
|
e.preventDefault();
|
||||||
|
await tableSelectRef.value.open();
|
||||||
|
await tableSelectRef.value.crudExpose.openAdd({});
|
||||||
|
}
|
||||||
|
const selectSlots = ref({
|
||||||
|
dropdownRender({ menuNode }: any) {
|
||||||
|
const res = [];
|
||||||
|
res.push(menuNode);
|
||||||
|
res.push(<a-divider style="margin: 4px 0" />);
|
||||||
|
res.push(<a-space style="padding: 4px 8px" />);
|
||||||
|
res.push(<fs-button class="w-100" type="text" icon="plus-outlined" text="新建通知渠道" onClick={openTableSelectDialog}></fs-button>);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const target: Ref<any> = ref({});
|
||||||
|
|
||||||
|
function clear() {
|
||||||
|
if (props.disabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
emitValue(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function emitValue(value: any) {
|
||||||
|
const target = optionsDictRef.dataMap[value];
|
||||||
|
if (value !== 0 && pipeline?.value && target && pipeline.value.userId !== target.userId) {
|
||||||
|
message.error("对不起,您不能修改他人流水线的通知");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
emit("change", value);
|
||||||
|
emit("update:modelValue", value);
|
||||||
|
emit("selectedChange", target);
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => {
|
||||||
|
return props.modelValue;
|
||||||
|
},
|
||||||
|
async (value) => {
|
||||||
|
await optionsDictRef.loadDict();
|
||||||
|
target.value = optionsDictRef.dataMap[value];
|
||||||
|
},
|
||||||
|
{
|
||||||
|
immediate: true
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
//当不在pipeline中编辑时,可能为空
|
||||||
|
const pipeline = inject("pipeline", null);
|
||||||
</script>
|
</script>
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
.notification-selector {
|
.notification-selector {
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -107,6 +107,7 @@ export default function (certPluginGroup: PluginGroup, formWrapperRef: any): Cre
|
||||||
title: "失败通知",
|
title: "失败通知",
|
||||||
type: "text",
|
type: "text",
|
||||||
form: {
|
form: {
|
||||||
|
value: 0,
|
||||||
component: {
|
component: {
|
||||||
name: NotificationSelector,
|
name: NotificationSelector,
|
||||||
vModel: "modelValue",
|
vModel: "modelValue",
|
||||||
|
|
|
@ -140,4 +140,17 @@ export class NotificationController extends CrudController<NotificationService>
|
||||||
const res = await this.service.setDefault(id, this.getUserId());
|
const res = await this.service.setDefault(id, this.getUserId());
|
||||||
return this.ok(res);
|
return this.ok(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Post('/options', { summary: Constants.per.authOnly })
|
||||||
|
async options() {
|
||||||
|
const res = await this.service.list({
|
||||||
|
query: {
|
||||||
|
userId: this.getUserId(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
for (const item of res) {
|
||||||
|
delete item.setting;
|
||||||
|
}
|
||||||
|
return this.ok(res);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,27 @@ export class DiscordNotification extends BaseNotification {
|
||||||
})
|
})
|
||||||
mentionedList!: string[];
|
mentionedList!: string[];
|
||||||
|
|
||||||
|
@NotificationInput({
|
||||||
|
title: '代理',
|
||||||
|
component: {
|
||||||
|
placeholder: 'http://xxxxx:xx',
|
||||||
|
},
|
||||||
|
helper: '使用https_proxy',
|
||||||
|
required: false,
|
||||||
|
})
|
||||||
|
httpsProxy = '';
|
||||||
|
|
||||||
|
@NotificationInput({
|
||||||
|
title: '忽略证书校验',
|
||||||
|
value: false,
|
||||||
|
component: {
|
||||||
|
name: 'a-switch',
|
||||||
|
vModel: 'checked',
|
||||||
|
},
|
||||||
|
required: false,
|
||||||
|
})
|
||||||
|
skipSslVerify: boolean;
|
||||||
|
|
||||||
async send(body: NotificationBody) {
|
async send(body: NotificationBody) {
|
||||||
if (!this.webhook) {
|
if (!this.webhook) {
|
||||||
throw new Error('Webhook URL 不能为空');
|
throw new Error('Webhook URL 不能为空');
|
||||||
|
@ -49,6 +70,8 @@ export class DiscordNotification extends BaseNotification {
|
||||||
url: this.webhook,
|
url: this.webhook,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
data: json,
|
data: json,
|
||||||
|
httpProxy: this.httpsProxy,
|
||||||
|
skipSslVerify: this.skipSslVerify,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,27 @@ export class SlackNotification extends BaseNotification {
|
||||||
})
|
})
|
||||||
webhook = '';
|
webhook = '';
|
||||||
|
|
||||||
|
@NotificationInput({
|
||||||
|
title: '代理',
|
||||||
|
component: {
|
||||||
|
placeholder: 'http://xxxxx:xx',
|
||||||
|
},
|
||||||
|
helper: '使用https_proxy',
|
||||||
|
required: false,
|
||||||
|
})
|
||||||
|
httpsProxy = '';
|
||||||
|
|
||||||
|
@NotificationInput({
|
||||||
|
title: '忽略证书校验',
|
||||||
|
value: false,
|
||||||
|
component: {
|
||||||
|
name: 'a-switch',
|
||||||
|
vModel: 'checked',
|
||||||
|
},
|
||||||
|
required: false,
|
||||||
|
})
|
||||||
|
skipSslVerify: boolean;
|
||||||
|
|
||||||
async send(body: NotificationBody) {
|
async send(body: NotificationBody) {
|
||||||
if (!this.webhook) {
|
if (!this.webhook) {
|
||||||
throw new Error('token不能为空');
|
throw new Error('token不能为空');
|
||||||
|
@ -28,6 +49,8 @@ export class SlackNotification extends BaseNotification {
|
||||||
data: {
|
data: {
|
||||||
text: `${body.title}\n${body.content}\n[查看详情](${body.url})`,
|
text: `${body.title}\n${body.content}\n[查看详情](${body.url})`,
|
||||||
},
|
},
|
||||||
|
httpProxy: this.httpsProxy,
|
||||||
|
skipSslVerify: this.skipSslVerify,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,16 @@ import { BaseNotification, IsNotification, NotificationBody, NotificationInput }
|
||||||
needPlus: true,
|
needPlus: true,
|
||||||
})
|
})
|
||||||
export class TelegramNotification extends BaseNotification {
|
export class TelegramNotification extends BaseNotification {
|
||||||
|
@NotificationInput({
|
||||||
|
title: 'URL',
|
||||||
|
value: 'https://api.telegram.org',
|
||||||
|
component: {
|
||||||
|
placeholder: 'https://api.telegram.org',
|
||||||
|
},
|
||||||
|
required: true,
|
||||||
|
})
|
||||||
|
endpoint = 'https://api.telegram.org';
|
||||||
|
|
||||||
@NotificationInput({
|
@NotificationInput({
|
||||||
title: 'Bot Token',
|
title: 'Bot Token',
|
||||||
component: {
|
component: {
|
||||||
|
@ -27,6 +37,27 @@ export class TelegramNotification extends BaseNotification {
|
||||||
})
|
})
|
||||||
chatId = '';
|
chatId = '';
|
||||||
|
|
||||||
|
@NotificationInput({
|
||||||
|
title: '代理',
|
||||||
|
component: {
|
||||||
|
placeholder: 'http://xxxxx:xx',
|
||||||
|
},
|
||||||
|
helper: '使用https_proxy',
|
||||||
|
required: false,
|
||||||
|
})
|
||||||
|
httpsProxy = '';
|
||||||
|
|
||||||
|
@NotificationInput({
|
||||||
|
title: '忽略证书校验',
|
||||||
|
value: false,
|
||||||
|
component: {
|
||||||
|
name: 'a-switch',
|
||||||
|
vModel: 'checked',
|
||||||
|
},
|
||||||
|
required: false,
|
||||||
|
})
|
||||||
|
skipSslVerify: boolean;
|
||||||
|
|
||||||
async send(body: NotificationBody) {
|
async send(body: NotificationBody) {
|
||||||
if (!this.botToken || !this.chatId) {
|
if (!this.botToken || !this.chatId) {
|
||||||
throw new Error('Bot Token 和聊天ID不能为空');
|
throw new Error('Bot Token 和聊天ID不能为空');
|
||||||
|
@ -47,6 +78,8 @@ export class TelegramNotification extends BaseNotification {
|
||||||
text: messageContent,
|
text: messageContent,
|
||||||
parse_mode: 'MarkdownV2', // 或使用 'HTML' 取决于需要的格式
|
parse_mode: 'MarkdownV2', // 或使用 'HTML' 取决于需要的格式
|
||||||
},
|
},
|
||||||
|
httpProxy: this.httpsProxy,
|
||||||
|
skipSslVerify: this.skipSslVerify,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue