Files
NextEdu/src/modules/diagnostic/services/diagnostic-service-context.tsx
SpecialX b63d116b6c feat(diagnostic): refactor services with monitor and context providers
- Update default-diagnostic-service.ts

- Update diagnostic-monitor-context.tsx

- Update diagnostic-service-context.tsx

- Update monitored-diagnostic-service.ts

- Update teacher diagnostic page
2026-07-04 10:22:48 +08:00

62 lines
1.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client"
import { createContext, useContext, useMemo, type ReactNode } from "react"
import type { DiagnosticService } from "./diagnostic-service"
import { defaultDiagnosticService } from "./default-diagnostic-service"
import { createMonitoredDiagnosticService } from "./monitored-diagnostic-service"
import { noopDiagnosticMonitor } from "./diagnostic-monitor"
import { useDiagnosticMonitor } from "./diagnostic-monitor-context"
/**
* v2-P1-4: 诊断模块服务 Context。
*
* 组件通过 useDiagnosticService() 获取服务实现,
* 而非直接 import actions实现依赖反转。
*
* 默认由 DiagnosticServiceProvider 在客户端组装默认实现(调用 Server Actions
* 测试时可注入 mock 实现以隔离组件测试。
*/
const DiagnosticServiceContext = createContext<DiagnosticService | null>(null)
interface DiagnosticServiceProviderProps {
/** 可选自定义服务实现,未传则使用 defaultDiagnosticService + 监控包装 */
service?: DiagnosticService
children: ReactNode
}
export function DiagnosticServiceProvider({
service,
children,
}: DiagnosticServiceProviderProps): ReactNode {
const monitor = useDiagnosticMonitor()
const value = useMemo<DiagnosticService>(() => {
if (service) return service
// 客户端组装:默认 service + 监控埋点包装
return createMonitoredDiagnosticService(
defaultDiagnosticService,
monitor ?? noopDiagnosticMonitor,
)
}, [service, monitor])
return (
<DiagnosticServiceContext.Provider value={value}>
{children}
</DiagnosticServiceContext.Provider>
)
}
/**
* 获取诊断模块服务。
* 必须在 DiagnosticServiceProvider 内部使用。
*/
export function useDiagnosticService(): DiagnosticService {
const service = useContext(DiagnosticServiceContext)
if (!service) {
throw new Error(
"useDiagnosticService must be used within a DiagnosticServiceProvider",
)
}
return service
}