perf(frontend): split admin bundles and tighten data fetching

Add next/dynamic lazy loading for database, logs, and settings heavy
modules; migrate access-logs and task-executions to React Query; parallelize
login auth-sources with public config; consolidate users table tooltips;
enable lazy image decoding; and replace barrel @/lib/services imports with
direct module paths.
This commit is contained in:
ryan
2026-06-17 12:12:47 +08:00
parent 9550fa6ff3
commit a44043262e
43 changed files with 752 additions and 695 deletions
@@ -33,7 +33,8 @@ import {LoadingStateWithBorder} from "@/components/layout/loading"
import {EmptyStateWithBorder} from "@/components/layout/empty"
import services from "@/lib/services"
import {AdminService} from "@/lib/services/admin"
import {PushService} from "@/lib/services/push"
import type {CreatePushEventRequest, PushEvent, UpdatePushEventRequest,} from "@/lib/services/push"
export function EventsTab() {
@@ -42,7 +43,7 @@ export function EventsTab() {
// --- 获取所有自定义消息通道 ---
const channelsQuery = useQuery({
queryKey: ["admin", "push-channels"],
queryFn: () => services.push.listChannels(),
queryFn: () => PushService.listChannels(),
})
const availableChannels = React.useMemo(() => {
@@ -55,23 +56,23 @@ export function EventsTab() {
// --- 获取通知事件 ---
const eventsQuery = useQuery({
queryKey: ["admin", "push-events"],
queryFn: () => services.push.listEvents(),
queryFn: () => PushService.listEvents(),
})
const builtInEventsQuery = useQuery({
queryKey: ["admin", "push-builtin-events"],
queryFn: () => services.push.listBuiltInEvents(),
queryFn: () => PushService.listBuiltInEvents(),
})
// --- 获取所有系统可调度任务类型 ---
const taskTypesQuery = useQuery({
queryKey: ["admin", "task-types"],
queryFn: () => services.admin.getTaskTypes(),
queryFn: () => AdminService.getTaskTypes(),
})
// --- 修改保存事件 Mutation ---
const updateEventMutation = useMutation({
mutationFn: ({ id, data }: { id: number; data: UpdatePushEventRequest }) => services.push.updateEvent(id, data),
mutationFn: ({ id, data }: { id: number; data: UpdatePushEventRequest }) => PushService.updateEvent(id, data),
onSuccess: () => {
toast.success("事件更新成功")
queryClient.invalidateQueries({ queryKey: ["admin", "push-events"] })
@@ -83,7 +84,7 @@ export function EventsTab() {
})
const toggleEventMutation = useMutation({
mutationFn: (id: number) => services.push.toggleEvent(id),
mutationFn: (id: number) => PushService.toggleEvent(id),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["admin", "push-events"] })
},
@@ -93,7 +94,7 @@ export function EventsTab() {
})
const createEventMutation = useMutation({
mutationFn: (data: CreatePushEventRequest) => services.push.createEvent(data),
mutationFn: (data: CreatePushEventRequest) => PushService.createEvent(data),
onSuccess: () => {
toast.success("事件创建成功")
queryClient.invalidateQueries({ queryKey: ["admin", "push-events"] })
@@ -110,7 +111,7 @@ export function EventsTab() {
})
const deleteEventMutation = useMutation({
mutationFn: (id: number) => services.push.deleteEvent(id),
mutationFn: (id: number) => PushService.deleteEvent(id),
onSuccess: () => {
toast.success("配置删除成功")
queryClient.invalidateQueries({ queryKey: ["admin", "push-events"] })
@@ -26,7 +26,7 @@ import {
DialogTitle,
} from "@/components/ui/dialog"
import services from "@/lib/services"
import {PushService} from "@/lib/services/push"
import type {PushHistory} from "@/lib/services/push"
function getLevelBadgeVariant(level: string): "outline" | "secondary" | "destructive" | "default" {
@@ -56,7 +56,7 @@ export function HistoriesTab() {
const historiesQuery = useQuery({
queryKey: ["admin", "push-histories", historyPage, historySearch, historyStatus],
queryFn: () =>
services.push.listHistories({
PushService.listHistories({
page: historyPage,
page_size: 10,
event_key: historySearch || undefined,
@@ -29,7 +29,7 @@ import {Select, SelectContent, SelectItem, SelectTrigger, SelectValue,} from "@/
import {ErrorInline} from "@/components/layout/error"
import {LoadingStateWithBorder} from "@/components/layout/loading"
import services from "@/lib/services"
import {PushService} from "@/lib/services/push"
import type {ChannelDefinition, CreateChannelRequest, PushChannel, UpdateChannelRequest} from "@/lib/services/push"
export function SettingsTab() {
@@ -38,19 +38,19 @@ export function SettingsTab() {
// --- 获取所有自定义消息通道 ---
const channelsQuery = useQuery({
queryKey: ["admin", "push-channels"],
queryFn: () => services.push.listChannels(),
queryFn: () => PushService.listChannels(),
})
// --- 获取动态通道表单字段定义 ---
const definitionsQuery = useQuery({
queryKey: ["admin", "push-channels-definitions"],
queryFn: () => services.push.listChannelDefinitions(),
queryFn: () => PushService.listChannelDefinitions(),
})
// --- 消息通道 CRUD Mutations ---
const createChannelMutation = useMutation({
mutationFn: (data: CreateChannelRequest) => services.push.createChannel(data),
mutationFn: (data: CreateChannelRequest) => PushService.createChannel(data),
onSuccess: () => {
toast.success("通道创建成功")
queryClient.invalidateQueries({ queryKey: ["admin", "push-channels"] })
@@ -63,7 +63,7 @@ export function SettingsTab() {
const updateChannelMutation = useMutation({
mutationFn: ({ id, data }: { id: number; data: UpdateChannelRequest }) =>
services.push.updateChannel(id, data),
PushService.updateChannel(id, data),
onSuccess: () => {
toast.success("通道更新成功")
queryClient.invalidateQueries({ queryKey: ["admin", "push-channels"] })
@@ -75,7 +75,7 @@ export function SettingsTab() {
})
const deleteChannelMutation = useMutation({
mutationFn: (id: number) => services.push.deleteChannel(id),
mutationFn: (id: number) => PushService.deleteChannel(id),
onSuccess: () => {
toast.success("通道删除成功")
queryClient.invalidateQueries({ queryKey: ["admin", "push-channels"] })
@@ -237,7 +237,7 @@ export function SettingsTab() {
try {
setIsTestingChannel(true)
toast.info("正在发送测试推送...")
await services.push.testChannel({
await PushService.testChannel({
name: testChannelName,
target: testChannelTarget || undefined,
})