From b170ac9caf9e812db5531d15a3dc1b324ccc18cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=80=82?= Date: Mon, 6 Jul 2026 11:22:43 +0800 Subject: [PATCH] =?UTF-8?q?fix(workspace):=20=E5=85=BC=E5=AE=B9=E6=88=90?= =?UTF-8?q?=E5=91=98ID=E5=8C=B9=E9=85=8D=E4=B8=8E=E6=88=91=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E4=BB=BB=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web/app/workspace/page.tsx | 12 ++++++----- apps/web/hooks/useWorkspaceWorkItems.ts | 8 +++++--- apps/web/lib/workspace-engine.test.ts | 27 +++++++++++++++++++++++++ apps/web/lib/workspace-engine.ts | 27 ++++++++++++++++--------- 4 files changed, 56 insertions(+), 18 deletions(-) diff --git a/apps/web/app/workspace/page.tsx b/apps/web/app/workspace/page.tsx index d231b6d..dff30e2 100644 --- a/apps/web/app/workspace/page.tsx +++ b/apps/web/app/workspace/page.tsx @@ -77,8 +77,10 @@ export default function WorkspacePage() { useEffect(() => { fetchWorklogs(); }, [fetchWorklogs]); useEffect(() => { fetchActivities(); }, [fetchActivities]); + const userId = user?.id ?? ''; const userName = user?.name ?? ''; - const workspaceUserKey = userName || user?.id || ''; + const workspaceUserKey = userId || userName; + const workspaceUserRefs = useMemo(() => [userName, userId].filter(Boolean), [userId, userName]); useEffect(() => { if (!workspaceUserKey.trim()) { @@ -151,7 +153,7 @@ export default function WorkspacePage() { const workItems = useMemo(() => aggregateWorkItems( - userName, + workspaceUserRefs, workspaceCollections.versionPlans, workspaceCollections.devTasks, workspaceCollections.testCases, @@ -159,7 +161,7 @@ export default function WorkspacePage() { versionMap, requirementVersionMap, ), - [userName, workspaceCollections, versionMap, requirementVersionMap] + [workspaceUserRefs, workspaceCollections, versionMap, requirementVersionMap] ); const pendingCountByVersion = useMemo(() => getWorkspacePendingCountByVersion(workItems), [workItems]); @@ -198,10 +200,10 @@ export default function WorkspacePage() { activities, worklogs, workItems, - userId: userName, + userId: userName || userId, date: today, }), - [activities, worklogs, workItems, userName, today] + [activities, userId, worklogs, workItems, userName, today] ); // 待办数量按 tab 分(受 version filter 影响) diff --git a/apps/web/hooks/useWorkspaceWorkItems.ts b/apps/web/hooks/useWorkspaceWorkItems.ts index 25e00eb..2b0dad6 100644 --- a/apps/web/hooks/useWorkspaceWorkItems.ts +++ b/apps/web/hooks/useWorkspaceWorkItems.ts @@ -27,8 +27,10 @@ export function useWorkspaceWorkItems({ autoFetch = true }: { autoFetch?: boolea useEffect(() => { if (autoFetch) fetchOverview(); }, [autoFetch, fetchOverview]); + const userId = user?.id ?? ''; const userName = user?.name ?? ''; - const workspaceUserKey = userName || user?.id || ''; + const workspaceUserKey = userId || userName; + const workspaceUserRefs = useMemo(() => [userName, userId].filter(Boolean), [userId, userName]); useEffect(() => { if (!autoFetch || !workspaceUserKey.trim()) { setV22WorkspaceData(null); @@ -110,7 +112,7 @@ export function useWorkspaceWorkItems({ autoFetch = true }: { autoFetch?: boolea const workItems = useMemo( () => aggregateWorkItems( - userName, + workspaceUserRefs, workspaceCollections.versionPlans, workspaceCollections.devTasks, workspaceCollections.testCases, @@ -118,7 +120,7 @@ export function useWorkspaceWorkItems({ autoFetch = true }: { autoFetch?: boolea versionMap, requirementVersionMap, ), - [userName, workspaceCollections, versionMap, requirementVersionMap], + [workspaceUserRefs, workspaceCollections, versionMap, requirementVersionMap], ); return { diff --git a/apps/web/lib/workspace-engine.test.ts b/apps/web/lib/workspace-engine.test.ts index 37df64b..08b4407 100644 --- a/apps/web/lib/workspace-engine.test.ts +++ b/apps/web/lib/workspace-engine.test.ts @@ -91,3 +91,30 @@ test('aggregateWorkItems uses direct version id for no-requirement dev tasks', ( assert.equal(items[0].versionId, 'ver-1'); assert.equal(items[0].versionName, 'V1.0'); }); + +test('aggregateWorkItems matches V2.2 member ids as current user references', () => { + const items = aggregateWorkItems( + ['超级管理员', 'm-8'], + [{ + id: 'plan-1', + versionId: 'ver-1', + type: 'product', + title: '案例学习 V1.3 产品方案', + owner: 'm-8', + startTime: '2026-07-06T09:00:00.000Z', + endTime: '2026-07-06T18:00:00.000Z', + status: 'pending', + tasks: [], + createdAt: '2026-07-06T09:00:00.000Z', + } as any], + [], + [], + [], + new Map([['ver-1', { id: 'ver-1', name: '案例学习V1.3', productName: '案例学习', projectName: '案例学习' }]]), + new Map(), + ); + + assert.equal(items.length, 1); + assert.equal(items[0].type, 'plan_product'); + assert.equal(items[0].title, '案例学习 V1.3 产品方案'); +}); diff --git a/apps/web/lib/workspace-engine.ts b/apps/web/lib/workspace-engine.ts index 7c41b58..cde74dc 100644 --- a/apps/web/lib/workspace-engine.ts +++ b/apps/web/lib/workspace-engine.ts @@ -28,7 +28,7 @@ interface VersionContext { } export function aggregateWorkItems( - userName: string, + userRef: string | string[], plans: VersionPlan[], devTasks: DevTask[], testCases: TestCase[], @@ -37,10 +37,12 @@ export function aggregateWorkItems( requirementVersionMap: Map, ): WorkItem[] { const items: WorkItem[] = []; - if (!userName.trim()) return items; + const userRefs = normalizeUserRefs(userRef); + if (userRefs.size === 0) return items; + const isCurrentUser = (value?: string | null): boolean => Boolean(value && userRefs.has(value)); - // Plans: owner === userName - plans.filter((p) => p.owner === userName).forEach((p) => { + // Plans: owner matches the current user's name or stable member id. + plans.filter((p) => isCurrentUser(p.owner)).forEach((p) => { const ver = versionMap.get(p.versionId); items.push({ id: p.id, @@ -57,8 +59,8 @@ export function aggregateWorkItems( }); }); - // DevTasks: assigneeId === userName - devTasks.filter((t) => t.assigneeId === userName).forEach((t) => { + // DevTasks: assignee matches the current user's name or stable member id. + devTasks.filter((t) => isCurrentUser(t.assigneeId)).forEach((t) => { const versionId = t.versionId || requirementVersionMap.get(t.requirementId) || ''; const ver = versionMap.get(versionId); items.push({ @@ -83,8 +85,8 @@ export function aggregateWorkItems( }); }); - // TestCases: assigneeId === userName - testCases.filter((c) => c.assigneeId === userName).forEach((c) => { + // TestCases: assignee matches the current user's name or stable member id. + testCases.filter((c) => isCurrentUser(c.assigneeId)).forEach((c) => { const ver = versionMap.get(c.versionId); items.push({ id: c.id, @@ -102,8 +104,8 @@ export function aggregateWorkItems( }); }); - // Bugs: assigneeId === userName - bugs.filter((b) => b.assigneeId === userName).forEach((b) => { + // Bugs: assignee matches the current user's name or stable member id. + bugs.filter((b) => isCurrentUser(b.assigneeId)).forEach((b) => { const ver = versionMap.get(b.versionId); items.push({ id: b.id, @@ -124,6 +126,11 @@ export function aggregateWorkItems( return items; } +function normalizeUserRefs(userRef: string | string[]): Set { + const refs = Array.isArray(userRef) ? userRef : [userRef]; + return new Set(refs.map((ref) => ref.trim()).filter(Boolean)); +} + export function getWorkspacePendingCount(items: ReadonlyArray>): number { return items.reduce((sum, item) => sum + (item.completed ? 0 : 1), 0); }