mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-01-31 14:08:06 +08:00
feat: 机构增加详情查看页 (#3097)
This commit is contained in:
parent
6db80141ed
commit
120bec57b2
@ -86,7 +86,6 @@ type WebsiteCASearch struct {
|
||||
type WebsiteCACreate struct {
|
||||
CommonName string `json:"commonName" validate:"required"`
|
||||
Country string `json:"country" validate:"required"`
|
||||
Email string `json:"email" validate:"required"`
|
||||
Organization string `json:"organization" validate:"required"`
|
||||
OrganizationUint string `json:"organizationUint"`
|
||||
Name string `json:"name" validate:"required"`
|
||||
|
@ -25,4 +25,10 @@ type WebsiteDnsAccountDTO struct {
|
||||
|
||||
type WebsiteCADTO struct {
|
||||
model.WebsiteCA
|
||||
CommonName string `json:"commonName" `
|
||||
Country string `json:"country"`
|
||||
Organization string `json:"organization"`
|
||||
OrganizationUint string `json:"organizationUint"`
|
||||
Province string `json:"province" `
|
||||
City string `json:"city"`
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ type WebsiteCAService struct {
|
||||
type IWebsiteCAService interface {
|
||||
Page(search request.WebsiteCASearch) (int64, []response.WebsiteCADTO, error)
|
||||
Create(create request.WebsiteCACreate) (*request.WebsiteCACreate, error)
|
||||
GetCA(id uint) (response.WebsiteCADTO, error)
|
||||
GetCA(id uint) (*response.WebsiteCADTO, error)
|
||||
Delete(id uint) error
|
||||
ObtainSSL(req request.WebsiteCAObtain) error
|
||||
}
|
||||
@ -69,9 +69,10 @@ func (w WebsiteCAService) Create(create request.WebsiteCACreate) (*request.Websi
|
||||
}
|
||||
|
||||
pkixName := pkix.Name{
|
||||
CommonName: create.CommonName,
|
||||
Country: []string{create.Country},
|
||||
Organization: []string{create.Organization},
|
||||
CommonName: create.CommonName,
|
||||
Country: []string{create.Country},
|
||||
Organization: []string{create.Organization},
|
||||
OrganizationalUnit: []string{create.OrganizationUint},
|
||||
}
|
||||
if create.Province != "" {
|
||||
pkixName.Province = []string{create.Province}
|
||||
@ -138,14 +139,29 @@ func (w WebsiteCAService) Create(create request.WebsiteCACreate) (*request.Websi
|
||||
return &create, nil
|
||||
}
|
||||
|
||||
func (w WebsiteCAService) GetCA(id uint) (response.WebsiteCADTO, error) {
|
||||
func (w WebsiteCAService) GetCA(id uint) (*response.WebsiteCADTO, error) {
|
||||
res := &response.WebsiteCADTO{}
|
||||
ca, err := websiteCARepo.GetFirst(commonRepo.WithByID(id))
|
||||
if err != nil {
|
||||
return response.WebsiteCADTO{}, err
|
||||
return nil, err
|
||||
}
|
||||
return response.WebsiteCADTO{
|
||||
WebsiteCA: ca,
|
||||
}, nil
|
||||
res.WebsiteCA = ca
|
||||
certBlock, _ := pem.Decode([]byte(ca.CSR))
|
||||
if certBlock == nil {
|
||||
return nil, buserr.New("ErrSSLCertificateFormat")
|
||||
}
|
||||
cert, err := x509.ParseCertificate(certBlock.Bytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res.CommonName = cert.Issuer.CommonName
|
||||
res.Organization = strings.Join(cert.Issuer.Organization, ",")
|
||||
res.Country = strings.Join(cert.Issuer.Country, ",")
|
||||
res.Province = strings.Join(cert.Issuer.Province, ",")
|
||||
res.City = strings.Join(cert.Issuer.Locality, ",")
|
||||
res.OrganizationUint = strings.Join(cert.Issuer.OrganizationalUnit, ",")
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (w WebsiteCAService) Delete(id uint) error {
|
||||
@ -157,7 +173,6 @@ func (w WebsiteCAService) Delete(id uint) error {
|
||||
}
|
||||
|
||||
func (w WebsiteCAService) ObtainSSL(req request.WebsiteCAObtain) error {
|
||||
|
||||
var (
|
||||
domains []string
|
||||
ips []net.IP
|
||||
|
@ -17,5 +17,6 @@ func (a *WebsiteDnsAccountRouter) InitWebsiteCARouter(Router *gin.RouterGroup) {
|
||||
groupRouter.POST("/del", baseApi.DeleteWebsiteCA)
|
||||
groupRouter.POST("/obtain", baseApi.ObtainWebsiteCA)
|
||||
groupRouter.POST("/renew", baseApi.RenewWebsiteCA)
|
||||
groupRouter.GET("/:id", baseApi.GetWebsiteCA)
|
||||
}
|
||||
}
|
||||
|
@ -18935,7 +18935,6 @@ const docTemplate = `{
|
||||
"required": [
|
||||
"commonName",
|
||||
"country",
|
||||
"email",
|
||||
"keyType",
|
||||
"name",
|
||||
"organization"
|
||||
@ -18950,9 +18949,6 @@ const docTemplate = `{
|
||||
"country": {
|
||||
"type": "string"
|
||||
},
|
||||
"email": {
|
||||
"type": "string"
|
||||
},
|
||||
"keyType": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
@ -19532,12 +19528,18 @@ const docTemplate = `{
|
||||
"autoRenew": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"dir": {
|
||||
"type": "string"
|
||||
},
|
||||
"dnsAccountId": {
|
||||
"type": "integer"
|
||||
},
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"keyType": {
|
||||
"type": "string"
|
||||
},
|
||||
@ -19576,33 +19578,17 @@ const docTemplate = `{
|
||||
"request.WebsiteSSLUpdate": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"id",
|
||||
"type"
|
||||
"id"
|
||||
],
|
||||
"properties": {
|
||||
"autoRenew": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"certificate": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"privateKey": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"autoRenew",
|
||||
"description",
|
||||
"certificate",
|
||||
"privateKey"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -20189,6 +20175,15 @@ const docTemplate = `{
|
||||
"response.WebsiteCADTO": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"city": {
|
||||
"type": "string"
|
||||
},
|
||||
"commonName": {
|
||||
"type": "string"
|
||||
},
|
||||
"country": {
|
||||
"type": "string"
|
||||
},
|
||||
"createdAt": {
|
||||
"type": "string"
|
||||
},
|
||||
@ -20204,9 +20199,18 @@ const docTemplate = `{
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"organization": {
|
||||
"type": "string"
|
||||
},
|
||||
"organizationUint": {
|
||||
"type": "string"
|
||||
},
|
||||
"privateKey": {
|
||||
"type": "string"
|
||||
},
|
||||
"province": {
|
||||
"type": "string"
|
||||
},
|
||||
"updatedAt": {
|
||||
"type": "string"
|
||||
}
|
||||
|
@ -18928,7 +18928,6 @@
|
||||
"required": [
|
||||
"commonName",
|
||||
"country",
|
||||
"email",
|
||||
"keyType",
|
||||
"name",
|
||||
"organization"
|
||||
@ -18943,9 +18942,6 @@
|
||||
"country": {
|
||||
"type": "string"
|
||||
},
|
||||
"email": {
|
||||
"type": "string"
|
||||
},
|
||||
"keyType": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
@ -19525,12 +19521,18 @@
|
||||
"autoRenew": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"dir": {
|
||||
"type": "string"
|
||||
},
|
||||
"dnsAccountId": {
|
||||
"type": "integer"
|
||||
},
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"keyType": {
|
||||
"type": "string"
|
||||
},
|
||||
@ -19569,33 +19571,17 @@
|
||||
"request.WebsiteSSLUpdate": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"id",
|
||||
"type"
|
||||
"id"
|
||||
],
|
||||
"properties": {
|
||||
"autoRenew": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"certificate": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"privateKey": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"autoRenew",
|
||||
"description",
|
||||
"certificate",
|
||||
"privateKey"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -20182,6 +20168,15 @@
|
||||
"response.WebsiteCADTO": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"city": {
|
||||
"type": "string"
|
||||
},
|
||||
"commonName": {
|
||||
"type": "string"
|
||||
},
|
||||
"country": {
|
||||
"type": "string"
|
||||
},
|
||||
"createdAt": {
|
||||
"type": "string"
|
||||
},
|
||||
@ -20197,9 +20192,18 @@
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"organization": {
|
||||
"type": "string"
|
||||
},
|
||||
"organizationUint": {
|
||||
"type": "string"
|
||||
},
|
||||
"privateKey": {
|
||||
"type": "string"
|
||||
},
|
||||
"province": {
|
||||
"type": "string"
|
||||
},
|
||||
"updatedAt": {
|
||||
"type": "string"
|
||||
}
|
||||
|
@ -3747,8 +3747,6 @@ definitions:
|
||||
type: string
|
||||
country:
|
||||
type: string
|
||||
email:
|
||||
type: string
|
||||
keyType:
|
||||
enum:
|
||||
- P256
|
||||
@ -3769,7 +3767,6 @@ definitions:
|
||||
required:
|
||||
- commonName
|
||||
- country
|
||||
- email
|
||||
- keyType
|
||||
- name
|
||||
- organization
|
||||
@ -4145,10 +4142,14 @@ definitions:
|
||||
type: boolean
|
||||
autoRenew:
|
||||
type: boolean
|
||||
description:
|
||||
type: string
|
||||
dir:
|
||||
type: string
|
||||
dnsAccountId:
|
||||
type: integer
|
||||
id:
|
||||
type: integer
|
||||
keyType:
|
||||
type: string
|
||||
otherDomains:
|
||||
@ -4180,24 +4181,12 @@ definitions:
|
||||
properties:
|
||||
autoRenew:
|
||||
type: boolean
|
||||
certificate:
|
||||
type: string
|
||||
description:
|
||||
type: string
|
||||
id:
|
||||
type: integer
|
||||
privateKey:
|
||||
type: string
|
||||
type:
|
||||
enum:
|
||||
- autoRenew
|
||||
- description
|
||||
- certificate
|
||||
- privateKey
|
||||
type: string
|
||||
required:
|
||||
- id
|
||||
- type
|
||||
type: object
|
||||
request.WebsiteSSLUpload:
|
||||
properties:
|
||||
@ -4586,6 +4575,12 @@ definitions:
|
||||
type: object
|
||||
response.WebsiteCADTO:
|
||||
properties:
|
||||
city:
|
||||
type: string
|
||||
commonName:
|
||||
type: string
|
||||
country:
|
||||
type: string
|
||||
createdAt:
|
||||
type: string
|
||||
csr:
|
||||
@ -4596,8 +4591,14 @@ definitions:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
organization:
|
||||
type: string
|
||||
organizationUint:
|
||||
type: string
|
||||
privateKey:
|
||||
type: string
|
||||
province:
|
||||
type: string
|
||||
updatedAt:
|
||||
type: string
|
||||
type: object
|
||||
|
@ -473,7 +473,6 @@ export namespace Website {
|
||||
name: string;
|
||||
commonName: string;
|
||||
country: string;
|
||||
email: string;
|
||||
organization: string;
|
||||
organizationUint: string;
|
||||
keyType: string;
|
||||
@ -481,6 +480,15 @@ export namespace Website {
|
||||
city: string;
|
||||
}
|
||||
|
||||
export interface CADTO extends CA {
|
||||
commonName: string;
|
||||
country: string;
|
||||
organization: string;
|
||||
organizationUint: string;
|
||||
province: string;
|
||||
city: string;
|
||||
}
|
||||
|
||||
export interface SSLObtainByCA {
|
||||
id: number;
|
||||
domains: string;
|
||||
|
@ -270,3 +270,7 @@ export const DownloadFile = (params: Website.SSLDownload) => {
|
||||
timeout: TimeoutEnum.T_40S,
|
||||
});
|
||||
};
|
||||
|
||||
export const GetCA = (id: number) => {
|
||||
return http.get<Website.CADTO>(`/websites/ca/${id}`);
|
||||
};
|
||||
|
@ -1851,6 +1851,7 @@ const message = {
|
||||
dir: 'directory',
|
||||
pushDirHelper:
|
||||
'Two files will be generated in this directory, the certificate file: fullchain.pem and the key file: privkey.pem',
|
||||
organizationDetail: 'Organization Details',
|
||||
},
|
||||
firewall: {
|
||||
create: 'Create rule',
|
||||
|
@ -1737,6 +1737,7 @@ const message = {
|
||||
pushDir: '推送憑證到本機目錄',
|
||||
dir: '目錄',
|
||||
pushDirHelper: '會在此目錄下產生兩個文件,憑證檔案:fullchain.pem 金鑰檔案:privkey.pem',
|
||||
organizationDetail: '機構詳情',
|
||||
},
|
||||
firewall: {
|
||||
create: '創建規則',
|
||||
|
@ -1737,6 +1737,7 @@ const message = {
|
||||
pushDir: '推送证书到本地目录',
|
||||
dir: '目录',
|
||||
pushDirHelper: '会在此目录下生成两个文件,证书文件:fullchain.pem 密钥文件:privkey.pem',
|
||||
organizationDetail: '机构详情',
|
||||
},
|
||||
firewall: {
|
||||
create: '创建规则',
|
||||
|
@ -15,9 +15,6 @@
|
||||
<el-form-item :label="$t('ssl.commonName')" prop="commonName">
|
||||
<el-input v-model.trim="ca.commonName"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('website.email')" prop="email">
|
||||
<el-input v-model.trim="ca.email"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('ssl.company')" prop="organization">
|
||||
<el-input v-model.trim="ca.organization"></el-input>
|
||||
</el-form-item>
|
||||
@ -72,7 +69,6 @@ const caForm = ref<FormInstance>();
|
||||
const em = defineEmits(['close']);
|
||||
|
||||
const rules = ref({
|
||||
email: [Rules.requiredInput, Rules.email],
|
||||
keyType: [Rules.requiredSelect],
|
||||
name: [Rules.requiredInput, Rules.name],
|
||||
country: [Rules.requiredSelect],
|
||||
@ -82,7 +78,6 @@ const rules = ref({
|
||||
|
||||
const initData = () => ({
|
||||
name: '',
|
||||
email: '',
|
||||
keyType: 'P256',
|
||||
commonName: '',
|
||||
country: 'CN',
|
||||
|
103
frontend/src/views/website/ssl/ca/detail/index.vue
Normal file
103
frontend/src/views/website/ssl/ca/detail/index.vue
Normal file
@ -0,0 +1,103 @@
|
||||
<template>
|
||||
<el-drawer :close-on-click-modal="false" v-model="open" size="50%">
|
||||
<template #header>
|
||||
<DrawerHeader :header="$t('ssl.organizationDetail')" :back="handleClose" />
|
||||
</template>
|
||||
<div v-loading="loading">
|
||||
<el-radio-group v-model="curr">
|
||||
<el-radio-button label="detail">{{ $t('ssl.msg') }}</el-radio-button>
|
||||
<el-radio-button label="ssl">csr</el-radio-button>
|
||||
<el-radio-button label="key">{{ $t('ssl.key') }}</el-radio-button>
|
||||
</el-radio-group>
|
||||
<div v-if="curr === 'detail'" class="mt-5">
|
||||
<el-descriptions border :column="1">
|
||||
<el-descriptions-item :label="$t('commons.table.name')">
|
||||
{{ ca.name }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :label="$t('ssl.commonName')">
|
||||
{{ ca.commonName }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :label="$t('website.brand')">
|
||||
{{ ca.organization }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :label="$t('ssl.department')">
|
||||
{{ ca.organizationUint }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :label="$t('ssl.country')">
|
||||
{{ ca.country }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :label="$t('ssl.province')">
|
||||
{{ ca.province }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :label="$t('ssl.city')">
|
||||
{{ ca.city }}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</div>
|
||||
<div v-else-if="curr === 'ssl'" class="mt-5">
|
||||
<el-input v-model="ca.csr" :autosize="{ minRows: 15, maxRows: 30 }" type="textarea" id="textArea" />
|
||||
<div>
|
||||
<br />
|
||||
<el-button type="primary" @click="copyText(ca.csr)">{{ $t('file.copy') }}</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="mt-5">
|
||||
<el-input
|
||||
v-model="ca.privateKey"
|
||||
:autosize="{ minRows: 15, maxRows: 30 }"
|
||||
type="textarea"
|
||||
id="textArea"
|
||||
/>
|
||||
<div>
|
||||
<br />
|
||||
<el-button type="primary" @click="copyText(ca.privateKey)">{{ $t('file.copy') }}</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-drawer>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import DrawerHeader from '@/components/drawer-header/index.vue';
|
||||
import { GetCA } from '@/api/modules/website';
|
||||
import { ref } from 'vue';
|
||||
import i18n from '@/lang';
|
||||
import useClipboard from 'vue-clipboard3';
|
||||
import { MsgError, MsgSuccess } from '@/utils/message';
|
||||
const { toClipboard } = useClipboard();
|
||||
|
||||
const open = ref(false);
|
||||
const id = ref(0);
|
||||
const curr = ref('detail');
|
||||
const ca = ref<any>({});
|
||||
const loading = ref(false);
|
||||
|
||||
const handleClose = () => {
|
||||
open.value = false;
|
||||
};
|
||||
|
||||
const acceptParams = (caID: number) => {
|
||||
ca.value = {};
|
||||
id.value = caID;
|
||||
curr.value = 'detail';
|
||||
get();
|
||||
open.value = true;
|
||||
};
|
||||
|
||||
const get = async () => {
|
||||
const res = await GetCA(id.value);
|
||||
ca.value = res.data;
|
||||
};
|
||||
|
||||
const copyText = async (msg) => {
|
||||
try {
|
||||
await toClipboard(msg);
|
||||
MsgSuccess(i18n.global.t('commons.msg.copySuccess'));
|
||||
} catch (e) {
|
||||
MsgError(i18n.global.t('commons.msg.copyFailed'));
|
||||
}
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
acceptParams,
|
||||
});
|
||||
</script>
|
@ -7,28 +7,29 @@
|
||||
<template #toolbar>
|
||||
<el-button type="primary" @click="openCreate">{{ $t('ssl.createCA') }}</el-button>
|
||||
</template>
|
||||
<el-table-column
|
||||
:label="$t('commons.table.name')"
|
||||
fix
|
||||
show-overflow-tooltip
|
||||
prop="name"
|
||||
min-width="100px"
|
||||
></el-table-column>
|
||||
<el-table-column :label="$t('website.keyType')" fix show-overflow-tooltip prop="keyType">
|
||||
<el-table-column :label="$t('commons.table.name')" show-overflow-tooltip prop="name"></el-table-column>
|
||||
<el-table-column :label="$t('website.keyType')" show-overflow-tooltip prop="keyType">
|
||||
<template #default="{ row }">
|
||||
{{ getKeyName(row.keyType) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="createdAt"
|
||||
:label="$t('commons.table.date')"
|
||||
:formatter="dateFormat"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<fu-table-operations
|
||||
:ellipsis="1"
|
||||
:ellipsis="3"
|
||||
:buttons="buttons"
|
||||
:label="$t('commons.table.operate')"
|
||||
fixed="right"
|
||||
fix
|
||||
width="250px"
|
||||
/>
|
||||
</ComplexTable>
|
||||
<Create ref="createRef" @close="search()" />
|
||||
<Obtain ref="obtainRef" @close="handleClose()" />
|
||||
<Obtain ref="obtainRef" @close="search()" />
|
||||
<Detail ref="detailRef" />
|
||||
</el-drawer>
|
||||
<OpDialog ref="opRef" @search="search" />
|
||||
</template>
|
||||
@ -41,7 +42,8 @@ import { DeleteCA, SearchCAs } from '@/api/modules/website';
|
||||
import i18n from '@/lang';
|
||||
import { reactive, ref } from 'vue';
|
||||
import Create from './create/index.vue';
|
||||
import { getKeyName } from '@/utils/util';
|
||||
import Detail from './detail/index.vue';
|
||||
import { getKeyName, dateFormat } from '@/utils/util';
|
||||
import Obtain from './obtain/index.vue';
|
||||
|
||||
const open = ref(false);
|
||||
@ -57,6 +59,7 @@ const paginationConfig = reactive({
|
||||
const opRef = ref();
|
||||
const obtainRef = ref();
|
||||
const em = defineEmits(['close']);
|
||||
const detailRef = ref();
|
||||
|
||||
const buttons = [
|
||||
{
|
||||
@ -65,6 +68,12 @@ const buttons = [
|
||||
obtain(row);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: i18n.global.t('ssl.detail'),
|
||||
click: function (row: Website.CA) {
|
||||
detailRef.value.acceptParams(row.id);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: i18n.global.t('commons.button.delete'),
|
||||
click: function (row: Website.CA) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user