Login syncs projects from GET /api/v1/projects; create project uses POST with server-assigned id while preserving local sessions and templates. Co-authored-by: Cursor <cursoragent@cursor.com>
60 lines
1.8 KiB
TypeScript
60 lines
1.8 KiB
TypeScript
import { Project } from '../types/projectWorkflow';
|
|
import { ProjectInfo, ProjectMember } from '../types/workbench';
|
|
|
|
type UserCatalogEntry = { id: number; name: string };
|
|
|
|
export function resolveUserDisplayName(
|
|
userId: number,
|
|
catalog: UserCatalogEntry[],
|
|
fallback = '未知用户'
|
|
): string {
|
|
return catalog.find((u) => u.id === userId)?.name ?? fallback;
|
|
}
|
|
|
|
export function mapServerProjectToProjectInfo(
|
|
project: Project,
|
|
catalog: UserCatalogEntry[],
|
|
existing?: ProjectInfo
|
|
): ProjectInfo {
|
|
const creatorName = resolveUserDisplayName(project.creator_user_id, catalog);
|
|
const defaultMember: ProjectMember = {
|
|
userId: project.creator_user_id,
|
|
userName: creatorName,
|
|
role: 'creator',
|
|
status: 'active',
|
|
joinedAt: project.created_at,
|
|
};
|
|
|
|
return {
|
|
id: project.id,
|
|
title: project.name,
|
|
deviceType: project.device_type || existing?.deviceType || '',
|
|
description: project.intended_use || existing?.description || '',
|
|
creatorId: project.creator_user_id,
|
|
creatorName,
|
|
createdAt: project.created_at,
|
|
members: existing?.members?.length ? existing.members : [defaultMember],
|
|
};
|
|
}
|
|
|
|
/** 服务端项目覆盖同 id 本地项,保留本地成员等演示扩展字段。 */
|
|
export function mergeProjectLists(local: ProjectInfo[], fromServer: ProjectInfo[]): ProjectInfo[] {
|
|
const byId = new Map<number, ProjectInfo>();
|
|
for (const project of local) {
|
|
byId.set(project.id, project);
|
|
}
|
|
for (const project of fromServer) {
|
|
const previous = byId.get(project.id);
|
|
if (!previous) {
|
|
byId.set(project.id, project);
|
|
continue;
|
|
}
|
|
byId.set(project.id, {
|
|
...previous,
|
|
...project,
|
|
members: previous.members.length > 0 ? previous.members : project.members,
|
|
});
|
|
}
|
|
return [...byId.values()];
|
|
}
|