diff --git a/src/App.css b/src/App.css index 275197a..cffcefd 100644 --- a/src/App.css +++ b/src/App.css @@ -1,47 +1,60 @@ .i-icon { - display: flex; + display: flex; } -.ant-tree-iconEle{ - .i-icon { - display: inherit; - line-height: 28px; - } + +.ant-tree-iconEle { + .i-icon { + display: inherit; + line-height: 28px; + } } .top-breadcrumb { - .item { + .item { - display: flex; - align-items: center; - justify-content: center; - gap: 5px; - } + display: flex; + align-items: center; + justify-content: center; + gap: 5px; + } } -.ant-drawer .ant-drawer-footer{ +.ant-drawer .ant-drawer-footer { background-color: #fcfcfc; } -.hover{ +.hover { cursor: pointer; - &:hover{ + + &:hover { color: #1c7ed6; } } /*灰色*/ -.color-gray{ +.color-gray { color: #999; } -.color-65{ - color:rgba(0, 0, 0, 0.65); + +.color-65 { + color: rgba(0, 0, 0, 0.65); } -.color-333{ + +.color-333 { color: #333; } -.text-bold{ + +.color-green { + color: green; +} + +.color-yellow { + color: rgb(250 145 0) +} + +.text-bold { font-weight: bold; } diff --git a/src/pages/websites/domain/components/NameServer.tsx b/src/pages/websites/domain/components/NameServer.tsx new file mode 100644 index 0000000..b85d747 --- /dev/null +++ b/src/pages/websites/domain/components/NameServer.tsx @@ -0,0 +1,96 @@ +import { INameServer, IWebsiteDomain } from '@/types/website/domain' +import { Typography, Popover, Table } from 'antd' +import { memo, useCallback, useMemo } from 'react' +import { useAtomValue } from 'jotai' +import { describeDomainNSAtom } from '@/store/websites/domain.ts' +import { + CheckCircleFilled, + CheckCircleOutlined, + ExclamationCircleFilled, + ExclamationCircleOutlined, + LoadingOutlined +} from '@ant-design/icons' + +export interface NameServerProps { + data: IWebsiteDomain +} + +interface FormattedDnsData { + expectDnsServers: string; + dnsServers: string; +} + +function formatNameServerData(data?: INameServer) { + + if (!data) { + return [] + } + + const formattedData: FormattedDnsData[] = [] + const maxLength = Math.max(data.expectDnsServers.length, data.dnsServers.length) + + for (let i = 0; i < maxLength; i++) { + formattedData.push({ + expectDnsServers: data.expectDnsServers[i] || '', + dnsServers: data.dnsServers[i] || '', + }) + } + + return formattedData +} + +const NameServer = memo(({ data }: NameServerProps) => { + + const { data: result, isFetching } = useAtomValue(useMemo(() => describeDomainNSAtom(data?.id), [])) + + const columns = [ + { + title: '当前DNS', + dataIndex: 'dnsServers' + }, + { + title: '系统分配DNS', + dataIndex: 'expectDnsServers', + render: (text: string) => { + return {text} + } + }, + ] + + const content = useCallback(() => { + return ( + + ) + }, [ result ]) + + const title = useCallback(() => { + if (result?.success) + return 域名的DNS信息配置正确。 + + return 探测超时,请稍后查看。 + }, [ result ]) + + if (data?.nameservers?.length === 0) { + return null + } + + return ( + + {isFetching ? : null} + { + result?.success ? + 正常 + : {result?.message || '探测超时'} + } + + ) +}) + +export default NameServer \ No newline at end of file diff --git a/src/pages/websites/domain/components/style.ts b/src/pages/websites/domain/components/style.ts new file mode 100644 index 0000000..412f4fb --- /dev/null +++ b/src/pages/websites/domain/components/style.ts @@ -0,0 +1,15 @@ +import { createStyles } from '@/theme' + +export const useStyle = createStyles(({ token, css, cx, prefixCls }, props: any) => { + const prefix = `${prefixCls}-${token?.proPrefix}-name-server-component` + + const container = css` + .green { + color: green; + } + ` + + return { + container: cx(prefix, props?.className, container), + } +}) \ No newline at end of file diff --git a/src/service/website/domain_group.ts b/src/service/website/domain_group.ts new file mode 100644 index 0000000..280e32b --- /dev/null +++ b/src/service/website/domain_group.ts @@ -0,0 +1,8 @@ +import { createCURD } from '@/service/base.ts' +import { WebSite } from '@/types/website/domain_group' + +const domain_group = { + ...createCURD('/website/group'), +} + +export default domain_group \ No newline at end of file diff --git a/src/service/websites.ts b/src/service/websites.ts index 01b1265..0faa708 100644 --- a/src/service/websites.ts +++ b/src/service/websites.ts @@ -1,7 +1,7 @@ import { createCURD } from '@/service/base.ts' import { WebSite } from '@/types' import request from '@/request.ts' -import { IWebsiteDomain } from '@/types/website/domain' +import { IWebsiteDomain, INameServer } from '@/types/website/domain' import { IWebsiteDnsRecords } from '@/types/website/record' import { IWebsiteDnsAccount } from '@/types/website/dns_account' @@ -32,9 +32,30 @@ const websitesServ = { }, domain: { ...createCURD('/website/domain'), + //remark + remark: async (params: { id: string, remark: string }) => { + return request.post('/website/domain/remark', params) + }, + //tag + tag: async (params: { id: string, tags: string}) => { + return request.post('/website/domain/tag', params) + }, + //binding + binding: async (params: { id:string , user_id: string }) => { + return request.post('/website/domain/binding', params) + }, + //group + group: async (params: { id: string[], group_id: string }) => { + return request.post('/website/domain/group', params) + }, + describeDomainNS: async (params: { id: number }) => { + return request.post('/website/domain/describe_domain_ns', params) + }, + }, record: { ...createCURD('/website/dns_records'), + // }, dnsAccount: { ...createCURD('/website/dns_account'), diff --git a/src/store/websites/dns_account.ts b/src/store/websites/dns_account.ts index 14239ff..5442105 100644 --- a/src/store/websites/dns_account.ts +++ b/src/store/websites/dns_account.ts @@ -50,7 +50,7 @@ export const websiteDnsAccountIdsAtom = atom([]) export const websiteDnsAccountAtom = atom(undefined as unknown as IWebsiteDnsAccount) export const websiteDnsAccountSearchAtom = atom({ - key: '', + // key: '', pageSize: 10, page: 1, } as SearchParams) diff --git a/src/store/websites/domain.ts b/src/store/websites/domain.ts index 467372c..ab0868c 100644 --- a/src/store/websites/domain.ts +++ b/src/store/websites/domain.ts @@ -16,10 +16,10 @@ export const websiteDomainIdAtom = atom(0) export const websiteDomainIdsAtom = atom([]) -export const websiteDomainAtom = atom(undefined as unknown as IWebsiteDomain ) +export const websiteDomainAtom = atom(undefined as unknown as IWebsiteDomain) export const websiteDomainSearchAtom = atom({ - key: '', + // key: '', pageSize: 10, page: 1, } as SearchParams) @@ -89,3 +89,81 @@ export const deleteWebsiteDomainAtom = atomWithMutation((get) => { } } }) + +//updateRemark +export const updateRemarkWebsiteDomainAtom = atomWithMutation((get) => { + return { + mutationKey: [ 'updateRemarkWebsiteDomain' ], + mutationFn: async (data) => { + return await websitesServ.domain.remark(data) + }, + onSuccess: (res) => { + message.success(t('message.editSuccess', '编辑成功')) + //更新列表 + get(queryClientAtom).invalidateQueries({ queryKey: [ 'websiteDomains', get(websiteDomainSearchAtom) ] }) + return res + } + } +}) + +//updateTag +export const updateTagWebsiteDomainAtom = atomWithMutation((get) => { + return { + mutationKey: [ 'updateTagWebsiteDomain' ], + mutationFn: async (data) => { + return await websitesServ.domain.tag(data) + }, + onSuccess: (res) => { + message.success(t('message.editSuccess', '编辑成功')) + //更新列表 + get(queryClientAtom).invalidateQueries({ queryKey: [ 'websiteDomains', get(websiteDomainSearchAtom) ] }) + return res + } + } +}) + +//updateBanding +export const updateBandingWebsiteDomainAtom = atomWithMutation((get) => { + return { + mutationKey: [ 'updateBandingWebsiteDomain' ], + mutationFn: async (data) => { + return await websitesServ.domain.binding(data) + }, + onSuccess: (res) => { + message.success(t('message.editSuccess', '编辑成功')) + //更新列表 + get(queryClientAtom).invalidateQueries({ queryKey: [ 'websiteDomains', get(websiteDomainSearchAtom) ] }) + return res + } + } +}) +//updateGroup +export const updateGroupWebsiteDomainAtom = atomWithMutation((get) => { + return { + mutationKey: [ 'updateGroupWebsiteDomain' ], + mutationFn: async (data) => { + return await websitesServ.domain.group(data) + }, + onSuccess: (res) => { + message.success(t('message.editSuccess', '编辑成功')) + //更新列表 + get(queryClientAtom).invalidateQueries({ queryKey: [ 'websiteDomains', get(websiteDomainSearchAtom) ] }) + return res + } + } +}) + + +//describeDomainNS +export const describeDomainNSAtom = (id: number) => atomWithQuery(() => { + return { + queryKey: [ 'describeDomainNS', id ], + queryFn: async ({ queryKey: [ , id ] }) => { + return await websitesServ.domain.describeDomainNS({ id: id as number }) + }, + select: (data) => { + return data.data + } + + } +}) diff --git a/src/store/websites/domain_groups.ts b/src/store/websites/domain_groups.ts new file mode 100644 index 0000000..51bffcc --- /dev/null +++ b/src/store/websites/domain_groups.ts @@ -0,0 +1,90 @@ +import { atom } from 'jotai' +import { IApiResult, IPage } from '@/global' +import { atomWithMutation, atomWithQuery, queryClientAtom } from 'jotai-tanstack-query' +import { message } from 'antd' +import { t } from 'i18next' +import { WebSite } from '@/types/website/domain_group' +import webSiteServ from '@/service/website/domain_group' + +type SearchParams = IPage & { + key?: string + + [key: string]: any +} + +export const domainGroupIdAtom = atom(0) + +export const domainGroupIdsAtom = atom([]) + +export const domainGroupAtom = atom(undefined as unknown as WebSite.IDomainGroup ) + +export const domainGroupSearchAtom = atom({ + key: '', + pageSize: 10, + page: 1, +} as SearchParams) + +export const domainGroupPageAtom = atom({ + pageSize: 10, + page: 1, +}) + +export const domainGroupsAtom = atomWithQuery((get) => { + return { + queryKey: [ 'domainGroups', get(domainGroupSearchAtom) ], + queryFn: async ({ queryKey: [ , params ] }) => { + return await webSiteServ.list(params as SearchParams) + }, + select: res => { + const data = res.data + data.rows = data.rows?.map(row => { + return { + ...row, + //status: convertToBool(row.status) + } + }) + return data + } + } +}) + +//saveOrUpdateAtom +export const saveOrUpdateDomainGroupAtom = atomWithMutation((get) => { + + return { + mutationKey: [ 'updateDomainGroup' ], + mutationFn: async (data) => { + //data.status = data.status ? '1' : '0' + if (data.id === 0) { + return await webSiteServ.add(data) + } + return await webSiteServ.update(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: [ 'domainGroups', get(domainGroupSearchAtom) ] }) + + return res + } + } +}) + +export const deleteDomainGroupAtom = atomWithMutation((get) => { + return { + mutationKey: [ 'deleteDomainGroup' ], + mutationFn: async (ids: number[]) => { + return await webSiteServ.batchDelete(ids ?? get(domainGroupIdsAtom)) + }, + onSuccess: (res) => { + message.success('message.deleteSuccess') + //更新列表 + get(queryClientAtom).invalidateQueries({ queryKey: [ 'domainGroups', get(domainGroupSearchAtom) ] }) + return res + } + } +}) diff --git a/src/theme/index.ts b/src/theme/index.ts index 723ef8d..f37b03d 100644 --- a/src/theme/index.ts +++ b/src/theme/index.ts @@ -1,4 +1,4 @@ -import { createInstance, } from 'antd-style' +import { createInstance, } from 'antd-style' import { ProThemeToken } from './themes' type ProToken = { @@ -19,8 +19,8 @@ const { createStyles, ThemeProvider } = createInstance({ export { createGlobalStyle, extractStaticStyle, - createStylish, - styleManager, + createStylish, + styleManager, css, cx, injectGlobal, diff --git a/src/types/website/domain.d.ts b/src/types/website/domain.d.ts index 4f25376..e71d606 100644 --- a/src/types/website/domain.d.ts +++ b/src/types/website/domain.d.ts @@ -10,3 +10,10 @@ export interface IWebsiteDomain { tag: string; remark: string; } + +export interface INameServer { + dnsServers: string[]; + expectDnsServers: string[] + success: boolean; + message: string +} diff --git a/src/types/website/domain_group.d.ts b/src/types/website/domain_group.d.ts new file mode 100644 index 0000000..64939f8 --- /dev/null +++ b/src/types/website/domain_group.d.ts @@ -0,0 +1,9 @@ +export namespace WebSite { + export interface IDomainGroup { + id: number; + user_id: number; + sort: number; + name: string; + created_at: string; + } +} \ No newline at end of file