You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

170 lines
6.8 KiB

1 year ago
1 year ago
1 year ago
1 year ago
  1. import { useMemo, useState } from 'react'
  2. import { BetaSchemaForm, ProColumns, ProFormColumnsType, ProTable } from '@ant-design/pro-components'
  3. import { IAcmeAccount } from '@/types/website/acme'
  4. import { useTranslation } from '@/i18n.ts'
  5. import { AcmeAccountTypes, acmeListAtom, acmePageAtom, AcmeType, saveOrUpdateAcmeAtom } from '@/store/websites/acme.ts'
  6. import { useAtom, useAtomValue } from 'jotai'
  7. import { Alert, Button, Form, Popconfirm } from 'antd'
  8. import { KeyTypeEnum, KeyTypes } from '@/store/websites/ssl.ts'
  9. import { deleteDNSAtom } from '@/store/websites/dns.ts'
  10. const AcmeList = () => {
  11. const { t } = useTranslation()
  12. const [ form ] = Form.useForm()
  13. const [ page, setPage ] = useAtom(acmePageAtom)
  14. const { data, isLoading, refetch } = useAtomValue(acmeListAtom)
  15. const { mutate: saveOrUpdate, isPending: isSubmitting, isSuccess } = useAtomValue(saveOrUpdateAcmeAtom)
  16. const { mutate: deleteDNS, isPending: isDeleting } = useAtomValue(deleteDNSAtom)
  17. const [ open, setOpen ] = useState(false)
  18. const columns = useMemo<ProColumns<IAcmeAccount>[]>(() => {
  19. return [
  20. {
  21. title: 'ID',
  22. dataIndex: 'id',
  23. hideInTable: true,
  24. formItemProps: {
  25. hidden: true,
  26. }
  27. },
  28. {
  29. title: t('website.ssl.acme.columns.email', '邮箱'),
  30. dataIndex: 'email',
  31. valueType: 'text',
  32. formItemProps: {
  33. rules: [
  34. { required: true, message: t('message.required', '请输入') }
  35. ]
  36. }
  37. },
  38. {
  39. title: t('website.ssl.acme.columns.type', '帐号类型'),
  40. dataIndex: 'type',
  41. valueType: 'select',
  42. fieldProps: {
  43. options: AcmeAccountTypes
  44. },
  45. formItemProps: {
  46. rules: [
  47. { required: true, message: t('message.required', '请选择') }
  48. ]
  49. }
  50. },
  51. {
  52. title: t('website.ssl.acme.columns.keyType', '密钥算法'),
  53. dataIndex: 'keyType',
  54. valueType: 'select',
  55. fieldProps: {
  56. options: KeyTypes
  57. },
  58. formItemProps: {
  59. rules: [
  60. { required: true, message: t('message.required', '请选择') }
  61. ]
  62. },
  63. },
  64. {
  65. title: t('website.ssl.acme.columns.url', 'URL'),
  66. dataIndex: 'url',
  67. valueType: 'text',
  68. ellipsis: true, // 文本溢出省略
  69. hideInForm: true,
  70. }, {
  71. title: '操作',
  72. valueType: 'option',
  73. render: (_, record) => {
  74. return [
  75. <Popconfirm
  76. key={'del_confirm'}
  77. disabled={isDeleting}
  78. onConfirm={() => {
  79. deleteDNS(record.id)
  80. }}
  81. title={t('message.deleteConfirm')}>
  82. <a key="del">
  83. {t('actions.delete', '删除')}
  84. </a>
  85. </Popconfirm>
  86. ]
  87. }
  88. }
  89. ]
  90. }, [])
  91. return (
  92. <>
  93. <Alert message={t('website.ssl.acme.tip', 'Acme账户用于申请免费证书')}/>
  94. <ProTable<IAcmeAccount>
  95. cardProps={{
  96. bodyStyle: {
  97. padding: 0,
  98. }
  99. }}
  100. rowKey="id"
  101. headerTitle={
  102. <Button
  103. onClick={() => {
  104. form.setFieldsValue({
  105. id: 0,
  106. type: AcmeType.LetsEncrypt,
  107. keyType: KeyTypeEnum.EC256,
  108. })
  109. setOpen(true)
  110. }}
  111. type={'primary'}>{t('website.ssl.acme.add', '添加Acme帐户')}</Button>
  112. }
  113. loading={isLoading}
  114. dataSource={data?.rows ?? []}
  115. columns={columns}
  116. search={false}
  117. options={{
  118. reload: () => {
  119. refetch()
  120. },
  121. }}
  122. pagination={{
  123. total: data?.total,
  124. pageSize: page.pageSize,
  125. current: page.page,
  126. onChange: (current, pageSize) => {
  127. setPage(prev => {
  128. return {
  129. ...prev,
  130. page: current,
  131. pageSize: pageSize,
  132. }
  133. })
  134. },
  135. }}
  136. />
  137. <BetaSchemaForm<IAcmeAccount>
  138. shouldUpdate={false}
  139. width={600}
  140. form={form}
  141. layout={'horizontal'}
  142. scrollToFirstError={true}
  143. title={t(`website.ssl.acme.title_${form.getFieldValue('id') !== 0 ? 'edit' : 'add'}`, form.getFieldValue('id') !== 0 ? '证书编辑' : '证书添加')}
  144. // colProps={{ span: 24 }}
  145. labelCol={{ span: 6 }}
  146. wrapperCol={{ span: 14 }}
  147. layoutType={'ModalForm'}
  148. open={open}
  149. modalProps={{
  150. maskClosable: false,
  151. }}
  152. onOpenChange={(open) => {
  153. setOpen(open)
  154. }}
  155. loading={isSubmitting}
  156. onFinish={async (values) => {
  157. // console.log('values', values)
  158. saveOrUpdate(values)
  159. return isSuccess
  160. }}
  161. columns={columns as ProFormColumnsType[]}/>
  162. </>
  163. )
  164. }
  165. export default AcmeList