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.

301 lines
8.2 KiB

11 months ago
  1. import { useEffect, useMemo, useState } from 'react'
  2. import { BetaSchemaForm, ProColumns, ProFormColumnsType, ProTable } from '@ant-design/pro-components'
  3. import { useTranslation } from '@/i18n.ts'
  4. import { useAtom, useAtomValue } from 'jotai'
  5. import { Button, Form, Popconfirm } from 'antd'
  6. import {
  7. deleteDNSAtom,
  8. dnsListAtom,
  9. dnsPageAtom,
  10. DNSTypeEnum,
  11. DNSTypes,
  12. saveOrUpdateDNSAtom
  13. } from '@/store/websites/dns.ts'
  14. import { WebSite } from '@/types'
  15. const getKeyColumn = (type: string, t) => {
  16. const columns: ProColumns<WebSite.IDnsAccount>[] = []
  17. switch (type) {
  18. case DNSTypeEnum.AliYun: {
  19. columns.push(...[
  20. {
  21. title: t('website.ssl.dns.columns.accessKey', 'Access Key'),
  22. dataIndex: 'accessKey',
  23. formItemProps: {
  24. rules: [ { required: true, message: t('message.required') } ]
  25. }
  26. },
  27. {
  28. title: t('website.ssl.dns.columns.secretKey', 'Secret Key'),
  29. dataIndex: 'secretKey',
  30. formItemProps: {
  31. rules: [ { required: true, message: t('message.required') } ]
  32. }
  33. },
  34. ])
  35. }
  36. break
  37. case DNSTypeEnum.TencentCloud: {
  38. columns.push(...[
  39. {
  40. title: t('website.ssl.dns.columns.secretID', 'Secret ID'),
  41. dataIndex: 'secretID',
  42. formItemProps: {
  43. rules: [ { required: true, message: t('message.required') } ]
  44. }
  45. }, {
  46. title: t('website.ssl.dns.columns.secretKey', 'Secret Key'),
  47. dataIndex: 'secretKey',
  48. formItemProps: {
  49. rules: [ { required: true, message: t('message.required') } ]
  50. }
  51. },
  52. ])
  53. break
  54. }
  55. case DNSTypeEnum.DnsPod: {
  56. columns.push(...[
  57. {
  58. title: t('website.ssl.dns.columns.apiId', 'ID'),
  59. dataIndex: 'apiId',
  60. formItemProps: {
  61. rules: [ { required: true, message: t('message.required') } ]
  62. }
  63. }, {
  64. title: t('website.ssl.dns.columns.token', 'Token'),
  65. dataIndex: 'token',
  66. formItemProps: {
  67. rules: [ { required: true, message: t('message.required') } ]
  68. }
  69. },
  70. ])
  71. break
  72. }
  73. case DNSTypeEnum.CloudFlare: {
  74. columns.push(...[
  75. {
  76. title: t('website.ssl.dns.columns.email', 'Email'),
  77. dataIndex: 'email',
  78. formItemProps: {
  79. rules: [ { required: true, message: t('message.required') } ]
  80. }
  81. }, {
  82. title: t('website.ssl.dns.columns.apiKey', 'API ToKen'),
  83. dataIndex: 'apiKey',
  84. formItemProps: {
  85. rules: [ { required: true, message: t('message.required') } ]
  86. }
  87. },
  88. ]
  89. )
  90. break
  91. }
  92. case DNSTypeEnum.Godaddy:
  93. case DNSTypeEnum.NameCheap:
  94. case DNSTypeEnum.NameSilo:
  95. columns.push({
  96. title: t('website.ssl.dns.columns.apiKey', 'API Key'),
  97. dataIndex: 'apiKey',
  98. formItemProps: {
  99. rules: [ { required: true, message: t('message.required') } ]
  100. }
  101. },
  102. )
  103. if (type === DNSTypeEnum.NameCheap) {
  104. columns.push({
  105. title: t('website.ssl.dns.columns.apiUser', 'API User'),
  106. dataIndex: 'apiUser',
  107. formItemProps: {
  108. rules: [ { required: true, message: t('message.required') } ]
  109. }
  110. })
  111. } else if (type === DNSTypeEnum.Godaddy) {
  112. columns.push({
  113. title: t('website.ssl.dns.columns.apiSecret', 'API Secret'),
  114. dataIndex: 'apiSecret',
  115. formItemProps: {
  116. rules: [ { required: true, message: t('message.required') } ]
  117. }
  118. })
  119. }
  120. break
  121. case DNSTypeEnum.NameCom: {
  122. columns.push(
  123. {
  124. title: t('website.ssl.dns.columns.apiUser', 'UserName'),
  125. dataIndex: 'apiUser',
  126. formItemProps: {
  127. rules: [ { required: true, message: t('message.required') } ]
  128. }
  129. },
  130. {
  131. title: t('website.ssl.dns.columns.token', 'Token'),
  132. dataIndex: 'token',
  133. formItemProps: {
  134. rules: [ { required: true, message: t('message.required') } ]
  135. }
  136. }
  137. )
  138. break
  139. }
  140. default:
  141. break
  142. }
  143. return columns
  144. }
  145. const DNSList = () => {
  146. const { t } = useTranslation()
  147. const [ form ] = Form.useForm()
  148. const [ page, setPage ] = useAtom(dnsPageAtom)
  149. const { data, isLoading, isFetching, refetch } = useAtomValue(dnsListAtom)
  150. const { mutate: saveOrUpdate, isPending: isSubmitting, isSuccess } = useAtomValue(saveOrUpdateDNSAtom)
  151. const { mutate: deleteDNS, isPending: isDeleting } = useAtomValue(deleteDNSAtom)
  152. const [ open, setOpen ] = useState(false)
  153. const columns = useMemo<ProColumns<WebSite.IDnsAccount>[]>(() => {
  154. return [
  155. {
  156. title: 'ID',
  157. dataIndex: 'id',
  158. hideInTable: true,
  159. formItemProps: {
  160. hidden: true,
  161. }
  162. },
  163. {
  164. title: t('website.ssl.dns.columns.name', '名称'),
  165. dataIndex: 'name',
  166. valueType: 'text',
  167. formItemProps: {
  168. rules: [
  169. { required: true, message: t('message.required', '请输入') }
  170. ]
  171. }
  172. },
  173. {
  174. title: t('website.ssl.dns.columns.type', '类型'),
  175. dataIndex: 'type',
  176. valueType: 'select',
  177. fieldProps: {
  178. options: DNSTypes
  179. },
  180. formItemProps: {
  181. rules: [
  182. { required: true, message: t('message.required', '请选择') }
  183. ]
  184. },
  185. },
  186. {
  187. name: [ 'type' ],
  188. valueType: 'dependency',
  189. hideInSetting: true,
  190. hideInTable: true,
  191. columns: ({ type }) => {
  192. return getKeyColumn(type, t)
  193. }
  194. },
  195. {
  196. title: '操作',
  197. valueType: 'option',
  198. render: (_, record) => {
  199. return [
  200. <Popconfirm
  201. key={'del_confirm'}
  202. disabled={isDeleting}
  203. onConfirm={() => {
  204. deleteDNS(record.id)
  205. }}
  206. title={t('message.deleteConfirm')}>
  207. <a key="del">
  208. {t('actions.delete', '删除')}
  209. </a>
  210. </Popconfirm>
  211. ]
  212. }
  213. }
  214. ]
  215. }, [])
  216. useEffect(() => {
  217. if (isSuccess) {
  218. setOpen(false)
  219. }
  220. }, [ isSuccess ])
  221. return (
  222. <>
  223. <ProTable<WebSite.IDnsAccount>
  224. cardProps={{
  225. bodyStyle: {
  226. padding: 0,
  227. }
  228. }}
  229. rowKey="id"
  230. headerTitle={
  231. <Button
  232. onClick={() => {
  233. form.setFieldsValue({
  234. id: 0,
  235. type: DNSTypeEnum.DnsPod,
  236. })
  237. setOpen(true)
  238. }}
  239. type={'primary'}>{t('website.ssl.dns.add', '添加DNS帐户')}</Button>
  240. }
  241. loading={isLoading || isFetching}
  242. dataSource={data?.rows ?? []}
  243. columns={columns}
  244. search={false}
  245. options={{
  246. reload: () => {
  247. refetch()
  248. },
  249. }}
  250. pagination={{
  251. total: data?.total,
  252. pageSize: page.pageSize,
  253. current: page.page,
  254. onChange: (current, pageSize) => {
  255. setPage(prev => {
  256. return {
  257. ...prev,
  258. page: current,
  259. pageSize: pageSize,
  260. }
  261. })
  262. },
  263. }}
  264. />
  265. <BetaSchemaForm<WebSite.IDnsAccount>
  266. shouldUpdate={false}
  267. width={600}
  268. form={form}
  269. layout={'horizontal'}
  270. scrollToFirstError={true}
  271. title={t(`website.ssl.dns.title_${form.getFieldValue('id') !== 0 ? 'edit' : 'add'}`, form.getFieldValue('id') !== 0 ? 'DNS帐号编辑' : 'DNS帐号添加')}
  272. // colProps={{ span: 24 }}
  273. labelCol={{ span: 6 }}
  274. wrapperCol={{ span: 14 }}
  275. layoutType={'ModalForm'}
  276. open={open}
  277. modalProps={{
  278. maskClosable: false,
  279. }}
  280. onOpenChange={(open) => {
  281. setOpen(open)
  282. }}
  283. loading={isSubmitting}
  284. onFinish={async (values) => {
  285. // console.log('values', values)
  286. saveOrUpdate(values)
  287. }}
  288. columns={columns as ProFormColumnsType[]}/>
  289. </>
  290. )
  291. }
  292. export default DNSList