useNodeMutations.ts 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. import { useMutation, useQueryClient } from '@tanstack/react-query';
  2. import { HttpUtil, Msg } from '@/utils';
  3. import { parseMsg } from '@/utils/zodValidate';
  4. import { keys } from '@/api/queryKeys';
  5. import type { NodeRecord } from '@/api/queries/useNodesQuery';
  6. import { ProbeResultSchema, type ProbeResult } from '@/schemas/node';
  7. export type { ProbeResult };
  8. export interface NodeUpdateResult {
  9. id: number;
  10. name?: string;
  11. ok: boolean;
  12. error?: string;
  13. }
  14. export interface RemoteInboundOption {
  15. tag: string;
  16. remark?: string;
  17. protocol?: string;
  18. port?: number;
  19. }
  20. export function useNodeMutations() {
  21. const queryClient = useQueryClient();
  22. const invalidate = () => {
  23. queryClient.invalidateQueries({ queryKey: keys.nodes.root() });
  24. queryClient.invalidateQueries({ queryKey: keys.inbounds.options() });
  25. };
  26. const createMut = useMutation({
  27. mutationFn: (payload: Partial<NodeRecord>) =>
  28. HttpUtil.post('/panel/api/nodes/add', payload),
  29. onSuccess: (msg) => { if (msg?.success) invalidate(); },
  30. });
  31. const updateMut = useMutation({
  32. mutationFn: ({ id, payload }: { id: number; payload: Partial<NodeRecord> }) =>
  33. HttpUtil.post(`/panel/api/nodes/update/${id}`, payload),
  34. onSuccess: (msg) => { if (msg?.success) invalidate(); },
  35. });
  36. const removeMut = useMutation({
  37. mutationFn: (id: number) =>
  38. HttpUtil.post(`/panel/api/nodes/del/${id}`),
  39. onSuccess: (msg) => { if (msg?.success) invalidate(); },
  40. });
  41. const setEnableMut = useMutation({
  42. mutationFn: ({ id, enable }: { id: number; enable: boolean }) =>
  43. HttpUtil.post(`/panel/api/nodes/setEnable/${id}`, { enable }),
  44. onSuccess: (msg) => { if (msg?.success) invalidate(); },
  45. });
  46. const probeMut = useMutation({
  47. mutationFn: async (id: number): Promise<Msg<ProbeResult>> => {
  48. const raw = await HttpUtil.post(`/panel/api/nodes/probe/${id}`);
  49. return parseMsg(raw, ProbeResultSchema, 'nodes/probe');
  50. },
  51. onSuccess: (msg) => { if (msg?.success) invalidate(); },
  52. });
  53. const updatePanelsMut = useMutation({
  54. mutationFn: ({ ids, dev }: { ids: number[]; dev: boolean }) =>
  55. HttpUtil.post<NodeUpdateResult[]>('/panel/api/nodes/updatePanel', { ids, dev }, {
  56. headers: { 'Content-Type': 'application/json' },
  57. }),
  58. onSuccess: (msg) => { if (msg?.success) invalidate(); },
  59. });
  60. return {
  61. create: (payload: Partial<NodeRecord>) => createMut.mutateAsync(payload),
  62. update: (id: number, payload: Partial<NodeRecord>) => updateMut.mutateAsync({ id, payload }),
  63. remove: (id: number) => removeMut.mutateAsync(id),
  64. setEnable: (id: number, enable: boolean) => setEnableMut.mutateAsync({ id, enable }),
  65. probe: (id: number) => probeMut.mutateAsync(id),
  66. updatePanels: (ids: number[], dev: boolean): Promise<Msg<NodeUpdateResult[]>> => updatePanelsMut.mutateAsync({ ids, dev }),
  67. testConnection: async (payload: Partial<NodeRecord>): Promise<Msg<ProbeResult>> => {
  68. const raw = await HttpUtil.post('/panel/api/nodes/test', payload);
  69. return parseMsg(raw, ProbeResultSchema, 'nodes/test');
  70. },
  71. fetchFingerprint: (payload: Partial<NodeRecord>): Promise<Msg<string>> =>
  72. HttpUtil.post<string>('/panel/api/nodes/certFingerprint', payload),
  73. fetchInbounds: (payload: Partial<NodeRecord>): Promise<Msg<RemoteInboundOption[]>> =>
  74. HttpUtil.post<RemoteInboundOption[]>('/panel/api/nodes/inbounds', payload),
  75. };
  76. }