7 changed files with 1364 additions and 1333 deletions
			
			
		- 
					76src/components/status/Status.tsx
 - 
					325src/pages/websites/ssl/acme/AcmeList.tsx
 - 
					447src/pages/websites/ssl/ca/CAList.tsx
 - 
					551src/pages/websites/ssl/dns/DNSList.tsx
 - 
					796src/pages/websites/ssl/index.tsx
 - 
					420src/routes.tsx
 - 
					82src/store/websites/acme.ts
 
@ -1,171 +1,184 @@ | 
				
			|||
import { useMemo, useState } from 'react' | 
				
			|||
import { useEffect, useMemo, useState } from 'react' | 
				
			|||
import { BetaSchemaForm, ProColumns, ProFormColumnsType, ProTable } from '@ant-design/pro-components' | 
				
			|||
import { useTranslation } from '@/i18n.ts' | 
				
			|||
import { AcmeAccountTypes, acmeListAtom, acmePageAtom, AcmeType, saveOrUpdateAcmeAtom } from '@/store/websites/acme.ts' | 
				
			|||
import { | 
				
			|||
  AcmeAccountTypes, | 
				
			|||
  acmeListAtom, | 
				
			|||
  acmePageAtom, | 
				
			|||
  AcmeType, | 
				
			|||
  deleteAcmeAtom, | 
				
			|||
  saveOrUpdateAcmeAtom | 
				
			|||
} from '@/store/websites/acme.ts' | 
				
			|||
import { useAtom, useAtomValue } from 'jotai' | 
				
			|||
import { Alert, Button, Form, Popconfirm } from 'antd' | 
				
			|||
import { KeyTypeEnum, KeyTypes } from '@/store/websites/ssl.ts' | 
				
			|||
import { deleteDNSAtom } from '@/store/websites/dns.ts' | 
				
			|||
import { WebSite } from '@/types' | 
				
			|||
 | 
				
			|||
