1、(超时时间等)增加信息提示

2、告警通知增加短信的抽象接口
3、更换刷新图标
This commit is contained in:
SGK\17962 2025-06-27 11:27:32 +08:00
parent 0253412bce
commit 69dd96cc19
15 changed files with 161 additions and 20 deletions

2
.env
View File

@ -2,7 +2,7 @@
# if use a sub directory, it must be end with "/", like "/admin/" but not "/admin"
VITE_BASE_URL=/
VITE_APP_TITLE=Snail Job
VITE_APP_TITLE=Task Flux
VITE_APP_DESC=A flexible, reliable, and fast platform for distributed task retry and distributed task scheduling.

View File

@ -2,7 +2,7 @@
<html lang="zh-cmn-Hans">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.svg" />
<link rel="icon" href="/time-svgrepo-com.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="color-scheme" content="light dark" />
<title>%VITE_APP_TITLE%</title>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="48" height="48" fill="white" fill-opacity="0.01"/>
<path d="M24 44C35.0457 44 44 35.0457 44 24C44 12.9543 35.0457 4 24 4C12.9543 4 4 12.9543 4 24C4 35.0457 12.9543 44 24 44Z" fill="#2F88FF" stroke="#000000" stroke-width="4" stroke-linejoin="round"/>
<path d="M24.0083 12L24.0071 24.0088L32.4865 32.4882" stroke="white" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 625 B

View File

@ -1,3 +1,6 @@
<svg id="snail-job" data-name="snail-job" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 709.6845005488 690.7728719041">
<path d="M338.3025810878.1920476727c-24.3000003621,2.1000000313-31.0000004619,2.8000000417-41.0000006109,4.5000000671C156.7025783818,28.3920480929,44.9025767158,131.4920496292,10.4025762017,269.0920516796,2.8025760885,299.5920521341.0025760468,322.4920524753.0025760468,354.0920529462c-.1000000015,33.1000004932,2.7000000402,55.8000008315,10.400000155,86.7000012919,9.9000001475,39.4000005871,26.0000003874,76.0000011325,47.9000007138,109.1000016257,13.9000002071,20.9000003114,25.100000374,34.7000005171,42.5000006333,52.6000007838,29.8000004441,30.5000004545,62.0000009239,53.8000008017,99.2000014782,71.8000010699,8.3000001237,4.0000000596,15.7000002339,7.3000001088,16.4000002444,7.3000001088.6000000089,0,5.4000000805,1.3000000194,10.5000001565,3.0000000447,44.7000006661,14.3000002131,92.2000013739,3.7000000551,138.4000020623-30.9000004604,4.1000000611-3.1000000462,12.9000001922-10.8000001609,19.4000002891-17.1000002548,10.1000001505-9.7000001445,12.4000001848-12.6000001878,15.2000002265-18.5000002757,15.6000002325-33.9000005051,14.6000002176-69.0000010282-3.2000000477-110.9000016525-8.6000001281-20.1000002995-25.9000003859-46.1000006869-43.3000006452-65.0000009686-3.0000000447-3.4000000507-10.7000001594-9.6000001431-17.1000002548-14.0000002086-24.5000003651-16.7000002488-43.7000006512-32.1000004783-54.3000008091-43.4000006467-6.3000000939-6.8000001013-16.1000002399-21.9000003263-18.7000002787-28.9000004306-2.8000000417-7.5000001118-3.6000000536-17.5000002608-2.0000000298-24.4000003636,1.8000000268-7.8000001162,7.2000001073-18.7000002787,12.0000001788-24.2000003606,4.1000000611-4.6000000685,4.2000000626-4.8000000715,3.5000000522-10.000000149-1.6000000238-11.7000001743-17.8000002652-62.0000009239-20.600000307-63.8000009507-.6000000089-.3000000045-3.3000000492-.9000000134-6.0000000894-1.2000000179-10.5000001565-1.3000000194-18.3000002727-6.9000001028-22.7000003383-16.6000002474-2.1000000313-4.5000000671-2.4000000358-6.4000000954-2.0000000298-12.1000001803,1.1000000164-15.500000231,13.5000002012-26.0000003874,29.2000004351-24.8000003695,18.3000002727,1.5000000224,30.1000004485,19.2000002861,23.7000003532,35.8000005335-1.2000000179,3.0000000447-2.1000000313,6.5000000969-2.1000000313,7.7000001147,0,3.1000000462,8.2000001222,18.5000002757,14.2000002116,26.6000003964,13.9000002071,18.8000002801,30.000000447,27.6000004113,48.4000007212,26.4000003934,10.600000158-.6000000089,13.3000001982-2.0000000298,16.4000002444-8.2000001222,2.3000000343-4.5000000671,2.5000000373-6.2000000924,2.5000000373-17.0000002533,0-7.7000001147-.7000000104-15.0000002235-1.9000000283-20.5000003055-2.5000000373-11.6000001729-11.3000001684-38.4000005722-13.7000002041-41.4000006169-1.1000000164-1.3000000194-4.1000000611-3.2000000477-6.8000001013-4.1000000611-14.700000219-4.900000073-23.3000003472-16.7000002488-23.3000003472-32.1000004783,0-13.1000001952,7.2000001073-24.3000003621,19.5000002906-30.000000447,7.8000001162-3.6000000536,19.0000002831-3.4000000507,27.2000004053.5000000075,3.5000000522,1.6000000238,7.8000001162,4.8000000715,10.3000001535,7.5000001118,10.3000001535,11.2000001669,11.8000001758,24.4000003636,4.5000000671,39.4000005871-3.3000000492,6.7000000998-3.0000000447,8.1000001207,5.100000076,24.6000003666,18.2000002712,36.8000005484,52.2000007778,76.8000011444,101.1000015065,118.7000017688,39.2000005841,33.7000005022,64.9000009671,65.4000009745,84.9000012651,105.1000015661,15.6000002325,31.0000004619,24.1000003591,57.9000008628,30.20000045,96.300001435,1.0000000149,6.1000000909,1.8000000268,19.7000002936,2.1000000313,34.6000005156.6000000089,26.0000003874-.3000000045,39.5000005886-3.8000000566,59.3000008836-1.1000000164,6.0000000894-1.8000000268,11.0000001639-1.6000000238,11.2000001669.8000000119.8000000119,31.7000004724-31.7000004724,40.1000005975-42.1000006273,18.9000002816-23.5000003502,38.6000005752-56.6000008434,50.400000751-84.5000012591,13.0000001937-30.800000459,22.7000003383-68.9000010267,26.4000003934-104.0000015497,1.8000000268-17.3000002578,1.5000000224-54.7000008151-.6000000089-72.0000010729-13.2000001967-111.000001654-73.5000010952-206.1000030711-167.300002493-264.0000039339-13.3000001982-8.2000001222-37.4000005573-20.5000003055-52.2000007778-26.5000003949-29.7000004426-12.1000001803-67.1000009999-21.3000003174-99.1000014767-24.5000003651-11.4000001699-1.1000000164-43.8000006527-2.0000000298-51.00000076-1.4000000209Z"/>
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="48" height="48" fill="white" fill-opacity="0.01"/>
<path d="M24 44C35.0457 44 44 35.0457 44 24C44 12.9543 35.0457 4 24 4C12.9543 4 4 12.9543 4 24C4 35.0457 12.9543 44 24 44Z" fill="#2F88FF" stroke="#000000" stroke-width="4" stroke-linejoin="round"/>
<path d="M24.0083 12L24.0071 24.0088L32.4865 32.4882" stroke="white" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 625 B

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="48" height="48" fill="white" fill-opacity="0.01"/>
<path d="M24 44C35.0457 44 44 35.0457 44 24C44 12.9543 35.0457 4 24 4C12.9543 4 4 12.9543 4 24C4 35.0457 12.9543 44 24 44Z" fill="#2F88FF" stroke="#000000" stroke-width="4" stroke-linejoin="round"/>
<path d="M24.0083 12L24.0071 24.0088L32.4865 32.4882" stroke="white" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 625 B

