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: [ - - - + + } + 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: [ + + + + - - - - ) - }, - - }} - // onValuesChange={(values) => { - // - // }} - - 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?.submitText} + + + + ); + }, + }} + // 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`, "证书申请")} + >
{ }} onFinish={async (values) => { if (dnsVerifyOK) { - saveOrUpdate(values) + saveOrUpdate(values); } }} > + {/* */} + {/* */} + {/**/} + {/* {t(`${i18nPrefix}.apply.remaining`, "剩余5张")}*/} + {/* / {t(`${i18nPrefix}.apply.total`, "共5张")}*/} + {/**/} + {/* */} + {/* */} + {/* */} - { - setDomains(e.target.value) - }} + onBlur={(e) => { + setDomains(e.target.value); + }} /> - + - + - - - - + + - - + + + + +
- ) -} + ); +}; -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 ( - - - - - } - tableAlertRender={(props) => { - return - 确认删除此域名?
删除域名,解析记录会同步删除,且无法恢复。} - onOk={() => { - deleteWebsiteDomain(props.selectedRows?.map(item => item.id)) - }} - > - -
- -
- - { + 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 }); + }} + > + +
+
+ ); + }} + 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: [ + + + + + + + ); + }, + }} + 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: {