diff --git a/.env.proxy.local b/.env.proxy.local
index 119f693..608bd49 100644
--- a/.env.proxy.local
+++ b/.env.proxy.local
@@ -1 +1 @@
-API_URL=http://47.113.117.106:10000
\ No newline at end of file
+API_URL=http://192.168.31.96:8686
\ No newline at end of file
diff --git a/mock/menus.ts b/mock/menus.ts
index 433977e..91a7f5e 100644
--- a/mock/menus.ts
+++ b/mock/menus.ts
@@ -12,7 +12,7 @@ export default [
{
id:1,
path: '/welcome',
- name: '欢迎',
+ name: '欢迎1111111111111',
icon: 'ApplicationMenu',
component: './pages/dashboard',
type: 1,
diff --git a/src/pages/dashboard/index.tsx b/src/pages/dashboard/index.tsx
index 2cd3a5f..7a5532b 100644
--- a/src/pages/dashboard/index.tsx
+++ b/src/pages/dashboard/index.tsx
@@ -12,7 +12,7 @@ const Index = () => {
}}
>
-
Dashboard
+ Dashboard操作面板
>
@@ -20,7 +20,7 @@ const Index = () => {
}
// @ts-ignore
-export const Route = createFileRoute('/dashboard')({
- component: Index,
-})
+// export const Route = createFileRoute('/dashboard')({
+// component: Index,
+// })
export default Index
\ No newline at end of file
diff --git a/src/pages/globle/globle_style.css b/src/pages/globle/globle_style.css
new file mode 100644
index 0000000..6bb8990
--- /dev/null
+++ b/src/pages/globle/globle_style.css
@@ -0,0 +1,4 @@
+.disabled_text {
+ pointer-events: none; /* 禁用鼠标事件 */
+ color: gray; /* 设置文本颜色为灰色 */
+}
\ No newline at end of file
diff --git a/src/pages/websites/account/index.tsx b/src/pages/websites/account/index.tsx
index 64466eb..3f1792b 100644
--- a/src/pages/websites/account/index.tsx
+++ b/src/pages/websites/account/index.tsx
@@ -1,482 +1,519 @@
-import { useTranslation } from '../../../i18n.ts'
-import { Button, Form, Space, Tooltip, Badge, Divider } from 'antd'
-import { useAtom, useAtomValue, useSetAtom } from 'jotai'
+import { useTranslation } from "../../../i18n.ts";
+import { Button, Form, Space, Tooltip, Badge, Divider, Spin } from "antd";
+import { useAtom, useAtomValue, useSetAtom } from "jotai";
import {
deleteWebsiteDnsAccountAtom,
- saveOrUpdateWebsiteDnsAccountAtom, websiteDnsAccountAtom, websiteDnsAccountsAtom, websiteDnsAccountSearchAtom,
-} from '@/store/websites/dns_account.ts'
-import { useEffect, useMemo, useState } from 'react'
-import Action from '@/components/action/Action.tsx'
-import {
- BetaSchemaForm,
- ProColumns,
- ProFormColumnsType,
-} from '@ant-design/pro-components'
-import ListPageLayout from '@/layout/ListPageLayout.tsx'
-import { useStyle } from './style.ts'
-import { FilterOutlined } from '@ant-design/icons'
-import { getValueCount, unSetColumnRules } from '@/utils'
-import { Table as ProTable } from '@/components/table'
-import { DNSTypeEnum, DNSTypes, syncDNSAtom } from '@/store/websites/dns.ts'
-import { WebSite } from '@/types'
-import Switch from '@/components/switch'
-import Popconfirm from '@/components/popconfirm'
+ saveOrUpdateWebsiteDnsAccountAtom,
+ websiteDnsAccountAtom,
+ websiteDnsAccountsAtom,
+ websiteDnsAccountSearchAtom,
+} from "@/store/websites/dns_account.ts";
+import { useEffect, useMemo, useState } from "react";
+import Action from "@/components/action/Action.tsx";
+import { BetaSchemaForm, ProColumns, ProFormColumnsType } from "@ant-design/pro-components";
+import ListPageLayout from "@/layout/ListPageLayout.tsx";
+import { useStyle } from "./style.ts";
+import { FilterOutlined } from "@ant-design/icons";
+import { getValueCount, unSetColumnRules } from "@/utils";
+import { Table as ProTable } from "@/components/table";
+import { DNSTypeEnum, DNSTypes, syncDNSAtom } from "@/store/websites/dns.ts";
+import { WebSite } from "@/types";
+import Switch from "@/components/switch";
+import Popconfirm from "@/components/popconfirm";
+import { Link } from "@tanstack/react-router";
+import "@/pages/globle/globle_style.css";
-const i18nPrefix = 'websiteDnsAccounts.list'
+const i18nPrefix = "websiteDnsAccounts.list";
const getKeyColumn = (type: string, t) => {
- const columns: ProColumns[] = []
+ const columns: ProColumns[] = [];
switch (type) {
- case DNSTypeEnum.AliYun: {
- columns.push(...[
- {
- title: t('website.ssl.dns.columns.accessKey', 'Access Key'),
- dataIndex: [ 'authorization', 'accessKey' ],
- formItemProps: {
- rules: [ { required: true, message: t('message.required') } ]
- }
- },
- {
- title: t('website.ssl.dns.columns.secretKey', 'Secret Key'),
- dataIndex: [ 'authorization', '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: [ 'authorization', 'secretID' ],
- formItemProps: {
- rules: [ { required: true, message: t('message.required') } ]
- }
- }, {
- title: t('website.ssl.dns.columns.secretKey', 'Secret Key'),
- dataIndex: [ 'authorization', 'secretKey' ],
- formItemProps: {
- rules: [ { required: true, message: t('message.required') } ]
- }
- },
- ])
- break
+ case DNSTypeEnum.AliYun:
+ {
+ columns.push(
+ ...[
+ {
+ title: t("website.ssl.dns.columns.accessKey", "Access Key"),
+ dataIndex: ["authorization", "accessKey"],
+ formItemProps: {
+ rules: [{ required: true, message: t("message.required") }],
+ },
+ },
+ {
+ title: t("website.ssl.dns.columns.secretKey", "Secret Key"),
+ dataIndex: ["authorization", "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: ["authorization", "secretID"],
+ formItemProps: {
+ rules: [{ required: true, message: t("message.required") }],
+ },
+ },
+ {
+ title: t("website.ssl.dns.columns.secretKey", "Secret Key"),
+ dataIndex: ["authorization", "secretKey"],
+ formItemProps: {
+ rules: [{ required: true, message: t("message.required") }],
+ },
+ },
+ ],
+ );
+ break;
}
case DNSTypeEnum.DnsPod: {
- columns.push(...[
- {
- title: t('website.ssl.dns.columns.apiId', 'ID'),
- dataIndex: [ 'authorization', 'apiId' ],
- formItemProps: {
- rules: [ { required: true, message: t('message.required') } ]
- }
- }, {
- title: t('website.ssl.dns.columns.token', 'Token'),
- dataIndex: [ 'authorization', 'token' ],
- formItemProps: {
- rules: [ { required: true, message: t('message.required') } ]
- }
- },
- ])
- break
+ columns.push(
+ ...[
+ {
+ title: t("website.ssl.dns.columns.apiId", "ID"),
+ dataIndex: ["authorization", "apiId"],
+ formItemProps: {
+ rules: [{ required: true, message: t("message.required") }],
+ },
+ },
+ {
+ title: t("website.ssl.dns.columns.token", "Token"),
+ dataIndex: ["authorization", "token"],
+ formItemProps: {
+ rules: [{ required: true, message: t("message.required") }],
+ },
+ },
+ ],
+ );
+ break;
}
case DNSTypeEnum.CloudFlare: {
- columns.push(...[
- {
- title: t('website.ssl.dns.columns.email', 'Email'),
- dataIndex: [ 'authorization', 'email' ],
- formItemProps: {
- rules: [ { required: true, message: t('message.required') } ]
- }
- }, {
- title: t('website.ssl.dns.columns.apiKey', 'API ToKen'),
- dataIndex: [ 'authorization', 'apiKey' ],
- formItemProps: {
- rules: [ { required: true, message: t('message.required') } ]
- }
- },
- ]
- )
- break
+ columns.push(
+ ...[
+ {
+ title: t("website.ssl.dns.columns.email", "Email"),
+ dataIndex: ["authorization", "email"],
+ formItemProps: {
+ rules: [{ required: true, message: t("message.required") }],
+ },
+ },
+ {
+ title: t("website.ssl.dns.columns.apiKey", "API ToKen"),
+ dataIndex: ["authorization", "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: [ 'authorization', 'apiKey' ],
- formItemProps: {
- rules: [ { required: true, message: t('message.required') } ]
- }
- },
- )
+ title: t("website.ssl.dns.columns.apiKey", "API Key"),
+ dataIndex: ["authorization", "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: [ 'authorization', 'apiUser' ],
+ title: t("website.ssl.dns.columns.apiUser", "API User"),
+ dataIndex: ["authorization", "apiUser"],
formItemProps: {
- rules: [ { required: true, message: t('message.required') } ]
- }
- })
+ rules: [{ required: true, message: t("message.required") }],
+ },
+ });
} else if (type === DNSTypeEnum.Godaddy) {
columns.push({
- title: t('website.ssl.dns.columns.apiSecret', 'API Secret'),
- dataIndex: [ 'authorization', 'apiSecret' ],
+ title: t("website.ssl.dns.columns.apiSecret", "API Secret"),
+ dataIndex: ["authorization", "apiSecret"],
formItemProps: {
- rules: [ { required: true, message: t('message.required') } ]
- }
- })
+ rules: [{ required: true, message: t("message.required") }],
+ },
+ });
}
- break
+ break;
case DNSTypeEnum.NameCom: {
columns.push(
- {
- title: t('website.ssl.dns.columns.apiUser', 'UserName'),
- dataIndex: [ 'authorization', 'apiUser' ],
- formItemProps: {
- rules: [ { required: true, message: t('message.required') } ]
- }
- },
- {
- title: t('website.ssl.dns.columns.token', 'Token'),
- dataIndex: [ 'authorization', 'token' ],
- formItemProps: {
- rules: [ { required: true, message: t('message.required') } ]
- }
- }
- )
- break
+ {
+ title: t("website.ssl.dns.columns.apiUser", "UserName"),
+ dataIndex: ["authorization", "apiUser"],
+ formItemProps: {
+ rules: [{ required: true, message: t("message.required") }],
+ },
+ },
+ {
+ title: t("website.ssl.dns.columns.token", "Token"),
+ dataIndex: ["authorization", "token"],
+ formItemProps: {
+ rules: [{ required: true, message: t("message.required") }],
+ },
+ },
+ );
+ break;
}
default:
- break
-
+ break;
}
- return columns
-}
+ return columns;
+};
const WebsiteDnsAccount = () => {
+ const { styles, cx } = useStyle();
+ const { t } = useTranslation();
+ const [form] = Form.useForm();
+ const [filterForm] = Form.useForm();
+ const { mutate: saveOrUpdate, isPending: isSubmitting, isSuccess } = useAtomValue(saveOrUpdateWebsiteDnsAccountAtom);
+ const [search, setSearch] = useAtom(websiteDnsAccountSearchAtom);
+ const setWebsiteDnsAccount = useSetAtom(websiteDnsAccountAtom);
+ const { data, isFetching, isLoading, refetch } = useAtomValue(websiteDnsAccountsAtom);
+ const { mutate: deleteWebsiteDnsAccount, isPending: isDeleting } = useAtomValue(deleteWebsiteDnsAccountAtom);
+ const { mutate: asyncDNS, isPending: isAsyncing } = useAtomValue(syncDNSAtom);
+ const [open, setOpen] = useState(false);
+ const [openFilter, setFilterOpen] = useState(false);
+ const [searchKey, setSearchKey] = useState(search?.title);
- const { styles, cx } = useStyle()
- const { t } = useTranslation()
- const [ form ] = Form.useForm()
- const [ filterForm ] = Form.useForm()
- const { mutate: saveOrUpdate, isPending: isSubmitting, isSuccess } = useAtomValue(saveOrUpdateWebsiteDnsAccountAtom)
- const [ search, setSearch ] = useAtom(websiteDnsAccountSearchAtom)
- const setWebsiteDnsAccount = useSetAtom(websiteDnsAccountAtom)
- const { data, isFetching, isLoading, refetch } = useAtomValue(websiteDnsAccountsAtom)
- const { mutate: deleteWebsiteDnsAccount, isPending: isDeleting } = useAtomValue(deleteWebsiteDnsAccountAtom)
- const { mutate: asyncDNS, isPending: isAsyncing } = useAtomValue(syncDNSAtom)
- const [ open, setOpen ] = useState(false)
- const [ openFilter, setFilterOpen ] = useState(false)
- const [ searchKey, setSearchKey ] = useState(search?.title)
const columns = useMemo(() => {
return [
{
- title: 'ID',
- dataIndex: 'id',
+ title: "ID",
+ dataIndex: "id",
hideInTable: true,
hideInSearch: true,
- formItemProps: { hidden: true }
+ formItemProps: { hidden: true },
},
{
- title: t(`${i18nPrefix}.columns.name`, '名称'),
- dataIndex: 'name',
- valueType: 'text',
+ title: t(`${i18nPrefix}.columns.name`, "名称"),
+ dataIndex: "name",
+ valueType: "text",
width: 250,
fieldProps: {
style: {
- width: '100%'
- }
+ width: "100%",
+ },
},
formItemProps: {
- rules: [
- { required: true, message: t('message.required', '请输入') }
- ]
- }
+ rules: [{ required: true, message: t("message.required", "请输入") }],
+ },
+ render: (text, record) => {record.name},
},
{
- title: t(`${i18nPrefix}.columns.name`, '标签'),
- dataIndex: 'tag',
- valueType: 'text',
+ title: t(`${i18nPrefix}.columns.name`, "标签"),
+ dataIndex: "tag",
+ valueType: "text",
hideInForm: true,
width: 200,
fieldProps: {
style: {
- width: '100%'
- }
- }
+ width: "100%",
+ },
+ },
},
{
- title: t(`${i18nPrefix}.columns.type`, '类型'),
- dataIndex: 'type',
- valueType: 'select',
+ title: t(`${i18nPrefix}.columns.type`, "类型"),
+ dataIndex: "type",
+ valueType: "select",
width: 200,
fieldProps: {
style: {
- width: '100%'
+ width: "100%",
},
- options: DNSTypes
+ options: DNSTypes,
},
formItemProps: {
- rules: [
- { required: true, message: t('message.required', '请选择') }
- ]
+ rules: [{ required: true, message: t("message.required", "请选择") }],
},
},
{
- name: [ 'type' ],
- valueType: 'dependency',
+ name: ["type"],
+ valueType: "dependency",
hideInSetting: true,
hideInTable: true,
columns: ({ type }) => {
- return getKeyColumn(type, t)
- }
+ return getKeyColumn(type, t);
+ },
},
{
- title: t(`${i18nPrefix}.columns.status`, '状态'),
- dataIndex: 'status',
- valueType: 'switch',
+ title: t(`${i18nPrefix}.columns.status`, "状态111111"),
+ dataIndex: "status",
+ valueType: "switch",
width: 200,
+ //disable禁用,enable正常,syncing正在同步中
render(_dom, record) {
- return
- }
+ // return ;
+ if (record.status == "syncing") {
+ return (
+
+
+
+
{t(`${i18nPrefix}.columns.syncing`, "同步中")}
+
+ );
+ } else {
+ return ;
+ }
+ },
},
{
- title: t(`${i18nPrefix}.columns.option`, '操作'),
- key: 'option',
+ title: t(`${i18nPrefix}.columns.option`, "操作"),
+ key: "option",
width: 300,
- valueType: 'option',
- fixed: 'right',
+ valueType: "option",
+ fixed: "right",
render: (_, record) => [
- {
- record.status = record.status > 0
- if (typeof record.authorization === 'string') {
- record.authorization = JSON.parse(record.authorization)
- }
- form.setFieldsValue(record)
- setOpen(true)
- }}>{t('actions.edit')},
- ,
+ {
+ form.setFieldsValue(record);
+ setOpen(true);
+ }}
+ >
+ {t("actions.edit", "编辑")}
+ ,
+ ,
{
- asyncDNS(record.id)
- }}
- title={t('message.syncConfirm', '您确定要同步吗?')}>
- {t('actions.sync', '同步')}
+ key={"sync_confirm"}
+ disabled={record.status == "syncing"}
+ onConfirm={() => {
+ asyncDNS(record.id);
+ }}
+ title={t("message.syncConfirm", "您确定要同步吗?")}
+ >
+ {t("actions.sync", "同步")}
,
- ,
+ ,
{
- deleteWebsiteDnsAccount([ record.id ])
- }}
- title={t('message.deleteConfirm')}>
- {t('actions.delete', '删除')}
-
- ]
- }
- ] as ProColumns[]
- }, [ isAsyncing, isDeleting, form, asyncDNS, deleteWebsiteDnsAccount ])
+ key={"del_confirm"}
+ disabled={isDeleting}
+ onConfirm={() => {
+ deleteWebsiteDnsAccount([record.id]);
+ }}
+ title={t("message.deleteConfirm")}
+ >
+ {t("actions.delete", "删除")}
+ ,
+ ],
+ },
+ ] as ProColumns[];
+ }, [isAsyncing, isDeleting, form, asyncDNS, deleteWebsiteDnsAccount]);
useEffect(() => {
- setSearchKey(search?.title)
- filterForm.setFieldsValue(search)
- }, [ search ])
+ setSearchKey(search?.title);
+ filterForm.setFieldsValue(search);
+ }, [search]);
useEffect(() => {
if (isSuccess) {
- setOpen(false)
+ setOpen(false);
}
- }, [ isSuccess ])
+ }, [isSuccess]);
return (
-
-
-
-
- }
- toolbar={{
- search: {
- loading: isFetching && !!search?.title,
- onSearch: (value: string) => {
- setSearch(prev => ({
- ...prev,
- title: value
- }))
- },
- allowClear: true,
- onChange: (e) => {
- setSearchKey(e.target?.value)
- },
- value: searchKey,
- placeholder: t(`${i18nPrefix}.placeholder`, '输入账号管理名称')
- },
- actions: [
-
-
-
- ,
- ,
- ]
- }}
- scroll={{
- // x: 2500,
- y: 'calc(100vh - 290px)'
- }}
- search={false}
- onRow={(record) => {
- return {
- className: cx({
- // 'ant-table-row-selected': currentWebsiteDnsAccount?.id === record.id
- }),
- onClick: () => {
- setWebsiteDnsAccount(record as any)
- }
- }
- }}
- dateFormatter="string"
- loading={isLoading || isFetching}
- dataSource={data?.rows ?? []}
- columns={columns}
- options={{
- reload: () => {
- refetch()
- },
- }}
- pagination={{
- total: data?.total,
- pageSize: search.pageSize,
- current: search.page,
- onShowSizeChange: (current: number, size: number) => {
- setSearch({
- ...search,
- pageSize: size,
- page: current
- })
- },
- onChange: (current, pageSize) => {
- setSearch(prev => {
- return {
- ...prev,
- page: current,
- pageSize: pageSize,
- }
- })
- },
- }}
- />
- {
- setOpen(open)
- }}
- loading={isSubmitting}
- // onValuesChange={(values) => {
- //
- // }}
- onFinish={async (values) => {
- values.status = values.status ? 1 : 0
- saveOrUpdate(values)
- }}
- columns={columns as ProFormColumnsType[]}/>
+
+
+
+
+ }
+ toolbar={{
+ search: {
+ loading: isFetching && !!search?.title,
+ onSearch: (value: string) => {
+ setSearch((prev) => ({
+ ...prev,
+ title: value,
+ }));
+ },
+ allowClear: true,
+ onChange: (e) => {
+ setSearchKey(e.target?.value);
+ },
+ value: searchKey,
+ placeholder: t(`${i18nPrefix}.placeholder`, "输入账号管理名称"),
+ },
+ actions: [
+
+
+
+ ,
+ ,
+ ],
+ }}
+ scroll={{
+ // x: 2500,
+ y: "calc(100vh - 290px)",
+ }}
+ search={false}
+ onRow={(record) => {
+ return {
+ className: cx({
+ // 'ant-table-row-selected': currentWebsiteDnsAccount?.id === record.id
+ }),
+ onClick: () => {
+ setWebsiteDnsAccount(record as any);
+ },
+ };
+ }}
+ dateFormatter="string"
+ loading={isLoading || isFetching}
+ dataSource={data?.rows ?? []}
+ columns={columns}
+ options={{
+ reload: () => {
+ refetch();
+ },
+ }}
+ pagination={{
+ total: data?.total,
+ pageSize: search.pageSize,
+ current: search.page,
+ onShowSizeChange: (current: number, size: number) => {
+ setSearch({
+ ...search,
+ pageSize: size,
+ page: current,
+ });
+ },
+ onChange: (current, pageSize) => {
+ setSearch((prev) => {
+ return {
+ ...prev,
+ page: current,
+ pageSize: pageSize,
+ };
+ });
+ },
+ }}
+ />
+ {
+ setOpen(open);
+ }}
+ loading={isSubmitting}
+ // onValuesChange={(values) => {
+ //
+ // }}
+ //disable禁用,enable正常,syncing正在同步中
+ onFinish={async (values) => {
+ values.status = values.status ?'enable': 'disable';
+ saveOrUpdate(values);
+ }}
+ columns={columns as ProFormColumnsType[]}
+ />
- {
- setFilterOpen(open)
+ {
+ setFilterOpen(open);
+ }}
+ layout={"vertical"}
+ scrollToFirstError={true}
+ layoutType={"DrawerForm"}
+ drawerProps={{
+ maskClosable: false,
+ mask: false,
+ }}
+ submitter={{
+ searchConfig: {
+ resetText: t(`${i18nPrefix}.filter.reset`, "清空"),
+ submitText: t(`${i18nPrefix}.filter.submit`, "查询"),
+ },
+ onReset: () => {
+ filterForm.resetFields();
+ },
+ render: (props) => {
+ return (
+
+
+
+
+
+
+ );
+ },
+ }}
+ // onValuesChange={(values) => {
+ //
+ // }}
- }}
- columns={unSetColumnRules(columns.filter(item => !item.hideInSearch) as ProFormColumnsType[])}/>
+ onFinish={async (values) => {
+ //处理,变成数组
+ Object.keys(values).forEach((key) => {
+ if (typeof values[key] === "string" && values[key].includes(",")) {
+ values[key] = values[key].split(",");
+ }
+ });
-
- )
-}
+ setSearch(values);
+ }}
+ columns={unSetColumnRules(columns.filter((item) => !item.hideInSearch) as ProFormColumnsType[])}
+ />
+
+ );
+};
-export default WebsiteDnsAccount
\ No newline at end of file
+export default WebsiteDnsAccount;
diff --git a/src/pages/websites/account/style.ts b/src/pages/websites/account/style.ts
index 022cbff..adbb96a 100644
--- a/src/pages/websites/account/style.ts
+++ b/src/pages/websites/account/style.ts
@@ -1,9 +1,9 @@
-import { createStyles } from '../../../theme'
+import { createStyles } from "../../../theme";
export const useStyle = createStyles(({ token, css, cx, prefixCls }, props: any) => {
- const prefix = `${prefixCls}-${token?.proPrefix}-websiteDnsAccount-list-page`
+ const prefix = `${prefixCls}-${token?.proPrefix}-websiteDnsAccount-list-page`;
- const container = css`
+ const container = css`
.ant-table-cell{
.ant-tag{
padding-inline: 3px;
@@ -18,9 +18,19 @@ export const useStyle = createStyles(({ token, css, cx, prefixCls }, props: any)
.ant-pro-table-highlight{
}
- `
- return {
- container: cx(prefix, props?.className, container),
+ .loadingStyle{
+ display: flex;
+ align-items: center;
+ justify-content: flex-start; /* 将内容左对齐 */
}
-})
\ No newline at end of file
+ .loadingStyle_table{
+ margin-left: 10px; /* 给内容和tip之间留一些间距 */
+ color : cadetblue;
+ }
+ `;
+
+ return {
+ container: cx(prefix, props?.className, container),
+ };
+});
diff --git a/src/pages/websites/cert/apply.tsx b/src/pages/websites/cert/apply.tsx
index f5045b2..5a271d5 100644
--- a/src/pages/websites/cert/apply.tsx
+++ b/src/pages/websites/cert/apply.tsx
@@ -1,232 +1,266 @@
-import { t } from '@/i18n.ts'
-import { useAtom, useAtomValue, useSetAtom } from 'jotai'
+import { t } from "@/i18n.ts";
+import { useAtom, useAtomValue, useSetAtom } from "jotai";
import {
algorithmTypes,
dnsConfigAtom,
- dnsVerifyAtom, dnsVerifyOKAtom,
+ dnsVerifyAtom,
+ dnsVerifyOKAtom,
saveOrUpdateCertAtom,
-} from '@/store/websites/cert.ts'
-import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
-import {
- Button,
- Flex,
- Form,
- Input,
- Select,
- Space,
- Table, Tooltip,
-} from 'antd'
-import google from '@/pages/websites/cert/assets/google.png'
-import zerossl from '@/pages/websites/cert/assets/zerossl.png'
-import lets_encrypt from '@/pages/websites/cert/assets/lets_encrypt.png'
-import { useStyle } from './style'
-import ListPageLayout from '@/layout/ListPageLayout.tsx'
-import { ColumnsType } from 'antd/es/table'
-import { atomWithStorage } from 'jotai/utils'
-import Copy from '@/components/copy'
-import { InfoCircleOutlined, LoadingOutlined } from '@ant-design/icons'
+} from "@/store/websites/cert.ts";
+import { useCallback, useEffect, useMemo, useRef, useState } from "react";
+import { Button, Flex, Form, Input, Progress, Select, Space, Table, Tooltip } from "antd";
+import google from "@/pages/websites/cert/assets/google.png";
+import zerossl from "@/pages/websites/cert/assets/zerossl.png";
+import lets_encrypt from "@/pages/websites/cert/assets/lets_encrypt.png";
+import { useStyle } from "./style";
+import ListPageLayout from "@/layout/ListPageLayout.tsx";
+import { ColumnsType } from "antd/es/table";
+import { atomWithStorage } from "jotai/utils";
+import Copy from "@/components/copy";
+import { InfoCircleOutlined, LoadingOutlined } from "@ant-design/icons";
-const i18nPrefix = 'cert.apply'
+const i18nPrefix = "cert.apply";
const BrandSelect = (props: any) => {
-
- const { styles, cx } = useStyle()
- const [ value, setValue ] = useState(() => props.value)
+ const { styles, cx } = useStyle();
+ const [value, setValue] = useState(() => props.value);
useEffect(() => {
- setValue(props.value)
- }, [ props.value ])
+ setValue(props.value);
+ }, [props.value]);
const onChange = useCallback((val: string) => {
- props.onChange?.(val)
- }, [])
+ props.onChange?.(val);
+ }, []);
- return <>
-
- onChange('Google')}
- className={cx('band-normal', {
- 'band-active': value === 'Google'
- })}>
-
- Google Trust Services
-
- onChange('ZeroSSL')}
- className={cx('band-normal', {
- 'band-active': value === 'ZeroSSL'
- })}>
-
- ZeroSSL
-
- onChange('Let\'s Encrypt')}
- className={cx('band-normal', {
- 'band-active': value === 'Let\'s Encrypt'
- })}>
-
- Let's Encrypt
-
-
- >
-}
+ return (
+ <>
+
+ onChange("Google")}
+ className={cx("band-normal", {
+ "band-active": value === "Google",
+ })}
+ >
+
+ Google Trust Services
+
+ onChange("ZeroSSL")}
+ className={cx("band-normal", {
+ "band-active": value === "ZeroSSL",
+ })}
+ >
+
+ ZeroSSL
+
+ onChange("Let's Encrypt")}
+ className={cx("band-normal", {
+ "band-active": value === "Let's Encrypt",
+ })}
+ >
+
+ Let's Encrypt
+
+
+ >
+ );
+};
const StatusTable = (props: { value: string }) => {
-
-
- const { data, isFetching } = useAtomValue(useMemo(() => dnsConfigAtom(props.value), [ props.value ]))
+ const [data, setData] = useState(null); // 临时状态来存储模拟数据
+ const { isFetching } = useAtomValue(useMemo(() => dnsConfigAtom(props.value), [props.value]));
const {
data: dnsVerifyStatus,
isFetching: isVerifyFetching,
- refetch
- } = useAtomValue(useMemo(() => dnsVerifyAtom(props.value, isFetching), [ props.value, isFetching ]))
+ refetch,
+ } = useAtomValue(useMemo(() => dnsVerifyAtom(props.value, isFetching), [props.value, isFetching]));
- const setDnsVerifyOK = useSetAtom(dnsVerifyOKAtom)
+ const setDnsVerifyOK = useSetAtom(dnsVerifyOKAtom);
- const timerRef = useRef()
+ const timerRef = useRef();
const columns = useMemo(() => {
-
return [
{
- title: <>{t(`${i18nPrefix}.status.columns.status`, '状态')} >,
- dataIndex: 'status',
+ title: (
+ <>
+ {t(`${i18nPrefix}.status.columns.status`, "状态")}
+
+
+ {" "}
+ >
+ ),
+ dataIndex: "status",
width: 100,
render: (_, record) => {
if (isFetching) {
- return {t(`${i18nPrefix}.actions.dnsVerifyStatus.0`, '等待')}
+ return {t(`${i18nPrefix}.actions.dnsVerifyStatus.0`, "等待")};
}
if (isVerifyFetching) {
//0,等待 1,域名OK,2,域名分析错误,3:检测中 4:检测成功,匹配失败 5:检测失败,9:检测成功
- return {t(`${i18nPrefix}.actions.dnsVerifyStatus.3`, '检测中')}
+ return (
+
+
+ {t(`${i18nPrefix}.actions.dnsVerifyStatus.3`, "检测中")}
+
+ );
}
- const dns = record.dns_name
- const info = (dnsVerifyStatus as any)?.find((item) => item.dns_name === dns) as any
+ const dns = record.dns_name;
+ const info = (dnsVerifyStatus as any)?.find((item) => item.dns_name === dns) as any;
if (info) {
- return {t(`${i18nPrefix}.actions.dnsVerifyStatus.${info.status}`, `${info?.status_txt}`)}
+ return {t(`${i18nPrefix}.actions.dnsVerifyStatus.${info.status}`, `${info?.status_txt}`)};
}
- return {t(`${i18nPrefix}.actions.dnsVerifyStatus.0`, '等待')}
+ return {t(`${i18nPrefix}.actions.dnsVerifyStatus.0`, "等待")};
},
},
{
//服务商
- title: t(`${i18nPrefix}.status.columns.name_servers`, '服务商'),
- dataIndex: 'name_servers',
+ title: t(`${i18nPrefix}.status.columns.name_servers`, "服务商"),
+ dataIndex: "name_servers",
width: 150,
render(text) {
if (text) {
- return {text}
+ return {text};
}
- return 未知
- }
+ return 未知;
+ },
},
{
//域名
- title: t(`${i18nPrefix}.status.columns.domain`, '域名'),
- dataIndex: 'dns_name',
+ title: t(`${i18nPrefix}.status.columns.domain`, "域名"),
+ dataIndex: "dns_name",
width: 200,
},
{
//主机记录
- title: t(`${i18nPrefix}.status.columns.record`, '主机记录'),
- dataIndex: 'host',
+ title: t(`${i18nPrefix}.status.columns.record`, "主机记录"),
+ dataIndex: "host",
width: 200,
render: (text) => {
- return
- }
+ return ;
+ },
},
{
//记录类型
- title: t(`${i18nPrefix}.status.columns.record_type`, '记录类型'),
- dataIndex: 'type',
+ title: t(`${i18nPrefix}.status.columns.record_type`, "记录类型"),
+ dataIndex: "type",
width: 100,
render: (text) => {
- return {text}
- }
+ return {text};
+ },
},
{
//记录值
- title: t(`${i18nPrefix}.status.columns.record_value`, '记录值'),
- dataIndex: 'record_value',
+ title: t(`${i18nPrefix}.status.columns.record_value`, "记录值"),
+ dataIndex: "record_value",
width: 200,
render: (text) => {
- return
- }
- }
- ] as ColumnsType
-
- }, [ isFetching, isVerifyFetching, dnsVerifyStatus ])
+ return ;
+ },
+ },
+ ] as ColumnsType;
+ }, [isFetching, isVerifyFetching, dnsVerifyStatus]);
useEffect(() => {
+ // 模拟数据
+ const mockData = {
+ dns_list: [
+ {
+ status: 1,
+ name_servers: "Example NS",
+ dns_name: "example.com",
+ host: "example",
+ type: "A",
+ record_value: "192.168.1.1"
+ },
+ {
+ status: 3,
+ name_servers: "Another NS",
+ dns_name: "another.com",
+ host: "another",
+ type: "CNAME",
+ record_value: "cname.another.com"
+ }
+ ]
+ };
+
+ setData(mockData);
if ((dnsVerifyStatus as any)?.every((item) => item.status === 9)) {
- setDnsVerifyOK(true)
- return
+ setDnsVerifyOK(true);
+ return;
}
timerRef.current = window.setInterval(() => {
if (isVerifyFetching) {
- return
+ return;
}
- //dnsVerifyStatus 如果所有status 为 9 则说明域名验证通过
+ // dnsVerifyStatus 如果所有status 为 9 则说明域名验证通过
if ((dnsVerifyStatus as any)?.every((item) => item.status === 9)) {
- setDnsVerifyOK(true)
- window.clearInterval(timerRef.current)
+ setDnsVerifyOK(true);
+ window.clearInterval(timerRef.current);
} else {
- refetch()
+ refetch();
}
- }, 2000)
+ }, 2000);
return () => {
- window.clearInterval(timerRef.current)
- }
+ window.clearInterval(timerRef.current);
+ };
+ }, [dnsVerifyStatus, isVerifyFetching]);
- }, [ dnsVerifyStatus, isVerifyFetching ])
-
- return <>
-
-
请您添加以下DNS解析记录 参考文档
-
1. 只需要添加一次即可,添加后请勿删除记录。
-
2. 耐心等待1~2分钟。
-
-
- >
-}
-
-const domainsAtom = atomWithStorage('domains', '')
+ return (
+ <>
+
+
+ 请您添加以下DNS解析记录
+ 参考文档
+
+
1. 只需要添加一次即可,添加后请勿删除记录。
+
2. 耐心等待1~2分钟。
+
+
+ >
+ );
+};
+const domainsAtom = atomWithStorage("domains", "");
-const Apply = ( ) => {
- const { styles } = useStyle()
- const [ form ] = Form.useForm()
- const { mutate: saveOrUpdate, isPending: isSubmitting } = useAtomValue(saveOrUpdateCertAtom)
- const [ domains, setDomains ] = useAtom(domainsAtom)
- const dnsVerifyOK = useAtomValue(dnsVerifyOKAtom)
+const Apply = () => {
+ const { styles } = useStyle();
+ const [form] = Form.useForm();
+ const { mutate: saveOrUpdate, isPending: isSubmitting } = useAtomValue(saveOrUpdateCertAtom);
+ const [domains, setDomains] = useAtom(domainsAtom);
+ const dnsVerifyOK = useAtomValue(dnsVerifyOKAtom);
useEffect(() => {
-
if (domains) {
form.setFieldsValue({
- domains
- })
+ domains,
+ });
}
- }, [ domains ])
+ }, [domains]);
return (
-
+ className={styles.applyContainer}
+ title={t(`${i18nPrefix}.apply.title`, "证书申请")}
+ >
*/}
+ {/* */}
+ {/**/}
+ {/* {t(`${i18nPrefix}.apply.remaining`, "剩余5张")}*/}
+ {/* / {t(`${i18nPrefix}.apply.total`, "共5张")}*/}
+ {/**/}
+ {/* */}
+ {/* */}
+ {/* */}
- {
- setDomains(e.target.value)
- }}
+ onBlur={(e) => {
+ setDomains(e.target.value);
+ }}
/>
-
+
-
+
-
-
-
-
+
+
-
- {t(`${i18nPrefix}.apply.submit`, '提交申请')}
+
+
+
+ {t(`${i18nPrefix}.apply.prev`, "上一步")}
+
+
+ {t(`${i18nPrefix}.apply.submit`, "提交申请")}
+
+
- )
-}
+ );
+};
-export default Apply
\ No newline at end of file
+export default Apply;
\ No newline at end of file
diff --git a/src/pages/websites/domain/index.tsx b/src/pages/websites/domain/index.tsx
index 62f7e70..bfd4a61 100644
--- a/src/pages/websites/domain/index.tsx
+++ b/src/pages/websites/domain/index.tsx
@@ -1,448 +1,529 @@
-import { useTranslation } from '@/i18n.ts'
-import { Button, Form, Divider, Space, Tooltip, Badge, Tag, Input, Flex, Select } from 'antd'
-import { useAtom, useAtomValue } from 'jotai'
+import { useTranslation } from "@/i18n.ts";
+import { Button, Form, Divider, Space, Tooltip, Badge, Tag, Input, Flex, Select, Spin } from "antd";
+import { useAtom, useAtomValue } from "jotai";
import {
deleteWebsiteDomainAtom,
- saveOrUpdateWebsiteDomainAtom, updateGroupWebsiteDomainAtom,
- updateRemarkWebsiteDomainAtom, updateTagWebsiteDomainAtom,
+ saveOrUpdateWebsiteDomainAtom,
+ updateGroupWebsiteDomainAtom,
+ updateRemarkWebsiteDomainAtom,
+ updateTagWebsiteDomainAtom,
websiteDomainAtom,
websiteDomainsAtom,
websiteDomainSearchAtom,
-} from '@/store/websites/domain'
-import { useEffect, useMemo, useState } from 'react'
-import Action from '@/components/action/Action.tsx'
-import {
- BetaSchemaForm,
- ProColumns,
- ProFormColumnsType,
-} from '@ant-design/pro-components'
-import ListPageLayout from '@/layout/ListPageLayout.tsx'
-import { useStyle } from './style'
-import { FilterOutlined } from '@ant-design/icons'
-import { getValueCount, unSetColumnRules } from '@/utils'
-import { Table as ProTable } from '@/components/table'
-import { Link } from '@tanstack/react-router'
-import Popconfirm from '@/components/popconfirm'
-import { accountStatus, accountStatusColor } from '@/store/websites/dns_account.ts'
-import Icon from '@/components/icon'
-import { useDialog } from '@/components/dialog'
-import { dnsListAtom } from '@/store/websites/dns.ts'
-import ModalPro from '@/components/modal-pro'
-import { domainGroupsAtom } from '@/store/websites/domain_groups.ts'
-import NameServer from '@/pages/websites/domain/components/NameServer.tsx'
+} from "@/store/websites/domain";
+import { useEffect, useMemo, useState } from "react";
+import Action from "@/components/action/Action.tsx";
+import { BetaSchemaForm, ProColumns, ProFormColumnsType } from "@ant-design/pro-components";
+import ListPageLayout from "@/layout/ListPageLayout.tsx";
+import { useStyle } from "./style";
+import { FilterOutlined } from "@ant-design/icons";
+import { getValueCount, unSetColumnRules } from "@/utils";
+import { Table as ProTable } from "@/components/table";
+import { Link, useNavigate } from "@tanstack/react-router";
+import Popconfirm from "@/components/popconfirm";
+import { accountStatus, accountStatusColor } from "@/store/websites/dns_account.ts";
+import Icon from "@/components/icon";
+import { useDialog } from "@/components/dialog";
+import { dnsListAtom } from "@/store/websites/dns.ts";
+import ModalPro from "@/components/modal-pro";
+import { domainGroupsAtom } from "@/store/websites/domain_groups.ts";
+import NameServer from "@/pages/websites/domain/components/NameServer.tsx";
+import Switch from "@/components/switch";
-const i18nPrefix = 'websites.domain.list'
+const i18nPrefix = "websites.domain.list";
const WebsiteDomain = () => {
+ const { styles, cx } = useStyle();
+ const { t } = useTranslation();
+ const [form] = Form.useForm();
+ const [filterForm] = Form.useForm();
+ const navigate = useNavigate();
+ const { mutate: saveOrUpdate, isPending: isSubmitting, isSuccess } = useAtomValue(saveOrUpdateWebsiteDomainAtom);
+ const { mutate: updateRemark } = useAtomValue(updateRemarkWebsiteDomainAtom);
+ const { mutate: updateTags } = useAtomValue(updateTagWebsiteDomainAtom);
+ const { mutate: updateGroup } = useAtomValue(updateGroupWebsiteDomainAtom);
+ const [search, setSearch] = useAtom(websiteDomainSearchAtom);
+ const [currentWebsiteDomain, setWebsiteDomain] = useAtom(websiteDomainAtom);
+ const { data, isFetching, isLoading, refetch } = useAtomValue(websiteDomainsAtom);
+ const { data: groupData, isFetching: isGroupLoading } = useAtomValue(domainGroupsAtom);
- const { styles, cx } = useStyle()
- const { t } = useTranslation()
- const [ form ] = Form.useForm()
- const [ filterForm ] = Form.useForm()
- const { mutate: saveOrUpdate, isPending: isSubmitting, isSuccess } = useAtomValue(saveOrUpdateWebsiteDomainAtom)
- const { mutate: updateRemark } = useAtomValue(updateRemarkWebsiteDomainAtom)
- const { mutate: updateTags } = useAtomValue(updateTagWebsiteDomainAtom)
- const { mutate: updateGroup } = useAtomValue(updateGroupWebsiteDomainAtom)
- const [ search, setSearch ] = useAtom(websiteDomainSearchAtom)
- const [ currentWebsiteDomain, setWebsiteDomain ] = useAtom(websiteDomainAtom)
- const { data, isFetching, isLoading, refetch } = useAtomValue(websiteDomainsAtom)
- const { data: groupData, isFetching: isGroupLoading } = useAtomValue(domainGroupsAtom)
-
- const { mutate: deleteWebsiteDomain, isPending: isDeleting } = useAtomValue(deleteWebsiteDomainAtom)
- const { data: dnsData } = useAtomValue(dnsListAtom)
+ const { mutate: deleteWebsiteDomain, isPending: isDeleting } = useAtomValue(deleteWebsiteDomainAtom);
+ const { data: dnsData } = useAtomValue(dnsListAtom);
- const [ open, setOpen ] = useState(false)
- const [ openFilter, setFilterOpen ] = useState(false)
- const [ searchKey, setSearchKey ] = useState(search?.title)
+ const [open, setOpen] = useState(false);
+ const [openFilter, setFilterOpen] = useState(false);
+ const [searchKey, setSearchKey] = useState(search?.title);
- const [ , dialog, openDialog ] = useDialog({
- title: '编辑备注',
- children:
-
-
- ,
+ const [, dialog, openDialog] = useDialog({
+ title: "编辑备注",
+ children: (
+
+
+
+
+ ),
onOk: () => {
- const id = form.getFieldValue('id')
- const remark = form.getFieldValue('remark')
- return updateRemark({ remark, id } as any)
- }
- })
+ const id = form.getFieldValue("id");
+ const remark = form.getFieldValue("remark");
+ return updateRemark({ remark, id } as any);
+ },
+ });
const columns = useMemo(() => {
return [
{
- title: 'ID',
- dataIndex: 'id',
+ title: "ID",
+ dataIndex: "id",
hideInTable: true,
hideInSearch: true,
- formItemProps: { hidden: true }
+ formItemProps: { hidden: true },
},
{
- title: t(`${i18nPrefix}.columns.name`, '域名'),
- dataIndex: 'name',
+ title: t(`${i18nPrefix}.columns.name`, "域名"),
+ dataIndex: "name",
width: 300,
fieldProps: {
- style: { width: '100%' }
+ style: { width: "100%" },
},
render(_text, record) {
- const edit = {
- form.setFieldsValue(record)
- openDialog(record)
- }}
- style={{ paddingBlockStart: 0 }} type={'EditTwo'} size={14}/>
- return
-
- {record.name}
- {edit}
-
- {record.remark}
-
- }
+ const edit = (
+ {
+ form.setFieldsValue(record);
+ openDialog(record);
+ }}
+ style={{ paddingBlockStart: 0 }}
+ type={"EditTwo"}
+ size={14}
+ />
+ );
+ return (
+
+
+ {record.name}
+ {edit}
+
+ {record.remark}
+
+ );
+ },
},
{
- title: t(`${i18nPrefix}.columns.record_count`, '记录数'),
- dataIndex: 'record_count',
+ title: t(`${i18nPrefix}.columns.record_count`, "记录数"),
+ dataIndex: "record_count",
hideInForm: true,
hideInSearch: true,
},
{
- title: t(`${i18nPrefix}.columns.dns_account_id`, 'DNS账号'),
- dataIndex: 'dns_account_id',
- valueType: 'select',
+ title: t(`${i18nPrefix}.columns.dns_account_id`, "DNS账号"),
+ dataIndex: "dns_account_id",
+ valueType: "select",
fieldProps: {
- options: dnsData?.rows?.map?.(item => {
+ options: dnsData?.rows?.map?.((item) => {
return {
data: item,
label: item.name,
value: item.id,
- }
- })
- }
+ };
+ }),
+ },
},
{
- title: t(`${i18nPrefix}.columns.status`, '状态'),
- dataIndex: 'status',
+ title: t(`${i18nPrefix}.columns.status`, "状态"),
+ dataIndex: "status",
hideInForm: true,
- valueType: 'select',
+ valueType: "select",
valueEnum: accountStatus,
render(_dom, record) {
- const loading = [ 'pending', 'syncing' ].includes(record.status) ?
- : null
- return
-
- {t(`websites.common.status.${record.status!}`, record.status + '')}
-
- {loading}
-
-
- }
+ switch (record.status) {
+ //active活动,pending等待,delete已经删除,disable禁用,syn正在同步
+ case "enable":
+ case "active":
+ return (
+
+
+
+ {t(`websites.common.status.${record.status!}`, record.status + "")}
+
+
+
+ );
+ case "pending":
+ // return ;
+ return (
+
+
+
{t(`${i18nPrefix}.columns.syncing`, "等待")}
+
+ );
+ case "delete":
+ case "disable":
+ return (
+
+
+
+ {t(`websites.common.status.${record.status!}`, record.status + "")}
+
+
+
+ );
+ case "syncing":
+ return (
+
+
+
{t(`${i18nPrefix}.columns.syncing`, "同步中")}
+
+ );
+ }
+ },
},
{
- title: t(`${i18nPrefix}.columns.nameservers`, 'DNS服务器地址'),
- dataIndex: 'nameservers',
+ title: t(`${i18nPrefix}.columns.nameservers`, "DNS服务器地址"),
+ dataIndex: "nameservers",
width: 150,
hideInSearch: true,
hideInForm: true,
render(_dom, record) {
- return
- }
+ return ;
+ },
},
{
- title: t(`${i18nPrefix}.columns.created`, '创建时间'),
- dataIndex: 'created',
+ title: t(`${i18nPrefix}.columns.created`, "创建时间"),
+ dataIndex: "created",
hideInSearch: true,
hideInForm: true,
},
{
- title: t(`${i18nPrefix}.columns.option`, '操作'),
- key: 'option',
- valueType: 'option',
- fixed: 'right',
+ title: t(`${i18nPrefix}.columns.option`, "操作"),
+ key: "option",
+ valueType: "option",
+ fixed: "right",
render: (_, record) => [
- 解析设置,
-
- /* {
- // form.setFieldsValue(record)
- // setOpen(true)
-
- }}>{t('actions.recordSet', '解析设置')},*/
- ,
- {
+ // 解析设置,
- }}>{t('actions.sync', '同步')},
+ {
+ form.setFieldsValue(record);
+ setOpen(true);
+ }}
+ >
+ {t("actions.recordSet", "设置")}
+ ,
+ ,
+ {
+ navigate({
+ to: `/cert/record`,
+ search: { id: record.id },
+ });
+ }}
+ >
+ {t("actions.recordSet", "记录")}
+ ,
+ ,
+ {}}>
+ {t("actions.sync", "同步")}
+ ,
- ,
+ ,
{
- deleteWebsiteDomain([ record.id ])
- }}
- title={t('message.deleteConfirm')}>
- {t('actions.delete', '删除')}
-
- ]
- }
- ] as ProColumns[]
- }, [ isDeleting, currentWebsiteDomain, search, dnsData ])
+ key={"del_confirm"}
+ disabled={isDeleting}
+ onConfirm={() => {
+ deleteWebsiteDomain([record.id]);
+ }}
+ title={t("message.deleteConfirm")}
+ >
+ {t("actions.delete", "删除")}
+ ,
+ ],
+ },
+ ] as ProColumns[];
+ }, [isDeleting, currentWebsiteDomain, search, dnsData]);
useEffect(() => {
+ const queryParams = new URLSearchParams(location.search);
+ const dnsAccountId = queryParams.get("id");
- setSearchKey(search?.title)
- filterForm.setFieldsValue(search)
+ if (dnsAccountId) {
+ setSearch((prev) => ({
+ ...prev,
+ name: "",
+ dns_account_id: dnsAccountId,
+ }));
+ }
+ }, [location.search]);
- }, [ search ])
+ useEffect(() => {
+ setSearchKey(search?.title);
+ filterForm.setFieldsValue(search);
+ }, [search]);
useEffect(() => {
if (isSuccess) {
- setOpen(false)
+ setOpen(false);
}
- }, [ isSuccess ])
+ }, [isSuccess]);
return (
-
-
- {
- form.resetFields()
- form.setFieldsValue({
- id: 0,
- })
- setOpen(true)
- }}
- type={'primary'}>{t(`${i18nPrefix}.add`, '添加域名')}
-
- }
- tableAlertRender={(props) => {
- return
- 确认删除此域名?
删除域名,解析记录会同步删除,且无法恢复。}
- onOk={() => {
- deleteWebsiteDomain(props.selectedRows?.map(item => item.id))
- }}
- >
- {t('actions.delete', '删除')}
-
-
-
- {
- return {
- label: item.name,
- value: item.id,
- }
- }) ?? [])
- ]
- }/>
-
-
- >}
- onLoad={() => {
- form.setFieldsValue({ group_id: 0 })
- }}
- onOk={() => {
- const group_id = form.getFieldValue('group_id')
- updateGroup({ id: props.selectedRows?.map(item => item.id), group_id })
- }}
- >
- {t(`${i18nPrefix}.actions.changeGroup`, '更换分组')}
-
-
- }}
- tableAlertOptionRender={false}
- toolbar={{
- search: {
- loading: isFetching && !!search?.title,
- onSearch: (value: string) => {
- setSearch(prev => ({
- ...prev,
- title: value
- }))
- },
- allowClear: true,
- onChange: (e) => {
- setSearchKey(e.target?.value)
- },
- value: searchKey,
- placeholder: t(`${i18nPrefix}.placeholder`, '输入域名管理名称')
- },
- actions: [
-
-
- {
- setFilterOpen(true)
- }}
- icon={} shape={'circle'} size={'small'}/>
-
- ,
- ,
-
- ]
- }}
- scroll={{
- // x: 2500,
- y: 'calc(100vh - 290px)'
- }}
- search={false}
- onRow={(record) => {
- return {
- className: cx({
- // 'ant-table-row-selected': currentWebsiteDomain?.id === record.id
- }),
- onClick: () => {
- setWebsiteDomain(record)
- }
- }
- }}
- rowSelection={{
- type: 'checkbox',
- alwaysShowAlert: true,
- }}
- dateFormatter="string"
- loading={isLoading || isFetching}
- dataSource={data?.rows ?? []}
- columns={columns}
- options={{
- reload: () => {
- refetch()
- },
- }}
- pagination={{
- total: data?.total,
- pageSize: search.pageSize,
- current: search.page,
- onShowSizeChange: (current: number, size: number) => {
- setSearch({
- ...search,
- pageSize: size,
- page: current
- })
- },
- onChange: (current, pageSize) => {
- setSearch(prev => {
- return {
- ...prev,
- page: current,
- pageSize: pageSize,
- }
- })
- },
- }}
- />
- {
- setOpen(open)
- }}
- loading={isSubmitting}
-
- onFinish={async (values) => {
- saveOrUpdate(values)
- }}
- columns={columns as ProFormColumnsType[]}/>
- {
- setFilterOpen(open)
- }}
- layout={'vertical'}
- scrollToFirstError={true}
- layoutType={'DrawerForm'}
- drawerProps={{
- maskClosable: false,
- mask: false,
- }}
- submitter={{
- searchConfig: {
- resetText: t(`${i18nPrefix}.filter.reset`, '清空'),
- submitText: t(`${i18nPrefix}.filter.submit`, '查询'),
- },
- onReset: () => {
- filterForm.resetFields()
- },
- render: (props,) => {
- return (
-
-
- {
- props.reset()
-
- }}>{props.searchConfig?.resetText}
- {
- props.submit()
- }}
- >{props.searchConfig?.submitText}
-
-
- )
- },
-
+
+
+ {
+ form.resetFields();
+ form.setFieldsValue({
+ id: 0,
+ });
+ setOpen(true);
+ }}
+ type={"primary"}
+ >
+ {t(`${i18nPrefix}.add`, "添加域名")}
+
+
+ }
+ tableAlertRender={(props) => {
+ return (
+
+
+ 确认删除此域名?
+
+ 删除域名,解析记录会同步删除,且无法恢复。
+
+ }
+ onOk={() => {
+ deleteWebsiteDomain(props.selectedRows?.map((item) => item.id));
+ }}
+ >
+ {t("actions.delete", "删除")}
+
+
+
+ {
+ return {
+ label: item.name,
+ value: item.id,
+ };
+ }) ?? []),
+ ]}
+ />
+
+
+ >
+ }
+ onLoad={() => {
+ form.setFieldsValue({ group_id: 0 });
+ }}
+ onOk={() => {
+ const group_id = form.getFieldValue("group_id");
+ updateGroup({ id: props.selectedRows?.map((item) => item.id), group_id });
+ }}
+ >
+
+ {t(`${i18nPrefix}.actions.changeGroup`, "更换分组")}
+
+
+
+ );
+ }}
+ tableAlertOptionRender={false}
+ toolbar={{
+ search: {
+ loading: isFetching && !!search?.title,
+ onSearch: (value: string) => {
+ setSearch((prev) => ({
+ ...prev,
+ title: value,
+ }));
+ },
+ allowClear: true,
+ onChange: (e) => {
+ setSearchKey(e.target?.value);
+ },
+ value: searchKey,
+ placeholder: t(`${i18nPrefix}.placeholder`, "输入域名管理名称"),
+ },
+ actions: [
+
+
+ {
+ setFilterOpen(true);
+ }}
+ icon={}
+ shape={"circle"}
+ size={"small"}
+ />
+
+ ,
+ ,
+ ],
+ }}
+ scroll={{
+ // x: 2500,
+ y: "calc(100vh - 290px)",
+ }}
+ search={false}
+ onRow={(record) => {
+ return {
+ className: cx({
+ // 'ant-table-row-selected': currentWebsiteDomain?.id === record.id
+ }),
+ onClick: () => {
+ setWebsiteDomain(record);
+ },
+ };
+ }}
+ rowSelection={{
+ type: "checkbox",
+ alwaysShowAlert: true,
+ }}
+ dateFormatter="string"
+ loading={isLoading || isFetching}
+ dataSource={data?.rows ?? []}
+ columns={columns}
+ options={{
+ reload: () => {
+ refetch();
+ },
+ }}
+ pagination={{
+ total: data?.total,
+ pageSize: search.pageSize,
+ current: search.page,
+ onShowSizeChange: (current: number, size: number) => {
+ setSearch({
+ ...search,
+ pageSize: size,
+ page: current,
+ });
+ },
+ onChange: (current, pageSize) => {
+ setSearch((prev) => {
+ return {
+ ...prev,
+ page: current,
+ pageSize: pageSize,
+ };
+ });
+ },
+ }}
+ />
+ {
+ setOpen(open);
+ }}
+ loading={isSubmitting}
+ onFinish={async (values) => {
+ saveOrUpdate(values);
+ }}
+ columns={columns as ProFormColumnsType[]}
+ />
+ {
+ setFilterOpen(open);
+ }}
+ layout={"vertical"}
+ scrollToFirstError={true}
+ layoutType={"DrawerForm"}
+ drawerProps={{
+ maskClosable: false,
+ mask: false,
+ }}
+ submitter={{
+ searchConfig: {
+ resetText: t(`${i18nPrefix}.filter.reset`, "清空"),
+ submitText: t(`${i18nPrefix}.filter.submit`, "查询"),
+ },
+ onReset: () => {
+ filterForm.resetFields();
+ },
+ render: (props) => {
+ return (
+
+
+ {
+ props.reset();
}}
-
-
- onFinish={async (values) => {
- //处理,变成数组
- Object.keys(values).forEach(key => {
- if (typeof values[key] === 'string' && values[key].includes(',')) {
- values[key] = values[key].split(',')
- }
- })
-
- setSearch(values)
-
+ >
+ {props.searchConfig?.resetText}
+
+ {
+ props.submit();
}}
- columns={unSetColumnRules(columns.filter(item => !item.hideInSearch) as ProFormColumnsType[])}/>
- {
- dialog
+ >
+ {props.searchConfig?.submitText}
+
+
+
+ );
+ },
+ }}
+ onFinish={async (values) => {
+ //处理,变成数组
+ Object.keys(values).forEach((key) => {
+ if (typeof values[key] === "string" && values[key].includes(",")) {
+ values[key] = values[key].split(",");
}
-
- )
-}
+ });
+
+ setSearch(values);
+ }}
+ columns={unSetColumnRules(columns.filter((item) => !item.hideInSearch) as ProFormColumnsType[])}
+ />
+ {dialog}
+
+ );
+};
-export default WebsiteDomain
\ No newline at end of file
+export default WebsiteDomain;
diff --git a/src/pages/websites/domain/style.ts b/src/pages/websites/domain/style.ts
index e1d04b4..aae0829 100644
--- a/src/pages/websites/domain/style.ts
+++ b/src/pages/websites/domain/style.ts
@@ -18,6 +18,16 @@ export const useStyle = createStyles(({ token, css, cx, prefixCls }, props: any)
.ant-pro-table-highlight{
}
+
+ .loadingStyle{
+ display: flex;
+ align-items: center;
+ justify-content: flex-start; /* 将内容左对齐 */
+ }
+ .loadingStyle_table{
+ margin-left: 10px; /* 给内容和tip之间留一些间距 */
+ color : cadetblue;
+ }
`
return {
diff --git a/src/pages/websites/mytest/index.tsx b/src/pages/websites/mytest/index.tsx
new file mode 100644
index 0000000..49446cb
--- /dev/null
+++ b/src/pages/websites/mytest/index.tsx
@@ -0,0 +1,52 @@
+import React, { useMemo } from 'react';
+import { ProTable } from '@ant-design/pro-components';
+import type { ProColumns } from '@ant-design/pro-components';
+
+type DataType = {
+ key: number;
+ name: string;
+ age: number;
+ address: string;
+};
+
+const data: DataType[] = [
+ { key: 1, name: 'John Brown', age: 32, address: 'New York No. 1 Lake Park' },
+ { key: 2, name: 'Jim Green', age: 42, address: 'London No. 1 Lake Park' },
+ { key: 3, name: 'Joe Black', age: 32, address: 'Sidney No. 1 Lake Park' },
+];
+
+const MyTable: React.FC = () => {
+ const columns: ProColumns[] = useMemo(() => [
+ {
+ title: 'Name',
+ dataIndex: 'name',
+ key: 'name',
+ },
+ {
+ title: 'Age',
+ dataIndex: 'age',
+ key: 'age',
+ },
+ {
+ title: 'Address',
+ dataIndex: 'address',
+ key: 'address',
+ },
+ ], []);
+
+ const memoizedData = useMemo(() => data, []);
+
+ return (
+
+ columns={columns}
+ dataSource={memoizedData}
+ rowKey="key"
+ search={false}
+ pagination={{
+ pageSize: 5,
+ }}
+ />
+ );
+};
+
+export default MyTable;
\ No newline at end of file
diff --git a/src/pages/websites/record/index.tsx b/src/pages/websites/record/index.tsx
index d810372..7ec1697 100644
--- a/src/pages/websites/record/index.tsx
+++ b/src/pages/websites/record/index.tsx
@@ -9,7 +9,7 @@ import {
websiteDnsRecordsAtom,
websiteDnsRecordssAtom,
websiteDnsRecordsSearchAtom,
-} from '@/store/websites/record'
+} from '@/store/websites/record.ts'
import { useEffect, useMemo, useRef, useState } from 'react'
import Action from '@/components/action/Action.tsx'
import {
@@ -18,7 +18,7 @@ import {
ProFormColumnsType,
} from '@ant-design/pro-components'
import ListPageLayout from '@/layout/ListPageLayout.tsx'
-import { useStyle } from './style'
+import { useStyle } from './style.ts'
import { FilterOutlined, MinusCircleOutlined, PlusOutlined, QuestionCircleOutlined } from '@ant-design/icons'
import { getValueCount, unSetColumnRules } from '@/utils'
import { Table as ProTable } from '@/components/table'
diff --git a/src/service/website/domain_group.ts b/src/service/website/domain_group.ts
index 280e32b..e728da5 100644
--- a/src/service/website/domain_group.ts
+++ b/src/service/website/domain_group.ts
@@ -2,7 +2,7 @@ import { createCURD } from '@/service/base.ts'
import { WebSite } from '@/types/website/domain_group'
const domain_group = {
- ...createCURD('/website/group'),
+ ...createCURD('/cert/dns_group'),
}
export default domain_group
\ No newline at end of file
diff --git a/src/service/websites.ts b/src/service/websites.ts
index c57bed8..aff0817 100644
--- a/src/service/websites.ts
+++ b/src/service/websites.ts
@@ -16,6 +16,10 @@ const websitesServ = {
dnsVerify: async (params: any) => {
return request.post('/website/cert/dns_verify', params)
},
+ //cert-apply
+ certApply: async (params: any) => {
+ return request.post('/website/cert/dns_verify', params)
+ },
},
ssl: {
@@ -31,9 +35,9 @@ const websitesServ = {
...createCURD('/website/acme')
},
dns: {
- ...createCURD('/website/dns_account'),
+ ...createCURD('/cert/dns_account'),
sync: async (id: any) => {
- return request.post('/website/dns_account/sync', { id: id })
+ return request.post('/cert/dns_account/sync', { id: id })
}
},
ca: {
@@ -43,36 +47,36 @@ const websitesServ = {
},
},
domain: {
- ...createCURD('/website/domain'),
+ ...createCURD('/cert/domain'),
//remark
remark: async (params: { id: string, remark: string }) => {
- return request.post('/website/domain/remark', params)
+ return request.post('/cert/domain/remark', params)
},
//tag
tag: async (params: { id: string, tags: string }) => {
- return request.post('/website/domain/tag', params)
+ return request.post('/cert/domain/tag', params)
},
//binding
binding: async (params: { id: string, user_id: string }) => {
- return request.post('/website/domain/binding', params)
+ return request.post('/cert/domain/binding', params)
},
//group
group: async (params: { id: string[], group_id: string }) => {
- return request.post('/website/domain/group', params)
+ return request.post('/cert/domain/group', params)
},
describeDomainNS: async (params: { id: number }) => {
- return request.post('/website/domain/describe_domain_ns', params)
+ return request.post('/cert/domain/describe_domain_ns', params)
},
},
record: {
- ...createCURD('/website/dns_records'),
+ ...createCURD('/cert/dns_records'),
//
},
dnsAccount: {
- ...createCURD('/website/dns_account'),
+ ...createCURD('/cert/dns_account'),
sync: async (params: IWebsiteDnsAccount) => {
- return request.post('/website/dns_account/sync', params)
+ return request.post('/cert/dns_account/sync', params)
}
},
}
diff --git a/src/store/websites/cert.ts b/src/store/websites/cert.ts
index 9e1ff01..a1f9038 100644
--- a/src/store/websites/cert.ts
+++ b/src/store/websites/cert.ts
@@ -46,6 +46,31 @@ export const certPageAtom = atom({
page: 1,
})
+//certApple
+export const certAppleCertAtom = atomWithMutation((get) => {
+
+ return {
+ mutationKey: [ 'appleCert' ],
+ mutationFn: async (data) => {
+ //data.status = data.status ? '1' : '0'
+ return await websitesServ.cert.certApply(data)
+ },
+ onSuccess: (res) => {
+ const isAdd = !!res.data?.id
+ message.success(t(isAdd ? 'message.saveSuccess' : 'message.editSuccess', '保存成功'))
+
+ //更新列表
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+ // @ts-ignore fix
+ get(queryClientAtom).invalidateQueries({ queryKey: [ 'certs', get(certSearchAtom) ] })
+
+ return res
+ }
+ }
+})
+
+
+
export const certsAtom = atomWithQuery((get) => {
return {
queryKey: [ 'certs', get(certSearchAtom) ],
diff --git a/vite.config.ts b/vite.config.ts
index b3518e7..75bb7c0 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -11,6 +11,8 @@ import jotaiReactRefresh from 'jotai/babel/plugin-react-refresh'
const proxyMap = {
'/api/v1/package': 'http://154.88.7.8:45321',
'/api/v1/movie': 'http://47.113.117.106:10000',
+ //'/api/v1/certold': 'http://192.168.31.41:8000',
+ '/api/v1/cert': 'http://127.0.0.1:8000',
} as Record
const proxyConfig = Object.keys(proxyMap).reduce((acc, key) => {
@@ -29,6 +31,7 @@ export default defineConfig(({ mode }) => {
// 设置第三个参数为 '' 来加载所有环境变量,而不管是否有 `VITE_` 前缀。
// @ts-ignore fix process
const env = loadEnv(mode, process.cwd(), '')
+ // 你可以在这里打印出 env 变量来检查加载的内容
return {
//定义别名的路径
resolve: {