From c5c0b02f977d276079940c685e9e91e8ebd7d117 Mon Sep 17 00:00:00 2001 From: dark Date: Sat, 4 May 2024 00:01:53 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84SSL=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/drawer-picker/DrawerPicker.tsx | 20 ++++--- src/pages/websites/ssl/components/CAList.tsx | 78 ++++++++++++++++++++++++--- src/pages/websites/ssl/components/DNSList.tsx | 1 + src/pages/websites/ssl/index.tsx | 34 ++++++++---- src/request.ts | 9 +++- src/store/websites/ca.ts | 11 ++-- src/types/website/acme.d.ts | 16 +++--- src/types/website/ca.d.ts | 18 ++++--- src/types/website/dns.d.ts | 8 +-- src/types/website/ssl.d.ts | 30 +++++------ 10 files changed, 162 insertions(+), 63 deletions(-) diff --git a/src/components/drawer-picker/DrawerPicker.tsx b/src/components/drawer-picker/DrawerPicker.tsx index ef36f4a..6eac557 100644 --- a/src/components/drawer-picker/DrawerPicker.tsx +++ b/src/components/drawer-picker/DrawerPicker.tsx @@ -7,9 +7,10 @@ export interface DrawerPickerProps extends DrawerProps { target?: React.ReactNode children?: React.ReactNode key?: string + foreRender?: boolean } -const DrawerPicker = ({ children, target, ...props }: DrawerPickerProps) => { +const DrawerPicker = ({ children, target, foreRender, ...props }: DrawerPickerProps) => { const { styles } = useStyle() @@ -22,15 +23,18 @@ const DrawerPicker = ({ children, target, ...props }: DrawerPickerProps) => { return (
- { +
{ setOpen(true) }}> - {getTarget()} - - setOpen(false)} - >{children} + {getTarget()} +
+ { + (foreRender || open) && setOpen(false)} + >{children} + } +
) } diff --git a/src/pages/websites/ssl/components/CAList.tsx b/src/pages/websites/ssl/components/CAList.tsx index 161514f..99a9e45 100644 --- a/src/pages/websites/ssl/components/CAList.tsx +++ b/src/pages/websites/ssl/components/CAList.tsx @@ -4,7 +4,7 @@ import { ICA, } from '@/types/website/ca' import { useTranslation } from '@/i18n.ts' import { deleteCaAtom } from '@/store/websites/ca.ts' import { useAtom, useAtomValue } from 'jotai' -import { Alert, Button, Form, Popconfirm } from 'antd' +import { Button, Form, Popconfirm } from 'antd' import { KeyTypeEnum, KeyTypes } from '@/store/websites/ssl.ts' import { caListAtom, caPageAtom, saveOrUpdateCaAtom } from '@/store/websites/ca.ts' @@ -39,6 +39,68 @@ const CAList = () => { ] } }, + { + title: t('website.ssl.ca.form.common_name', '证书主体名称(CN)'), + dataIndex: 'common_name', + hideInTable: true, + hideInSetting: true, + valueType: 'text', + formItemProps: { + rules: [ + { required: true, message: t('message.required', '请输入') } + ] + } + }, + + { + title: t('website.ssl.ca.form.organization', '公司/组织'), + dataIndex: 'organization', + hideInTable: true, + hideInSetting: true, + valueType: 'text', + formItemProps: { + rules: [ + { required: true, message: t('message.required', '请输入') } + ] + } + }, + + { + title: t('website.ssl.ca.form.organization_uint', '部门'), + dataIndex: 'organization_uint', + hideInTable: true, + hideInSetting: true, + valueType: 'text', + formItemProps: {} + }, + { + title: t('website.ssl.ca.form.country', '国家代号'), + dataIndex: 'country', + hideInTable: true, + hideInSetting: true, + valueType: 'text', + formItemProps: { + rules: [ + { required: true, message: t('message.required', '请输入') } + ] + } + }, + { + title: t('website.ssl.ca.form.province', '省份'), + dataIndex: 'province', + hideInTable: true, + hideInSetting: true, + valueType: 'text', + formItemProps: {} + }, + { + title: t('website.ssl.ca.form.city', '城市'), + dataIndex: 'city', + hideInTable: true, + hideInSetting: true, + valueType: 'text', + formItemProps: {} + }, { title: t('website.ssl.ca.columns.keyType', '密钥算法'), @@ -54,12 +116,12 @@ const CAList = () => { }, }, { - title: t('website.ssl.ca.columns.url', 'URL'), - dataIndex: 'url', - valueType: 'text', - ellipsis: true, // 文本溢出省略 + title: t('website.ssl.ca.columns.createAt', '时间'), + dataIndex: 'create_at', + valueType: 'dateTime', hideInForm: true, - }, { + }, + { title: '操作', valueType: 'option', render: (_, record) => { @@ -83,7 +145,6 @@ const CAList = () => { return ( <> - cardProps={{ bodyStyle: { @@ -96,11 +157,12 @@ const CAList = () => { onClick={() => { form.setFieldsValue({ id: 0, + country: 'CN', keyType: KeyTypeEnum.EC256, }) setOpen(true) }} - type={'primary'}>{t('website.ssl.ca.add', '添加ca帐户')} + type={'primary'}>{t('website.ssl.ca.add', '创建机构')} } loading={isLoading} dataSource={data?.rows ?? []} diff --git a/src/pages/websites/ssl/components/DNSList.tsx b/src/pages/websites/ssl/components/DNSList.tsx index 62e90cf..aa5d055 100644 --- a/src/pages/websites/ssl/components/DNSList.tsx +++ b/src/pages/websites/ssl/components/DNSList.tsx @@ -192,6 +192,7 @@ const DNSList = () => { { name: [ 'type' ], valueType: 'dependency', + hideInSetting: true, columns: ({ type }) => { return getKeyColumn(type, t) } diff --git a/src/pages/websites/ssl/index.tsx b/src/pages/websites/ssl/index.tsx index 75f63dc..0df9e08 100644 --- a/src/pages/websites/ssl/index.tsx +++ b/src/pages/websites/ssl/index.tsx @@ -21,6 +21,7 @@ import AcmeList from './components/AcmeList.tsx' import { acmeListAtom, AcmeType, getAcmeAccountTypeName } from '@/store/websites/acme.ts' import { dnsListAtom, getDNSTypeName } from '@/store/websites/dns.ts' import DNSList from './components/DNSList.tsx' +import CAList from '@/pages/websites/ssl/components/CAList.tsx' const SSL = () => { @@ -33,7 +34,7 @@ const SSL = () => { const { data: dnsData, isLoading: dnsLoading } = useAtomValue(dnsListAtom) const { data, isLoading, isFetching, refetch } = useAtomValue(sslListAtom) const { mutate: saveOrUpdate, isSuccess, isPending: isSubmitting } = useAtomValue(saveOrUpdateSslAtom) - const { mutate: delateSSL, isPending: isDeleteing } = useAtomValue(deleteSslAtom) + const { mutate: deleteSSL, isPending: isDeleting } = useAtomValue(deleteSslAtom) const [ open, setOpen ] = useState(false) @@ -125,6 +126,7 @@ const SSL = () => { { name: [ 'provider' ], valueType: 'dependency', + hideInSetting: true, columns: ({ provider }) => { if (provider === ProviderTypeEnum.DnsAccount) { return [ { @@ -141,8 +143,6 @@ const SSL = () => { value: item.id })) }, - - } ] } return [] @@ -166,6 +166,7 @@ const SSL = () => { { name: [ 'pushDir' ], valueType: 'dependency', + hideInSetting: true, columns: ({ pushDir }) => { if (pushDir) { return [ { @@ -198,9 +199,9 @@ const SSL = () => { , { - delateSSL(record.id) + deleteSSL(record.id) }} title={t('message.deleteConfirm')}> @@ -222,6 +223,11 @@ const SSL = () => { rowKey={'id'} dataSource={data?.rows ?? []} columns={columns} + columnsState={{ + defaultValue: { + option: { fixed: 'right', disable: true }, + }, + }} options={{ reload: () => { refetch() @@ -238,9 +244,19 @@ const SSL = () => { actions: [ + {t('website.ssl.actions.selfSigned', '自签证书')} + } + > + + , + + target={} > @@ -248,9 +264,9 @@ const SSL = () => { , + target={}> diff --git a/src/request.ts b/src/request.ts index 8df22eb..cc300d3 100644 --- a/src/request.ts +++ b/src/request.ts @@ -46,10 +46,9 @@ axiosInstance.interceptors.response.use( message.destroy() const result = response.data as IApiResult - switch (result.code) { case 200: - //login + //login if (response.config.url?.includes('/sys/login')) { setToken(result.data.token) const search = new URLSearchParams(window.location.search) @@ -105,6 +104,12 @@ axiosInstance.interceptors.response.use( } window.location.href = `/login?redirect=${encodeURIComponent(redirect)}` return + case 403: + message.error('没有权限') + break + case 404: + message.error('请求的资源不存在') + break default: message.error(response.data.message ?? response.data ?? error.message ?? '请求失败') return Promise.reject(response) diff --git a/src/store/websites/ca.ts b/src/store/websites/ca.ts index 0b8c1be..7421360 100644 --- a/src/store/websites/ca.ts +++ b/src/store/websites/ca.ts @@ -2,7 +2,7 @@ import { atom } from 'jotai/index' import { IApiResult, IPage } from '@/global' import { atomWithMutation, atomWithQuery } from 'jotai-tanstack-query' import websitesServ from '@/service/websites.ts' -import { message } from 'antd' +import { message, } from 'antd' import { t } from 'i18next' import { ICA } from '@/types/website/ca' @@ -22,7 +22,7 @@ export const caListAtom = atomWithQuery(get => ({ })) //saveOrUpdate -export const saveOrUpdateCaAtom = atomWithMutation(get => ({ +export const saveOrUpdateCaAtom = atomWithMutation(get => ({ mutationKey: [ 'saveOrUpdateCA' ], mutationFn: async (data: ICA) => { if (data.id > 0) { @@ -35,7 +35,12 @@ export const saveOrUpdateCaAtom = atomWithMutation(get => ({ message.success(t(isAdd ? 'message.saveSuccess' : 'message.editSuccess', '保存成功')) get(caListAtom).refetch() return res - } + }, + // onError: (err) => { + // const msg = err.data?.message || err.message || t('message.saveFail', '提交失败') + // message.error(msg) + // return err + // }, })) export const deleteCaAtom = atomWithMutation(get => ({ diff --git a/src/types/website/acme.d.ts b/src/types/website/acme.d.ts index e62f62a..67468dd 100644 --- a/src/types/website/acme.d.ts +++ b/src/types/website/acme.d.ts @@ -1,14 +1,14 @@ export interface IAcmeAccount { id: number; - createdAt?: string; - createdBy: number; - updatedAt?: string; - updatedBy: number; + created_at: string | null; + created_by: number; + updated_at: string | null; + updated_by: number; email: string; url: string; - privateKey: string; + private_key: string; type: string; - eabKid: string; - eabHmacKey: string; - keyType: string; + eab_kid: string; + eab_hmac_key: string; + key_type: string; } \ No newline at end of file diff --git a/src/types/website/ca.d.ts b/src/types/website/ca.d.ts index 182d70f..fab3f47 100644 --- a/src/types/website/ca.d.ts +++ b/src/types/website/ca.d.ts @@ -1,11 +1,17 @@ export interface ICA { id: number; - createdAt: string | null; - createdBy: number; - updatedAt: string | null; - updatedBy: number; + created_at: string | null; + created_by: number; + updated_at: string | null; + updated_by: number; csr: string; name: string; - privateKey: string; - keyType: string; + common_name: string; + organization: string; + organization_unit: string; + country: string; + province: string; + city: string; + private_key: string; + key_type: string; } \ No newline at end of file diff --git a/src/types/website/dns.d.ts b/src/types/website/dns.d.ts index 0b9cdbc..6f160e6 100644 --- a/src/types/website/dns.d.ts +++ b/src/types/website/dns.d.ts @@ -1,9 +1,9 @@ export interface IDnsAccount { id: number; - createdAt: string | null; - createdBy: number; - updatedAt: string | null; - updatedBy: number; + created_at: string | null; + created_by: number; + updated_at: string | null; + updated_by: number; name: string; type: string; authorization: string; diff --git a/src/types/website/ssl.d.ts b/src/types/website/ssl.d.ts index 446fbe1..4b576f9 100644 --- a/src/types/website/ssl.d.ts +++ b/src/types/website/ssl.d.ts @@ -1,27 +1,27 @@ export interface ISSL { id: number; - createdAt: Date | null; - createdBy: number; - updatedAt: Date | null; - updatedBy: number; - primaryDomain: string; - privateKey: string; + created_at: string | null; + created_by: number; + updated_at: string | null; + updated_by: number; + primary_domain: string; + private_key: string; pem: string; domains: string; - certUrl: string; + cert_url: string; type: string; provider: string; organization: string; - dnsAccountId: number; - acmeAccountId: number; - caId: number; - autoRenew: boolean; - expireDate: string | null; - startDate: string | null; + dns_account_id: number; + acme_account_id: number; + ca_id: number; + auto_renew: boolean; + expire_date: string | null; + start_date: string | null; status: string; message: string; - keyType: string; - pushDir: boolean; + key_type: string; + push_dir: boolean; dir: string; description: string; }