'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 { 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, 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 requirementVersionMap = useMemo(() => { const map = new Map(); requirements.forEach((requirement) => { if (requirement.versionId) map.set(requirement.id, requirement.versionId); }); return map; }, [requirements]); const workItems = useMemo(() => buildXiaobaoWorkItems({ plans, devTasks, testCases, bugs, versions: allVersions.map((version) => ({ id: version.id, name: version.name, productName: version.productName, projectName: version.projectName, })), requirementVersionMap, }), [allVersions, bugs, devTasks, plans, requirementVersionMap, testCases]); const risks = useMemo(() => visibleVersions.map((version) => { const versionRequirements = requirements.filter((requirement) => requirement.versionId === version.id); const requirementIds = new Set(versionRequirements.map((requirement) => requirement.id)); const dailyEvidence = buildVersionDailyEvidence({ versionId: version.id, workItems, activities, worklogs, }); return calcXiaobaoVersionRisk({ version, devTasks: devTasks.filter((task) => requirementIds.has(task.requirementId)), testCases: testCases.filter((testCase) => testCase.versionId === version.id), bugs: bugs.filter((bug) => bug.versionId === version.id), 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, bugs, devTasks, requirements, testCases, visibleVersions, workItems, worklogs, snapshots, today, calculationNow, ]); return { risks, snapshots, insights, pendingInsightKeys, riskDataLoaded, saveSnapshot, saveInsight, beginInsightUpdate, finishInsightUpdate, today, }; }