diff --git a/src/components/status/Status.tsx b/src/components/status/Status.tsx
index 5415959..b54e873 100644
--- a/src/components/status/Status.tsx
+++ b/src/components/status/Status.tsx
@@ -3,57 +3,57 @@ import { useTranslation } from '@/i18n.ts'
import { SyncOutlined } from '@ant-design/icons'
export interface StatusProps extends TagProps {
- status: string
+ status: string
}
const getColor = (status: string) => {
- if (status.includes('error') || status.includes('err')) {
- return 'danger'
- }
- switch (status) {
- case 'running':
- return 'success'
- case 'stopped':
- return 'danger'
- case 'unhealthy':
- case 'paused':
- case 'exited':
- case 'dead':
- case 'removing':
- return 'warning'
- default:
- return 'primary'
- }
+ if (status.includes('error') || status.includes('err')) {
+ return 'danger'
+ }
+ switch (status) {
+ case 'running':
+ return 'success'
+ case 'stopped':
+ return 'danger'
+ case 'unhealthy':
+ case 'paused':
+ case 'exited':
+ case 'dead':
+ case 'removing':
+ return 'warning'
+ default:
+ return 'default'
+ }
}
const loadingStatus = [
- 'installing',
- 'building',
- 'restarting',
- 'upgrading',
- 'rebuilding',
- 'recreating',
- 'creating',
- 'starting',
- 'removing',
- 'applying',
+ 'installing',
+ 'building',
+ 'restarting',
+ 'upgrading',
+ 'rebuilding',
+ 'recreating',
+ 'creating',
+ 'starting',
+ 'removing',
+ 'applying',
]
const loadingIcon = (status: string): boolean => {
- return loadingStatus.indexOf(status) > -1
+ return loadingStatus.indexOf(status) > -1
}
export const Status = ({ status = 'running', ...props }: StatusProps) => {
- const { t } = useTranslation()
- const icon = loadingIcon(status) ? : null
- return (
- <>
- {t(`status.${status}`, status)}
- >
- )
+ const { t } = useTranslation()
+ const icon = loadingIcon(status) ? : null
+ return (
+ <>
+ {t(`status.${status}`, status)}
+ >
+ )
}
export default Status
\ No newline at end of file
diff --git a/src/pages/websites/ssl/acme/AcmeList.tsx b/src/pages/websites/ssl/acme/AcmeList.tsx
index 1f685c0..1abf58b 100644
--- a/src/pages/websites/ssl/acme/AcmeList.tsx
+++ b/src/pages/websites/ssl/acme/AcmeList.tsx
@@ -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[]>(() => {
- 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 [
- {
- deleteDNS(record.id)
- }}
- title={t('message.deleteConfirm')}>
-
- {t('actions.delete', '删除')}
-
-
- ]
- }
- }
- ]
- }, [])
+ const columns = useMemo[]>(() => {
+ 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 [
+ {
+ deleteAcme(record.id)
+ }}
+ title={t('message.deleteConfirm')}>
+
+ {t('actions.delete', '删除')}
+
+
+ ]
+ }
+ }
+ ]
+ }, [])
- return (
- <>
-
-
- cardProps={{
- bodyStyle: {
- padding: 0,
- }
- }}
- rowKey="id"
- headerTitle={
-
- }
- 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 ])
- }}
- />
-
- 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 (
+ <>
+
+
+ cardProps={{
+ bodyStyle: {
+ padding: 0,
+ }
+ }}
+ rowKey="id"
+ headerTitle={
+
+ }
+ 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,
+ }
+ })
+ },
+
+ }}
+ />
+
+ 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
\ No newline at end of file
diff --git a/src/pages/websites/ssl/ca/CAList.tsx b/src/pages/websites/ssl/ca/CAList.tsx
index c503334..c185043 100644
--- a/src/pages/websites/ssl/ca/CAList.tsx
+++ b/src/pages/websites/ssl/ca/CAList.tsx
@@ -1,4 +1,4 @@
-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 { deleteCaAtom } from '@/store/websites/ca.ts'
@@ -13,233 +13,238 @@ import SelfSign from './SelfSign.tsx'
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 { mutate: deleteCA, isPending: isDeleting } = useAtomValue(deleteCaAtom)
- const [ open, setOpen ] = useState(false)
- const updateUI = useSetAtom(detailAtom)
- const selfSignUI = useSetAtom(selfSignAtom)
- const columns = useMemo[]>(() => {
- 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.form.common_name', '证书主体名称(CN)'),
- dataIndex: 'common_name',
- hideInTable: true,
- hideInSetting: true,
- valueType: 'text',
- formItemProps: {
- rules: [
- { required: true, message: t('message.required', '请输入') }
- ]
- }
- },
+ const { t } = useTranslation()
+ const [ form ] = Form.useForm()
+ const [ page, setPage ] = useAtom(caPageAtom)
+ const { data, isLoading, isFetching, refetch } = useAtomValue(caListAtom)
+ const { mutate: saveOrUpdate, isPending: isSubmitting, isSuccess } = useAtomValue(saveOrUpdateCaAtom)
+ const { mutate: deleteCA, isPending: isDeleting } = useAtomValue(deleteCaAtom)
+ const [ open, setOpen ] = useState(false)
+ const updateUI = useSetAtom(detailAtom)
+ const selfSignUI = useSetAtom(selfSignAtom)
+ const columns = useMemo[]>(() => {
+ 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.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', '公司/组织'),
+ 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.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.columns.keyType', '密钥算法'),
+ dataIndex: 'key_type',
+ valueType: 'select',
+ fieldProps: {
+ options: KeyTypes
+ },
+ formItemProps: {
+ rules: [
+ { required: true, message: t('message.required', '请选择') }
+ ]
+ },
+ },
+ {
+ title: t('website.ssl.ca.columns.createAt', '时间'),
+ dataIndex: 'created_at',
+ valueType: 'dateTime',
+ hideInForm: true,
+ },
+ {
+ title: '操作',
+ valueType: 'option',
+ render: (_, record) => {
+ return [
+ {
+ selfSignUI({
+ open: true,
+ record: {
+ id: record.id,
+ key_type: KeyTypeEnum.EC256,
+ unit: 'year',
+ auto_renew: true,
+ time: 10,
}
- },
- {
- 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: {}
- },
+ })
+ }}>{t('website.actions.selfSign', '签发证书')},
+ {
+ updateUI({
+ open: true, record,
+ })
+ }}>{t('website.actions.detail', '详情')},
- {
- title: t('website.ssl.ca.columns.keyType', '密钥算法'),
- dataIndex: 'key_type',
- valueType: 'select',
- fieldProps: {
- options: KeyTypes
- },
- formItemProps: {
- rules: [
- { required: true, message: t('message.required', '请选择') }
- ]
- },
- },
- {
- title: t('website.ssl.ca.columns.createAt', '时间'),
- dataIndex: 'created_at',
- valueType: 'dateTime',
- hideInForm: true,
- },
- {
- title: '操作',
- valueType: 'option',
- render: (_, record) => {
- return [
- {
- selfSignUI({
- open: true,
- record: {
- id: record.id,
- key_type: KeyTypeEnum.EC256,
- unit: 'year',
- auto_renew: true,
- time: 10,
- }
- })
- }}>{t('website.actions.selfSign', '签发证书')},
- {
- updateUI({
- open: true, record,
- })
- }}>{t('website.actions.detail', '详情')},
+ {
+ deleteCA(record.id)
+ }}
+ title={t('message.deleteConfirm')}>
+
+ {t('actions.delete', '删除')}
+
+
+ ]
+ }
+ }
+ ]
+ }, [])
- {
- deleteCA(record.id)
- }}
- title={t('message.deleteConfirm')}>
-
- {t('actions.delete', '删除')}
-
-
- ]
- }
- }
- ]
- }, [])
+ useEffect(() => {
+ if (isSuccess) {
+ setOpen(false)
+ }
+ }, [ isSuccess ])
- return (
- <>
-
- cardProps={{
- bodyStyle: {
- padding: 0,
- }
- }}
- rowKey="id"
- headerTitle={
-
- }
- 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,
- }
- })
- },
+ return (
+ <>
+
+ cardProps={{
+ bodyStyle: {
+ padding: 0,
+ }
+ }}
+ rowKey="id"
+ headerTitle={
+
+ }
+ 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,
+ }
+ })
+ },
- }}
- />
-
- 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[]}/>
-
-
- >
- )
+ }}
+ />
+
+ 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)
+ }}
+ columns={columns as ProFormColumnsType[]}/>
+
+
+ >
+ )
}
export default CAList
\ No newline at end of file
diff --git a/src/pages/websites/ssl/dns/DNSList.tsx b/src/pages/websites/ssl/dns/DNSList.tsx
index ef25654..08c020f 100644
--- a/src/pages/websites/ssl/dns/DNSList.tsx
+++ b/src/pages/websites/ssl/dns/DNSList.tsx
@@ -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[] = []
- 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[] = []
+ 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[]>(() => {
- 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[]>(() => {
+ 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 [
- {
- deleteDNS(record.id)
- }}
- title={t('message.deleteConfirm')}>
-
- {t('actions.delete', '删除')}
-
-
- ]
- }
- }
- ]
- }, [])
+ {
+ 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 [
+ {
+ deleteDNS(record.id)
+ }}
+ title={t('message.deleteConfirm')}>
+
+ {t('actions.delete', '删除')}
+
+
+ ]
+ }
+ }
+ ]
+ }, [])
- return (
- <>
-
- cardProps={{
- bodyStyle: {
- padding: 0,
- }
- }}
- rowKey="id"
- headerTitle={
-
- }
- 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 (
+ <>
+
+ cardProps={{
+ bodyStyle: {
+ padding: 0,
+ }
+ }}
+ rowKey="id"
+ headerTitle={
+
+ }
+ 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,
+ }
+ })
+ },
- }}
- />
-
- 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[]}/>
- >
- )
+ }}
+ />
+
+ 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
\ No newline at end of file
diff --git a/src/pages/websites/ssl/index.tsx b/src/pages/websites/ssl/index.tsx
index b9504ab..cc766a0 100644
--- a/src/pages/websites/ssl/index.tsx
+++ b/src/pages/websites/ssl/index.tsx
@@ -1,17 +1,17 @@
import { useAtom, useAtomValue, useSetAtom } from 'jotai'
import {
- deleteSslAtom, getProvider,
- KeyTypeEnum,
- KeyTypes,
- ProviderTypeEnum,
- saveOrUpdateSslAtom,
- sslListAtom,
- sslPageAtom,
- sslSearchAtom, uploadSslAtom
+ deleteSslAtom, getProvider,
+ KeyTypeEnum,
+ KeyTypes,
+ ProviderTypeEnum,
+ saveOrUpdateSslAtom,
+ sslListAtom,
+ sslPageAtom,
+ sslSearchAtom, uploadSslAtom
} from '@/store/websites/ssl.ts'
import ListPageLayout from '@/layout/ListPageLayout.tsx'
import { BetaSchemaForm, ProColumns, ProFormColumnsType, ProTable } from '@ant-design/pro-components'
-import { memo, useMemo, useRef, useState } from 'react'
+import { memo, useEffect, useMemo, useRef, useState } from 'react'
import { useTranslation } from '@/i18n.ts'
import { Button, Form, Popconfirm, Space } from 'antd'
import { PlusOutlined } from '@ant-design/icons'
@@ -35,403 +35,409 @@ import Download from '@/components/download/Download.tsx'
const SSL = () => {
- const { t } = useTranslation()
- const [ form ] = Form.useForm()
- const uploadFormRef = useRef()
- const [ page, setPage ] = useAtom(sslPageAtom)
- const [ search, setSearch ] = useAtom(sslSearchAtom)
- const { data: acmeData, isLoading: acmeLoading } = useAtomValue(acmeListAtom)
- const { data: dnsData, isLoading: dnsLoading } = useAtomValue(dnsListAtom)
- const { data, isLoading, isFetching, refetch } = useAtomValue(sslListAtom)
- const { mutate: saveOrUpdate, isSuccess, isPending: isSubmitting } = useAtomValue(saveOrUpdateSslAtom)
- const { mutate: deleteSSL, isPending: isDeleting } = useAtomValue(deleteSslAtom)
- const { mutate: uploadSSL, isSuccess: isUploadSuccess, isPending: isUploading } = useAtomValue(uploadSslAtom)
- const updateDetail = useSetAtom(detailAtom)
- const uploadDrawerRef = useRef()
- const [ open, setOpen ] = useState(false)
+ const { t } = useTranslation()
+ const [ form ] = Form.useForm()
+ const uploadFormRef = useRef()
+ const [ page, setPage ] = useAtom(sslPageAtom)
+ const [ search, setSearch ] = useAtom(sslSearchAtom)
+ const { data: acmeData, isLoading: acmeLoading } = useAtomValue(acmeListAtom)
+ const { data: dnsData, isLoading: dnsLoading } = useAtomValue(dnsListAtom)
+ const { data, isLoading, isFetching, refetch } = useAtomValue(sslListAtom)
+ const { mutate: saveOrUpdate, isSuccess, isPending: isSubmitting } = useAtomValue(saveOrUpdateSslAtom)
+ const { mutate: deleteSSL, isPending: isDeleting } = useAtomValue(deleteSslAtom)
+ const { mutate: uploadSSL, isSuccess: isUploadSuccess, isPending: isUploading } = useAtomValue(uploadSslAtom)
+ const updateDetail = useSetAtom(detailAtom)
+ const uploadDrawerRef = useRef()
+ const [ open, setOpen ] = useState(false)
- const columns = useMemo[]>(() => {
- return [
- {
- title: 'ID',
- dataIndex: 'id',
- hideInTable: true,
- hideInSearch: false,
- formItemProps: {
- hidden: true,
- }
- },
- {
- title: t('website.ssl.columns.primaryDomain', '域名'),
- dataIndex: 'primary_domain',
- formItemProps: {
- label: t('website.ssl.form.primaryDomain', '主域名'),
- rules: [ { required: true, message: t('message.required', '主域名') } ]
- }
- },
- {
- title: t('website.ssl.columns.otherDomains', '其它域名'),
- dataIndex: 'domains',
- },
- {
- title: t('website.ssl.columns.acmeAccountId', 'Acme帐号'),
- dataIndex: 'acme_account_id',
- valueType: 'select',
- fieldProps: {
- loading: acmeLoading,
- options: acmeData?.rows?.map(item => ({
- label: `${item.email} [${getAcmeAccountTypeName(item.type as AcmeType)}]`,
- value: item.id
- }))
- },
- formItemProps: {
- rules: [
- { required: true, message: t('message.required', '请选择') }
- ]
- }
- },
- {
- title: t('website.ssl.columns.status', '状态'),
- dataIndex: 'status',
- render: (_, record) => {
- return
- },
- hideInForm: true,
- },
- {
- title: t('website.ssl.columns.keyType', '密钥算法'),
- dataIndex: 'key_type',
- hideInTable: true,
- valueType: 'select',
- fieldProps: {
- options: KeyTypes
- },
- formItemProps: {
- rules: [
- { required: true, message: t('message.required', '请选择') }
- ]
- },
- },
- {
- title: t('website.ssl.columns.provider', '申请方式'),
- dataIndex: 'provider',
- valueType: 'radio',
- valueEnum: {
- [ProviderTypeEnum.DnsAccount]: {
- text: t('website.ssl.providerTypeEnum.DnsAccount', 'DNS帐号'),
- },
- [ProviderTypeEnum.DnsManual]: {
- text: t('website.ssl.providerTypeEnum.DnsManual', '手动验证'),
- },
- [ProviderTypeEnum.Http]: {
- text: t('website.ssl.providerTypeEnum.Http', 'HTTP'),
- }
- },
- dependencies: [ 'provider' ],
- renderText: (text) => {
- return getProvider(text)
- },
- formItemProps: (form, config) => {
- const val = form.getFieldValue(config.dataIndex)
- const help = {
- [ProviderTypeEnum.DnsAccount]: t('website.ssl.form.provider_{{v}}', '', { v: val }),
- [ProviderTypeEnum.DnsManual]: t('website.ssl.form.provider_{{v}}', '手动解析模式需要在创建完之后点击申请按钮获取 DNS 解析值', { v: val }),
- [ProviderTypeEnum.Http]: t('website.ssl.form.provider_{{v}}', 'HTTP 模式需要安装 OpenResty
HTTP 模式无法申请泛域名证书', { v: val }),
- }
- return {
- label: t('website.ssl.form.provider', '验证方式'),
- help: ,
- rules: [ { required: true, message: t('message.required', '请选择') } ]
- }
- },
- },
- {
- name: [ 'provider' ],
- valueType: 'dependency',
- hideInSetting: true,
- hideInTable: true,
- columns: ({ provider }) => {
- if (provider === ProviderTypeEnum.DnsAccount) {
- return [ {
- title: t('website.ssl.columns.dnsAccountId', 'DNS帐号'),
- dataIndex: 'dns_account_id',
- valueType: 'select',
- formItemProps: {
- rules: [ { required: true, message: t('message.required', '请输入DNS帐号') } ]
- },
- fieldProps: {
- loading: dnsLoading,
- options: dnsData?.rows.map(item => ({
- label: `${item.name} [${getDNSTypeName(item.type)}]`,
- value: item.id
- }))
- },
- } ]
- }
- return []
+ const columns = useMemo[]>(() => {
+ return [
+ {
+ title: 'ID',
+ dataIndex: 'id',
+ hideInTable: true,
+ hideInSearch: false,
+ formItemProps: {
+ hidden: true,
+ }
+ },
+ {
+ title: t('website.ssl.columns.primaryDomain', '域名'),
+ dataIndex: 'primary_domain',
+ formItemProps: {
+ label: t('website.ssl.form.primaryDomain', '主域名'),
+ rules: [ { required: true, message: t('message.required', '主域名') } ]
+ }
+ },
+ {
+ title: t('website.ssl.columns.otherDomains', '其它域名'),
+ dataIndex: 'domains',
+ },
+ {
+ title: t('website.ssl.columns.acmeAccountId', 'Acme帐号'),
+ dataIndex: 'acme_account_id',
+ valueType: 'select',
+ fieldProps: {
+ loading: acmeLoading,
+ options: acmeData?.rows?.map(item => ({
+ label: `${item.email} [${getAcmeAccountTypeName(item.type as AcmeType)}]`,
+ value: item.id
+ }))
+ },
+ formItemProps: {
+ rules: [
+ { required: true, message: t('message.required', '请选择') }
+ ]
+ }
+ },
+ {
+ title: t('website.ssl.columns.status', '状态'),
+ dataIndex: 'status',
+ render: (_, record) => {
+ return
+ },
+ hideInForm: true,
+ },
+ {
+ title: t('website.ssl.columns.keyType', '密钥算法'),
+ dataIndex: 'key_type',
+ hideInTable: true,
+ valueType: 'select',
+ fieldProps: {
+ options: KeyTypes
+ },
+ formItemProps: {
+ rules: [
+ { required: true, message: t('message.required', '请选择') }
+ ]
+ },
+ },
+ {
+ title: t('website.ssl.columns.provider', '申请方式'),
+ dataIndex: 'provider',
+ valueType: 'radio',
+ valueEnum: {
+ [ProviderTypeEnum.DnsAccount]: {
+ text: t('website.ssl.providerTypeEnum.DnsAccount', 'DNS帐号'),
+ },
+ [ProviderTypeEnum.DnsManual]: {
+ text: t('website.ssl.providerTypeEnum.DnsManual', '手动验证'),
+ },
+ [ProviderTypeEnum.Http]: {
+ text: t('website.ssl.providerTypeEnum.Http', 'HTTP'),
+ }
+ },
+ dependencies: [ 'provider' ],
+ renderText: (text) => {
+ return getProvider(text)
+ },
+ formItemProps: (form, config) => {
+ const val = form.getFieldValue(config.dataIndex)
+ const help = {
+ [ProviderTypeEnum.DnsAccount]: t('website.ssl.form.provider_{{v}}', '', { v: val }),
+ [ProviderTypeEnum.DnsManual]: t('website.ssl.form.provider_{{v}}', '手动解析模式需要在创建完之后点击申请按钮获取 DNS 解析值', { v: val }),
+ [ProviderTypeEnum.Http]: t('website.ssl.form.provider_{{v}}', 'HTTP 模式需要安装 OpenResty
HTTP 模式无法申请泛域名证书', { v: val }),
+ }
+ return {
+ label: t('website.ssl.form.provider', '验证方式'),
+ help: ,
+ rules: [ { required: true, message: t('message.required', '请选择') } ]
+ }
+ },
+ },
+ {
+ name: [ 'provider' ],
+ valueType: 'dependency',
+ hideInSetting: true,
+ hideInTable: true,
+ columns: ({ provider }) => {
+ if (provider === ProviderTypeEnum.DnsAccount) {
+ return [ {
+ title: t('website.ssl.columns.dnsAccountId', 'DNS帐号'),
+ dataIndex: 'dns_account_id',
+ valueType: 'select',
+ formItemProps: {
+ rules: [ { required: true, message: t('message.required', '请输入DNS帐号') } ]
+ },
+ fieldProps: {
+ loading: dnsLoading,
+ options: dnsData?.rows?.map(item => ({
+ label: `${item.name} [${getDNSTypeName(item.type)}]`,
+ value: item.id
+ }))
+ },
+ } ]
+ }
+ return []
- }
- },
- {
- title: t('website.ssl.columns.autoRenew', '自动续签'),
- dataIndex: 'auto_renew',
- valueType: 'switch',
- render: (_, record) => {
- return
- }
- },
- {
- title: t('website.ssl.columns.pushDir', '推送证书到本地目录'),
- dataIndex: 'push_dir',
- valueType: 'switch',
- hideInTable: true,
- hideInSearch: true,
+ }
+ },
+ {
+ title: t('website.ssl.columns.autoRenew', '自动续签'),
+ dataIndex: 'auto_renew',
+ valueType: 'switch',
+ render: (_, record) => {
+ return
+ }
+ },
+ {
+ title: t('website.ssl.columns.pushDir', '推送证书到本地目录'),
+ dataIndex: 'push_dir',
+ valueType: 'switch',
+ hideInTable: true,
+ hideInSearch: true,
- },
- {
- name: [ 'push_dir' ],
- valueType: 'dependency',
- hideInSetting: true,
- hideInTable: true,
- columns: ({ pushDir }) => {
- if (pushDir) {
- return [ {
- title: t('website.ssl.columns.dir', '目录'),
- dataIndex: 'dir',
- formItemProps: {
- help: t('website.ssl.form.dir_help', '会在此目录下生成两个文件,证书文件:fullchain.pem 密钥文件:privkey.pem'),
- rules: [ { required: true, message: t('message.required', '请输入目录') } ]
- }
- } ]
- }
- return []
+ },
+ {
+ name: [ 'push_dir' ],
+ valueType: 'dependency',
+ hideInSetting: true,
+ hideInTable: true,
+ columns: ({ pushDir }) => {
+ if (pushDir) {
+ return [ {
+ title: t('website.ssl.columns.dir', '目录'),
+ dataIndex: 'dir',
+ formItemProps: {
+ help: t('website.ssl.form.dir_help', '会在此目录下生成两个文件,证书文件:fullchain.pem 密钥文件:privkey.pem'),
+ rules: [ { required: true, message: t('message.required', '请输入目录') } ]
+ }
+ } ]
+ }
+ return []
- }
- },
- {
- title: t('website.ssl.columns.description', '备注'),
- dataIndex: 'description',
- },
- {
- title: t('website.ssl.columns.expire_date', '过期时间'),
- dataIndex: 'expire_date',
- valueType: 'dateTime',
- hideInForm: true,
- },
- {
- title: t('website.ssl.columns.option', '操作'), valueType: 'option',
- key: 'option',
- fixed: 'right',
- width: 300,
- render: (_, record) => [
+ }
+ },
+ {
+ title: t('website.ssl.columns.description', '备注'),
+ dataIndex: 'description',
+ },
+ {
+ title: t('website.ssl.columns.expire_date', '过期时间'),
+ dataIndex: 'expire_date',
+ valueType: 'dateTime',
+ hideInForm: true,
+ },
+ {
+ title: t('website.ssl.columns.option', '操作'), valueType: 'option',
+ key: 'option',
+ fixed: 'right',
+ width: 300,
+ render: (_, record) => [
- {
- updateDetail({
- open: true,
- record
- })
- }}
- >
- {t('actions.detail', '详情')}
- ,
- record.status !== 'manual'}>
-
- {
+ updateDetail({
+ open: true,
+ record
+ })
+ }}
+ >
+ {t('actions.detail', '详情')}
+ ,
+ record.status !== 'manual'}>
+
+ {
+ onClick={() => {
- }}
- >
- {t('actions.apply', '申请')}
-
-
-
- {
+ }}
+ >
+ {t('actions.apply', '申请')}
+
+
+
+ {
- }}
- >
- {t('actions.update', '更新')}
-
-
+ }}
+ >
+ {t('actions.update', '更新')}
+
+
- ,
- {
- }}
- >
- {t('actions.download', '下载')}
- ,
- {
- deleteSSL(record.id)
- }}
- title={t('message.deleteConfirm')}>
-
- {t('actions.delete', '删除')}
-
-
- ,
- ],
- },
- ]
- }, [])
+ ,
+ {
+ }}
+ >
+ {t('actions.download', '下载')}
+ ,
+ {
+ deleteSSL(record.id)
+ }}
+ title={t('message.deleteConfirm')}>
+
+ {t('actions.delete', '删除')}
+
+
+ ,
+ ],
+ },
+ ]
+
+ }, [ acmeData, dnsData ])
- return (
-
-
- headerTitle={t('website.ssl.title', '证书列表')}
- search={false}
- loading={isLoading || isFetching}
- rowKey={'id'}
- dataSource={data?.rows ?? []}
- columns={columns}
- columnsState={{
- defaultValue: {
- option: { fixed: 'right', disable: true },
- },
- }}
- options={{
- reload: () => {
- refetch()
- },
- }}
- toolbar={{
- search: {
- loading: isFetching && !!search.key,
- onSearch: (value: string) => {
- setSearch({ key: value })
- },
- placeholder: t('website.ssl.search.placeholder', '输入域名')
- },
- actions: [
-
- {t('website.ssl.actions.selfSigned', '自签证书')}
- }
- >
-
- ,
-
- {t('website.ssl.actions.acme', 'Acme帐户')}
- }
- >
-
- ,
-
- {t('website.ssl.actions.dns', 'DNS帐户')}
- }>
-
- ,
- ,
- ,
- ]
- }}
- pagination={{
- pageSize: page?.pageSize ?? 10,
- total: data?.total ?? 0,
- current: page?.page ?? 1,
- onChange: (page, pageSize) => {
- setPage(prev => ({
- ...prev,
- page,
- pageSize,
- }))
- },
- }}
- >
+ useEffect(() => {
+ if (isSuccess) {
+ setOpen(false)
+ }
+ }, [ isSuccess ])
-
-
- shouldUpdate={false}
- width={600}
- form={form}
- layout={'vertical'}
- scrollToFirstError={true}
- title={t(`website.ssl.title_${form.getFieldValue('id') !== 0 ? 'edit' : 'add'}`, form.getFieldValue('id') !== 0 ? '证书编辑' : '证书添加')}
- // colProps={{ span: 24 }}
- labelCol={{ span: 12 }}
- wrapperCol={{ span: 24 }}
- layoutType={'DrawerForm'}
- open={open}
- drawerProps={{
- maskClosable: false,
- }}
- onOpenChange={(open) => {
- setOpen(open)
- }}
- loading={isSubmitting}
- onFinish={async (values) => {
- // console.log('values', values)
- saveOrUpdate(values)
- return isSuccess
- }}
- columns={columns as ProFormColumnsType[]}/>
-
-
-
-
- ]}
- target={false}
- >
-
-
-
-
- )
+ return (
+
+
+ headerTitle={t('website.ssl.title', '证书列表')}
+ search={false}
+ loading={isLoading || isFetching}
+ rowKey={'id'}
+ dataSource={data?.rows ?? []}
+ columns={columns}
+ columnsState={{
+ defaultValue: {
+ option: { fixed: 'right', disable: true },
+ },
+ }}
+ options={{
+ reload: () => {
+ refetch()
+ },
+ }}
+ toolbar={{
+ search: {
+ loading: isFetching && !!search.key,
+ onSearch: (value: string) => {
+ setSearch({ key: value })
+ },
+ placeholder: t('website.ssl.search.placeholder', '输入域名')
+ },
+ actions: [
+
+ {t('website.ssl.actions.selfSigned', '自签证书')}
+ }
+ >
+
+ ,
+
+ {t('website.ssl.actions.acme', 'Acme帐户')}
+ }
+ >
+
+ ,
+
+ {t('website.ssl.actions.dns', 'DNS帐户')}
+ }>
+
+ ,
+ ,
+ ,
+ ]
+ }}
+ pagination={{
+ pageSize: page?.pageSize ?? 10,
+ total: data?.total ?? 0,
+ current: page?.page ?? 1,
+ onChange: (page, pageSize) => {
+ setPage(prev => ({
+ ...prev,
+ page,
+ pageSize,
+ }))
+ },
+ }}
+ >
+
+
+
+ shouldUpdate={false}
+ width={600}
+ form={form}
+ layout={'vertical'}
+ scrollToFirstError={true}
+ title={t(`website.ssl.title_${form.getFieldValue('id') !== 0 ? 'edit' : 'add'}`, form.getFieldValue('id') !== 0 ? '证书编辑' : '证书添加')}
+ // colProps={{ span: 24 }}
+ labelCol={{ span: 12 }}
+ wrapperCol={{ span: 24 }}
+ layoutType={'DrawerForm'}
+ open={open}
+ drawerProps={{
+ maskClosable: false,
+ }}
+ onOpenChange={(open) => {
+ setOpen(open)
+ }}
+ loading={isSubmitting}
+ onFinish={async (values) => {
+ // console.log('values', values)
+ saveOrUpdate(values)
+ }}
+ columns={columns as ProFormColumnsType[]}/>
+
+
+
+
+ ]}
+ target={false}
+ >
+
+
+
+
+ )
}
export default memo(SSL)
\ No newline at end of file
diff --git a/src/routes.tsx b/src/routes.tsx
index 7c0adc0..f334478 100644
--- a/src/routes.tsx
+++ b/src/routes.tsx
@@ -13,13 +13,13 @@ import { Route as LoginRouteImport } from '@/pages/login'
import { generateUUID } from '@/utils/uuid.ts'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import {
- AnyRoute,
- createRootRouteWithContext,
- createRoute,
- createRouter, lazyRouteComponent,
- Outlet,
- redirect,
- RouterProvider,
+ AnyRoute,
+ createRootRouteWithContext,
+ createRoute,
+ createRouter, lazyRouteComponent,
+ Outlet,
+ redirect,
+ RouterProvider,
} from '@tanstack/react-router'
// import { TanStackRouterDevtools } from '@tanstack/router-devtools'
import { memo, useEffect, useRef } from 'react'
@@ -30,70 +30,70 @@ import { useAtomValue } from 'jotai'
import { userMenuDataAtom } from '@/store/system/user.ts'
const PageRootLayout = () => {
- return
-
-
+ return
+
+
}
export const queryClient = new QueryClient({
- defaultOptions: {
- queries: {
- retry: false,
- }
+ defaultOptions: {
+ queries: {
+ retry: false,
}
+ }
})
const rootRoute = createRootRouteWithContext()({
- component: () => (
-
- <>
-
-
-
- {/**/}
- >
- ),
- beforeLoad: ({ location }) => {
- if (location.pathname === '/') {
- return redirect({ to: '/dashboard' })
- }
- },
- loader: () => {
+ component: () => (
+
+ <>
+
+
+
+ {/**/}
+ >
+ ),
+ beforeLoad: ({ location }) => {
+ if (location.pathname === '/') {
+ return redirect({ to: '/dashboard' })
+ }
+ },
+ loader: () => {
- },
- notFoundComponent: NotFound,
- pendingComponent: PageLoading,
- errorComponent: ({ error }) => ,
+ },
+ notFoundComponent: NotFound,
+ pendingComponent: PageLoading,
+ errorComponent: ({ error }) => ,
})
const emptyRoute = createRoute({
- getParentRoute: () => rootRoute,
- id: '/_empty',
- component: EmptyLayout,
+ getParentRoute: () => rootRoute,
+ id: '/_empty',
+ component: EmptyLayout,
})
const authRoute = AuthenticatedImport.update({
- getParentRoute: () => rootRoute,
- id: '/_authenticated',
+ getParentRoute: () => rootRoute,
+ id: '/_authenticated',
} as any)
const layoutNormalRoute = createRoute({
- getParentRoute: () => rootRoute,
- id: '/_normal_layout',
- component: PageRootLayout,
+ getParentRoute: () => rootRoute,
+ id: '/_normal_layout',
+ component: PageRootLayout,
})
const layoutAuthRoute = createRoute({
- getParentRoute: () => authRoute,
- id: '/_auth_layout',
- component: PageRootLayout,
+ getParentRoute: () => authRoute,
+ id: '/_auth_layout',
+ component: PageRootLayout,
})
const notAuthRoute = createRoute({
- getParentRoute: () => layoutNormalRoute,
- path: '/not-auth',
- component: NotPermission
+ getParentRoute: () => layoutNormalRoute,
+ path: '/not-auth',
+ component: NotPermission
})
// const dashboardRoute = DashboardImport.update({
@@ -102,8 +102,8 @@ const notAuthRoute = createRoute({
// } as any)
const loginRoute = LoginRouteImport.update({
- path: '/login',
- getParentRoute: () => emptyRoute,
+ path: '/login',
+ getParentRoute: () => emptyRoute,
} as any)
//
@@ -129,189 +129,191 @@ const loginRoute = LoginRouteImport.update({
declare module '@tanstack/react-router' {
- interface FileRoutesByPath {
- '/_authenticated': {
- preLoaderRoute: typeof AuthenticatedImport
- parentRoute: typeof rootRoute
- },
- '/_normal_layout': {
- preLoaderRoute: typeof layoutNormalRoute
- parentRoute: typeof rootRoute
- },
- '/_layout': {
- preLoaderRoute: typeof layoutAuthRoute
- parentRoute: typeof rootRoute
- },
- // '/': {
- // preLoaderRoute: typeof DashboardImport
- // parentRoute: typeof layoutAuthRoute
- // },
- // '/dashboard': {
- // preLoaderRoute: typeof DashboardImport
- // parentRoute: typeof layoutAuthRoute
- // },
- '/login': {
- preLoaderRoute: typeof LoginRouteImport
- parentRoute: typeof rootRoute
- },
- // '/system/menus': {
- // preLoaderRoute: typeof menusRoute
- // parentRoute: typeof layoutAuthRoute
- // },
- // '/system/departments': {
- // preLoaderRoute: typeof departmentsRoute
- // parentRoute: typeof layoutAuthRoute
- // },
- // '/system/users': {
- // preLoaderRoute: typeof usersRoute
- // parentRoute: typeof layoutAuthRoute
- // },
- // '/system/roles': {
- // preLoaderRoute: typeof rolesRoute
- // parentRoute: typeof layoutAuthRoute
- // },
- '/welcome': {
- preLoaderRoute: typeof rootRoute
- parentRoute: typeof layoutAuthRoute
- },
- }
+ interface FileRoutesByPath {
+ '/_authenticated': {
+ preLoaderRoute: typeof AuthenticatedImport
+ parentRoute: typeof rootRoute
+ },
+ '/_normal_layout': {
+ preLoaderRoute: typeof layoutNormalRoute
+ parentRoute: typeof rootRoute
+ },
+ '/_layout': {
+ preLoaderRoute: typeof layoutAuthRoute
+ parentRoute: typeof rootRoute
+ },
+ // '/': {
+ // preLoaderRoute: typeof DashboardImport
+ // parentRoute: typeof layoutAuthRoute
+ // },
+ // '/dashboard': {
+ // preLoaderRoute: typeof DashboardImport
+ // parentRoute: typeof layoutAuthRoute
+ // },
+ '/login': {
+ preLoaderRoute: typeof LoginRouteImport
+ parentRoute: typeof rootRoute
+ },
+ // '/system/menus': {
+ // preLoaderRoute: typeof menusRoute
+ // parentRoute: typeof layoutAuthRoute
+ // },
+ // '/system/departments': {
+ // preLoaderRoute: typeof departmentsRoute
+ // parentRoute: typeof layoutAuthRoute
+ // },
+ // '/system/users': {
+ // preLoaderRoute: typeof usersRoute
+ // parentRoute: typeof layoutAuthRoute
+ // },
+ // '/system/roles': {
+ // preLoaderRoute: typeof rolesRoute
+ // parentRoute: typeof layoutAuthRoute
+ // },
+ '/welcome': {
+ preLoaderRoute: typeof rootRoute
+ parentRoute: typeof layoutAuthRoute
+ },
+ }
}
const generateDynamicRoutes = (menuData: MenuItem[], parentRoute: AnyRoute) => {
- // 递归生成路由,如果有routes则递归生成子路由
-
- const generateRoutes = (menu: MenuItem, parentRoute: AnyRoute) => {
- const path = menu.path?.replace(parentRoute.options?.path, '')
- const isLayout = menu.children && menu.children.length > 0 && menu.type === 'menu'
-
- if (isLayout && (!menu.path || !menu.component)) {
- //没有component的layout,直接返回
- return createRoute({
- getParentRoute: () => layoutAuthRoute,
- id: `/layout-no-path-${generateUUID()}`,
- component: EmptyLayout,
- })
- }
-
- // @ts-ignore 添加menu属性,方便后面获取
- const options = {
- getParentRoute: () => parentRoute,
- menu,
- } as any
-
- if (isLayout) {
- options.id = path ?? `/layout-${generateUUID()}`
- } else {
- if (!path) {
- console.log(`${menu.name}没有设置视图`)
- } else {
- options.path = path
- }
- }
-
- let component = menu.component
- // menu.type
- // 1,组件(页面),2,IFrame,3,外链接,4,按钮
- if (menu.type === 'iframe') {
- component = '@/components/Iframe'
- }
-
- //处理component路径
- component = component.replace(/^\/pages/, '')
- component = component.replace(/^\//, '')
+ // 递归生成路由,如果有routes则递归生成子路由
+
+ const generateRoutes = (menu: MenuItem, parentRoute: AnyRoute) => {
+ const path = menu.path?.replace(parentRoute.options?.path, '')
+ const isLayout = menu.children && menu.children.length > 0 && menu.type === 'menu'
+
+ if (isLayout && (!menu.path || !menu.component)) {
+ //没有component的layout,直接返回
+ return createRoute({
+ getParentRoute: () => layoutAuthRoute,
+ id: `/layout-no-path-${generateUUID()}`,
+ component: EmptyLayout,
+ })
+ }
- return createRoute({
- ...options,
- component: lazyRouteComponent(() => import(`./pages/${component}`)),
- notFoundComponent: NotFound,
- })
+ // @ts-ignore 添加menu属性,方便后面获取
+ const options = {
+ getParentRoute: () => parentRoute,
+ menu,
+ } as any
+
+ if (isLayout) {
+ options.id = path ?? `/layout-${generateUUID()}`
+ } else {
+ if (!path) {
+ console.log(`${menu.name}没有设置视图`)
+ } else {
+ options.path = path
+ }
}
- // 对menuData递归生成路由,只处理type =1 的菜单
- const did = (menus: MenuItem[], parentRoute: AnyRoute) => {
- return menus.filter((item) => item.type === 'menu').map((item, index) => {
- // 如果有children则递归生成子路由,同样只处理type =1 的菜单
- const route = generateRoutes(item, parentRoute)
-
- // console.log(route)
- if (item.children && item.children.length > 0) {
- const children = did(item.children, route)
- if (children.length > 0) {
- route.addChildren(children)
- }
- }
- route.init({ originalIndex: index })
- return route
- })
+ let component = menu.component
+ // menu.type
+ // 1,组件(页面),2,IFrame,3,外链接,4,按钮
+ if (menu.type === 'iframe') {
+ component = '@/components/Iframe'
}
- const routes = did(menuData, parentRoute)
+ //处理component路径
+ component = component.replace(/^\/pages/, '')
+ component = component.replace(/^\//, '')
+
+ return createRoute({
+ ...options,
+ component: lazyRouteComponent(() => import(`./pages/${component}`)),
+ notFoundComponent: NotFound,
+ })
+ }
+
+ // 对menuData递归生成路由,只处理type =1 的菜单
+ const did = (menus: MenuItem[], parentRoute: AnyRoute) => {
+ return menus.filter((item) => item.type === 'menu').map((item, index) => {
+ // 如果有children则递归生成子路由,同样只处理type =1 的菜单
+ const route = generateRoutes(item, parentRoute)
+
+ // console.log(route)
+ if (item.children && item.children.length > 0) {
+ const children = did(item.children, route)
+ if (children.length > 0) {
+ route.addChildren(children)
+ }
+ }
+ route.init({ originalIndex: index })
+ return route
+ })
+ }
+
+ const routes = did(menuData, parentRoute)
- parentRoute.addChildren(routes)
+ parentRoute.addChildren(routes)
}
const routeTree = rootRoute.addChildren(
- [
- //非Layout
- loginRoute,
- emptyRoute,
-
- //不带权限Layout
- layoutNormalRoute.addChildren([
- notAuthRoute,
- ]),
-
- //带权限Layout
- // dashboardRoute,
- authRoute.addChildren(
- [
- layoutAuthRoute
- /*.addChildren(
- [
- menusRoute,
- departmentsRoute,
- usersRoute,
- rolesRoute,
- ]
- ),*/
- ]),
- ]
+ [
+ //非Layout
+ loginRoute,
+ emptyRoute,
+
+ //不带权限Layout
+ layoutNormalRoute.addChildren([
+ notAuthRoute,
+ ]),
+
+ //带权限Layout
+ // dashboardRoute,
+ authRoute.addChildren(
+ [
+ layoutAuthRoute
+ /*.addChildren(
+ [
+ menusRoute,
+ departmentsRoute,
+ usersRoute,
+ rolesRoute,
+ ]
+ ),*/
+ ]),
+ ]
)
export const RootProvider = memo((props: { context: Partial }) => {
- const { data: menuData, isLoading, refetch } = useAtomValue(userMenuDataAtom)
+ const { data: menuData, isLoading, refetch } = useAtomValue(userMenuDataAtom)
- const isFetchRef = useRef(false)
+ const isFetchRef = useRef(false)
- useEffect(() => {
+ useEffect(() => {
- if (isFetchRef.current) {
- return
- }
- isFetchRef.current = true
- refetch()
+ if (isFetchRef.current) {
+ return
+ }
+ isFetchRef.current = true
+ refetch()
- }, [])
+ }, [])
- if (isLoading) {
- return
- }
+ if (isLoading) {
+ return
+ }
- generateDynamicRoutes(menuData ?? [], layoutAuthRoute)
+ generateDynamicRoutes(menuData ?? [], layoutAuthRoute)
+
+ const router = createRouter({
+ routeTree,
+ context: { queryClient, menuData: [] },
+ defaultPreload: 'intent',
+ defaultPendingComponent: () =>
+ })
- const router = createRouter({
- routeTree,
- context: { queryClient, menuData: [] },
- defaultPreload: 'intent',
- defaultPendingComponent: () =>
- })
+ return (
+
+
+
+ )
+})
- return (
-
-
-
- )
-})
\ No newline at end of file
+export default RootProvider
\ No newline at end of file
diff --git a/src/store/websites/acme.ts b/src/store/websites/acme.ts
index 9ccf02a..96a80e0 100644
--- a/src/store/websites/acme.ts
+++ b/src/store/websites/acme.ts
@@ -7,65 +7,65 @@ import { atom } from 'jotai'
import { WebSite } from '@/types'
export enum AcmeType {
- LetsEncrypt = 'LetsEncrypt',
- //zerossl
- ZeroSSl = 'ZeroSSl',
- //buypass
- Buypass = 'Buypass',
- //google
- Google = 'Google',
+ LetsEncrypt = 'LetsEncrypt',
+ //zerossl
+ ZeroSSl = 'ZeroSsl',
+ //buypass
+ Buypass = 'Buypass',
+ //google
+ Google = 'Google',
}
export const AcmeAccountTypes = [
- { label: 'Let\'s Encrypt', value: AcmeType.LetsEncrypt },
- { label: 'ZeroSSL', value: AcmeType.ZeroSSl },
- { label: 'Buypass', value: AcmeType.Buypass },
- { label: 'Google Cloud', value: AcmeType.Google },
+ { label: 'Let\'s Encrypt', value: AcmeType.LetsEncrypt },
+ { label: 'ZeroSSL', value: AcmeType.ZeroSSl },
+ { label: 'Buypass', value: AcmeType.Buypass },
+ { label: 'Google Cloud', value: AcmeType.Google },
]
export const getAcmeAccountTypeName = (type: AcmeType) => {
- return AcmeAccountTypes.find(item => item.value === type)?.label
+ return AcmeAccountTypes.find(item => item.value === type)?.label
}
export const acmePageAtom = atom({
- page: 1, pageSize: 10,
+ page: 1, pageSize: 10,
})
//list
export const acmeListAtom = atomWithQuery(get => ({
- queryKey: [ 'acmeList', get(acmePageAtom) ],
- queryFn: async ({ queryKey: [ , page ] }) => {
- return await websitesServ.acme.list(page)
- },
- select: (data) => {
- return data.data
- }
+ queryKey: [ 'acmeList', get(acmePageAtom) ],
+ queryFn: async ({ queryKey: [ , page ] }) => {
+ return await websitesServ.acme.list(page)
+ },
+ select: (data) => {
+ return data.data
+ }
}))
//saveOrUpdate
-export const saveOrUpdateAcmeAtom = atomWithMutation(get => ({
- mutationKey: [ 'saveOrUpdateAcme' ],
- mutationFn: async (data: WebSite.IAcmeAccount) => {
- if (data.id > 0) {
- return await websitesServ.acme.update(data)
- }
- return await websitesServ.acme.add(data)
- },
- onSuccess: (res) => {
- const isAdd = !!res.data?.id
- message.success(t(isAdd ? 'message.saveSuccess' : 'message.editSuccess', '保存成功'))
- get(acmeListAtom).refetch()
- return res
+export const saveOrUpdateAcmeAtom = atomWithMutation(get => ({
+ mutationKey: [ 'saveOrUpdateAcme' ],
+ mutationFn: async (data: WebSite.IAcmeAccount) => {
+ if (data.id > 0) {
+ return await websitesServ.acme.update(data)
}
+ return await websitesServ.acme.add(data)
+ },
+ onSuccess: (res) => {
+ const isAdd = !!res.data?.id
+ message.success(t(isAdd ? 'message.saveSuccess' : 'message.editSuccess', '保存成功'))
+ get(acmeListAtom).refetch()
+ return res
+ }
}))
export const deleteAcmeAtom = atomWithMutation(get => ({
- mutationKey: [ 'sslDelete' ],
- mutationFn: async (id) => {
- return await websitesServ.acme.delete(id)
- },
- onSuccess: () => {
- message.success(t('message.deleteSuccess', '删除成功'))
- get(acmeListAtom).refetch()
- }
+ mutationKey: [ 'sslDelete' ],
+ mutationFn: async (id) => {
+ return await websitesServ.acme.delete(id)
+ },
+ onSuccess: () => {
+ message.success(t('message.deleteSuccess', '删除成功'))
+ get(acmeListAtom).refetch()
+ }
}))
\ No newline at end of file