View File

@ -3,7 +3,7 @@ defineOptions({ name: 'SystemLogo' });
</script>
<template>
<icon-local-logo />
<icon-local-time />
</template>
<style scoped></style>

View File

@ -28,7 +28,8 @@ export const alarmTypeRecord: Record<Api.NotifyRecipient.AlarmType, App.I18n.I18
2: 'page.notifyRecipient.email',
3: 'page.notifyRecipient.weCom',
4: 'page.notifyRecipient.lark',
5: 'page.notifyRecipient.webhook'
5: 'page.notifyRecipient.webhook',
6: 'page.notifyRecipient.sms'
};
export const alarmTypeRecordOptions = transformRecordToNumberOption(alarmTypeRecord);

View File

@ -1,6 +1,6 @@
const local: App.I18n.Schema = {
system: {
title: 'Snail Job',
title: 'Task Flux',
desc: 'A flexible, reliable, and fast platform for distributed task retry and distributed task scheduling.',
updateTitle: 'System Version Update Notification',
updateContent: 'A new version of the system has been detected. Do you want to refresh the page immediately?',
@ -653,11 +653,13 @@ const local: App.I18n.Schema = {
webhookUrl: 'Notification Address',
secret: 'secret',
tos: 'Recipient Email Address',
phoneNumbers: 'Recipient PhoneNumber',
dingDing: 'DingTalk',
email: 'Email',
weCom: 'WeCom',
lark: 'Lark',
webhook: 'webhook',
sms: 'sms',
contentType: 'Request type'
},
retryDeadLetter: {
@ -860,6 +862,7 @@ const local: App.I18n.Schema = {
triggerType: 'Please enter trigger type',
jobName: 'Please enter Mission name',
executorTimeout: 'Please enter executor timeout',
timeoutTip: 'The value is 0 or -1 means this task do not have executorTimeout',
triggerInterval: 'Please enter interval duration',
triggerInterval_CRON: 'Please enter cron expression',
taskType: 'Please enter Task type',

View File

@ -1,6 +1,6 @@
const local: App.I18n.Schema = {
system: {
title: 'Snail Job',
title: 'Task Flux',
desc: '灵活,可靠和快速的分布式任务重试和分布式任务调度平台',
updateTitle: '系统版本更新通知',
updateContent: '检测到系统有新版本发布,是否立即刷新页面?',
@ -661,11 +661,13 @@ const local: App.I18n.Schema = {
webhookUrl: '通知地址',
secret: '密钥',
tos: '通知人邮箱地址',
phoneNumbers: '通知人手机号',
dingDing: '钉钉',
email: '邮箱',
weCom: '企业微信',
lark: '飞书',
webhook: 'webhook',
sms: '短信',
contentType: '请求类型'
},
retryDeadLetter: {
@ -868,6 +870,7 @@ const local: App.I18n.Schema = {
triggerType: '请输入触发类型',
jobName: '请输入任务名称',
executorTimeout: '请输入超时时间',
timeoutTip: '超时时间为0或-1表示不设超时时间',
triggerInterval: '请输入间隔时长(秒)',
triggerInterval_CRON: '请输入间隔时长',
taskType: '请输入任务类型',

View File

@ -77,7 +77,7 @@ export const themeSettings: App.Theme.ThemeSetting = {
},
watermark: {
visible: false,
text: 'Snail Job'
text: 'Task Flux'
}
};

11
src/typings/api.d.ts vendored
View File

@ -668,6 +668,13 @@ declare namespace Api {
}> &
NotifyRecipient;
/** SMS Notify */
type SmsNotify = Common.CommonRecord<{
/** 短信接收人 */
phoneNumbers: string[];
}> &
NotifyRecipient;
/** webhook Notify */
type WebhookNotify = Common.CommonRecord<{
/** 接收人名称 */
@ -687,8 +694,8 @@ declare namespace Api {
/** notifyRecipient list */
type NotifyRecipientList = Common.PaginatingQueryRecord<NotifyRecipient>;
/** 1: 钉钉通知 2: 邮件通知 3: 企业通知 4: 飞书 5: Webhook */
type AlarmType = 1 | 2 | 3 | 4 | 5;
/** 1: 钉钉通知 2: 邮件通知 3: 企业通知 4: 飞书 5: Webhook 6: 短信 */
type AlarmType = 1 | 2 | 3 | 4 | 5 | 6;
type ExportNotifyRecipient = Common.CommonRecord<{
notifyRecipientIds: string[];

View File

@ -863,12 +863,14 @@ declare namespace App {
ats: string;
webhookUrl: string;
tos: string;
phoneNumbers: string;
dingDing: string;
email: string;
weCom: string;
lark: string;
secret: string;
webhook: string;
sms: string;
contentType: string;
};
retryDeadLetter: {
@ -1071,6 +1073,7 @@ declare namespace App {
description: string;
triggerType: string;
executorTimeout: string;
timeoutTip: string;
triggerInterval: string;
triggerInterval_CRON: string;
taskType: string;

View File

@ -653,6 +653,18 @@ const scriptMethodOptions = [
<NGrid cols="2 s:1 m:2" responsive="screen" x-gap="20">
<NGi>
<NFormItem :label="$t('page.jobTask.executorTimeout')" path="executorTimeout">
<template #label>
{{ $t('page.jobTask.executorTimeout') }}
<NTooltip placement="top">
<template #trigger>
<NButton text type="primary" circle size="tiny" class="ml-4px">
<icon-ic-round-info class="text-icon" />
</NButton>
</template>
{{ $t('page.jobTask.form.timeoutTip') }}
</NTooltip>
</template>
<NInputGroup>
<NInputNumber
v-model:value="model.executorTimeout"

View File

@ -9,6 +9,7 @@ import LarkForm from './lark-form.vue';
import EmailForm from './email-form.vue';
import WeComForm from './wecom-form.vue';
import WebhookForm from './webhook-form.vue';
import SmsForm from './sms-form.vue';
defineOptions({
name: 'NotifyRecipientOperateDrawer'
@ -110,20 +111,23 @@ watch(visible, () => {
<template>
<OperateDrawer v-model="visible" :min-size="480" :title="title">
<NTabs v-model:value="notifyTabPane" type="segment" animated>
<NTabPane :name="1" tab="钉钉" :disabled="notifyTabPane !== 1 && props.operateType === 'edit'">
<DingDingForm ref="formRef" v-model:value="model" />
</NTabPane>
<!-- <NTabPane :name="1" tab="钉钉" :disabled="notifyTabPane !== 1 && props.operateType === 'edit'">-->
<!-- <DingDingForm ref="formRef" v-model:value="model" />-->
<!-- </NTabPane>-->
<NTabPane :name="2" tab="邮箱" :disabled="notifyTabPane !== 2 && props.operateType === 'edit'">
<EmailForm ref="formRef" v-model:value="model" />
</NTabPane>
<NTabPane :name="3" tab="企业微信" :disabled="notifyTabPane !== 3 && props.operateType === 'edit'">
<WeComForm ref="formRef" v-model:value="model" />
</NTabPane>
<NTabPane :name="4" tab="飞书" :disabled="notifyTabPane !== 4 && props.operateType === 'edit'">
<LarkForm ref="formRef" v-model:value="model" />
</NTabPane>
<NTabPane :name="5" tab="Webhook" :disabled="notifyTabPane !== 5 && props.operateType === 'edit'">
<WebhookForm ref="formRef" v-model:value="model" />
<!-- <NTabPane :name="4" tab="飞书" :disabled="notifyTabPane !== 4 && props.operateType === 'edit'">-->
<!-- <LarkForm ref="formRef" v-model:value="model" />-->
<!-- </NTabPane>-->
<!-- <NTabPane :name="5" tab="Webhook" :disabled="notifyTabPane !== 5 && props.operateType === 'edit'">-->
<!-- <WebhookForm ref="formRef" v-model:value="model" />-->
<!-- </NTabPane>-->
<NTabPane :name="6" tab="短信" :disabled="notifyTabPane !== 6 && props.operateType === 'edit'">
<SmsForm ref="formRef" v-model:value="model" />
</NTabPane>
</NTabs>
<template #footer>

View File

@ -0,0 +1,93 @@
<template>
<NForm ref="formRef" :model="model" :rules="rules">
<NFormItem :label="$t('page.notifyRecipient.recipientName')" path="recipientName">
<NInput v-model:value="model.recipientName" :placeholder="$t('page.notifyRecipient.form.recipientName')" />
</NFormItem>
<NFormItem :label="$t('page.notifyRecipient.phoneNumbers')" path="phoneNumbers">
<NDynamicTags v-model:value="model.phoneNumbers" />
</NFormItem>
<NFormItem :label="$t('page.notifyRecipient.description')" path="description">
<NInput
v-model:value="model.description"
type="textarea"
:placeholder="$t('page.notifyRecipient.form.description')"
clearable
round
/>
</NFormItem>
</NForm>
</template>
<script setup lang="ts">
import { reactive, watch } from 'vue';
import { useFormRules, useNaiveForm } from '@/hooks/common/form';
import { $t } from '@/locales';
defineOptions({
name: 'SmsForm'
});
interface Props {
value: Api.NotifyRecipient.NotifyRecipient;
}
const props = defineProps<Props>();
interface Emits {
(e: 'update:value', value: Api.NotifyRecipient.NotifyRecipient): void;
}
const emit = defineEmits<Emits>();
const { formRef, validate, restoreValidation } = useNaiveForm();
const { defaultRequiredRule } = useFormRules();
type Model = Pick<
Api.NotifyRecipient.SmsNotify,
'id' | 'recipientName' | 'notifyType' | 'phoneNumbers' | 'description'
>;
const model: Model = reactive(createDefaultModel());
function createDefaultModel(): Model {
const { phoneNumbers } = JSON.parse(props.value.notifyAttribute!) as { phoneNumbers: string[] };
return {
id: props.value.id,
recipientName: props.value.recipientName,
notifyType: 6,
phoneNumbers,
description: props.value.description
};
}
type RuleKey = Extract<keyof Model, 'recipientName' | 'notifyType' | 'phoneNumbers'>;
const rules: Record<RuleKey, App.Global.FormRule> = {
recipientName: defaultRequiredRule,
notifyType: defaultRequiredRule,
phoneNumbers: defaultRequiredRule
};
const buildNotifyAttribute = (phoneNumbers: string[]) => {
return JSON.stringify({ phoneNumbers });
};
watch(
() => model,
() => {
const { id, recipientName, notifyType, phoneNumbers, description } = model;
const notifyAttribute = buildNotifyAttribute(phoneNumbers);
emit('update:value', { id, recipientName, notifyType, notifyAttribute, description });
},
{ immediate: true, deep: true }
);
defineExpose({
validate,
restoreValidation
});
</script>
<style scoped></style>