perf: 证书监控支持设置证书即将过期天数

This commit is contained in:
xiaojunnuo
2025-10-14 22:25:04 +08:00
parent f612509cac
commit cd35568e04
8 changed files with 30 additions and 7 deletions
@@ -133,9 +133,9 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
name: "icon-select", name: "icon-select",
vModel: "value", vModel: "value",
options: [ options: [
{ value: "letsencrypt", label: "Let's Encrypt", icon: "simple-icons:letsencrypt" }, { value: "letsencrypt", label: "Let's Encrypt(免费,新手推荐)", icon: "simple-icons:letsencrypt" },
{ value: "google", label: "Google", icon: "flat-color-icons:google" }, { value: "google", label: "Google(免费)", icon: "flat-color-icons:google" },
{ value: "zerossl", label: "ZeroSSL", icon: "emojione:digit-zero" }, { value: "zerossl", label: "ZeroSSL(免费)", icon: "emojione:digit-zero" },
{ value: "sslcom", label: "SSL.com(仅主域名和www免费)", icon: "la:expeditedssl" }, { value: "sslcom", label: "SSL.com(仅主域名和www免费)", icon: "la:expeditedssl" },
], ],
}, },
@@ -281,6 +281,8 @@ export default {
cronTrigger: "Scheduled trigger for monitoring", cronTrigger: "Scheduled trigger for monitoring",
dnsServer: "DNS Server", dnsServer: "DNS Server",
dnsServerHelper: "Use a custom domain name resolution server, such as: 1.1.1.1 , support multiple", dnsServerHelper: "Use a custom domain name resolution server, such as: 1.1.1.1 , support multiple",
certValidDays: "Certificate Valid Days",
certValidDaysHelper: "Number of days before expiration to send a notification",
}, },
}, },
checkStatus: { checkStatus: {
@@ -286,6 +286,8 @@ export default {
cronTrigger: "定时触发监控", cronTrigger: "定时触发监控",
dnsServer: "DNS服务器", dnsServer: "DNS服务器",
dnsServerHelper: "使用自定义的域名解析服务器,如:1.1.1.1 , 支持多个", dnsServerHelper: "使用自定义的域名解析服务器,如:1.1.1.1 , 支持多个",
certValidDays: "证书到期前天数",
certValidDaysHelper: "证书到期前多少天发送通知",
}, },
}, },
checkStatus: { checkStatus: {
@@ -2,6 +2,7 @@
import { useI18n } from "/src/locales"; import { useI18n } from "/src/locales";
import { AddReq, ColumnCompositionProps, compute, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud"; import { AddReq, ColumnCompositionProps, compute, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
import { siteInfoApi } from "./api"; import { siteInfoApi } from "./api";
import * as settingApi from "./setting/api";
import dayjs from "dayjs"; import dayjs from "dayjs";
import { Modal, notification } from "ant-design-vue"; import { Modal, notification } from "ant-design-vue";
import { useSettingStore } from "/@/store/settings"; import { useSettingStore } from "/@/store/settings";
@@ -9,6 +10,7 @@ import { mySuiteApi } from "/@/views/certd/suite/mine/api";
import { mitter } from "/@/utils/util.mitt"; import { mitter } from "/@/utils/util.mitt";
import { useSiteIpMonitor } from "./ip/use"; import { useSiteIpMonitor } from "./ip/use";
import { useSiteImport } from "/@/views/certd/monitor/site/use"; import { useSiteImport } from "/@/views/certd/monitor/site/use";
import { ref } from "vue";
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet { export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const { t } = useI18n(); const { t } = useI18n();
@@ -47,6 +49,14 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
const { openSiteIpMonitorDialog } = useSiteIpMonitor(); const { openSiteIpMonitorDialog } = useSiteIpMonitor();
const { openSiteImportDialog } = useSiteImport(); const { openSiteImportDialog } = useSiteImport();
const certValidDaysRef = ref(10);
async function loadSetting() {
const setting = await settingApi.SiteMonitorSettingsGet();
certValidDaysRef.value = setting?.certValidDays || 10;
}
loadSetting()
function checkAll() { function checkAll() {
Modal.confirm({ Modal.confirm({
title: t("certd.monitor.confirmTitle"), // "确认" title: t("certd.monitor.confirmTitle"), // "确认"
@@ -385,6 +395,8 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
column: { column: {
conditionalRender: false, conditionalRender: false,
cellRender({ row }) { cellRender({ row }) {
const certValidDays = certValidDaysRef.value;
const { certEffectiveTime: effectiveTime, certExpiresTime: expiresTime } = row || {}; const { certEffectiveTime: effectiveTime, certExpiresTime: expiresTime } = row || {};
if (!expiresTime) { if (!expiresTime) {
return "-"; return "-";
@@ -397,7 +409,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
const effectiveDays = Math.max(90, dayjs(expiresTime).diff(applyDate, "day")); const effectiveDays = Math.max(90, dayjs(expiresTime).diff(applyDate, "day"));
// 距离失效时间剩余天数 // 距离失效时间剩余天数
const leftDays = dayjs(expiresTime).diff(dayjs(), "day"); const leftDays = dayjs(expiresTime).diff(dayjs(), "day");
const color = leftDays < 20 ? "red" : "#389e0d"; const color = leftDays < certValidDays ? "red" : "#389e0d";
const percent = (leftDays / effectiveDays) * 100; const percent = (leftDays / effectiveDays) * 100;
// console.log('cellRender', 'effectiveDays', effectiveDays, 'expiresTime', expiresTime, 'applyTime', applyTime, 'percent', percent, row) // console.log('cellRender', 'effectiveDays', effectiveDays, 'expiresTime', expiresTime, 'applyTime', applyTime, 'percent', percent, row)
return <a-progress title={expireDate + t("certd.monitor.expired")} percent={percent} strokeColor={color} format={(percent: number) => `${leftDays}${t("certd.monitor.days")}`} />; return <a-progress title={expireDate + t("certd.monitor.expired")} percent={percent} strokeColor={color} format={(percent: number) => `${leftDays}${t("certd.monitor.days")}`} />;
@@ -6,6 +6,7 @@ export type UserSiteMonitorSetting = {
retryTimes?: number; retryTimes?: number;
cron?: string; cron?: string;
dnsServer?: string[]; dnsServer?: string[];
certValidDays?: number;
}; };
export async function SiteMonitorSettingsGet() { export async function SiteMonitorSettingsGet() {
@@ -17,6 +17,12 @@
</div> </div>
<div class="helper">{{ t("certd.monitor.setting.monitorRetryTimes") }}</div> <div class="helper">{{ t("certd.monitor.setting.monitorRetryTimes") }}</div>
</a-form-item> </a-form-item>
<a-form-item :label="t('certd.monitor.setting.certValidDays')" :name="['certValidDays']">
<div class="flex">
<a-input-number v-model:value="formState.certValidDays" />
</div>
<div class="helper">{{ t("certd.monitor.setting.certValidDaysHelper") }}</div>
</a-form-item>
<a-form-item :label="t('certd.monitor.setting.dnsServer')" :name="['dnsServer']"> <a-form-item :label="t('certd.monitor.setting.dnsServer')" :name="['dnsServer']">
<div class="flex"> <div class="flex">
<a-select v-model:value="formState.dnsServer" mode="tags" :open="false" /> <a-select v-model:value="formState.dnsServer" mode="tags" :open="false" />
@@ -28,6 +28,7 @@ export class UserSiteMonitorSetting extends BaseSettings {
cron?:string = undefined; cron?:string = undefined;
retryTimes?:number = 3; retryTimes?:number = 3;
dnsServer?:string[] = undefined; dnsServer?:string[] = undefined;
certValidDays?:number = 10;
} }
export class UserEmailSetting extends BaseSettings { export class UserEmailSetting extends BaseSettings {
@@ -275,13 +275,12 @@ export class SiteInfoService extends BaseService<SiteInfoEntity> {
} }
async sendExpiresNotify(site: SiteInfoEntity) { async sendExpiresNotify(site: SiteInfoEntity) {
const setting = await this.userSettingsService.getSetting<UserSiteMonitorSetting>(site.userId, UserSiteMonitorSetting)
const tipDays = 10; const tipDays = setting?.certValidDays || 10;
const expires = site.certExpiresTime; const expires = site.certExpiresTime;
const validDays = dayjs(expires).diff(dayjs(), "day"); const validDays = dayjs(expires).diff(dayjs(), "day");
const url = await this.notificationService.getBindUrl("#/certd/monitor/site"); const url = await this.notificationService.getBindUrl("#/certd/monitor/site");
const setting = await this.userSettingsService.getSetting<UserSiteMonitorSetting>(site.userId, UserSiteMonitorSetting)
const content = `站点名称: ${site.name} \n站点域名: ${site.domain} \n证书域名: ${site.certDomains} \n颁发机构: ${site.certProvider} \n过期时间: ${dayjs(site.certExpiresTime).format("YYYY-MM-DD")} \n`; const content = `站点名称: ${site.name} \n站点域名: ${site.domain} \n证书域名: ${site.certDomains} \n颁发机构: ${site.certProvider} \n过期时间: ${dayjs(site.certExpiresTime).format("YYYY-MM-DD")} \n`;
if (validDays >= 0 && validDays < tipDays) { if (validDays >= 0 && validDays < tipDays) {
// 发通知 // 发通知