dark
6 months ago
8 changed files with 355 additions and 41 deletions
-
22src/pages/websites/ssl/components/AcmeList.tsx
-
150src/pages/websites/ssl/components/CAList.tsx
-
43src/pages/websites/ssl/index.tsx
-
9src/service/websites.ts
-
24src/store/websites/acme.ts
-
50src/store/websites/ca.ts
-
89src/store/websites/dns.ts
-
9src/store/websites/ssl.ts
@ -0,0 +1,150 @@ |
|||||
|
import { useMemo, useState } from 'react' |
||||
|
import { BetaSchemaForm, ProColumns, ProFormColumnsType, ProTable } from '@ant-design/pro-components' |
||||
|
import { ICA, IcaAccount } from '@/types/website/ca' |
||||
|
import { useTranslation } from '@/i18n.ts' |
||||
|
import { caAccountTypes, caType } from '@/store/websites/ca.ts' |
||||
|
import { useAtom, useAtomValue } from 'jotai' |
||||
|
import { Alert, Button, Form } from 'antd' |
||||
|
import { KeyTypeEnum, KeyTypes } from '@/store/websites/ssl.ts' |
||||
|
import { caListAtom, caPageAtom, saveOrUpdateCaAtom } from '@/store/websites/ca.ts' |
||||
|
|
||||
|
const CAList = () => { |
||||
|
|
||||
|
const { t } = useTranslation() |
||||
|
const [ form ] = Form.useForm() |
||||
|
const [ page, setPage ] = useAtom(caPageAtom) |
||||
|
const { data, isLoading, refetch } = useAtomValue(caListAtom) |
||||
|
const { mutate: saveOrUpdate, isPending: isSubmitting, isSuccess } = useAtomValue(saveOrUpdateCaAtom) |
||||
|
const [ open, setOpen ] = useState(false) |
||||
|
|
||||
|
const columns = useMemo<ProColumns<ICA>[]>(() => { |
||||
|
return [ |
||||
|
{ |
||||
|
title: 'ID', |
||||
|
dataIndex: 'id', |
||||
|
hideInTable: true, |
||||
|
formItemProps: { |
||||
|
hidden: true, |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
title: t('website.ssl.ca.columns.name', '名称'), |
||||
|
dataIndex: 'name', |
||||
|
valueType: 'text', |
||||
|
formItemProps: { |
||||
|
label: t('website.ssl.ca.form.name', '机构名称'), |
||||
|
rules: [ |
||||
|
{ required: true, message: t('message.required', '请输入') } |
||||
|
] |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
{ |
||||
|
title: t('website.ssl.ca.columns.keyType', '密钥算法'), |
||||
|
dataIndex: 'keyType', |
||||
|
valueType: 'select', |
||||
|
fieldProps: { |
||||
|
options: KeyTypes |
||||
|
}, |
||||
|
formItemProps: { |
||||
|
rules: [ |
||||
|
{ required: true, message: t('message.required', '请选择') } |
||||
|
] |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
title: t('website.ssl.ca.columns.url', 'URL'), |
||||
|
dataIndex: 'url', |
||||
|
valueType: 'text', |
||||
|
ellipsis: true, // 文本溢出省略
|
||||
|
hideInForm: true, |
||||
|
}, { |
||||
|
title: '操作', |
||||
|
valueType: 'option', |
||||
|
render: (_, record) => { |
||||
|
return [ |
||||
|
<a key="delete" onClick={() => { |
||||
|
}}>{t('actions.delete', '删除')}</a>, |
||||
|
] |
||||
|
} |
||||
|
} |
||||
|
] |
||||
|
}, []) |
||||
|
|
||||
|
return ( |
||||
|
<> |
||||
|
<Alert message={t('website.ssl.ca.tip', 'ca账户用于申请免费证书')}/> |
||||
|
<ProTable<IcaAccount> |
||||
|
cardProps={{ |
||||
|
bodyStyle: { |
||||
|
padding: 0, |
||||
|
} |
||||
|
}} |
||||
|
rowKey="id" |
||||
|
headerTitle={ |
||||
|
<Button |
||||
|
onClick={() => { |
||||
|
form.setFieldsValue({ |
||||
|
id: 0, |
||||
|
type: caType.LetsEncrypt, |
||||
|
keyType: KeyTypeEnum.EC256, |
||||
|
}) |
||||
|
setOpen(true) |
||||
|
}} |
||||
|
type={'primary'}>{t('website.ssl.ca.add', '添加ca帐户')}</Button> |
||||
|
} |
||||
|
loading={isLoading} |
||||
|
dataSource={data?.rows ?? []} |
||||
|
columns={columns} |
||||
|
search={false} |
||||
|
options={{ |
||||
|
reload: () => { |
||||
|
refetch() |
||||
|
}, |
||||
|
}} |
||||
|
pagination={{ |
||||
|
total: data?.total, |
||||
|
pageSize: page.pageSize, |
||||
|
current: page.page, |
||||
|
onChange: (current, pageSize) => { |
||||
|
setPage(prev => { |
||||
|
return { |
||||
|
...prev, |
||||
|
page: current, |
||||
|
pageSize: pageSize, |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
|
||||
|
}} |
||||
|
/> |
||||
|
<BetaSchemaForm<IcaAccount> |
||||
|
shouldUpdate={false} |
||||
|
width={600} |
||||
|
form={form} |
||||
|
layout={'horizontal'} |
||||
|
scrollToFirstError={true} |
||||
|
title={t(`website.ssl.ca.title_${form.getFieldValue('id') !== 0 ? 'edit' : 'add'}`, form.getFieldValue('id') !== 0 ? '证书编辑' : '证书添加')} |
||||
|
// colProps={{ span: 24 }}
|
||||
|
labelCol={{ span: 6 }} |
||||
|
wrapperCol={{ span: 14 }} |
||||
|
layoutType={'ModalForm'} |
||||
|
open={open} |
||||
|
modalProps={{ |
||||
|
maskClosable: false, |
||||
|
}} |
||||
|
onOpenChange={(open) => { |
||||
|
setOpen(open) |
||||
|
}} |
||||
|
loading={isSubmitting} |
||||
|
onFinish={async (values) => { |
||||
|
// console.log('values', values)
|
||||
|
saveOrUpdate(values) |
||||
|
return isSuccess |
||||
|
}} |
||||
|
columns={columns as ProFormColumnsType[]}/> |
||||
|
</> |
||||
|
) |
||||
|
} |
||||
|
|
||||
|
export default CAList |
@ -0,0 +1,50 @@ |
|||||
|
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 { t } from 'i18next' |
||||
|
import { ICA } from '@/types/website/ca' |
||||
|
|
||||
|
export const caPageAtom = atom<IPage>({ |
||||
|
page: 1, pageSize: 10, |
||||
|
}) |
||||
|
|
||||
|
//list
|
||||
|
export const caListAtom = atomWithQuery(get => ({ |
||||
|
queryKey: [ 'caList', get(caPageAtom) ], |
||||
|
queryFn: async ({ queryKey: [ , page ] }) => { |
||||
|
return await websitesServ.ca.list(page) |
||||
|
}, |
||||
|
select: (data) => { |
||||
|
return data.data |
||||
|
} |
||||
|
})) |
||||
|
|
||||
|
//saveOrUpdate
|
||||
|
export const saveOrUpdateCaAtom = atomWithMutation<any, ICA>(get => ({ |
||||
|
mutationKey: [ 'saveOrUpdateCA' ], |
||||
|
mutationFn: async (data: ICA) => { |
||||
|
if (data.id > 0) { |
||||
|
return await websitesServ.ca.update(data) |
||||
|
} |
||||
|
return await websitesServ.ca.add(data) |
||||
|
}, |
||||
|
onSuccess: (res) => { |
||||
|
const isAdd = !!res.data?.id |
||||
|
message.success(t(isAdd ? 'message.saveSuccess' : 'message.editSuccess', '保存成功')) |
||||
|
get(caListAtom).refetch() |
||||
|
return res |
||||
|
} |
||||
|
})) |
||||
|
|
||||
|
export const deleteCaAtom = atomWithMutation<IApiResult, number>(get => ({ |
||||
|
mutationKey: [ 'sslDelete' ], |
||||
|
mutationFn: async (id) => { |
||||
|
return await websitesServ.ca.delete(id) |
||||
|
}, |
||||
|
onSuccess: () => { |
||||
|
message.success(t('message.deleteSuccess', '删除成功')) |
||||
|
get(caListAtom).refetch() |
||||
|
} |
||||
|
})) |
@ -1,10 +1,79 @@ |
|||||
export interface IDnsAccount { |
|
||||
id: number; |
|
||||
createdAt: Date | null; |
|
||||
createdBy: number; |
|
||||
updatedAt: Date | null; |
|
||||
updatedBy: number; |
|
||||
name: string; |
|
||||
type: string; |
|
||||
authorization: string; |
|
||||
} |
|
||||
|
import { t } from 'i18next' |
||||
|
import { atom } from 'jotai/index' |
||||
|
import { IPage } from '@/global' |
||||
|
import { atomWithMutation, atomWithQuery } from 'jotai-tanstack-query' |
||||
|
import websitesServ from '@/service/websites.ts' |
||||
|
import { message } from 'antd' |
||||
|
import { IDnsAccount } from '@/types/website/dns' |
||||
|
|
||||
|
export const DNSTypes = [ |
||||
|
{ |
||||
|
label: t('website.dns.types.aliyun', '阿里云DNS'), |
||||
|
value: 'AliYun', |
||||
|
}, |
||||
|
{ |
||||
|
label: t('website.dns.types.tencentCloud', '腾讯云'), |
||||
|
value: 'TencentCloud', |
||||
|
}, |
||||
|
{ |
||||
|
label: t('website.dns.types.dnsPod', 'DNSPod'), |
||||
|
value: 'DnsPod', |
||||
|
}, |
||||
|
{ |
||||
|
label: 'CloudFlare', |
||||
|
value: 'CloudFlare', |
||||
|
}, |
||||
|
{ |
||||
|
label: 'NameSilo', |
||||
|
value: 'NameSilo', |
||||
|
}, |
||||
|
{ |
||||
|
label: 'NameCheap', |
||||
|
value: 'NameCheap', |
||||
|
}, |
||||
|
{ |
||||
|
label: 'Name.com', |
||||
|
value: 'NameCom', |
||||
|
}, |
||||
|
{ |
||||
|
label: 'GoDaddy', |
||||
|
value: 'Godaddy', |
||||
|
}, |
||||
|
] |
||||
|
|
||||
|
|
||||
|
export const getDNSTypeName = (type: string) => { |
||||
|
return DNSTypes.find(item => item.value === type)?.label |
||||
|
} |
||||
|
|
||||
|
export const dnsPageAtom = atom<IPage>({ |
||||
|
page: 1, pageSize: 10, |
||||
|
}) |
||||
|
|
||||
|
//list
|
||||
|
export const dnsListAtom = atomWithQuery(get => ({ |
||||
|
queryKey: [ 'dnsList', get(dnsPageAtom) ], |
||||
|
queryFn: async ({ queryKey: [ , page ] }) => { |
||||
|
return await websitesServ.dns.list(page) |
||||
|
}, |
||||
|
select: (data) => { |
||||
|
return data.data |
||||
|
} |
||||
|
})) |
||||
|
|
||||
|
//saveOrUpdate
|
||||
|
export const saveOrUpdateDNSAtom = atomWithMutation<any, IDnsAccount>(get => ({ |
||||
|
mutationKey: [ 'saveOrUpdatedDNS' ], |
||||
|
mutationFn: async (data: IDnsAccount) => { |
||||
|
if (data.id > 0) { |
||||
|
return await websitesServ.dns.update(data) |
||||
|
} |
||||
|
return await websitesServ.dns.add(data) |
||||
|
}, |
||||
|
onSuccess: (res) => { |
||||
|
const isAdd = !!res.data?.id |
||||
|
message.success(t(isAdd ? 'message.saveSuccess' : 'message.editSuccess', '保存成功')) |
||||
|
get(dnsListAtom).refetch() |
||||
|
return res |
||||
|
} |
||||
|
})) |
Write
Preview
Loading…
Cancel
Save
Reference in new issue