const AcmeList = () => { | 
				
			|||
 | 
				
			|||
    const { t } = useTranslation() | 
				
			|||
    const [ form ] = Form.useForm() | 
				
			|||
    const [ page, setPage ] = useAtom(acmePageAtom) | 
				
			|||
    const { data, isLoading, refetch } = useAtomValue(acmeListAtom) | 
				
			|||
    const { mutate: saveOrUpdate, isPending: isSubmitting, isSuccess } = useAtomValue(saveOrUpdateAcmeAtom) | 
				
			|||
    const { mutate: deleteDNS, isPending: isDeleting } = useAtomValue(deleteDNSAtom) | 
				
			|||
    const [ open, setOpen ] = useState(false) | 
				
			|||
  const { t } = useTranslation() | 
				
			|||
  const [ form ] = Form.useForm() | 
				
			|||
  const [ page, setPage ] = useAtom(acmePageAtom) | 
				
			|||
  const { data, isLoading, isFetching, refetch } = useAtomValue(acmeListAtom) | 
				
			|||
  const { mutate: saveOrUpdate, isPending: isSubmitting, isSuccess } = useAtomValue(saveOrUpdateAcmeAtom) | 
				
			|||
  const { mutate: deleteAcme, isPending: isDeleting } = useAtomValue(deleteAcmeAtom) | 
				
			|||
  const [ open, setOpen ] = useState(false) | 
				
			|||
 | 
				
			|||
    const columns = useMemo<ProColumns<WebSite.IAcmeAccount>[]>(() => { | 
				
			|||
        return [ | 
				
			|||
            { | 
				
			|||
                title: 'ID', | 
				
			|||
                dataIndex: 'id', | 
				
			|||
                hideInTable: true, | 
				
			|||
                formItemProps: { | 
				
			|||
                    hidden: true, | 
				
			|||
                } | 
				
			|||
            }, | 
				
			|||
            { | 
				
			|||
                title: t('website.ssl.acme.columns.email', '邮箱'), | 
				
			|||
                dataIndex: 'email', | 
				
			|||
                valueType: 'text', | 
				
			|||
                formItemProps: { | 
				
			|||
                    rules: [ | 
				
			|||
                        { required: true, message: t('message.required', '请输入') } | 
				
			|||
                    ] | 
				
			|||
                } | 
				
			|||
            }, | 
				
			|||
            { | 
				
			|||
                title: t('website.ssl.acme.columns.type', '帐号类型'), | 
				
			|||
                dataIndex: 'type', | 
				
			|||
                valueType: 'select', | 
				
			|||
                fieldProps: { | 
				
			|||
                    options: AcmeAccountTypes | 
				
			|||
                }, | 
				
			|||
                formItemProps: { | 
				
			|||
                    rules: [ | 
				
			|||
                        { required: true, message: t('message.required', '请选择') } | 
				
			|||
                    ] | 
				
			|||
                } | 
				
			|||
            }, | 
				
			|||
            { | 
				
			|||
                title: t('website.ssl.acme.columns.keyType', '密钥算法'), | 
				
			|||
                dataIndex: 'keyType', | 
				
			|||
                valueType: 'select', | 
				
			|||
                fieldProps: { | 
				
			|||
                    options: KeyTypes | 
				
			|||
                }, | 
				
			|||
                formItemProps: { | 
				
			|||
                    rules: [ | 
				
			|||
                        { required: true, message: t('message.required', '请选择') } | 
				
			|||
                    ] | 
				
			|||
                }, | 
				
			|||
            }, | 
				
			|||
            { | 
				
			|||
                title: t('website.ssl.acme.columns.url', 'URL'), | 
				
			|||
                dataIndex: 'url', | 
				
			|||
                valueType: 'text', | 
				
			|||
                ellipsis: true, // 文本溢出省略
 | 
				
			|||
                hideInForm: true, | 
				
			|||
            }, { | 
				
			|||
                title: '操作', | 
				
			|||
                valueType: 'option', | 
				
			|||
                render: (_, record) => { | 
				
			|||
                    return [ | 
				
			|||
                        <Popconfirm | 
				
			|||
                                key={'del_confirm'} | 
				
			|||
                                disabled={isDeleting} | 
				
			|||
                                onConfirm={() => { | 
				
			|||
                                    deleteDNS(record.id) | 
				
			|||
                                }} | 
				
			|||
                                title={t('message.deleteConfirm')}> | 
				
			|||
                            <a key="del"> | 
				
			|||
                                {t('actions.delete', '删除')} | 
				
			|||
                            </a> | 
				
			|||
                        </Popconfirm> | 
				
			|||
                    ] | 
				
			|||
                } | 
				
			|||
            } | 
				
			|||
        ] | 
				
			|||
    }, []) | 
				
			|||
  const columns = useMemo<ProColumns<WebSite.IAcmeAccount>[]>(() => { | 
				
			|||
    return [ | 
				
			|||
      { | 
				
			|||
        title: 'ID', | 
				
			|||
        dataIndex: 'id', | 
				
			|||
        hideInTable: true, | 
				
			|||
        formItemProps: { | 
				
			|||
          hidden: true, | 
				
			|||
        } | 
				
			|||
      }, | 
				
			|||
      { | 
				
			|||
        title: t('website.ssl.acme.columns.email', '邮箱'), | 
				
			|||
        dataIndex: 'email', | 
				
			|||
        valueType: 'text', | 
				
			|||
        formItemProps: { | 
				
			|||
          rules: [ | 
				
			|||
            { required: true, message: t('message.required', '请输入') } | 
				
			|||
          ] | 
				
			|||
        } | 
				
			|||
      }, | 
				
			|||
      { | 
				
			|||
        title: t('website.ssl.acme.columns.type', '帐号类型'), | 
				
			|||
        dataIndex: 'type', | 
				
			|||
        valueType: 'select', | 
				
			|||
        fieldProps: { | 
				
			|||
          options: AcmeAccountTypes | 
				
			|||
        }, | 
				
			|||
        formItemProps: { | 
				
			|||
          rules: [ | 
				
			|||
            { required: true, message: t('message.required', '请选择') } | 
				
			|||
          ] | 
				
			|||
        } | 
				
			|||
      }, | 
				
			|||
      { | 
				
			|||
        title: t('website.ssl.acme.columns.keyType', '密钥算法'), | 
				
			|||
        dataIndex: 'key_type', | 
				
			|||
        valueType: 'select', | 
				
			|||
        fieldProps: { | 
				
			|||
          options: KeyTypes | 
				
			|||
        }, | 
				
			|||
        formItemProps: { | 
				
			|||
          rules: [ | 
				
			|||
            { required: true, message: t('message.required', '请选择') } | 
				
			|||
          ] | 
				
			|||
        }, | 
				
			|||
      }, | 
				
			|||
      { | 
				
			|||
        title: t('website.ssl.acme.columns.url', 'URL'), | 
				
			|||
        dataIndex: 'url', | 
				
			|||
        valueType: 'text', | 
				
			|||
        ellipsis: true, // 文本溢出省略
 | 
				
			|||
        hideInForm: true, | 
				
			|||
      }, { | 
				
			|||
        title: t('website.ssl.acme.columns.option', '操作'), | 
				
			|||
        valueType: 'option', | 
				
			|||
        fixed: 'right', | 
				
			|||
        render: (_, record) => { | 
				
			|||
          return [ | 
				
			|||
            <Popconfirm | 
				
			|||
              key={'del_confirm'} | 
				
			|||
              disabled={isDeleting} | 
				
			|||
              onConfirm={() => { | 
				
			|||
                deleteAcme(record.id) | 
				
			|||
              }} | 
				
			|||
              title={t('message.deleteConfirm')}> | 
				
			|||
              <a key="del"> | 
				
			|||
                {t('actions.delete', '删除')} | 
				
			|||
              </a> | 
				
			|||
            </Popconfirm> | 
				
			|||
          ] | 
				
			|||
        } | 
				
			|||
      } | 
				
			|||
    ] | 
				
			|||
  }, []) | 
				
			|||
 | 
				
			|||
    return ( | 
				
			|||
            <> | 
				
			|||
                <Alert message={t('website.ssl.acme.tip', 'Acme账户用于申请免费证书')}/> | 
				
			|||
                <ProTable<WebSite.IAcmeAccount> | 
				
			|||
                        cardProps={{ | 
				
			|||
                            bodyStyle: { | 
				
			|||
                                padding: 0, | 
				
			|||
                            } | 
				
			|||
                        }} | 
				
			|||
                        rowKey="id" | 
				
			|||
                        headerTitle={ | 
				
			|||
                            <Button | 
				
			|||
                                    onClick={() => { | 
				
			|||
                                        form.setFieldsValue({ | 
				
			|||
                                            id: 0, | 
				
			|||
                                            type: AcmeType.LetsEncrypt, | 
				
			|||
                                            keyType: KeyTypeEnum.EC256, | 
				
			|||
                                        }) | 
				
			|||
                                        setOpen(true) | 
				
			|||
                                    }} | 
				
			|||
                                    type={'primary'}>{t('website.ssl.acme.add', '添加Acme帐户')}</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, | 
				
			|||
                                    } | 
				
			|||
                                }) | 
				
			|||
                            }, | 
				
			|||
  useEffect(() => { | 
				
			|||
    if (isSuccess) { | 
				
			|||
      setOpen(false) | 
				
			|||
    } | 
				
			|||
  }, [ isSuccess ]) | 
				
			|||
 | 
				
			|||
                        }} | 
				
			|||
                /> | 
				
			|||
                <BetaSchemaForm<WebSite.IAcmeAccount> | 
				
			|||
                        shouldUpdate={false} | 
				
			|||
                        width={600} | 
				
			|||
                        form={form} | 
				
			|||
                        layout={'horizontal'} | 
				
			|||
                        scrollToFirstError={true} | 
				
			|||
                        title={t(`website.ssl.acme.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[]}/> | 
				
			|||
            </> | 
				
			|||
    ) | 
				
			|||
  return ( | 
				
			|||
    <> | 
				
			|||
      <Alert message={t('website.ssl.acme.tip', 'Acme账户用于申请免费证书')}/> | 
				
			|||
      <ProTable<WebSite.IAcmeAccount> | 
				
			|||
        cardProps={{ | 
				
			|||
          bodyStyle: { | 
				
			|||
            padding: 0, | 
				
			|||
          } | 
				
			|||
        }} | 
				
			|||
        rowKey="id" | 
				
			|||
        headerTitle={ | 
				
			|||
          <Button | 
				
			|||
            onClick={() => { | 
				
			|||
              form.setFieldsValue({ | 
				
			|||
                id: 0, | 
				
			|||
                type: AcmeType.LetsEncrypt, | 
				
			|||
                keyType: KeyTypeEnum.EC256, | 
				
			|||
              }) | 
				
			|||
              setOpen(true) | 
				
			|||
            }} | 
				
			|||
            type={'primary'}>{t('website.ssl.acme.add', '添加Acme帐户')}</Button> | 
				
			|||
        } | 
				
			|||
        loading={isLoading || isFetching} | 
				
			|||
        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<WebSite.IAcmeAccount> | 
				
			|||
        shouldUpdate={false} | 
				
			|||
        width={600} | 
				
			|||
        form={form} | 
				
			|||
        layout={'horizontal'} | 
				
			|||
        scrollToFirstError={true} | 
				
			|||
        title={t(`website.ssl.acme.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) | 
				
			|||
 | 
				
			|||
        }} | 
				
			|||
        columns={columns as ProFormColumnsType[]}/> | 
				
			|||
    </> | 
				
			|||
  ) | 
				
			|||
} | 
				
			|||
 | 
				
			|||
