feat: 优化项目目录结构

This commit is contained in:
2025-12-12 17:25:26 +08:00
parent ae627d0496
commit b89f83291e
235 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,33 @@
"use client"
import { list, UserListParams, UserListResponse } from '@/lib/api/admin/user'
import { useCallback } from 'react'
import { toast } from 'sonner'
import useSWR from 'swr'
export function useUserList(params?: UserListParams) {
const { data, error, isLoading, mutate } = useSWR<UserListResponse>(
['/api/admin/user', params],
() => list(params),
{
onError: (e) => {
toast.error(`${e.message || e}`)
}
}
)
const refresh = useCallback(() => {
return mutate()
}, [mutate])
return {
users: data?.items ?? [],
total: data?.total ?? 0,
page: data?.page ?? 1,
pageSize: data?.pageSize ?? 20,
isLoading,
error,
mutate,
refresh,
}
}

View File

@@ -0,0 +1,26 @@
import { AdminApi } from "@/lib/api";
import { User } from "@/lib/types/user";
import { toast } from "sonner";
import useSWR from "swr";
export function useUser(userId: string) {
const { data, error, isLoading, mutate } = useSWR<User>(
['/api/admin/user', userId],
() => AdminApi.user.get(userId),
{
revalidateOnReconnect: false,
revalidateIfStale: false,
dedupingInterval: 0,
onError: (e) => {
toast.error(`${e.message || e}`)
}
}
)
return {
user: data,
isLoading,
error,
mutate,
}
}

View File

@@ -0,0 +1,30 @@
"use client"
import { AdminApi } from "@/lib/api";
import { useCallback } from "react";
import { toast } from "sonner";
import useSWR from "swr";
export function useBlogList() {
const { data, error, isLoading, mutate } = useSWR(
['/admin/web/blog'],
() => AdminApi.web.blog.list(),
{
onError: (e) => {
toast.error(`${e.message || e}`)
}
}
)
const refresh = useCallback(() => {
return mutate()
}, [mutate])
return {
blogs: data,
error,
isLoading,
mutate,
refresh,
}
}

View File

@@ -0,0 +1,22 @@
import { useOssSts } from "@/hooks/oss/use-oss-sts";
import { StsToken } from "@/lib/api/oss";
import { useEffect } from "react";
export function useOssStore(options: { onStsTokenDataChanged?: (data: StsToken | undefined) => void; } = {}) {
const { stsTokenData, isLoading, error, mutate } = useOssSts();
useEffect(() => {
options.onStsTokenDataChanged?.(stsTokenData);
}, [stsTokenData]);
const refresh = async () => {
await mutate();
}
return {
stsTokenData,
isLoading,
error,
refresh,
}
}

View File

@@ -0,0 +1,30 @@
"use client"
import { AdminApi } from "@/lib/api";
import { useCallback } from "react";
import { toast } from "sonner";
import useSWR from "swr";
export function useResourceList() {
const { data, error, isLoading, mutate } = useSWR(
['/admin/web/resource'],
() => AdminApi.web.resource.list(),
{
onError: (e) => {
toast.error(`${e.message || e}`)
}
}
)
const refresh = useCallback(() => {
return mutate()
}, [mutate])
return {
resources: data,
error,
isLoading,
mutate,
refresh,
}
}

View File

@@ -0,0 +1,25 @@
import { OssApi } from "@/lib/api";
import { toast } from "sonner";
import useSWR from "swr";
export function useOssSts() {
const { data: stsTokenData, isLoading, error, mutate } = useSWR(
'/api/oss/sts',
() => OssApi.getStsToken(),
{
shouldRetryOnError: false,
// refreshInterval: 59 * 60 * 1000,
revalidateOnFocus: false,
onError: (e) => {
toast.error(`${e.message || e}`)
}
}
);
return {
stsTokenData,
isLoading,
error,
mutate,
}
}

View File

@@ -0,0 +1,19 @@
import * as React from "react"
const MOBILE_BREAKPOINT = 768
export function useIsMobile() {
const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined)
React.useEffect(() => {
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`)
const onChange = () => {
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
}
mql.addEventListener("change", onChange)
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
return () => mql.removeEventListener("change", onChange)
}, [])
return !!isMobile
}

View File

@@ -0,0 +1,41 @@
import { UserApi } from "@/lib/api";
import useSWR from "swr";
export function useUserMe({ onError }: { onError?: (e: any) => void } = {}) {
const isClientSide = typeof window !== 'undefined';
const { data: user, isLoading, error } = useSWR(
'/api/user/me',
async () => {
if (isClientSide && !localStorage.getItem('token')) {
throw Object.assign(new Error('未登录'), { statusCode: -1 });
}
return await UserApi.me();
},
{
onError: (error) => {
if (error.statusCode === 401) {
if (isClientSide) {
localStorage.removeItem('token');
}
}
onError?.(error);
},
revalidateIfStale: false,
revalidateOnFocus: false,
shouldRetryOnError: (err) => {
if ([-1, 401].includes(err.statusCode)) {
return false;
}
return true;
},
}
);
return {
user,
isLoading,
error
}
}