mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-10-08 22:46:51 +08:00
feat: 证书页面增加上传证书功能 (#2735)
Refs https://github.com/1Panel-dev/1Panel/issues/1323
This commit is contained in:
parent
c526e7a5ac
commit
d43bc3e427
15 changed files with 440 additions and 34 deletions
|
@ -192,3 +192,24 @@ func (b *BaseApi) UpdateWebsiteSSL(c *gin.Context) {
|
|||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
||||
// @Tags Website SSL
|
||||
// @Summary Upload ssl
|
||||
// @Description 上传 ssl
|
||||
// @Accept json
|
||||
// @Param request body request.WebsiteSSLUpload true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /websites/ssl/upload [post]
|
||||
// @x-panel-log {"bodyKeys":["type"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"上传 ssl [type]","formatEN":"Upload ssl [type]"}
|
||||
func (b *BaseApi) UploadWebsiteSSL(c *gin.Context) {
|
||||
var req request.WebsiteSSLUpload
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
if err := websiteSSLService.Upload(req); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, nil)
|
||||
}
|
||||
|
|
|
@ -50,3 +50,11 @@ type WebsiteSSLUpdate struct {
|
|||
ID uint `json:"id" validate:"required"`
|
||||
AutoRenew bool `json:"autoRenew" validate:"required"`
|
||||
}
|
||||
|
||||
type WebsiteSSLUpload struct {
|
||||
PrivateKey string `json:"privateKey"`
|
||||
Certificate string `json:"certificate"`
|
||||
PrivateKeyPath string `json:"privateKeyPath"`
|
||||
CertificatePath string `json:"certificatePath"`
|
||||
Type string `json:"type" validate:"required,oneof=paste local"`
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"github.com/1Panel-dev/1Panel/backend/buserr"
|
||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||
"github.com/1Panel-dev/1Panel/backend/global"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/files"
|
||||
"github.com/1Panel-dev/1Panel/backend/utils/ssl"
|
||||
"path"
|
||||
"strconv"
|
||||
|
@ -30,6 +31,7 @@ type IWebsiteSSLService interface {
|
|||
GetWebsiteSSL(websiteId uint) (response.WebsiteSSLDTO, error)
|
||||
Delete(id uint) error
|
||||
Update(update request.WebsiteSSLUpdate) error
|
||||
Upload(req request.WebsiteSSLUpload) error
|
||||
}
|
||||
|
||||
func NewIWebsiteSSLService() IWebsiteSSLService {
|
||||
|
@ -289,3 +291,60 @@ func (w WebsiteSSLService) Update(update request.WebsiteSSLUpdate) error {
|
|||
websiteSSL.AutoRenew = update.AutoRenew
|
||||
return websiteSSLRepo.Save(websiteSSL)
|
||||
}
|
||||
|
||||
func (w WebsiteSSLService) Upload(req request.WebsiteSSLUpload) error {
|
||||
newSSL := &model.WebsiteSSL{
|
||||
Provider: constant.Manual,
|
||||
}
|
||||
|
||||
if req.Type == "local" {
|
||||
fileOp := files.NewFileOp()
|
||||
if !fileOp.Stat(req.PrivateKeyPath) {
|
||||
return buserr.New("ErrSSLKeyNotFound")
|
||||
}
|
||||
if !fileOp.Stat(req.CertificatePath) {
|
||||
return buserr.New("ErrSSLCertificateNotFound")
|
||||
}
|
||||
if content, err := fileOp.GetContent(req.PrivateKeyPath); err != nil {
|
||||
return err
|
||||
} else {
|
||||
newSSL.PrivateKey = string(content)
|
||||
}
|
||||
if content, err := fileOp.GetContent(req.CertificatePath); err != nil {
|
||||
return err
|
||||
} else {
|
||||
newSSL.Pem = string(content)
|
||||
}
|
||||
} else {
|
||||
newSSL.PrivateKey = req.PrivateKey
|
||||
newSSL.Pem = req.Certificate
|
||||
}
|
||||
|
||||
privateKeyCertBlock, _ := pem.Decode([]byte(newSSL.PrivateKey))
|
||||
if privateKeyCertBlock == nil {
|
||||
return buserr.New("ErrSSLKeyFormat")
|
||||
}
|
||||
|
||||
certBlock, _ := pem.Decode([]byte(newSSL.Pem))
|
||||
if certBlock == nil {
|
||||
return buserr.New("ErrSSLCertificateFormat")
|
||||
}
|
||||
cert, err := x509.ParseCertificate(certBlock.Bytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
newSSL.ExpireDate = cert.NotAfter
|
||||
newSSL.StartDate = cert.NotBefore
|
||||
newSSL.Type = cert.Issuer.CommonName
|
||||
if len(cert.Issuer.Organization) > 0 {
|
||||
newSSL.Organization = cert.Issuer.Organization[0]
|
||||
} else {
|
||||
newSSL.Organization = cert.Issuer.CommonName
|
||||
}
|
||||
if len(cert.DNSNames) > 0 {
|
||||
newSSL.PrimaryDomain = cert.DNSNames[0]
|
||||
newSSL.Domains = strings.Join(cert.DNSNames, ",")
|
||||
}
|
||||
|
||||
return websiteSSLRepo.Create(context.Background(), newSSL)
|
||||
}
|
||||
|
|
|
@ -23,5 +23,6 @@ func (a *WebsiteSSLRouter) InitWebsiteSSLRouter(Router *gin.RouterGroup) {
|
|||
groupRouter.GET("/website/:websiteId", baseApi.GetWebsiteSSLByWebsiteId)
|
||||
groupRouter.GET("/:id", baseApi.GetWebsiteSSLById)
|
||||
groupRouter.POST("/update", baseApi.UpdateWebsiteSSL)
|
||||
groupRouter.POST("/upload", baseApi.UploadWebsiteSSL)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
@ -12234,6 +12234,48 @@ const docTemplate = `{
|
|||
}
|
||||
}
|
||||
},
|
||||
"/websites/ssl/upload": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "上传 ssl",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Website SSL"
|
||||
],
|
||||
"summary": "Upload ssl",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "request",
|
||||
"name": "request",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/request.WebsiteSSLUpload"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK"
|
||||
}
|
||||
},
|
||||
"x-panel-log": {
|
||||
"BeforeFunctions": [],
|
||||
"bodyKeys": [
|
||||
"type"
|
||||
],
|
||||
"formatEN": "Upload ssl [type]",
|
||||
"formatZH": "上传 ssl [type]",
|
||||
"paramKeys": []
|
||||
}
|
||||
}
|
||||
},
|
||||
"/websites/ssl/website/:websiteId": {
|
||||
"get": {
|
||||
"security": [
|
||||
|
@ -16861,19 +16903,10 @@ const docTemplate = `{
|
|||
"type": "boolean"
|
||||
},
|
||||
"sortBy": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"name",
|
||||
"size",
|
||||
"modTime"
|
||||
]
|
||||
"type": "string"
|
||||
},
|
||||
"sortOrder": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"ascending",
|
||||
"descending"
|
||||
]
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -18160,6 +18193,33 @@ const docTemplate = `{
|
|||
}
|
||||
}
|
||||
},
|
||||
"request.WebsiteSSLUpload": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"type"
|
||||
],
|
||||
"properties": {
|
||||
"certificate": {
|
||||
"type": "string"
|
||||
},
|
||||
"certificatePath": {
|
||||
"type": "string"
|
||||
},
|
||||
"privateKey": {
|
||||
"type": "string"
|
||||
},
|
||||
"privateKeyPath": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"paste",
|
||||
"local"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"request.WebsiteSearch": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
|
|
|
@ -12227,6 +12227,48 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"/websites/ssl/upload": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "上传 ssl",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Website SSL"
|
||||
],
|
||||
"summary": "Upload ssl",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "request",
|
||||
"name": "request",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/request.WebsiteSSLUpload"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK"
|
||||
}
|
||||
},
|
||||
"x-panel-log": {
|
||||
"BeforeFunctions": [],
|
||||
"bodyKeys": [
|
||||
"type"
|
||||
],
|
||||
"formatEN": "Upload ssl [type]",
|
||||
"formatZH": "上传 ssl [type]",
|
||||
"paramKeys": []
|
||||
}
|
||||
}
|
||||
},
|
||||
"/websites/ssl/website/:websiteId": {
|
||||
"get": {
|
||||
"security": [
|
||||
|
@ -16854,19 +16896,10 @@
|
|||
"type": "boolean"
|
||||
},
|
||||
"sortBy": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"name",
|
||||
"size",
|
||||
"modTime"
|
||||
]
|
||||
"type": "string"
|
||||
},
|
||||
"sortOrder": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"ascending",
|
||||
"descending"
|
||||
]
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -18153,6 +18186,33 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"request.WebsiteSSLUpload": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"type"
|
||||
],
|
||||
"properties": {
|
||||
"certificate": {
|
||||
"type": "string"
|
||||
},
|
||||
"certificatePath": {
|
||||
"type": "string"
|
||||
},
|
||||
"privateKey": {
|
||||
"type": "string"
|
||||
},
|
||||
"privateKeyPath": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"paste",
|
||||
"local"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"request.WebsiteSearch": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
|
|
|
@ -2963,15 +2963,8 @@ definitions:
|
|||
showHidden:
|
||||
type: boolean
|
||||
sortBy:
|
||||
enum:
|
||||
- name
|
||||
- size
|
||||
- modTime
|
||||
type: string
|
||||
sortOrder:
|
||||
enum:
|
||||
- ascending
|
||||
- descending
|
||||
type: string
|
||||
type: object
|
||||
request.FilePathCheck:
|
||||
|
@ -3838,6 +3831,24 @@ definitions:
|
|||
- autoRenew
|
||||
- id
|
||||
type: object
|
||||
request.WebsiteSSLUpload:
|
||||
properties:
|
||||
certificate:
|
||||
type: string
|
||||
certificatePath:
|
||||
type: string
|
||||
privateKey:
|
||||
type: string
|
||||
privateKeyPath:
|
||||
type: string
|
||||
type:
|
||||
enum:
|
||||
- paste
|
||||
- local
|
||||
type: string
|
||||
required:
|
||||
- type
|
||||
type: object
|
||||
request.WebsiteSearch:
|
||||
properties:
|
||||
name:
|
||||
|
@ -12080,6 +12091,33 @@ paths:
|
|||
formatEN: Update ssl config [domain]
|
||||
formatZH: 更新证书设置 [domain]
|
||||
paramKeys: []
|
||||
/websites/ssl/upload:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 上传 ssl
|
||||
parameters:
|
||||
- description: request
|
||||
in: body
|
||||
name: request
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/request.WebsiteSSLUpload'
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: Upload ssl
|
||||
tags:
|
||||
- Website SSL
|
||||
x-panel-log:
|
||||
BeforeFunctions: []
|
||||
bodyKeys:
|
||||
- type
|
||||
formatEN: Upload ssl [type]
|
||||
formatZH: 上传 ssl [type]
|
||||
paramKeys: []
|
||||
/websites/ssl/website/:websiteId:
|
||||
get:
|
||||
consumes:
|
||||
|
|
|
@ -439,4 +439,12 @@ export namespace Website {
|
|||
userGroup: string;
|
||||
msg: string;
|
||||
}
|
||||
|
||||
export interface SSLUpload {
|
||||
privateKey: string;
|
||||
certificate: string;
|
||||
privateKeyPath: string;
|
||||
certificatePath: string;
|
||||
type: string;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -239,3 +239,7 @@ export const ChangePHPVersion = (req: Website.PHPVersionChange) => {
|
|||
export const GetDirConfig = (req: Website.ProxyReq) => {
|
||||
return http.post<Website.DirConfig>(`/websites/dir`, req);
|
||||
};
|
||||
|
||||
export const UploadSSL = (req: Website.SSLUpload) => {
|
||||
return http.post<any>(`/websites/ssl/upload`, req);
|
||||
};
|
||||
|
|
|
@ -1715,6 +1715,7 @@ const message = {
|
|||
'This certificate has been associated with the following websites, and the renewal will be applied to these websites simultaneously',
|
||||
createAcme: 'Create Account',
|
||||
acmeHelper: 'Acme account is used to apply for free certificates',
|
||||
upload: 'Upload Certificate',
|
||||
},
|
||||
firewall: {
|
||||
create: 'Create rule',
|
||||
|
|
|
@ -1626,6 +1626,7 @@ const message = {
|
|||
renewWebsite: '該證書已經和以下網站關聯,續簽會同步應用到這些網站',
|
||||
createAcme: '創建賬戶',
|
||||
acmeHelper: 'Acme 賬戶用於申請免費證書',
|
||||
upload: '上傳證書',
|
||||
},
|
||||
firewall: {
|
||||
create: '創建規則',
|
||||
|
|
|
@ -1626,6 +1626,7 @@ const message = {
|
|||
renewWebsite: '该证书已经和以下网站关联,续签会同步应用到这些网站',
|
||||
createAcme: '创建账户',
|
||||
acmeHelper: 'Acme 账户用于申请免费证书',
|
||||
upload: '上传证书',
|
||||
},
|
||||
firewall: {
|
||||
create: '创建规则',
|
||||
|
|
|
@ -28,9 +28,12 @@
|
|||
>
|
||||
{{ ssl.acmeAccount.email }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :label="$t('website.brand')">
|
||||
<el-descriptions-item :label="$t('commons.table.type')">
|
||||
{{ ssl.type }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :label="$t('website.brand')">
|
||||
{{ ssl.organization }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :label="$t('ssl.startDate')">
|
||||
{{ dateFormatSimple(ssl.startDate) }}
|
||||
</el-descriptions-item>
|
||||
|
|
|
@ -13,6 +13,9 @@
|
|||
<el-button type="primary" @click="openSSL()">
|
||||
{{ $t('ssl.create') }}
|
||||
</el-button>
|
||||
<el-button type="primary" @click="openUpload()">
|
||||
{{ $t('ssl.upload') }}
|
||||
</el-button>
|
||||
<el-button type="primary" plain @click="openAcmeAccount()">
|
||||
{{ $t('website.acmeAccountManage') }}
|
||||
</el-button>
|
||||
|
@ -79,6 +82,7 @@
|
|||
<Create ref="sslCreateRef" @close="search()"></Create>
|
||||
<Renew ref="renewRef" @close="search()"></Renew>
|
||||
<Detail ref="detailRef"></Detail>
|
||||
<SSLUpload ref="sslUploadRef" @close="search()"></SSLUpload>
|
||||
</LayoutContent>
|
||||
|
||||
<OpDialog ref="opRef" @search="search" />
|
||||
|
@ -99,6 +103,7 @@ import i18n from '@/lang';
|
|||
import { Website } from '@/api/interface/website';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import { GlobalStore } from '@/store';
|
||||
import SSLUpload from './upload/index.vue';
|
||||
const globalStore = GlobalStore();
|
||||
|
||||
const paginationConfig = reactive({
|
||||
|
@ -112,9 +117,10 @@ const dnsAccountRef = ref();
|
|||
const sslCreateRef = ref();
|
||||
const renewRef = ref();
|
||||
const detailRef = ref();
|
||||
let data = ref();
|
||||
let loading = ref(false);
|
||||
const data = ref();
|
||||
const loading = ref(false);
|
||||
const opRef = ref();
|
||||
const sslUploadRef = ref();
|
||||
|
||||
const routerButton = [
|
||||
{
|
||||
|
@ -187,6 +193,9 @@ const openDnsAccount = () => {
|
|||
const openSSL = () => {
|
||||
sslCreateRef.value.acceptParams();
|
||||
};
|
||||
const openUpload = () => {
|
||||
sslUploadRef.value.acceptParams();
|
||||
};
|
||||
const openRenewSSL = (id: number, websites: Website.Website[]) => {
|
||||
renewRef.value.acceptParams({ id: id, websites: websites });
|
||||
};
|
||||
|
|
132
frontend/src/views/website/ssl/upload/index.vue
Normal file
132
frontend/src/views/website/ssl/upload/index.vue
Normal file
|
@ -0,0 +1,132 @@
|
|||
<template>
|
||||
<el-drawer :close-on-click-modal="false" v-model="open" size="50%">
|
||||
<template #header>
|
||||
<DrawerHeader :header="$t('ssl.upload')" :back="handleClose" />
|
||||
</template>
|
||||
<el-row v-loading="loading">
|
||||
<el-col :span="22" :offset="1">
|
||||
<el-form ref="sslForm" label-position="top" :model="ssl" label-width="100px" :rules="rules">
|
||||
<el-form-item :label="$t('website.importType')" prop="type">
|
||||
<el-select v-model="ssl.type">
|
||||
<el-option :label="$t('website.pasteSSL')" :value="'paste'"></el-option>
|
||||
<el-option :label="$t('website.localSSL')" :value="'local'"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<div v-if="ssl.type === 'paste'">
|
||||
<el-form-item :label="$t('website.privateKey')" prop="privateKey">
|
||||
<el-input v-model="ssl.privateKey" :rows="6" type="textarea" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('website.certificate')" prop="certificate">
|
||||
<el-input v-model="ssl.certificate" :rows="6" type="textarea" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div v-if="ssl.type === 'local'">
|
||||
<el-form-item :label="$t('website.privateKeyPath')" prop="privateKeyPath">
|
||||
<el-input v-model="ssl.privateKeyPath">
|
||||
<template #prepend>
|
||||
<FileList @choose="getPrivateKeyPath" :dir="false"></FileList>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('website.certificatePath')" prop="certificatePath">
|
||||
<el-input v-model="ssl.certificatePath">
|
||||
<template #prepend>
|
||||
<FileList @choose="getCertificatePath" :dir="false"></FileList>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-form>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="handleClose" :disabled="loading">{{ $t('commons.button.cancel') }}</el-button>
|
||||
<el-button type="primary" @click="submit(sslForm)" :disabled="loading">
|
||||
{{ $t('commons.button.confirm') }}
|
||||
</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-drawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import DrawerHeader from '@/components/drawer-header/index.vue';
|
||||
import { UploadSSL } from '@/api/modules/website';
|
||||
import { Rules } from '@/global/form-rules';
|
||||
import i18n from '@/lang';
|
||||
import { FormInstance } from 'element-plus';
|
||||
import { ref } from 'vue';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
|
||||
const open = ref(false);
|
||||
const loading = ref(false);
|
||||
const sslForm = ref<FormInstance>();
|
||||
|
||||
const rules = ref({
|
||||
privateKey: [Rules.requiredInput],
|
||||
certificate: [Rules.requiredInput],
|
||||
privateKeyPath: [Rules.requiredInput],
|
||||
certificatePath: [Rules.requiredInput],
|
||||
type: [Rules.requiredSelect],
|
||||
});
|
||||
const ssl = ref({
|
||||
privateKey: '',
|
||||
certificate: '',
|
||||
privateKeyPath: '',
|
||||
certificatePath: '',
|
||||
type: 'paste',
|
||||
});
|
||||
|
||||
const em = defineEmits(['close']);
|
||||
const handleClose = () => {
|
||||
resetForm();
|
||||
open.value = false;
|
||||
em('close', false);
|
||||
};
|
||||
const resetForm = () => {
|
||||
sslForm.value?.resetFields();
|
||||
ssl.value = {
|
||||
privateKey: '',
|
||||
certificate: '',
|
||||
privateKeyPath: '',
|
||||
certificatePath: '',
|
||||
type: 'paste',
|
||||
};
|
||||
};
|
||||
|
||||
const acceptParams = () => {
|
||||
resetForm();
|
||||
open.value = true;
|
||||
};
|
||||
|
||||
const getPrivateKeyPath = (path: string) => {
|
||||
ssl.value.privateKeyPath = path;
|
||||
};
|
||||
|
||||
const getCertificatePath = (path: string) => {
|
||||
ssl.value.certificatePath = path;
|
||||
};
|
||||
|
||||
const submit = async (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return;
|
||||
await formEl.validate((valid) => {
|
||||
if (!valid) {
|
||||
return;
|
||||
}
|
||||
loading.value = true;
|
||||
UploadSSL(ssl.value)
|
||||
.then(() => {
|
||||
handleClose();
|
||||
MsgSuccess(i18n.global.t('commons.msg.createSuccess'));
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
acceptParams,
|
||||
});
|
||||
</script>
|
Loading…
Add table
Reference in a new issue