export default AcmeList | 
				
			|||
@ -1,296 +1,301 @@ | 
				
			|||
import { useMemo, useState } from 'react' | 
				
			|||
import { useEffect, useMemo, useState } from 'react' | 
				
			|||
import { BetaSchemaForm, ProColumns, ProFormColumnsType, ProTable } from '@ant-design/pro-components' | 
				
			|||
import { useTranslation } from '@/i18n.ts' | 
				
			|||
import { useAtom, useAtomValue } from 'jotai' | 
				
			|||
import { Button, Form, Popconfirm } from 'antd' | 
				
			|||
import { | 
				
			|||
    deleteDNSAtom, | 
				
			|||
    dnsListAtom, | 
				
			|||
    dnsPageAtom, | 
				
			|||
    DNSTypeEnum, | 
				
			|||
    DNSTypes, | 
				
			|||
    saveOrUpdateDNSAtom | 
				
			|||
  deleteDNSAtom, | 
				
			|||
  dnsListAtom, | 
				
			|||
  dnsPageAtom, | 
				
			|||
  DNSTypeEnum, | 
				
			|||
  DNSTypes, | 
				
			|||
  saveOrUpdateDNSAtom | 
				
			|||
} from '@/store/websites/dns.ts' | 
				
			|||
import { WebSite } from '@/types' | 
				
			|||
 | 
				
			|||
