From 5fa4219a3158e2d725e196005591106aa8d492c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=80=97=E5=AD=90?= Date: Mon, 7 Jul 2025 17:18:35 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E8=AF=81=E4=B9=A6?= =?UTF-8?q?=E5=88=B0=E6=9C=9F=E6=97=B6=E9=97=B4=E6=98=BE=E7=A4=BA=EF=BC=8C?= =?UTF-8?q?close=20#836?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/biz/website.go | 2 ++ internal/data/website.go | 9 ++++++++ web/src/views/website/IndexView.vue | 34 ++++++++++++++++++++++++++++- 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/internal/biz/website.go b/internal/biz/website.go index 9db94a41..44effa75 100644 --- a/internal/biz/website.go +++ b/internal/biz/website.go @@ -19,6 +19,8 @@ type Website struct { CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` + CertExpire string `gorm:"-:all" json:"cert_expire"` // 仅显示 + Cert *Cert `gorm:"foreignKey:WebsiteID" json:"cert"` } diff --git a/internal/data/website.go b/internal/data/website.go index b0b7147a..56bb7894 100644 --- a/internal/data/website.go +++ b/internal/data/website.go @@ -223,6 +223,15 @@ func (r *websiteRepo) List(page, limit uint) ([]*biz.Website, int64, error) { return nil, 0, err } + // 取证书剩余有效时间 + for _, website := range websites { + crt, _ := io.Read(filepath.Join(app.Root, "server/vhost/cert", website.Name+".pem")) + if decode, err := cert.ParseCert(crt); err == nil { + hours := decode.NotAfter.Sub(time.Now()).Hours() + website.CertExpire = fmt.Sprintf("%.2f", hours/24) + } + } + return websites, total, nil } diff --git a/web/src/views/website/IndexView.vue b/web/src/views/website/IndexView.vue index b6ca3084..0be1f0c8 100644 --- a/web/src/views/website/IndexView.vue +++ b/web/src/views/website/IndexView.vue @@ -73,6 +73,38 @@ const columns: any = [ }) } }, + { + title: $gettext('Certificate expiration'), + key: 'cert_expire', + width: 200, + render(row: any) { + return h( + NTag, + { + type: row.cert_expire == 0 ? 'default' : row.cert_expire > 0 ? 'success' : 'error', + class: 'cursor-pointer hover:opacity-60', + onClick: () => handleEdit(row) + }, + { + default: () => { + if (row.cert_expire == 0) { + return $gettext('Not configured') + } + if (row.cert_expire < 0) { + return $gettext('Expired %{ days } days ago', { + days: Math.abs(row.cert_expire) + }) + } + if (row.cert_expire > 0) { + return $gettext('Expires in %{ days } days', { + days: row.cert_expire + }) + } + } + } + ) + } + }, { title: $gettext('Remark'), key: 'remark', @@ -378,7 +410,7 @@ onMounted(() => { striped remote :loading="loading" - :scroll-x="1200" + :scroll-x="1400" :columns="columns" :data="data" :row-key="(row: any) => row.id"