mirror of https://github.com/certd/certd
Other translations
parent
cdac12bb2f
commit
daaef316e9
|
@ -1,21 +1,28 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="cron-editor">
|
<div class="cron-editor">
|
||||||
<div class="flex-o">
|
<div class="flex-o">
|
||||||
<cron-light :disabled="disabled" :readonly="readonly" :period="period" class="flex-o cron-ant" locale="zh-CN" format="quartz" :model-value="modelValue" @update:model-value="onUpdate" @error="onError" />
|
<cron-light :disabled="disabled" :readonly="readonly" :period="period" class="flex-o cron-ant"
|
||||||
|
locale="zh-CN" format="quartz" :model-value="modelValue" @update:model-value="onUpdate"
|
||||||
|
@error="onError" />
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-5 flex">
|
<div class="mt-5 flex">
|
||||||
<a-input :disabled="true" :readonly="readonly" :value="modelValue" @change="onChange"></a-input>
|
<a-input :disabled="true" :readonly="readonly" :value="modelValue" @change="onChange"></a-input>
|
||||||
<fs-icon icon="ion:close-circle" class="pointer fs-16 ml-5 color-gray" title="清除选择" @click="onClear"></fs-icon>
|
<fs-icon icon="ion:close-circle" class="pointer fs-16 ml-5 color-gray" :title="t('certd.cron.clearTip')"
|
||||||
|
@click="onClear"></fs-icon>
|
||||||
</div>
|
</div>
|
||||||
<div class="helper">下次触发时间:{{ nextTime }}</div>
|
<div class="helper">{{ t('certd.cron.nextTrigger') }}:{{ nextTime }}</div>
|
||||||
<div class="fs-helper">{{ errorMessage }}</div>
|
<div class="fs-helper">{{ errorMessage }}</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import parser from "cron-parser";
|
import parser from "cron-parser";
|
||||||
import { computed, ref } from "vue";
|
import { computed, ref } from "vue";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
|
import { useI18n } from "vue-i18n";
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
import { getCronNextTimes } from "/@/components/cron-editor/utils";
|
import { getCronNextTimes } from "/@/components/cron-editor/utils";
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: "CronEditor",
|
name: "CronEditor",
|
||||||
|
@ -83,7 +90,7 @@ const onClear = () => {
|
||||||
|
|
||||||
const nextTime = computed(() => {
|
const nextTime = computed(() => {
|
||||||
if (props.modelValue == null) {
|
if (props.modelValue == null) {
|
||||||
return "请先设置正确的cron表达式";
|
return t("certd.cron.tip");
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -91,26 +98,31 @@ const nextTime = computed(() => {
|
||||||
return nextTimes.join(",");
|
return nextTimes.join(",");
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
return "请先设置正确的cron表达式";
|
return t("certd.cron.tip");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
.cron-editor {
|
.cron-editor {
|
||||||
.cron-ant {
|
.cron-ant {
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
&* > {
|
|
||||||
|
&*> {
|
||||||
margin-bottom: 2px;
|
margin-bottom: 2px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vcron-select-list {
|
.vcron-select-list {
|
||||||
min-width: 56px;
|
min-width: 56px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vcron-select-input {
|
.vcron-select-input {
|
||||||
min-height: 22px;
|
min-height: 22px;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vcron-select-container {
|
.vcron-select-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
|
@ -185,4 +185,93 @@ export default {
|
||||||
download: {
|
download: {
|
||||||
title: "Download Certificate"
|
title: "Download Certificate"
|
||||||
},
|
},
|
||||||
|
source: "Source Code",
|
||||||
|
github: "GitHub",
|
||||||
|
gitee: "Gitee",
|
||||||
|
cron: {
|
||||||
|
clearTip: "Clear Selection",
|
||||||
|
nextTrigger: "Next Trigger Time",
|
||||||
|
tip: "Please set a valid cron expression first"
|
||||||
|
},
|
||||||
|
cronForm: {
|
||||||
|
title: "Scheduled Script",
|
||||||
|
helper: "Click the button above to select the time for daily execution.\nIt is recommended to run once a day. Tasks will be skipped if the certificate is not expiring.",
|
||||||
|
required: "This field is required"
|
||||||
|
},
|
||||||
|
email: {
|
||||||
|
title: "Recipient Email",
|
||||||
|
helper: "Enter your recipient email addresses. Multiple addresses are supported.",
|
||||||
|
required: "This field is required"
|
||||||
|
},
|
||||||
|
plugin: {
|
||||||
|
selectTitle: "Certificate Apply Plugin",
|
||||||
|
jsAcme: "JS-ACME: Easy to use, powerful features [Recommended]",
|
||||||
|
legoAcme: "Lego-ACME: Based on Lego, supports a wide range of DNS providers, suitable for users familiar with Lego"
|
||||||
|
},
|
||||||
|
pipelineForm: {
|
||||||
|
createTitle: "Create Certificate Pipeline",
|
||||||
|
moreParams: "More Parameters",
|
||||||
|
triggerCronTitle: "Scheduled Trigger",
|
||||||
|
triggerCronHelper:
|
||||||
|
"Click the button above to choose a daily execution time.\nIt is recommended to trigger once per day. The task will be skipped if the certificate has not expired and will not be executed repeatedly.",
|
||||||
|
notificationTitle: "Failure Notification",
|
||||||
|
notificationHelper: "Get real-time alerts when the task fails",
|
||||||
|
groupIdTitle: "Pipeline Group"
|
||||||
|
},
|
||||||
|
notificationDefault: "Use Default Notification",
|
||||||
|
monitor: {
|
||||||
|
title: "Site Certificate Monitoring",
|
||||||
|
description: "Check website certificates' expiration at 0:00 daily; reminders sent 10 days before expiration (using default notification channel);",
|
||||||
|
settingLink: "Site Monitoring Settings",
|
||||||
|
limitInfo: "Basic edition limited to 1, professional and above unlimited, current",
|
||||||
|
checkAll: "Check All",
|
||||||
|
confirmTitle: "Confirm",
|
||||||
|
confirmContent: "Confirm to trigger check for all site certificates?",
|
||||||
|
checkSubmitted: "Check task submitted",
|
||||||
|
pleaseRefresh: "Please refresh the page later to see the results",
|
||||||
|
siteName: "Site Name",
|
||||||
|
enterSiteName: "Please enter the site name",
|
||||||
|
domain: "Domain",
|
||||||
|
enterDomain: "Please enter the domain",
|
||||||
|
enterValidDomain: "Please enter a valid domain",
|
||||||
|
httpsPort: "HTTPS Port",
|
||||||
|
enterPort: "Please enter the port",
|
||||||
|
certInfo: "Certificate Info",
|
||||||
|
issuer: "Issuer",
|
||||||
|
certDomains: "Certificate Domains",
|
||||||
|
certProvider: "Issuer",
|
||||||
|
certStatus: "Certificate Status",
|
||||||
|
status: {
|
||||||
|
ok: "Valid",
|
||||||
|
expired: "Expired",
|
||||||
|
},
|
||||||
|
certExpiresTime: "Certificate Expiration",
|
||||||
|
expired: "expired",
|
||||||
|
days: "days",
|
||||||
|
lastCheckTime: "Last Check Time",
|
||||||
|
disabled: "Enable/Disable",
|
||||||
|
ipCheck: "Enable IP Check",
|
||||||
|
selectRequired: "Please select",
|
||||||
|
ipCheckConfirm: "Are you sure to {status} IP check?",
|
||||||
|
ipCount: "IP Count",
|
||||||
|
checkStatus: "Check Status",
|
||||||
|
pipelineId: "Linked Pipeline ID",
|
||||||
|
certInfoId: "Certificate ID",
|
||||||
|
checkSubmittedRefresh: "Check task submitted. Please refresh later to view the result.",
|
||||||
|
ipManagement: "IP Management",
|
||||||
|
bulkImport: "Bulk Import",
|
||||||
|
basicLimitError: "Basic version allows only one monitoring site. Please upgrade to the Pro version.",
|
||||||
|
limitExceeded: "Sorry, you can only create up to {max} monitoring records. Please purchase or upgrade your plan.",
|
||||||
|
},
|
||||||
|
checkStatus: {
|
||||||
|
success: "Success",
|
||||||
|
checking: "Checking",
|
||||||
|
error: "Error",
|
||||||
|
},
|
||||||
|
domainList: {
|
||||||
|
title: "Domain List",
|
||||||
|
helper: "Format: domain:port:name, one per line. Port and name are optional.\nExamples:\nwww.baidu.com:443:Baidu\nwww.taobao.com::Taobao\nwww.google.com",
|
||||||
|
required: "Please enter domains to import",
|
||||||
|
placeholder: "www.baidu.com:443:Baidu\nwww.taobao.com::Taobao\nwww.google.com\n",
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
{
|
|
||||||
"back": "Back",
|
|
||||||
"backToHome": "Back To Home",
|
|
||||||
"login": "Login",
|
|
||||||
"logout": "Logout",
|
|
||||||
"prompt": "Prompt",
|
|
||||||
"cancel": "Cancel",
|
|
||||||
"confirm": "Confirm",
|
|
||||||
"reset": "Reset",
|
|
||||||
"noData": "No Data",
|
|
||||||
"refresh": "Refresh",
|
|
||||||
"loadingMenu": "Loading Menu",
|
|
||||||
"query": "Search",
|
|
||||||
"search": "Search",
|
|
||||||
"enabled": "Enabled",
|
|
||||||
"disabled": "Disabled",
|
|
||||||
"edit": "Edit",
|
|
||||||
"delete": "Delete",
|
|
||||||
"create": "Create",
|
|
||||||
"yes": "Yes",
|
|
||||||
"no": "No"
|
|
||||||
}
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
export default {
|
||||||
|
"back": "Back",
|
||||||
|
"backToHome": "Back To Home",
|
||||||
|
"login": "Login",
|
||||||
|
"logout": "Logout",
|
||||||
|
"prompt": "Prompt",
|
||||||
|
"cancel": "Cancel",
|
||||||
|
"confirm": "Confirm",
|
||||||
|
"reset": "Reset",
|
||||||
|
"noData": "No Data",
|
||||||
|
"refresh": "Refresh",
|
||||||
|
"loadingMenu": "Loading Menu",
|
||||||
|
"query": "Search",
|
||||||
|
"search": "Search",
|
||||||
|
"enabled": "Enabled",
|
||||||
|
"disabled": "Disabled",
|
||||||
|
"edit": "Edit",
|
||||||
|
"delete": "Delete",
|
||||||
|
"create": "Create",
|
||||||
|
"yes": "Yes",
|
||||||
|
"no": "No"
|
||||||
|
}
|
|
@ -5,6 +5,7 @@ import tutorial from './tutorial';
|
||||||
import preferences from './preferences';
|
import preferences from './preferences';
|
||||||
import ui from './ui';
|
import ui from './ui';
|
||||||
import guide from './guide';
|
import guide from './guide';
|
||||||
|
import common from './common';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
certd,
|
certd,
|
||||||
|
@ -13,5 +14,6 @@ export default {
|
||||||
ui,
|
ui,
|
||||||
tutorial,
|
tutorial,
|
||||||
preferences,
|
preferences,
|
||||||
guide
|
guide,
|
||||||
|
common
|
||||||
};
|
};
|
|
@ -191,4 +191,93 @@ export default {
|
||||||
download: {
|
download: {
|
||||||
title: "下载证书"
|
title: "下载证书"
|
||||||
},
|
},
|
||||||
|
source: "源码",
|
||||||
|
github: "github",
|
||||||
|
gitee: "gitee",
|
||||||
|
cron: {
|
||||||
|
clearTip: "清除选择",
|
||||||
|
nextTrigger: "下次触发时间",
|
||||||
|
tip: "请先设置正确的cron表达式"
|
||||||
|
},
|
||||||
|
cronForm: {
|
||||||
|
title: "定时脚本",
|
||||||
|
helper: "点击上面的按钮,选择每天几点定时执行。\n建议设置为每天触发一次,证书未到期之前任务会跳过,不会重复执行",
|
||||||
|
required: "此项必填"
|
||||||
|
},
|
||||||
|
email: {
|
||||||
|
title: "收件邮箱",
|
||||||
|
helper: "输入你的收件邮箱地址,支持多个邮箱",
|
||||||
|
required: "此项必填"
|
||||||
|
},
|
||||||
|
plugin: {
|
||||||
|
selectTitle: "证书申请插件",
|
||||||
|
jsAcme: "JS-ACME:使用简单方便,功能强大【推荐】",
|
||||||
|
legoAcme: "Lego-ACME:基于Lego实现,支持海量DNS提供商,熟悉LEGO的用户可以使用"
|
||||||
|
},
|
||||||
|
pipelineForm: {
|
||||||
|
createTitle: "创建证书流水线",
|
||||||
|
moreParams: "更多参数",
|
||||||
|
triggerCronTitle: "定时触发",
|
||||||
|
triggerCronHelper:
|
||||||
|
"点击上面的按钮,选择每天几点定时执行。\n建议设置为每天触发一次,证书未到期之前任务会跳过,不会重复执行",
|
||||||
|
notificationTitle: "失败通知",
|
||||||
|
notificationHelper: "任务执行失败实时提醒",
|
||||||
|
groupIdTitle: "流水线分组"
|
||||||
|
},
|
||||||
|
notificationDefault: "使用默认通知",
|
||||||
|
monitor: {
|
||||||
|
title: "站点证书监控",
|
||||||
|
description: "每天0点,检查网站证书的过期时间,到期前10天时将发出提醒(使用默认通知渠道);",
|
||||||
|
settingLink: "站点监控设置",
|
||||||
|
limitInfo: "基础版限制1条,专业版以上无限制,当前",
|
||||||
|
checkAll: "检查全部",
|
||||||
|
confirmTitle: "确认",
|
||||||
|
confirmContent: "确认触发检查全部站点证书吗?",
|
||||||
|
checkSubmitted: "检查任务已提交",
|
||||||
|
pleaseRefresh: "请稍后刷新页面查看结果",
|
||||||
|
siteName: "站点名称",
|
||||||
|
enterSiteName: "请输入站点名称",
|
||||||
|
domain: "网站域名",
|
||||||
|
enterDomain: "请输入域名",
|
||||||
|
enterValidDomain: "请输入正确的域名",
|
||||||
|
httpsPort: "HTTPS端口",
|
||||||
|
enterPort: "请输入端口",
|
||||||
|
certInfo: "证书信息",
|
||||||
|
issuer: "证书颁发机构",
|
||||||
|
certDomains: "证书域名",
|
||||||
|
certProvider: "颁发机构",
|
||||||
|
certStatus: "证书状态",
|
||||||
|
status: {
|
||||||
|
ok: "正常",
|
||||||
|
expired: "过期",
|
||||||
|
},
|
||||||
|
certExpiresTime: "证书到期时间",
|
||||||
|
expired: "过期",
|
||||||
|
days: "天",
|
||||||
|
lastCheckTime: "上次检查时间",
|
||||||
|
disabled: "禁用启用",
|
||||||
|
ipCheck: "开启IP检查",
|
||||||
|
selectRequired: "请选择",
|
||||||
|
ipCheckConfirm: "确定{status}IP检查?",
|
||||||
|
ipCount: "IP数量",
|
||||||
|
checkStatus: "检查状态",
|
||||||
|
pipelineId: "关联流水线ID",
|
||||||
|
certInfoId: "证书ID",
|
||||||
|
checkSubmittedRefresh: "检查任务已提交,请稍后刷新查看结果",
|
||||||
|
ipManagement: "IP管理",
|
||||||
|
bulkImport: "批量导入",
|
||||||
|
basicLimitError: "基础版只能添加一个监控站点,请赞助升级专业版",
|
||||||
|
limitExceeded: "对不起,您最多只能创建条{max}监控记录,请购买或升级套餐",
|
||||||
|
},
|
||||||
|
checkStatus: {
|
||||||
|
success: "成功",
|
||||||
|
checking: "检查中",
|
||||||
|
error: "异常",
|
||||||
|
},
|
||||||
|
domainList: {
|
||||||
|
title: "域名列表",
|
||||||
|
helper: "格式【域名:端口:名称】,一行一个,其中端口、名称可以省略\n比如:\nwww.baidu.com:443:百度\nwww.taobao.com::淘宝\nwww.google.com",
|
||||||
|
required: "请输入要导入的域名",
|
||||||
|
placeholder: "www.baidu.com:443:百度\nwww.taobao.com::淘宝\nwww.google.com\n",
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
{
|
|
||||||
"back": "返回",
|
|
||||||
"backToHome": "返回首页",
|
|
||||||
"login": "登录",
|
|
||||||
"logout": "退出登录",
|
|
||||||
"prompt": "提示",
|
|
||||||
"cancel": "取消",
|
|
||||||
"confirm": "确认",
|
|
||||||
"reset": "重置",
|
|
||||||
"noData": "暂无数据",
|
|
||||||
"refresh": "刷新",
|
|
||||||
"loadingMenu": "加载菜单中",
|
|
||||||
"query": "查询",
|
|
||||||
"search": "搜索",
|
|
||||||
"enabled": "已启用",
|
|
||||||
"disabled": "已禁用",
|
|
||||||
"edit": "修改",
|
|
||||||
"delete": "删除",
|
|
||||||
"create": "新增",
|
|
||||||
"yes": "是",
|
|
||||||
"no": "否"
|
|
||||||
}
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
export default {
|
||||||
|
"back": "返回",
|
||||||
|
"backToHome": "返回首页",
|
||||||
|
"login": "登录",
|
||||||
|
"logout": "退出登录",
|
||||||
|
"prompt": "提示",
|
||||||
|
"cancel": "取消",
|
||||||
|
"confirm": "确认",
|
||||||
|
"reset": "重置",
|
||||||
|
"noData": "暂无数据",
|
||||||
|
"refresh": "刷新",
|
||||||
|
"loadingMenu": "加载菜单中",
|
||||||
|
"query": "查询",
|
||||||
|
"search": "搜索",
|
||||||
|
"enabled": "已启用",
|
||||||
|
"disabled": "已禁用",
|
||||||
|
"edit": "修改",
|
||||||
|
"delete": "删除",
|
||||||
|
"create": "新增",
|
||||||
|
"yes": "是",
|
||||||
|
"no": "否"
|
||||||
|
}
|
|
@ -5,6 +5,7 @@ import tutorial from './tutorial';
|
||||||
import preferences from './preferences';
|
import preferences from './preferences';
|
||||||
import ui from './ui';
|
import ui from './ui';
|
||||||
import guide from './guide';
|
import guide from './guide';
|
||||||
|
import common from './common';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
certd,
|
certd,
|
||||||
|
@ -13,5 +14,6 @@ export default {
|
||||||
ui,
|
ui,
|
||||||
tutorial,
|
tutorial,
|
||||||
preferences,
|
preferences,
|
||||||
guide
|
guide,
|
||||||
|
common
|
||||||
};
|
};
|
|
@ -1,13 +1,15 @@
|
||||||
|
import i18n from '/@/locales/i18n';
|
||||||
|
|
||||||
export const headerResource = [
|
export const headerResource = [
|
||||||
{
|
{
|
||||||
title: "文档",
|
title: i18n.global.t("certd.helpDoc"),
|
||||||
path: "https://certd.docmirror.cn",
|
path: "https://certd.docmirror.cn",
|
||||||
meta: {
|
meta: {
|
||||||
icon: "ion:document-text-outline"
|
icon: "ion:document-text-outline"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "源码",
|
title: i18n.global.t("certd.source"),
|
||||||
name: "source",
|
name: "source",
|
||||||
key: "source",
|
key: "source",
|
||||||
meta: {
|
meta: {
|
||||||
|
@ -15,14 +17,14 @@ export const headerResource = [
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
title: "github",
|
title: i18n.global.t("certd.github"),
|
||||||
path: "https://github.com/certd/certd",
|
path: "https://github.com/certd/certd",
|
||||||
meta: {
|
meta: {
|
||||||
icon: "ion:logo-github"
|
icon: "ion:logo-github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "gitee",
|
title: i18n.global.t("certd.gitee"),
|
||||||
path: "https://gitee.com/certd/certd",
|
path: "https://gitee.com/certd/certd",
|
||||||
meta: {
|
meta: {
|
||||||
icon: "ion:logo-octocat"
|
icon: "ion:logo-octocat"
|
||||||
|
@ -31,3 +33,4 @@ export const headerResource = [
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -2,16 +2,18 @@ import { IFrameView } from "/@/vben/layouts";
|
||||||
import { useSettingStore } from "/@/store/settings";
|
import { useSettingStore } from "/@/store/settings";
|
||||||
import { computed } from "vue";
|
import { computed } from "vue";
|
||||||
import TutorialButton from "/@/components/tutorial/index.vue";
|
import TutorialButton from "/@/components/tutorial/index.vue";
|
||||||
|
import i18n from '/@/locales/i18n';
|
||||||
|
|
||||||
export const aboutResource = [
|
export const aboutResource = [
|
||||||
{
|
{
|
||||||
title: "文档",
|
title: i18n.global.t("certd.dashboard.helpDoc"),
|
||||||
name: "document",
|
name: "document",
|
||||||
path: "/about/doc",
|
path: "/about/doc",
|
||||||
component: IFrameView,
|
component: IFrameView,
|
||||||
meta: {
|
meta: {
|
||||||
icon: "lucide:book-open-text",
|
icon: "lucide:book-open-text",
|
||||||
link: "https://certd.docmirror.cn",
|
link: "https://certd.docmirror.cn",
|
||||||
title: "文档",
|
title: i18n.global.t("certd.dashboard.helpDoc"),
|
||||||
order: 9999,
|
order: 9999,
|
||||||
show: () => {
|
show: () => {
|
||||||
const settingStore = useSettingStore();
|
const settingStore = useSettingStore();
|
||||||
|
|
|
@ -38,12 +38,13 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
|
|
||||||
const checkStatusDict = dict({
|
const checkStatusDict = dict({
|
||||||
data: [
|
data: [
|
||||||
{ label: "成功", value: "ok", color: "green" },
|
{ label: t("checkStatus.success"), value: "ok", color: "green" },
|
||||||
{ label: "检查中", value: "checking", color: "blue" },
|
{ label: t("checkStatus.checking"), value: "checking", color: "blue" },
|
||||||
{ label: "异常", value: "error", color: "red" },
|
{ label: t("checkStatus.error"), value: "error", color: "red" },
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
const { openSiteIpMonitorDialog } = useSiteIpMonitor();
|
const { openSiteIpMonitorDialog } = useSiteIpMonitor();
|
||||||
const { openSiteImportDialog } = useSiteImport();
|
const { openSiteImportDialog } = useSiteImport();
|
||||||
return {
|
return {
|
||||||
|
@ -74,35 +75,37 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
add: {
|
add: {
|
||||||
async click() {
|
async click() {
|
||||||
if (!settingsStore.isPlus) {
|
if (!settingsStore.isPlus) {
|
||||||
//非plus
|
// 非plus
|
||||||
if (crudBinding.value.data.length >= 1) {
|
if (crudBinding.value.data.length >= 1) {
|
||||||
notification.error({
|
notification.error({
|
||||||
message: "基础版只能添加一个监控站点,请赞助升级专业版",
|
message: t("certd.monitor.basicLimitError"),
|
||||||
});
|
});
|
||||||
mitter.emit("openVipModal");
|
mitter.emit("openVipModal");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//检查是否监控站点数量超出限制
|
//检查是否监控站点数量超出限制
|
||||||
if (settingsStore.isComm && settingsStore.suiteSetting.enabled) {
|
if (settingsStore.isComm && settingsStore.suiteSetting.enabled) {
|
||||||
//检查数量是否超限
|
// 检查数量是否超限
|
||||||
const suiteDetail = await mySuiteApi.SuiteDetailGet();
|
const suiteDetail = await mySuiteApi.SuiteDetailGet();
|
||||||
const max = suiteDetail.monitorCount.max;
|
const max = suiteDetail.monitorCount.max;
|
||||||
if (max != -1 && max <= suiteDetail.monitorCount.used) {
|
if (max != -1 && max <= suiteDetail.monitorCount.used) {
|
||||||
notification.error({
|
notification.error({
|
||||||
message: `对不起,您最多只能创建条${max}监控记录,请购买或升级套餐`,
|
message: t("certd.monitor.limitExceeded", { max }),
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await crudExpose.openAdd({});
|
await crudExpose.openAdd({});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
//导入按钮
|
//导入按钮
|
||||||
import: {
|
import: {
|
||||||
show: true,
|
show: true,
|
||||||
text: "批量导入",
|
text: t("certd.monitor.bulkImport"),
|
||||||
type: "primary",
|
type: "primary",
|
||||||
async click() {
|
async click() {
|
||||||
openSiteImportDialog({
|
openSiteImportDialog({
|
||||||
|
@ -130,7 +133,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
await api.DoCheck(row.id);
|
await api.DoCheck(row.id);
|
||||||
await crudExpose.doRefresh();
|
await crudExpose.doRefresh();
|
||||||
notification.success({
|
notification.success({
|
||||||
message: "检查任务已提交,请稍后刷新查看结果",
|
message: t("certd.monitor.checkSubmittedRefresh"),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -138,11 +141,9 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
order: 10,
|
order: 10,
|
||||||
type: "link",
|
type: "link",
|
||||||
text: null,
|
text: null,
|
||||||
show: compute(({ row }) => {
|
show: compute(({ row }) => row.ipCheck === true),
|
||||||
return row.ipCheck === true;
|
|
||||||
}),
|
|
||||||
tooltip: {
|
tooltip: {
|
||||||
title: "IP管理",
|
title: t("certd.monitor.ipManagement"),
|
||||||
},
|
},
|
||||||
icon: "entypo:address",
|
icon: "entypo:address",
|
||||||
click: async ({ row }) => {
|
click: async ({ row }) => {
|
||||||
|
@ -172,29 +173,29 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
name: {
|
name: {
|
||||||
title: "站点名称",
|
title: t("certd.monitor.siteName"),
|
||||||
search: {
|
search: {
|
||||||
show: true,
|
show: true,
|
||||||
},
|
},
|
||||||
type: "text",
|
type: "text",
|
||||||
form: {
|
form: {
|
||||||
rules: [{ required: true, message: "请输入站点名称" }],
|
rules: [{ required: true, message: t("certd.monitor.enterSiteName") }],
|
||||||
},
|
},
|
||||||
column: {
|
column: {
|
||||||
width: 160,
|
width: 160,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
domain: {
|
domain: {
|
||||||
title: "网站域名",
|
title: t("certd.monitor.domain"),
|
||||||
search: {
|
search: {
|
||||||
show: true,
|
show: true,
|
||||||
},
|
},
|
||||||
type: "text",
|
type: "text",
|
||||||
form: {
|
form: {
|
||||||
rules: [
|
rules: [
|
||||||
{ required: true, message: "请输入域名" },
|
{ required: true, message: t("certd.monitor.enterDomain") },
|
||||||
//@ts-ignore
|
// @ts-ignore
|
||||||
{ type: "domains", message: "请输入正确的域名" },
|
{ type: "domains", message: t("certd.monitor.enterValidDomain") },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
column: {
|
column: {
|
||||||
|
@ -215,14 +216,14 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
httpsPort: {
|
httpsPort: {
|
||||||
title: "HTTPS端口",
|
title: t("certd.monitor.httpsPort"),
|
||||||
search: {
|
search: {
|
||||||
show: false,
|
show: false,
|
||||||
},
|
},
|
||||||
type: "number",
|
type: "number",
|
||||||
form: {
|
form: {
|
||||||
value: 443,
|
value: 443,
|
||||||
rules: [{ required: true, message: "请输入端口" }],
|
rules: [{ required: true, message: t("certd.monitor.enterPort") }],
|
||||||
},
|
},
|
||||||
column: {
|
column: {
|
||||||
width: 100,
|
width: 100,
|
||||||
|
@ -230,7 +231,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
certInfo: {
|
certInfo: {
|
||||||
title: "证书信息",
|
title: t("certd.monitor.certInfo"),
|
||||||
type: "text",
|
type: "text",
|
||||||
form: { show: false },
|
form: { show: false },
|
||||||
column: {
|
column: {
|
||||||
|
@ -243,8 +244,8 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
content() {
|
content() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div>证书颁发机构:{row.certProvider}</div>
|
<div>{t("certd.monitor.issuer")}: {row.certProvider}</div>
|
||||||
<div>证书域名:{row.certDomains}</div>
|
<div>{t("certd.monitor.certDomains")}: {row.certDomains}</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -258,7 +259,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
certDomains: {
|
certDomains: {
|
||||||
title: "证书域名",
|
title: t("certd.monitor.certDomains"),
|
||||||
search: {
|
search: {
|
||||||
show: true,
|
show: true,
|
||||||
},
|
},
|
||||||
|
@ -280,7 +281,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
certProvider: {
|
certProvider: {
|
||||||
title: "颁发机构",
|
title: t("certd.monitor.certProvider"),
|
||||||
search: {
|
search: {
|
||||||
show: false,
|
show: false,
|
||||||
},
|
},
|
||||||
|
@ -298,15 +299,15 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
certStatus: {
|
certStatus: {
|
||||||
title: "证书状态",
|
title: t("certd.monitor.certStatus"),
|
||||||
search: {
|
search: {
|
||||||
show: true,
|
show: true,
|
||||||
},
|
},
|
||||||
type: "dict-select",
|
type: "dict-select",
|
||||||
dict: dict({
|
dict: dict({
|
||||||
data: [
|
data: [
|
||||||
{ label: "正常", value: "ok", color: "green" },
|
{ label: t("certd.monitor.status.ok"), value: "ok", color: "green" },
|
||||||
{ label: "过期", value: "expired", color: "red" },
|
{ label: t("certd.monitor.status.expired"), value: "expired", color: "red" },
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
form: {
|
form: {
|
||||||
|
@ -320,7 +321,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
certExpiresTime: {
|
certExpiresTime: {
|
||||||
title: "证书到期时间",
|
title: t("certd.monitor.certExpiresTime"),
|
||||||
search: {
|
search: {
|
||||||
show: false,
|
show: false,
|
||||||
},
|
},
|
||||||
|
@ -338,12 +339,19 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
const leftDays = dayjs(value).diff(dayjs(), "day");
|
const leftDays = dayjs(value).diff(dayjs(), "day");
|
||||||
const color = leftDays < 20 ? "red" : "#389e0d";
|
const color = leftDays < 20 ? "red" : "#389e0d";
|
||||||
const percent = (leftDays / 90) * 100;
|
const percent = (leftDays / 90) * 100;
|
||||||
return <a-progress title={expireDate + "过期"} percent={percent} strokeColor={color} format={(percent: number) => `${leftDays}天`} />;
|
return (
|
||||||
|
<a-progress
|
||||||
|
title={expireDate + t("certd.monitor.expired")}
|
||||||
|
percent={percent}
|
||||||
|
strokeColor={color}
|
||||||
|
format={(percent: number) => `${leftDays}${t("certd.monitor.days")}`}
|
||||||
|
/>
|
||||||
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
lastCheckTime: {
|
lastCheckTime: {
|
||||||
title: "上次检查时间",
|
title: t("certd.monitor.lastCheckTime"),
|
||||||
search: {
|
search: {
|
||||||
show: false,
|
show: false,
|
||||||
},
|
},
|
||||||
|
@ -357,15 +365,15 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
disabled: {
|
disabled: {
|
||||||
title: "禁用启用",
|
title: t("certd.monitor.disabled"),
|
||||||
search: {
|
search: {
|
||||||
show: false,
|
show: false,
|
||||||
},
|
},
|
||||||
type: "dict-switch",
|
type: "dict-switch",
|
||||||
dict: dict({
|
dict: dict({
|
||||||
data: [
|
data: [
|
||||||
{ label: "启用", value: false, color: "green" },
|
{ label: t("common.enabled"), value: false, color: "green" },
|
||||||
{ label: "禁用", value: true, color: "red" },
|
{ label: t("common.disabled"), value: true, color: "red" },
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
form: {
|
form: {
|
||||||
|
@ -388,17 +396,17 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ipCheck: {
|
ipCheck: {
|
||||||
title: "开启IP检查",
|
title: t("certd.monitor.ipCheck"),
|
||||||
type: "dict-switch",
|
type: "dict-switch",
|
||||||
dict: dict({
|
dict: dict({
|
||||||
data: [
|
data: [
|
||||||
{ label: "启用", value: true, color: "green" },
|
{ label: t("common.enabled"), value: true, color: "green" },
|
||||||
{ label: "禁用", value: false, color: "gray" },
|
{ label: t("common.disabled"), value: false, color: "gray" },
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
form: {
|
form: {
|
||||||
value: false,
|
value: false,
|
||||||
rules: [{ required: true, message: "请选择" }],
|
rules: [{ required: true, message: t("certd.monitor.selectRequired") }],
|
||||||
},
|
},
|
||||||
column: {
|
column: {
|
||||||
align: "center",
|
align: "center",
|
||||||
|
@ -410,8 +418,8 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
on: {
|
on: {
|
||||||
change({ row, $event }) {
|
change({ row, $event }) {
|
||||||
Modal.confirm({
|
Modal.confirm({
|
||||||
title: "提示",
|
title: t("common.confirm"),
|
||||||
content: `确定${$event ? "开启" : "关闭"}IP检查?`,
|
content: t("certd.monitor.ipCheckConfirm", { status: $event ? t("common.enabled") : t("common.disabled") }),
|
||||||
onOk: async () => {
|
onOk: async () => {
|
||||||
await api.IpCheckChange(row.id, $event);
|
await api.IpCheckChange(row.id, $event);
|
||||||
await crudExpose.doRefresh();
|
await crudExpose.doRefresh();
|
||||||
|
@ -426,10 +434,10 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
}
|
||||||
} as ColumnCompositionProps,
|
} as ColumnCompositionProps,
|
||||||
ipCount: {
|
ipCount: {
|
||||||
title: "IP数量",
|
title: t("certd.monitor.ipCount"),
|
||||||
search: {
|
search: {
|
||||||
show: false,
|
show: false,
|
||||||
},
|
},
|
||||||
|
@ -444,7 +452,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
checkStatus: {
|
checkStatus: {
|
||||||
title: "检查状态",
|
title: t("certd.monitor.checkStatus"),
|
||||||
search: {
|
search: {
|
||||||
show: false,
|
show: false,
|
||||||
},
|
},
|
||||||
|
@ -457,7 +465,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
width: 100,
|
width: 100,
|
||||||
align: "center",
|
align: "center",
|
||||||
sorter: true,
|
sorter: true,
|
||||||
cellRender({ value, row, key }) {
|
cellRender({ value, row }) {
|
||||||
return (
|
return (
|
||||||
<a-tooltip title={row.error}>
|
<a-tooltip title={row.error}>
|
||||||
<fs-values-format v-model={value} dict={checkStatusDict}></fs-values-format>
|
<fs-values-format v-model={value} dict={checkStatusDict}></fs-values-format>
|
||||||
|
@ -484,7 +492,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
// }
|
// }
|
||||||
// },
|
// },
|
||||||
pipelineId: {
|
pipelineId: {
|
||||||
title: "关联流水线id",
|
title: t("certd.monitor.pipelineId"),
|
||||||
search: {
|
search: {
|
||||||
show: false,
|
show: false,
|
||||||
},
|
},
|
||||||
|
@ -497,7 +505,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
certInfoId: {
|
certInfoId: {
|
||||||
title: "证书id",
|
title: t("certd.monitor.certInfoId"),
|
||||||
search: {
|
search: {
|
||||||
show: false,
|
show: false,
|
||||||
},
|
},
|
||||||
|
|
|
@ -2,47 +2,55 @@
|
||||||
<fs-page>
|
<fs-page>
|
||||||
<template #header>
|
<template #header>
|
||||||
<div class="title flex items-center">
|
<div class="title flex items-center">
|
||||||
站点证书监控
|
{{ t("certd.monitor.title") }}
|
||||||
<div class="sub flex-1">
|
<div class="sub flex-1">
|
||||||
<div>
|
<div>
|
||||||
每天0点,检查网站证书的过期时间,到期前10天时将发出提醒(使用默认通知渠道);
|
{{ t("certd.monitor.description") }}
|
||||||
<router-link to="/certd/monitor/setting">站点监控设置</router-link>
|
<router-link to="/certd/monitor/setting">{{ t("certd.monitor.settingLink") }}</router-link>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center">
|
||||||
|
{{ t("certd.monitor.limitInfo") }}
|
||||||
|
<vip-button class="ml-5" mode="nav"></vip-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center">基础版限制1条,专业版以上无限制,当前<vip-button class="ml-5" mode="nav"></vip-button></div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="more">
|
<div class="more">
|
||||||
<a-button type="primary" @click="checkAll">检查全部</a-button>
|
<a-button type="primary" @click="checkAll">{{ t("certd.monitor.checkAll") }}</a-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<fs-crud ref="crudRef" v-bind="crudBinding"> </fs-crud>
|
<fs-crud ref="crudRef" v-bind="crudBinding"> </fs-crud>
|
||||||
</fs-page>
|
</fs-page>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onActivated, onMounted } from "vue";
|
import { 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 { siteInfoApi } from "./api";
|
import { siteInfoApi } from "./api";
|
||||||
import { Modal, notification } from "ant-design-vue";
|
import { Modal, notification } from "ant-design-vue";
|
||||||
|
import { useI18n } from "vue-i18n";
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: "SiteCertMonitor",
|
name: "SiteCertMonitor",
|
||||||
});
|
});
|
||||||
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: {} });
|
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: {} });
|
||||||
function checkAll() {
|
function checkAll() {
|
||||||
Modal.confirm({
|
Modal.confirm({
|
||||||
title: "确认",
|
title: t("certd.monitor.confirmTitle"), // "确认"
|
||||||
content: "确认触发检查全部站点证书吗?",
|
content: t("certd.monitor.confirmContent"), // "确认触发检查全部站点证书吗?"
|
||||||
onOk: async () => {
|
onOk: async () => {
|
||||||
await siteInfoApi.CheckAll();
|
await siteInfoApi.CheckAll();
|
||||||
notification.success({
|
notification.success({
|
||||||
message: "检查任务已提交",
|
message: t("certd.monitor.checkSubmitted"), // "检查任务已提交"
|
||||||
description: "请稍后刷新页面查看结果",
|
description: t("certd.monitor.pleaseRefresh"), // "请稍后刷新页面查看结果"
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 页面打开后获取列表数据
|
// 页面打开后获取列表数据
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
crudExpose.doRefresh();
|
crudExpose.doRefresh();
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
import { useFormWrapper } from "@fast-crud/fast-crud";
|
import { useFormWrapper } from "@fast-crud/fast-crud";
|
||||||
import { siteInfoApi } from "./api";
|
import { siteInfoApi } from "./api";
|
||||||
|
import { useI18n } from "vue-i18n";
|
||||||
|
|
||||||
export function useSiteImport() {
|
export function useSiteImport() {
|
||||||
|
const { t } = useI18n();
|
||||||
const { openCrudFormDialog } = useFormWrapper();
|
const { openCrudFormDialog } = useFormWrapper();
|
||||||
|
|
||||||
async function openSiteImportDialog(opts: { afterSubmit: any }) {
|
async function openSiteImportDialog(opts: { afterSubmit: any }) {
|
||||||
|
@ -11,12 +13,12 @@ export function useSiteImport() {
|
||||||
columns: {
|
columns: {
|
||||||
text: {
|
text: {
|
||||||
type: "textarea",
|
type: "textarea",
|
||||||
title: "域名列表",
|
title: t("certd.domainList.title"), // 域名列表
|
||||||
form: {
|
form: {
|
||||||
helper: "格式【域名:端口:名称】,一行一个,其中端口、名称可以省略\n比如:\nwww.baidu.com:443:百度\nwww.taobao.com::淘宝\nwww.google.com",
|
helper: t("certd.domainList.helper"),
|
||||||
rules: [{ required: true, message: "请输入要导入的域名" }],
|
rules: [{ required: true, message: t("certd.domainList.required") }],
|
||||||
component: {
|
component: {
|
||||||
placeholder: "www.baidu.com:443:百度\nwww.taobao.com::淘宝\nwww.google.com\n",
|
placeholder: t("certd.domainList.placeholder"),
|
||||||
rows: 8,
|
rows: 8,
|
||||||
},
|
},
|
||||||
col: {
|
col: {
|
||||||
|
@ -25,6 +27,7 @@ export function useSiteImport() {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
form: {
|
form: {
|
||||||
async doSubmit({ form }) {
|
async doSubmit({ form }) {
|
||||||
return siteInfoApi.Import(form);
|
return siteInfoApi.Import(form);
|
||||||
|
|
|
@ -1,32 +1,22 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="notification-selector">
|
<div class="notification-selector">
|
||||||
<div class="flex-o w-100">
|
<div class="flex-o w-100">
|
||||||
<fs-dict-select class="flex-1" :value="modelValue" :dict="optionsDictRef" :disabled="disabled" :render-label="renderLabel" :slots="selectSlots" :allow-clear="true" v-bind="select" @update:value="onChange" />
|
<fs-dict-select class="flex-1" :value="modelValue" :dict="optionsDictRef" :disabled="disabled"
|
||||||
<fs-table-select
|
:render-label="renderLabel" :slots="selectSlots" :allow-clear="true" v-bind="select"
|
||||||
ref="tableSelectRef"
|
@update:value="onChange" />
|
||||||
class="flex-0"
|
<fs-table-select ref="tableSelectRef" class="flex-0" :model-value="modelValue" :dict="optionsDictRef"
|
||||||
:model-value="modelValue"
|
:create-crud-options="createCrudOptions" :crud-options-override="{
|
||||||
:dict="optionsDictRef"
|
|
||||||
:create-crud-options="createCrudOptions"
|
|
||||||
:crud-options-override="{
|
|
||||||
search: { show: false },
|
search: { show: false },
|
||||||
table: {
|
table: {
|
||||||
scroll: {
|
scroll: {
|
||||||
x: 540,
|
x: 540,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}"
|
}" :show-current="false" :show-select="false" :dialog="{ width: 960 }" :destroy-on-close="false" height="400px"
|
||||||
:show-current="false"
|
v-bind="tableSelect" @update:model-value="onChange" @dialog-closed="doRefresh">
|
||||||
:show-select="false"
|
|
||||||
:dialog="{ width: 960 }"
|
|
||||||
:destroy-on-close="false"
|
|
||||||
height="400px"
|
|
||||||
v-bind="tableSelect"
|
|
||||||
@update:model-value="onChange"
|
|
||||||
@dialog-closed="doRefresh"
|
|
||||||
>
|
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<fs-button class="ml-5" :disabled="disabled" :size="size" type="primary" icon="ant-design:edit-outlined" @click="scope.open"></fs-button>
|
<fs-button class="ml-5" :disabled="disabled" :size="size" type="primary"
|
||||||
|
icon="ant-design:edit-outlined" @click="scope.open"></fs-button>
|
||||||
</template>
|
</template>
|
||||||
</fs-table-select>
|
</fs-table-select>
|
||||||
</div>
|
</div>
|
||||||
|
@ -41,6 +31,9 @@ import { dict } from "@fast-crud/fast-crud";
|
||||||
import createCrudOptions from "../crud";
|
import createCrudOptions from "../crud";
|
||||||
import { notificationProvide } from "/@/views/certd/notification/common";
|
import { notificationProvide } from "/@/views/certd/notification/common";
|
||||||
import { useUserStore } from "/@/store/user";
|
import { useUserStore } from "/@/store/user";
|
||||||
|
import { useI18n } from "vue-i18n";
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: "NotificationSelector",
|
name: "NotificationSelector",
|
||||||
|
@ -83,7 +76,7 @@ const optionsDictRef = dict({
|
||||||
const data = [
|
const data = [
|
||||||
{
|
{
|
||||||
id: 0,
|
id: 0,
|
||||||
name: "使用默认通知",
|
name: t("certd.notificationDefault"),
|
||||||
icon: "ion:notifications",
|
icon: "ion:notifications",
|
||||||
},
|
},
|
||||||
...dict.data,
|
...dict.data,
|
||||||
|
@ -91,6 +84,7 @@ const optionsDictRef = dict({
|
||||||
dict.setData(data);
|
dict.setData(data);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const renderLabel = (option: any) => {
|
const renderLabel = (option: any) => {
|
||||||
return <span>{option.name}</span>;
|
return <span>{option.name}</span>;
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,8 +11,11 @@ import * as api from "../api";
|
||||||
import { PluginGroup, usePluginStore } from "/@/store/plugin";
|
import { PluginGroup, usePluginStore } from "/@/store/plugin";
|
||||||
import { createNotificationApi } from "/@/views/certd/notification/api";
|
import { createNotificationApi } from "/@/views/certd/notification/api";
|
||||||
import GroupSelector from "../group/group-selector.vue";
|
import GroupSelector from "../group/group-selector.vue";
|
||||||
|
import { useI18n } from "vue-i18n";
|
||||||
|
|
||||||
|
|
||||||
export function setRunnableIds(pipeline: any) {
|
export function setRunnableIds(pipeline: any) {
|
||||||
|
const { t } = useI18n();
|
||||||
const idMap: any = {};
|
const idMap: any = {};
|
||||||
function createId(oldId: any) {
|
function createId(oldId: any) {
|
||||||
if (oldId == null) {
|
if (oldId == null) {
|
||||||
|
@ -53,6 +56,7 @@ export function setRunnableIds(pipeline: any) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useCertPipelineCreator() {
|
export function useCertPipelineCreator() {
|
||||||
|
const { t } = useI18n();
|
||||||
const { openCrudFormDialog } = useFormWrapper();
|
const { openCrudFormDialog } = useFormWrapper();
|
||||||
|
|
||||||
const pluginStore = usePluginStore();
|
const pluginStore = usePluginStore();
|
||||||
|
@ -117,12 +121,12 @@ export function useCertPipelineCreator() {
|
||||||
wrapper: {
|
wrapper: {
|
||||||
width: 1350,
|
width: 1350,
|
||||||
saveRemind: false,
|
saveRemind: false,
|
||||||
title: "创建证书流水线",
|
title: t("certd.pipelineForm.createTitle"),
|
||||||
},
|
},
|
||||||
group: {
|
group: {
|
||||||
groups: {
|
groups: {
|
||||||
more: {
|
more: {
|
||||||
header: "更多参数",
|
header: t("certd.pipelineForm.moreParams"),
|
||||||
columns: moreParams,
|
columns: moreParams,
|
||||||
collapsed: true,
|
collapsed: true,
|
||||||
},
|
},
|
||||||
|
@ -131,7 +135,7 @@ export function useCertPipelineCreator() {
|
||||||
},
|
},
|
||||||
columns: {
|
columns: {
|
||||||
certApplyPlugin: {
|
certApplyPlugin: {
|
||||||
title: "证书申请插件",
|
title: t("certd.plugin.selectTitle"),
|
||||||
type: "dict-select",
|
type: "dict-select",
|
||||||
dict: dict({
|
dict: dict({
|
||||||
data: [
|
data: [
|
||||||
|
@ -146,8 +150,8 @@ export function useCertPipelineCreator() {
|
||||||
render: () => {
|
render: () => {
|
||||||
return (
|
return (
|
||||||
<ul>
|
<ul>
|
||||||
<li>JS-ACME:使用简单方便,功能强大【推荐】</li>
|
<li>{t("certd.plugin.jsAcme")}</li>
|
||||||
<li>Lego-ACME:基于Lego实现,支持海量DNS提供商,熟悉LEGO的用户可以使用</li>
|
<li>{t("certd.plugin.legoAcme")}</li>
|
||||||
</ul>
|
</ul>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -168,7 +172,7 @@ export function useCertPipelineCreator() {
|
||||||
},
|
},
|
||||||
...inputs,
|
...inputs,
|
||||||
triggerCron: {
|
triggerCron: {
|
||||||
title: "定时触发",
|
title: t("certd.pipelineForm.triggerCronTitle"),
|
||||||
type: "text",
|
type: "text",
|
||||||
form: {
|
form: {
|
||||||
value: `0 ${randomMin} ${randomHour} * * *`,
|
value: `0 ${randomMin} ${randomHour} * * *`,
|
||||||
|
@ -177,12 +181,12 @@ export function useCertPipelineCreator() {
|
||||||
vModel: "modelValue",
|
vModel: "modelValue",
|
||||||
placeholder: "0 0 4 * * *",
|
placeholder: "0 0 4 * * *",
|
||||||
},
|
},
|
||||||
helper: "点击上面的按钮,选择每天几点定时执行。\n建议设置为每天触发一次,证书未到期之前任务会跳过,不会重复执行",
|
helper: t("certd.pipelineForm.triggerCronHelper"),
|
||||||
order: 100,
|
order: 100,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
notification: {
|
notification: {
|
||||||
title: "失败通知",
|
title: t("certd.pipelineForm.notificationTitle"),
|
||||||
type: "text",
|
type: "text",
|
||||||
form: {
|
form: {
|
||||||
value: 0,
|
value: 0,
|
||||||
|
@ -196,11 +200,11 @@ export function useCertPipelineCreator() {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
order: 101,
|
order: 101,
|
||||||
helper: "任务执行失败实时提醒",
|
helper: t("certd.pipelineForm.notificationHelper"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
groupId: {
|
groupId: {
|
||||||
title: "流水线分组",
|
title: t("certd.pipelineForm.groupIdTitle"),
|
||||||
type: "dict-select",
|
type: "dict-select",
|
||||||
dict: groupDictRef,
|
dict: groupDictRef,
|
||||||
form: {
|
form: {
|
||||||
|
@ -210,7 +214,8 @@ export function useCertPipelineCreator() {
|
||||||
},
|
},
|
||||||
order: 9999,
|
order: 9999,
|
||||||
},
|
},
|
||||||
},
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<fs-form-item
|
<fs-form-item v-model="optionsFormState.receivers" :item="{
|
||||||
v-model="optionsFormState.receivers"
|
title: t('certd.email.title'),
|
||||||
:item="{
|
|
||||||
title: '收件邮箱',
|
|
||||||
key: 'type',
|
key: 'type',
|
||||||
component: {
|
component: {
|
||||||
name: 'a-select',
|
name: 'a-select',
|
||||||
|
@ -11,13 +9,13 @@
|
||||||
mode: 'tags',
|
mode: 'tags',
|
||||||
open: false
|
open: false
|
||||||
},
|
},
|
||||||
helper: '输入你的收件邮箱地址,支持多个邮箱',
|
helper: t('certd.email.helper'),
|
||||||
rules: [{ required: true, message: '此项必填' }]
|
rules: [{ required: true, message: t('certd.email.required') }]
|
||||||
}"
|
}" />
|
||||||
/>
|
|
||||||
|
|
||||||
<a-alert v-if="!settingStore.isPlus" class="m-1" type="info">
|
<a-alert v-if="!settingStore.isPlus" class="m-1" type="info">
|
||||||
<template #message> 还没有配置邮件服务器?<router-link :to="{ path: '/sys/settings/email' }">现在就去</router-link> </template>
|
<template #message> 还没有配置邮件服务器?<router-link :to="{ path: '/sys/settings/email' }">现在就去</router-link>
|
||||||
|
</template>
|
||||||
</a-alert>
|
</a-alert>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -25,11 +23,14 @@
|
||||||
import { Ref, ref, watch } from "vue";
|
import { Ref, ref, watch } from "vue";
|
||||||
import { useUserStore } from "/@/store/user";
|
import { useUserStore } from "/@/store/user";
|
||||||
import { useSettingStore } from "/@/store/settings";
|
import { useSettingStore } from "/@/store/settings";
|
||||||
|
import { useI18n } from "vue-i18n";
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
options: {
|
options: {
|
||||||
type: Object as PropType<any>,
|
type: Object as PropType<any>,
|
||||||
default: () => {}
|
default: () => { }
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,19 +1,21 @@
|
||||||
<template>
|
<template>
|
||||||
<a-drawer v-model:open="triggerDrawerVisible" placement="right" :closable="true" width="650px" class="pi-trigger-form" @after-open-change="triggerDrawerOnAfterVisibleChange">
|
<a-drawer v-model:open="triggerDrawerVisible" placement="right" :closable="true" width="650px"
|
||||||
|
class="pi-trigger-form" @after-open-change="triggerDrawerOnAfterVisibleChange">
|
||||||
<template #title>
|
<template #title>
|
||||||
<div>
|
<div>
|
||||||
编辑触发器
|
编辑触发器
|
||||||
<a-button v-if="mode === 'edit'" @click="triggerDelete()">
|
<a-button v-if="mode === 'edit'" @click="triggerDelete()">
|
||||||
<template #icon><DeleteOutlined /></template>
|
<template #icon>
|
||||||
|
<DeleteOutlined />
|
||||||
|
</template>
|
||||||
</a-button>
|
</a-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="currentTrigger">
|
<template v-if="currentTrigger">
|
||||||
<pi-container>
|
<pi-container>
|
||||||
<a-form ref="triggerFormRef" class="trigger-form" :model="currentTrigger" :label-col="labelCol" :wrapper-col="wrapperCol">
|
<a-form ref="triggerFormRef" class="trigger-form" :model="currentTrigger" :label-col="labelCol"
|
||||||
<fs-form-item
|
:wrapper-col="wrapperCol">
|
||||||
v-model="currentTrigger.title"
|
<fs-form-item v-model="currentTrigger.title" :item="{
|
||||||
:item="{
|
|
||||||
title: '触发器名称',
|
title: '触发器名称',
|
||||||
key: 'title',
|
key: 'title',
|
||||||
component: {
|
component: {
|
||||||
|
@ -22,12 +24,9 @@
|
||||||
disabled: !editMode,
|
disabled: !editMode,
|
||||||
},
|
},
|
||||||
rules: [{ required: true, message: '此项必填' }],
|
rules: [{ required: true, message: '此项必填' }],
|
||||||
}"
|
}" />
|
||||||
/>
|
|
||||||
|
|
||||||
<fs-form-item
|
<fs-form-item v-model="currentTrigger.type" :item="{
|
||||||
v-model="currentTrigger.type"
|
|
||||||
:item="{
|
|
||||||
title: '类型',
|
title: '类型',
|
||||||
key: 'type',
|
key: 'type',
|
||||||
value: 'timer',
|
value: 'timer',
|
||||||
|
@ -38,23 +37,19 @@
|
||||||
options: [{ value: 'timer', label: '定时' }],
|
options: [{ value: 'timer', label: '定时' }],
|
||||||
},
|
},
|
||||||
rules: [{ required: true, message: '此项必填' }],
|
rules: [{ required: true, message: '此项必填' }],
|
||||||
}"
|
}" />
|
||||||
/>
|
|
||||||
|
|
||||||
<fs-form-item
|
<fs-form-item v-model="currentTrigger.props.cron" :item="{
|
||||||
v-model="currentTrigger.props.cron"
|
title: t('certd.cronForm.title'),
|
||||||
:item="{
|
|
||||||
title: '定时脚本',
|
|
||||||
key: 'props.cron',
|
key: 'props.cron',
|
||||||
component: {
|
component: {
|
||||||
disabled: !editMode,
|
disabled: !editMode,
|
||||||
name: 'cron-editor',
|
name: 'cron-editor',
|
||||||
vModel: 'modelValue',
|
vModel: 'modelValue',
|
||||||
},
|
},
|
||||||
helper: '点击上面的按钮,选择每天几点定时执行。\n建议设置为每天触发一次,证书未到期之前任务会跳过,不会重复执行',
|
helper: t('certd.cronForm.helper'),
|
||||||
rules: [{ required: true, message: '此项必填' }],
|
rules: [{ required: true, message: t('certd.cronForm.required') }],
|
||||||
}"
|
}" />
|
||||||
/>
|
|
||||||
</a-form>
|
</a-form>
|
||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
|
@ -192,6 +187,5 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
.pi-trigger-form {
|
.pi-trigger-form {}
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|
Loading…
Reference in New Issue