const getKeyColumn = (type: string, t) => { | 
				
			|||
    const columns: ProColumns<IDnsAccount>[] = [] | 
				
			|||
    switch (type) { | 
				
			|||
        case DNSTypeEnum.AliYun: { | 
				
			|||
            columns.push(...[ | 
				
			|||
                { | 
				
			|||
                    title: t('website.ssl.dns.columns.accessKey', 'Access Key'), | 
				
			|||
                    dataIndex: 'accessKey', | 
				
			|||
                    formItemProps: { | 
				
			|||
                        rules: [ { required: true, message: t('message.required') } ] | 
				
			|||
                    } | 
				
			|||
                }, | 
				
			|||
                { | 
				
			|||
                    title: t('website.ssl.dns.columns.secretKey', 'Secret Key'), | 
				
			|||
                    dataIndex: 'secretKey', | 
				
			|||
                    formItemProps: { | 
				
			|||
                        rules: [ { required: true, message: t('message.required') } ] | 
				
			|||
                    } | 
				
			|||
                }, | 
				
			|||
            ]) | 
				
			|||
        } | 
				
			|||
            break | 
				
			|||
        case  DNSTypeEnum.TencentCloud: { | 
				
			|||
            columns.push(...[ | 
				
			|||
                { | 
				
			|||
                    title: t('website.ssl.dns.columns.secretID', 'Secret ID'), | 
				
			|||
                    dataIndex: 'secretID', | 
				
			|||
                    formItemProps: { | 
				
			|||
                        rules: [ { required: true, message: t('message.required') } ] | 
				
			|||
                    } | 
				
			|||
                }, { | 
				
			|||
                    title: t('website.ssl.dns.columns.secretKey', 'Secret Key'), | 
				
			|||
                    dataIndex: 'secretKey', | 
				
			|||
                    formItemProps: { | 
				
			|||
                        rules: [ { required: true, message: t('message.required') } ] | 
				
			|||
                    } | 
				
			|||
                }, | 
				
			|||
            ]) | 
				
			|||
            break | 
				
			|||
        } | 
				
			|||
        case DNSTypeEnum.DnsPod: { | 
				
			|||
            columns.push(...[ | 
				
			|||
                { | 
				
			|||
                    title: t('website.ssl.dns.columns.apiId', 'ID'), | 
				
			|||
                    dataIndex: 'apiId', | 
				
			|||
                    formItemProps: { | 
				
			|||
                        rules: [ { required: true, message: t('message.required') } ] | 
				
			|||
                    } | 
				
			|||
                }, { | 
				
			|||
                    title: t('website.ssl.dns.columns.token', 'Token'), | 
				
			|||
                    dataIndex: 'token', | 
				
			|||
                    formItemProps: { | 
				
			|||
                        rules: [ { required: true, message: t('message.required') } ] | 
				
			|||
                    } | 
				
			|||
                }, | 
				
			|||
            ]) | 
				
			|||
            break | 
				
			|||
        } | 
				
			|||
        case DNSTypeEnum.CloudFlare: { | 
				
			|||
            columns.push(...[ | 
				
			|||
                        { | 
				
			|||
                            title: t('website.ssl.dns.columns.email', 'Email'), | 
				
			|||
                            dataIndex: 'email', | 
				
			|||
                            formItemProps: { | 
				
			|||
                                rules: [ { required: true, message: t('message.required') } ] | 
				
			|||
                            } | 
				
			|||
                        }, { | 
				
			|||
                            title: t('website.ssl.dns.columns.apiKey', 'API ToKen'), | 
				
			|||
                            dataIndex: 'apiKey', | 
				
			|||
                            formItemProps: { | 
				
			|||
                                rules: [ { required: true, message: t('message.required') } ] | 
				
			|||
                            } | 
				
			|||
                        }, | 
				
			|||
                    ] | 
				
			|||
            ) | 
				
			|||
            break | 
				
			|||
        } | 
				
			|||
        case DNSTypeEnum.Godaddy: | 
				
			|||
        case DNSTypeEnum.NameCheap: | 
				
			|||
        case DNSTypeEnum.NameSilo: | 
				
			|||
            columns.push({ | 
				
			|||
                        title: t('website.ssl.dns.columns.apiKey', 'API Key'), | 
				
			|||
                        dataIndex: 'apiKey', | 
				
			|||
                        formItemProps: { | 
				
			|||
                            rules: [ { required: true, message: t('message.required') } ] | 
				
			|||
                        } | 
				
			|||
                    }, | 
				
			|||
            ) | 
				
			|||
            if (type === DNSTypeEnum.NameCheap) { | 
				
			|||
                columns.push({ | 
				
			|||
                    title: t('website.ssl.dns.columns.apiUser', 'API User'), | 
				
			|||
                    dataIndex: 'apiUser', | 
				
			|||
                    formItemProps: { | 
				
			|||
                        rules: [ { required: true, message: t('message.required') } ] | 
				
			|||
                    } | 
				
			|||
                }) | 
				
			|||
            } else if (type === DNSTypeEnum.Godaddy) { | 
				
			|||
                columns.push({ | 
				
			|||
                    title: t('website.ssl.dns.columns.apiSecret', 'API Secret'), | 
				
			|||
                    dataIndex: 'apiSecret', | 
				
			|||
                    formItemProps: { | 
				
			|||
                        rules: [ { required: true, message: t('message.required') } ] | 
				
			|||
                    } | 
				
			|||
                }) | 
				
			|||
  const columns: ProColumns<WebSite.IDnsAccount>[] = [] | 
				
			|||
  switch (type) { | 
				
			|||
    case DNSTypeEnum.AliYun: { | 
				
			|||
      columns.push(...[ | 
				
			|||
        { | 
				
			|||
          title: t('website.ssl.dns.columns.accessKey', 'Access Key'), | 
				
			|||
          dataIndex: 'accessKey', | 
				
			|||
          formItemProps: { | 
				
			|||
            rules: [ { required: true, message: t('message.required') } ] | 
				
			|||
          } | 
				
			|||
        }, | 
				
			|||
        { | 
				
			|||
          title: t('website.ssl.dns.columns.secretKey', 'Secret Key'), | 
				
			|||
          dataIndex: 'secretKey', | 
				
			|||
          formItemProps: { | 
				
			|||
            rules: [ { required: true, message: t('message.required') } ] | 
				
			|||
          } | 
				
			|||
        }, | 
				
			|||
      ]) | 
				
			|||
    } | 
				
			|||
      break | 
				
			|||
    case  DNSTypeEnum.TencentCloud: { | 
				
			|||
      columns.push(...[ | 
				
			|||
        { | 
				
			|||
          title: t('website.ssl.dns.columns.secretID', 'Secret ID'), | 
				
			|||
          dataIndex: 'secretID', | 
				
			|||
          formItemProps: { | 
				
			|||
            rules: [ { required: true, message: t('message.required') } ] | 
				
			|||
          } | 
				
			|||
        }, { | 
				
			|||
          title: t('website.ssl.dns.columns.secretKey', 'Secret Key'), | 
				
			|||
          dataIndex: 'secretKey', | 
				
			|||
          formItemProps: { | 
				
			|||
            rules: [ { required: true, message: t('message.required') } ] | 
				
			|||
          } | 
				
			|||
        }, | 
				
			|||
      ]) | 
				
			|||
      break | 
				
			|||
    } | 
				
			|||
    case DNSTypeEnum.DnsPod: { | 
				
			|||
      columns.push(...[ | 
				
			|||
        { | 
				
			|||
          title: t('website.ssl.dns.columns.apiId', 'ID'), | 
				
			|||
          dataIndex: 'apiId', | 
				
			|||
          formItemProps: { | 
				
			|||
            rules: [ { required: true, message: t('message.required') } ] | 
				
			|||
          } | 
				
			|||
        }, { | 
				
			|||
          title: t('website.ssl.dns.columns.token', 'Token'), | 
				
			|||
          dataIndex: 'token', | 
				
			|||
          formItemProps: { | 
				
			|||
            rules: [ { required: true, message: t('message.required') } ] | 
				
			|||
          } | 
				
			|||
        }, | 
				
			|||
      ]) | 
				
			|||
      break | 
				
			|||
    } | 
				
			|||
    case DNSTypeEnum.CloudFlare: { | 
				
			|||
      columns.push(...[ | 
				
			|||
          { | 
				
			|||
            title: t('website.ssl.dns.columns.email', 'Email'), | 
				
			|||
            dataIndex: 'email', | 
				
			|||
            formItemProps: { | 
				
			|||
              rules: [ { required: true, message: t('message.required') } ] | 
				
			|||
            } | 
				
			|||
          }, { | 
				
			|||
            title: t('website.ssl.dns.columns.apiKey', 'API ToKen'), | 
				
			|||
            dataIndex: 'apiKey', | 
				
			|||
            formItemProps: { | 
				
			|||
              rules: [ { required: true, message: t('message.required') } ] | 
				
			|||
            } | 
				
			|||
            break | 
				
			|||
        case DNSTypeEnum.NameCom: { | 
				
			|||
            columns.push( | 
				
			|||
                    { | 
				
			|||
                        title: t('website.ssl.dns.columns.apiUser', 'UserName'), | 
				
			|||
                        dataIndex: 'apiUser', | 
				
			|||
                        formItemProps: { | 
				
			|||
                            rules: [ { required: true, message: t('message.required') } ] | 
				
			|||
                        } | 
				
			|||
                    }, | 
				
			|||
                    { | 
				
			|||
                        title: t('website.ssl.dns.columns.token', 'Token'), | 
				
			|||
                        dataIndex: 'token', | 
				
			|||
                        formItemProps: { | 
				
			|||
                            rules: [ { required: true, message: t('message.required') } ] | 
				
			|||
                        } | 
				
			|||
                    } | 
				
			|||
            ) | 
				
			|||
            break | 
				
			|||
          }, | 
				
			|||
        ] | 
				
			|||
      ) | 
				
			|||
      break | 
				
			|||
    } | 
				
			|||
    case DNSTypeEnum.Godaddy: | 
				
			|||
    case DNSTypeEnum.NameCheap: | 
				
			|||
    case DNSTypeEnum.NameSilo: | 
				
			|||
      columns.push({ | 
				
			|||
          title: t('website.ssl.dns.columns.apiKey', 'API Key'), | 
				
			|||
          dataIndex: 'apiKey', | 
				
			|||
          formItemProps: { | 
				
			|||
            rules: [ { required: true, message: t('message.required') } ] | 
				
			|||
          } | 
				
			|||
        }, | 
				
			|||
      ) | 
				
			|||
      if (type === DNSTypeEnum.NameCheap) { | 
				
			|||
        columns.push({ | 
				
			|||
          title: t('website.ssl.dns.columns.apiUser', 'API User'), | 
				
			|||
          dataIndex: 'apiUser', | 
				
			|||
          formItemProps: { | 
				
			|||
            rules: [ { required: true, message: t('message.required') } ] | 
				
			|||
          } | 
				
			|||
        }) | 
				
			|||
      } else if (type === DNSTypeEnum.Godaddy) { | 
				
			|||
        columns.push({ | 
				
			|||
          title: t('website.ssl.dns.columns.apiSecret', 'API Secret'), | 
				
			|||
          dataIndex: 'apiSecret', | 
				
			|||
          formItemProps: { | 
				
			|||
            rules: [ { required: true, message: t('message.required') } ] | 
				
			|||
          } | 
				
			|||
        }) | 
				
			|||
      } | 
				
			|||
      break | 
				
			|||
    case DNSTypeEnum.NameCom: { | 
				
			|||
      columns.push( | 
				
			|||
        { | 
				
			|||
          title: t('website.ssl.dns.columns.apiUser', 'UserName'), | 
				
			|||
          dataIndex: 'apiUser', | 
				
			|||
          formItemProps: { | 
				
			|||
            rules: [ { required: true, message: t('message.required') } ] | 
				
			|||
          } | 
				
			|||
        }, | 
				
			|||
        { | 
				
			|||
          title: t('website.ssl.dns.columns.token', 'Token'), | 
				
			|||
          dataIndex: 'token', | 
				
			|||
          formItemProps: { | 
				
			|||
            rules: [ { required: true, message: t('message.required') } ] | 
				
			|||
          } | 
				
			|||
        } | 
				
			|||
        default: | 
				
			|||
            break | 
				
			|||
 | 
				
			|||
      ) | 
				
			|||
      break | 
				
			|||
    } | 
				
			|||
    return columns | 
				
			|||
    default: | 
				
			|||
      break | 
				
			|||
 | 
				
			|||
  } | 
				
			|||
  return columns | 
				
			|||
} | 
				
			|||
 | 
				
			|||
const DNSList = () => { | 
				
			|||
 | 
				
			|||
    const { t } = useTranslation() | 
				
			|||
    const [ form ] = Form.useForm() | 
				
			|||
    const [ page, setPage ] = useAtom(dnsPageAtom) | 
				
			|||
    const { data, isLoading, refetch } = useAtomValue(dnsListAtom) | 
				
			|||
    const { mutate: saveOrUpdate, isPending: isSubmitting, isSuccess } = useAtomValue(saveOrUpdateDNSAtom) | 
				
			|||
    const { mutate: deleteDNS, isPending: isDeleting } = useAtomValue(deleteDNSAtom) | 
				
			|||
    const [ open, setOpen ] = useState(false) | 
				
			|||
  const { t } = useTranslation() | 
				
			|||
  const [ form ] = Form.useForm() | 
				
			|||
  const [ page, setPage ] = useAtom(dnsPageAtom) | 
				
			|||
  const { data, isLoading, isFetching, refetch } = useAtomValue(dnsListAtom) | 
				
			|||
  const { mutate: saveOrUpdate, isPending: isSubmitting, isSuccess } = useAtomValue(saveOrUpdateDNSAtom) | 
				
			|||
  const { mutate: deleteDNS, isPending: isDeleting } = useAtomValue(deleteDNSAtom) | 
				
			|||
  const [ open, setOpen ] = useState(false) | 
				
			|||
 | 
				
			|||
    const columns = useMemo<ProColumns<WebSite.IDnsAccount>[]>(() => { | 
				
			|||
        return [ | 
				
			|||
            { | 
				
			|||
                title: 'ID', | 
				
			|||
                dataIndex: 'id', | 
				
			|||
                hideInTable: true, | 
				
			|||
                formItemProps: { | 
				
			|||
                    hidden: true, | 
				
			|||
                } | 
				
			|||
            }, | 
				
			|||
            { | 
				
			|||
                title: t('website.ssl.dns.columns.name', '名称'), | 
				
			|||
                dataIndex: 'name', | 
				
			|||
                valueType: 'text', | 
				
			|||
                formItemProps: { | 
				
			|||
                    rules: [ | 
				
			|||
                        { required: true, message: t('message.required', '请输入') } | 
				
			|||
                    ] | 
				
			|||
                } | 
				
			|||
            }, | 
				
			|||
  const columns = useMemo<ProColumns<WebSite.IDnsAccount>[]>(() => { | 
				
			|||
    return [ | 
				
			|||
      { | 
				
			|||
        title: 'ID', | 
				
			|||
        dataIndex: 'id', | 
				
			|||
        hideInTable: true, | 
				
			|||
        formItemProps: { | 
				
			|||
          hidden: true, | 
				
			|||
        } | 
				
			|||
      }, | 
				
			|||
      { | 
				
			|||
        title: t('website.ssl.dns.columns.name', '名称'), | 
				
			|||
        dataIndex: 'name', | 
				
			|||
        valueType: 'text', | 
				
			|||
        formItemProps: { | 
				
			|||
          rules: [ | 
				
			|||
            { required: true, message: t('message.required', '请输入') } | 
				
			|||
          ] | 
				
			|||
        } | 
				
			|||
      }, | 
				
			|||
 | 
				
			|||
            { | 
				
			|||
                title: t('website.ssl.dns.columns.type', '类型'), | 
				
			|||
                dataIndex: 'type', | 
				
			|||
                valueType: 'select', | 
				
			|||
                fieldProps: { | 
				
			|||
                    options: DNSTypes | 
				
			|||
                }, | 
				
			|||
                formItemProps: { | 
				
			|||
                    rules: [ | 
				
			|||
                        { required: true, message: t('message.required', '请选择') } | 
				
			|||
                    ] | 
				
			|||
                }, | 
				
			|||
            }, | 
				
			|||
            { | 
				
			|||
                name: [ 'type' ], | 
				
			|||
                valueType: 'dependency', | 
				
			|||
                hideInSetting: true, | 
				
			|||
                columns: ({ type }) => { | 
				
			|||
                    return getKeyColumn(type, t) | 
				
			|||
                } | 
				
			|||
            }, | 
				
			|||
            { | 
				
			|||
                title: '操作', | 
				
			|||
                valueType: 'option', | 
				
			|||
                render: (_, record) => { | 
				
			|||
                    return [ | 
				
			|||
                        <Popconfirm | 
				
			|||
                                key={'del_confirm'} | 
				
			|||
                                disabled={isDeleting} | 
				
			|||
                                onConfirm={() => { | 
				
			|||
                                    deleteDNS(record.id) | 
				
			|||
                                }} | 
				
			|||
                                title={t('message.deleteConfirm')}> | 
				
			|||
                            <a key="del"> | 
				
			|||
                                {t('actions.delete', '删除')} | 
				
			|||
                            </a> | 
				
			|||
                        </Popconfirm> | 
				
			|||
                    ] | 
				
			|||
                } | 
				
			|||
            } | 
				
			|||
        ] | 
				
			|||
    }, []) | 
				
			|||
      { | 
				
			|||
        title: t('website.ssl.dns.columns.type', '类型'), | 
				
			|||
        dataIndex: 'type', | 
				
			|||
        valueType: 'select', | 
				
			|||
        fieldProps: { | 
				
			|||
          options: DNSTypes | 
				
			|||
        }, | 
				
			|||
        formItemProps: { | 
				
			|||
          rules: [ | 
				
			|||
            { required: true, message: t('message.required', '请选择') } | 
				
			|||
          ] | 
				
			|||
        }, | 
				
			|||
      }, | 
				
			|||
      { | 
				
			|||
        name: [ 'type' ], | 
				
			|||
        valueType: 'dependency', | 
				
			|||
        hideInSetting: true, | 
				
			|||
        columns: ({ type }) => { | 
				
			|||
          return getKeyColumn(type, t) | 
				
			|||
        } | 
				
			|||
      }, | 
				
			|||
      { | 
				
			|||
        title: '操作', | 
				
			|||
        valueType: 'option', | 
				
			|||
        render: (_, record) => { | 
				
			|||
          return [ | 
				
			|||
            <Popconfirm | 
				
			|||
              key={'del_confirm'} | 
				
			|||
              disabled={isDeleting} | 
				
			|||
              onConfirm={() => { | 
				
			|||
                deleteDNS(record.id) | 
				
			|||
              }} | 
				
			|||
              title={t('message.deleteConfirm')}> | 
				
			|||
              <a key="del"> | 
				
			|||
                {t('actions.delete', '删除')} | 
				
			|||
              </a> | 
				
			|||
            </Popconfirm> | 
				
			|||
          ] | 
				
			|||
        } | 
				
			|||
      } | 
				
			|||
    ] | 
				
			|||
  }, []) | 
				
			|||
 | 
				
			|||
    return ( | 
				
			|||
            <> | 
				
			|||
                <ProTable<WebSite.IDnsAccount> | 
				
			|||
                        cardProps={{ | 
				
			|||
                            bodyStyle: { | 
				
			|||
                                padding: 0, | 
				
			|||
                            } | 
				
			|||
                        }} | 
				
			|||
                        rowKey="id" | 
				
			|||
                        headerTitle={ | 
				
			|||
                            <Button | 
				
			|||
                                    onClick={() => { | 
				
			|||
                                        form.setFieldsValue({ | 
				
			|||
                                            id: 0, | 
				
			|||
                                            type: DNSTypeEnum.DnsPod, | 
				
			|||
                                        }) | 
				
			|||
                                        setOpen(true) | 
				
			|||
                                    }} | 
				
			|||
                                    type={'primary'}>{t('website.ssl.dns.add', '添加DNS帐户')}</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, | 
				
			|||
                                    } | 
				
			|||
                                }) | 
				
			|||
                            }, | 
				
			|||
  useEffect(() => { | 
				
			|||
    if (isSuccess) { | 
				
			|||
      setOpen(false) | 
				
			|||
    } | 
				
			|||
  }, [ isSuccess ]) | 
				
			|||
 | 
				
			|||
  return ( | 
				
			|||
    <> | 
				
			|||
      <ProTable<WebSite.IDnsAccount> | 
				
			|||
        cardProps={{ | 
				
			|||
          bodyStyle: { | 
				
			|||
            padding: 0, | 
				
			|||
          } | 
				
			|||
        }} | 
				
			|||
        rowKey="id" | 
				
			|||
        headerTitle={ | 
				
			|||
          <Button | 
				
			|||
            onClick={() => { | 
				
			|||
              form.setFieldsValue({ | 
				
			|||
                id: 0, | 
				
			|||
                type: DNSTypeEnum.DnsPod, | 
				
			|||
              }) | 
				
			|||
              setOpen(true) | 
				
			|||
            }} | 
				
			|||
            type={'primary'}>{t('website.ssl.dns.add', '添加DNS帐户')}</Button> | 
				
			|||
        } | 
				
			|||
        loading={isLoading || isFetching} | 
				
			|||
        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<WebSite.IDnsAccount> | 
				
			|||
                        shouldUpdate={false} | 
				
			|||
                        width={600} | 
				
			|||
                        form={form} | 
				
			|||
                        layout={'horizontal'} | 
				
			|||
                        scrollToFirstError={true} | 
				
			|||
                        title={t(`website.ssl.dns.title_${form.getFieldValue('id') !== 0 ? 'edit' : 'add'}`, form.getFieldValue('id') !== 0 ? 'DNS帐号编辑' : 'DNS帐号添加')} | 
				
			|||
                        // 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[]}/> | 
				
			|||
            </> | 
				
			|||
    ) | 
				
			|||
        }} | 
				
			|||
      /> | 
				
			|||
      <BetaSchemaForm<WebSite.IDnsAccount> | 
				
			|||
        shouldUpdate={false} | 
				
			|||
        width={600} | 
				
			|||
        form={form} | 
				
			|||
        layout={'horizontal'} | 
				
			|||
        scrollToFirstError={true} | 
				
			|||
        title={t(`website.ssl.dns.title_${form.getFieldValue('id') !== 0 ? 'edit' : 'add'}`, form.getFieldValue('id') !== 0 ? 'DNS帐号编辑' : 'DNS帐号添加')} | 
				
			|||
        // 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) | 
				
			|||
        }} | 
				
			|||
        columns={columns as ProFormColumnsType[]}/> | 
				
			|||
    </> | 
				
			|||
  ) | 
				
			|||
} | 
				
			|||
 | 
				
			|||
export default DNSList | 
				
			|||
						Write
						Preview
					
					
					Loading…
					
					Cancel
						Save
					
		Reference in new issue