Browse Source

feat: 增加批量删除证书功能 (#3076)

pull/3079/head
zhengkunwang 1 year ago committed by GitHub
parent
commit
50b4458926
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      backend/app/api/v1/website_ssl.go
  2. 4
      backend/app/dto/request/website_ssl.go
  3. 1
      backend/app/service/website_ca.go
  4. 24
      backend/app/service/website_ssl.go
  5. 2
      backend/i18n/lang/en.yaml
  6. 2
      backend/i18n/lang/zh-Hant.yaml
  7. 2
      backend/i18n/lang/zh.yaml
  8. 26
      cmd/server/docs/docs.go
  9. 22
      cmd/server/docs/swagger.json
  10. 17
      cmd/server/docs/swagger.yaml
  11. 7
      frontend/src/components/del-dialog/index.vue
  12. 30
      frontend/src/views/website/ssl/index.vue

8
backend/app/api/v1/website_ssl.go

@ -132,17 +132,17 @@ func (b *BaseApi) GetDNSResolve(c *gin.Context) {
// @Summary Delete website ssl
// @Description 删除网站 ssl
// @Accept json
// @Param request body request.WebsiteResourceReq true "request"
// @Param request body request.WebsiteBatchDelReq true "request"
// @Success 200
// @Security ApiKeyAuth
// @Router /websites/ssl/del [post]
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"website_ssls","output_column":"primary_domain","output_value":"domain"}],"formatZH":"删除 ssl [domain]","formatEN":"Delete ssl [domain]"}
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"ids","isList":true,"db":"website_ssls","output_column":"primary_domain","output_value":"domain"}],"formatZH":"删除 ssl [domain]","formatEN":"Delete ssl [domain]"}
func (b *BaseApi) DeleteWebsiteSSL(c *gin.Context) {
var req request.WebsiteResourceReq
var req request.WebsiteBatchDelReq
if err := helper.CheckBindAndValidate(&req, c); err != nil {
return
}
if err := websiteSSLService.Delete(req.ID); err != nil {
if err := websiteSSLService.Delete(req.IDs); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}

4
backend/app/dto/request/website_ssl.go

@ -58,6 +58,10 @@ type WebsiteResourceReq struct {
ID uint `json:"id" validate:"required"`
}
type WebsiteBatchDelReq struct {
IDs []uint `json:"ids" validate:"required"`
}
type WebsiteSSLUpdate struct {
ID uint `json:"id" validate:"required"`
AutoRenew bool `json:"autoRenew"`

1
backend/app/service/website_ca.go

@ -149,6 +149,7 @@ func (w WebsiteCAService) GetCA(id uint) (response.WebsiteCADTO, error) {
}
func (w WebsiteCAService) Delete(id uint) error {
return websiteCARepo.DeleteBy(commonRepo.WithByID(id))
}

24
backend/app/service/website_ssl.go

@ -38,7 +38,7 @@ type IWebsiteSSLService interface {
Renew(sslId uint) error
GetDNSResolve(req request.WebsiteDNSReq) ([]response.WebsiteDNSRes, error)
GetWebsiteSSL(websiteId uint) (response.WebsiteSSLDTO, error)
Delete(id uint) error
Delete(ids []uint) error
Update(update request.WebsiteSSLUpdate) error
Upload(req request.WebsiteSSLUpload) error
ObtainSSL(apply request.WebsiteSSLApply) error
@ -299,6 +299,8 @@ func (w WebsiteSSLService) Renew(sslId uint) error {
if err := client.UseHTTP(path.Join(constant.AppInstallDir, constant.AppOpenresty, appInstall.Name, "root")); err != nil {
return err
}
case constant.SelfSigned:
}
resource, err := client.RenewSSL(websiteSSL.CertURL)
@ -380,11 +382,23 @@ func (w WebsiteSSLService) GetWebsiteSSL(websiteId uint) (response.WebsiteSSLDTO
return res, nil
}
func (w WebsiteSSLService) Delete(id uint) error {
if websites, _ := websiteRepo.GetBy(websiteRepo.WithWebsiteSSLID(id)); len(websites) > 0 {
return buserr.New(constant.ErrSSLCannotDelete)
func (w WebsiteSSLService) Delete(ids []uint) error {
var names []string
for _, id := range ids {
if websites, _ := websiteRepo.GetBy(websiteRepo.WithWebsiteSSLID(id)); len(websites) > 0 {
oldSSL, _ := websiteSSLRepo.GetFirst(commonRepo.WithByID(id))
if oldSSL.ID > 0 {
names = append(names, oldSSL.PrimaryDomain)
}
continue
} else {
_ = websiteSSLRepo.DeleteBy(commonRepo.WithByID(id))
}
}
if len(names) > 0 {
return buserr.WithName("ErrSSLCannotDelete", strings.Join(names, ","))
}
return websiteSSLRepo.DeleteBy(commonRepo.WithByID(id))
return nil
}
func (w WebsiteSSLService) Update(update request.WebsiteSSLUpdate) error {

2
backend/i18n/lang/en.yaml

@ -85,7 +85,7 @@ ErrDomainIsUsed: "Domain is already used by website {{ .name }}"
ErrDomainFormat: "{{ .name }} domain format error"
#ssl
ErrSSLCannotDelete: "The certificate is being used by the website and cannot be removed"
ErrSSLCannotDelete: "The certificate {{ .name }} is being used by the website and cannot be removed"
ErrAccountCannotDelete: "The certificate associated with the account cannot be deleted"
ErrSSLApply: "The certificate continues to be signed successfully, but openresty reload fails, please check the configuration!"
ErrEmailIsExist: 'Email is already exist'

2
backend/i18n/lang/zh-Hant.yaml

@ -85,7 +85,7 @@ ErrDomainIsUsed: "域名已被網站【{{ .name }}】使用"
ErrDomainFormat: "{{ .name }} 域名格式不正確"
#ssl
ErrSSLCannotDelete: "證書正在被網站使用,無法刪除"
ErrSSLCannotDelete: "{{ .name }} 證書正在被網站使用,無法刪除"
ErrAccountCannotDelete: "帳號關聯證書,無法刪除"
ErrSSLApply: "證書續簽成功,openresty reload失敗,請檢查配置!"
ErrEmailIsExist: '郵箱已存在'

2
backend/i18n/lang/zh.yaml

@ -85,7 +85,7 @@ ErrDomainIsUsed: "域名已被网站【{{ .name }}】使用"
ErrDomainFormat: "{{ .name }} 域名格式不正确"
#ssl
ErrSSLCannotDelete: "证书正在被网站使用,无法删除"
ErrSSLCannotDelete: "{{ .name }} 证书正在被网站使用,无法删除"
ErrAccountCannotDelete: "账号关联证书,无法删除"
ErrSSLApply: "证书续签成功,openresty reload失败,请检查配置!"
ErrEmailIsExist: '邮箱已存在'

26
cmd/server/docs/docs.go

@ -1,5 +1,5 @@
// Code generated by swaggo/swag. DO NOT EDIT.
// Package docs GENERATED BY SWAG; DO NOT EDIT
// This file was generated by swaggo/swag
package docs
import "github.com/swaggo/swag"
@ -12850,7 +12850,7 @@ const docTemplate = `{
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/request.WebsiteResourceReq"
"$ref": "#/definitions/request.WebsiteBatchDelReq"
}
}
],
@ -12864,14 +12864,14 @@ const docTemplate = `{
{
"db": "website_ssls",
"input_column": "id",
"input_value": "id",
"isList": false,
"input_value": "ids",
"isList": true,
"output_column": "primary_domain",
"output_value": "domain"
}
],
"bodyKeys": [
"id"
"ids"
],
"formatEN": "Delete ssl [domain]",
"formatZH": "删除 ssl [domain]",
@ -18907,6 +18907,20 @@ const docTemplate = `{
}
}
},
"request.WebsiteBatchDelReq": {
"type": "object",
"required": [
"ids"
],
"properties": {
"ids": {
"type": "array",
"items": {
"type": "integer"
}
}
}
},
"request.WebsiteCACreate": {
"type": "object",
"required": [

22
cmd/server/docs/swagger.json

@ -12843,7 +12843,7 @@
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/request.WebsiteResourceReq"
"$ref": "#/definitions/request.WebsiteBatchDelReq"
}
}
],
@ -12857,14 +12857,14 @@
{
"db": "website_ssls",
"input_column": "id",
"input_value": "id",
"isList": false,
"input_value": "ids",
"isList": true,
"output_column": "primary_domain",
"output_value": "domain"
}
],
"bodyKeys": [
"id"
"ids"
],
"formatEN": "Delete ssl [domain]",
"formatZH": "删除 ssl [domain]",
@ -18900,6 +18900,20 @@
}
}
},
"request.WebsiteBatchDelReq": {
"type": "object",
"required": [
"ids"
],
"properties": {
"ids": {
"type": "array",
"items": {
"type": "integer"
}
}
}
},
"request.WebsiteCACreate": {
"type": "object",
"required": [

17
cmd/server/docs/swagger.yaml

@ -3724,6 +3724,15 @@ definitions:
- keyType
- type
type: object
request.WebsiteBatchDelReq:
properties:
ids:
items:
type: integer
type: array
required:
- ids
type: object
request.WebsiteCACreate:
properties:
city:
@ -12840,7 +12849,7 @@ paths:
name: request
required: true
schema:
$ref: '#/definitions/request.WebsiteResourceReq'
$ref: '#/definitions/request.WebsiteBatchDelReq'
responses:
"200":
description: OK
@ -12853,12 +12862,12 @@ paths:
BeforeFunctions:
- db: website_ssls
input_column: id
input_value: id
isList: false
input_value: ids
isList: true
output_column: primary_domain
output_value: domain
bodyKeys:
- id
- ids
formatEN: Delete ssl [domain]
formatZH: 删除 ssl [domain]
paramKeys: []

7
frontend/src/components/del-dialog/index.vue

@ -1,6 +1,6 @@
<template>
<div>
<el-dialog v-model="open" :title="form.title" width="30%" :close-on-click-modal="false">
<el-dialog v-model="open" :title="form.title" width="30%" :close-on-click-modal="false" @close="handleClose">
<div v-loading="loading">
<el-row type="flex" justify="center">
<el-col :span="22">
@ -98,6 +98,11 @@ const onConfirm = async () => {
});
};
const handleClose = () => {
emit('cancel');
open.value = false;
};
onMounted(() => {});
defineExpose({

30
frontend/src/views/website/ssl/index.vue

@ -25,10 +25,20 @@
<el-button type="primary" plain @click="openDnsAccount()">
{{ $t('website.dnsAccountManage') }}
</el-button>
<el-button plain @click="deleteSSL(null)" :disabled="selects.length === 0">
{{ $t('commons.button.delete') }}
</el-button>
</template>
<template #main>
<br />
<ComplexTable :data="data" :pagination-config="paginationConfig" @search="search()" v-loading="loading">
<ComplexTable
:data="data"
:pagination-config="paginationConfig"
@search="search()"
v-model:selects="selects"
v-loading="loading"
>
<el-table-column type="selection" width="30" />
<el-table-column
:label="$t('website.domain')"
fix
@ -129,7 +139,7 @@
<Detail ref="detailRef"></Detail>
<SSLUpload ref="sslUploadRef" @close="search()"></SSLUpload>
<Apply ref="applyRef" @search="search" />
<OpDialog ref="opRef" @search="search" />
<OpDialog ref="opRef" @search="search" @cancel="search" />
<Log ref="logRef" @close="search()" />
<CA ref="caRef" @close="search()" />
</LayoutContent>
@ -172,6 +182,7 @@ const sslUploadRef = ref();
const applyRef = ref();
const logRef = ref();
const caRef = ref();
let selects = ref<any>([]);
const routerButton = [
{
@ -277,16 +288,27 @@ const applySSL = (row: Website.SSLDTO) => {
};
const deleteSSL = async (row: any) => {
let names = [];
let params = {};
if (row == null) {
names = selects.value.map((item: Website.SSLDTO) => item.primaryDomain);
params = { ids: selects.value.map((item: Website.SSLDTO) => item.id) };
} else {
names = [row.primaryDomain];
params = { ids: [row.id] };
}
opRef.value.acceptParams({
title: i18n.global.t('commons.button.delete'),
names: [row.primaryDomain],
names: names,
msg: i18n.global.t('commons.msg.operatorHelper', [
i18n.global.t('website.ssl'),
i18n.global.t('commons.button.delete'),
]),
api: DeleteSSL,
params: { id: row.id },
params: params,
});
search();
};
onMounted(() => {

Loading…
Cancel
Save