fix(workspace): 兼容成员ID匹配与我相关任务
This commit is contained in:
@@ -77,8 +77,10 @@ export default function WorkspacePage() {
|
|||||||
useEffect(() => { fetchWorklogs(); }, [fetchWorklogs]);
|
useEffect(() => { fetchWorklogs(); }, [fetchWorklogs]);
|
||||||
useEffect(() => { fetchActivities(); }, [fetchActivities]);
|
useEffect(() => { fetchActivities(); }, [fetchActivities]);
|
||||||
|
|
||||||
|
const userId = user?.id ?? '';
|
||||||
const userName = user?.name ?? '';
|
const userName = user?.name ?? '';
|
||||||
const workspaceUserKey = userName || user?.id || '';
|
const workspaceUserKey = userId || userName;
|
||||||
|
const workspaceUserRefs = useMemo(() => [userName, userId].filter(Boolean), [userId, userName]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!workspaceUserKey.trim()) {
|
if (!workspaceUserKey.trim()) {
|
||||||
@@ -151,7 +153,7 @@ export default function WorkspacePage() {
|
|||||||
|
|
||||||
const workItems = useMemo(() =>
|
const workItems = useMemo(() =>
|
||||||
aggregateWorkItems(
|
aggregateWorkItems(
|
||||||
userName,
|
workspaceUserRefs,
|
||||||
workspaceCollections.versionPlans,
|
workspaceCollections.versionPlans,
|
||||||
workspaceCollections.devTasks,
|
workspaceCollections.devTasks,
|
||||||
workspaceCollections.testCases,
|
workspaceCollections.testCases,
|
||||||
@@ -159,7 +161,7 @@ export default function WorkspacePage() {
|
|||||||
versionMap,
|
versionMap,
|
||||||
requirementVersionMap,
|
requirementVersionMap,
|
||||||
),
|
),
|
||||||
[userName, workspaceCollections, versionMap, requirementVersionMap]
|
[workspaceUserRefs, workspaceCollections, versionMap, requirementVersionMap]
|
||||||
);
|
);
|
||||||
const pendingCountByVersion = useMemo(() => getWorkspacePendingCountByVersion(workItems), [workItems]);
|
const pendingCountByVersion = useMemo(() => getWorkspacePendingCountByVersion(workItems), [workItems]);
|
||||||
|
|
||||||
@@ -198,10 +200,10 @@ export default function WorkspacePage() {
|
|||||||
activities,
|
activities,
|
||||||
worklogs,
|
worklogs,
|
||||||
workItems,
|
workItems,
|
||||||
userId: userName,
|
userId: userName || userId,
|
||||||
date: today,
|
date: today,
|
||||||
}),
|
}),
|
||||||
[activities, worklogs, workItems, userName, today]
|
[activities, userId, worklogs, workItems, userName, today]
|
||||||
);
|
);
|
||||||
|
|
||||||
// 待办数量按 tab 分(受 version filter 影响)
|
// 待办数量按 tab 分(受 version filter 影响)
|
||||||
|
|||||||
@@ -27,8 +27,10 @@ export function useWorkspaceWorkItems({ autoFetch = true }: { autoFetch?: boolea
|
|||||||
|
|
||||||
useEffect(() => { if (autoFetch) fetchOverview(); }, [autoFetch, fetchOverview]);
|
useEffect(() => { if (autoFetch) fetchOverview(); }, [autoFetch, fetchOverview]);
|
||||||
|
|
||||||
|
const userId = user?.id ?? '';
|
||||||
const userName = user?.name ?? '';
|
const userName = user?.name ?? '';
|
||||||
const workspaceUserKey = userName || user?.id || '';
|
const workspaceUserKey = userId || userName;
|
||||||
|
const workspaceUserRefs = useMemo(() => [userName, userId].filter(Boolean), [userId, userName]);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!autoFetch || !workspaceUserKey.trim()) {
|
if (!autoFetch || !workspaceUserKey.trim()) {
|
||||||
setV22WorkspaceData(null);
|
setV22WorkspaceData(null);
|
||||||
@@ -110,7 +112,7 @@ export function useWorkspaceWorkItems({ autoFetch = true }: { autoFetch?: boolea
|
|||||||
|
|
||||||
const workItems = useMemo(
|
const workItems = useMemo(
|
||||||
() => aggregateWorkItems(
|
() => aggregateWorkItems(
|
||||||
userName,
|
workspaceUserRefs,
|
||||||
workspaceCollections.versionPlans,
|
workspaceCollections.versionPlans,
|
||||||
workspaceCollections.devTasks,
|
workspaceCollections.devTasks,
|
||||||
workspaceCollections.testCases,
|
workspaceCollections.testCases,
|
||||||
@@ -118,7 +120,7 @@ export function useWorkspaceWorkItems({ autoFetch = true }: { autoFetch?: boolea
|
|||||||
versionMap,
|
versionMap,
|
||||||
requirementVersionMap,
|
requirementVersionMap,
|
||||||
),
|
),
|
||||||
[userName, workspaceCollections, versionMap, requirementVersionMap],
|
[workspaceUserRefs, workspaceCollections, versionMap, requirementVersionMap],
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -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].versionId, 'ver-1');
|
||||||
assert.equal(items[0].versionName, 'V1.0');
|
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 产品方案');
|
||||||
|
});
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ interface VersionContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function aggregateWorkItems(
|
export function aggregateWorkItems(
|
||||||
userName: string,
|
userRef: string | string[],
|
||||||
plans: VersionPlan[],
|
plans: VersionPlan[],
|
||||||
devTasks: DevTask[],
|
devTasks: DevTask[],
|
||||||
testCases: TestCase[],
|
testCases: TestCase[],
|
||||||
@@ -37,10 +37,12 @@ export function aggregateWorkItems(
|
|||||||
requirementVersionMap: Map<string, string>,
|
requirementVersionMap: Map<string, string>,
|
||||||
): WorkItem[] {
|
): WorkItem[] {
|
||||||
const items: 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: owner matches the current user's name or stable member id.
|
||||||
plans.filter((p) => p.owner === userName).forEach((p) => {
|
plans.filter((p) => isCurrentUser(p.owner)).forEach((p) => {
|
||||||
const ver = versionMap.get(p.versionId);
|
const ver = versionMap.get(p.versionId);
|
||||||
items.push({
|
items.push({
|
||||||
id: p.id,
|
id: p.id,
|
||||||
@@ -57,8 +59,8 @@ export function aggregateWorkItems(
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// DevTasks: assigneeId === userName
|
// DevTasks: assignee matches the current user's name or stable member id.
|
||||||
devTasks.filter((t) => t.assigneeId === userName).forEach((t) => {
|
devTasks.filter((t) => isCurrentUser(t.assigneeId)).forEach((t) => {
|
||||||
const versionId = t.versionId || requirementVersionMap.get(t.requirementId) || '';
|
const versionId = t.versionId || requirementVersionMap.get(t.requirementId) || '';
|
||||||
const ver = versionMap.get(versionId);
|
const ver = versionMap.get(versionId);
|
||||||
items.push({
|
items.push({
|
||||||
@@ -83,8 +85,8 @@ export function aggregateWorkItems(
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// TestCases: assigneeId === userName
|
// TestCases: assignee matches the current user's name or stable member id.
|
||||||
testCases.filter((c) => c.assigneeId === userName).forEach((c) => {
|
testCases.filter((c) => isCurrentUser(c.assigneeId)).forEach((c) => {
|
||||||
const ver = versionMap.get(c.versionId);
|
const ver = versionMap.get(c.versionId);
|
||||||
items.push({
|
items.push({
|
||||||
id: c.id,
|
id: c.id,
|
||||||
@@ -102,8 +104,8 @@ export function aggregateWorkItems(
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Bugs: assigneeId === userName
|
// Bugs: assignee matches the current user's name or stable member id.
|
||||||
bugs.filter((b) => b.assigneeId === userName).forEach((b) => {
|
bugs.filter((b) => isCurrentUser(b.assigneeId)).forEach((b) => {
|
||||||
const ver = versionMap.get(b.versionId);
|
const ver = versionMap.get(b.versionId);
|
||||||
items.push({
|
items.push({
|
||||||
id: b.id,
|
id: b.id,
|
||||||
@@ -124,6 +126,11 @@ export function aggregateWorkItems(
|
|||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function normalizeUserRefs(userRef: string | string[]): Set<string> {
|
||||||
|
const refs = Array.isArray(userRef) ? userRef : [userRef];
|
||||||
|
return new Set(refs.map((ref) => ref.trim()).filter(Boolean));
|
||||||
|
}
|
||||||
|
|
||||||
export function getWorkspacePendingCount(items: ReadonlyArray<Pick<WorkItem, 'completed'>>): number {
|
export function getWorkspacePendingCount(items: ReadonlyArray<Pick<WorkItem, 'completed'>>): number {
|
||||||
return items.reduce((sum, item) => sum + (item.completed ? 0 : 1), 0);
|
return items.reduce((sum, item) => sum + (item.completed ? 0 : 1), 0);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user