'use client'; import { useEffect, useMemo, useState } from 'react'; import { useHasPermission } from '@/components/auth/Guard'; import { useAuthStore } from '@/stores/useAuthStore'; import { useBugStore } from '@/stores/useBugStore'; import { useDevTaskStore } from '@/stores/useDevTaskStore'; import { useProductStore } from '@/stores/useProductStore'; import { useRequirementStore } from '@/stores/useRequirementStore'; import { useTaskWorklogStore } from '@/stores/useTaskWorklogStore'; import { useTestCaseStore } from '@/stores/useTestCaseStore'; import { useVersionPlanStore } from '@/stores/useVersionPlanStore'; import { useWorkActivityStore } from '@/stores/useWorkActivityStore'; import { useXiaobaoRiskStore } from '@/stores/useXiaobaoRiskStore'; import { flattenVersions } from '@/lib/derive'; import { buildVersionDataScopeMap } from '@/lib/version-data-scope'; import { calcXiaobaoVersionRisk } from '@/lib/xiaobao-risk'; import { buildVersionDailyEvidence, buildXiaobaoWorkItems } from '@/lib/xiaobao-risk-evidence'; import { filterXiaobaoWarningVersions } from '@/lib/xiaobao-warning-view'; export function useXiaobaoWarningRisks({ loadRiskCache = false }: { loadRiskCache?: boolean } = {}) { const canManage = useHasPermission('xiaobao.warning:manage'); const user = useAuthStore((s) => s.user); const { overview, fetchOverview } = useProductStore(); const { plans, fetchPlans } = useVersionPlanStore(); const { requirements, fetchRequirements } = useRequirementStore(); const { tasks: devTasks, fetchTasks } = useDevTaskStore(); const { testCases, fetchTestCases } = useTestCaseStore(); const { bugs, fetchBugs } = useBugStore(); const { activities, fetchActivities } = useWorkActivityStore(); const { worklogs, fetchWorklogs } = useTaskWorklogStore(); const { snapshots, insights, pendingInsightKeys, insightRequestAttempts, riskDataLoaded, fetchRiskData, saveSnapshot, saveInsight, beginInsightUpdate, finishInsightUpdate, } = useXiaobaoRiskStore(); const [calculationNow] = useState(() => new Date()); const today = useMemo(() => new Date().toISOString().slice(0, 10), []); useEffect(() => { fetchOverview(); }, [fetchOverview]); useEffect(() => { fetchPlans(); }, [fetchPlans]); useEffect(() => { fetchRequirements(); }, [fetchRequirements]); useEffect(() => { fetchTasks(); }, [fetchTasks]); useEffect(() => { fetchTestCases(); }, [fetchTestCases]); useEffect(() => { fetchBugs(); }, [fetchBugs]); useEffect(() => { fetchActivities(); }, [fetchActivities]); useEffect(() => { fetchWorklogs(); }, [fetchWorklogs]); useEffect(() => { if (loadRiskCache) fetchRiskData(); }, [fetchRiskData, loadRiskCache]); const allVersions = useMemo(() => flattenVersions(overview), [overview]); const visibleVersions = useMemo( () => filterXiaobaoWarningVersions(allVersions, { canManage, userName: user?.name }), [allVersions, canManage, user?.name], ); const visibleVersionScopeMap = useMemo(() => buildVersionDataScopeMap({ versionIds: visibleVersions.map((version) => version.id), plans, requirements, devTasks, testCases, bugs, }), [bugs, devTasks, plans, requirements, testCases, visibleVersions]); const workItemsByVersion = useMemo(() => { const map = new Map>(); for (const version of visibleVersions) { const scope = visibleVersionScopeMap[version.id]; if (!scope) continue; map.set(version.id, buildXiaobaoWorkItems({ plans: scope.plans, devTasks: scope.devTasks, testCases: scope.testCases, bugs: scope.bugs, versions: [{ id: version.id, name: version.name, productName: version.productName, projectName: version.projectName, }], requirementVersionMap: new Map(scope.requirements.map((requirement) => [requirement.id, version.id])), })); } return map; }, [visibleVersionScopeMap, visibleVersions]); const risks = useMemo(() => visibleVersions.map((version) => { const scope = visibleVersionScopeMap[version.id]; const workItems = workItemsByVersion.get(version.id) ?? []; const dailyEvidence = buildVersionDailyEvidence({ versionId: version.id, workItems, activities, worklogs, }); return calcXiaobaoVersionRisk({ version, devTasks: scope?.devTasks ?? [], testCases: scope?.testCases ?? [], bugs: scope?.bugs ?? [], dailyEvidence, recentActivityCount: dailyEvidence.recentActivityCount, lastActivityAt: dailyEvidence.lastActivityAt, snapshots: snapshots.filter((snapshot) => snapshot.versionId === version.id && snapshot.date < today), now: calculationNow, }); }).sort((a, b) => b.riskScore - a.riskScore), [ activities, visibleVersionScopeMap, visibleVersions, workItemsByVersion, worklogs, snapshots, today, calculationNow, ]); return { risks, snapshots, insights, pendingInsightKeys, insightRequestAttempts, riskDataLoaded, saveSnapshot, saveInsight, beginInsightUpdate, finishInsightUpdate, today, }; }