import { normalizeNullableStringId, normalizeStringId } from './shared'; type ProjectStatusCode = Api.Project.ProjectStatusCode; type ProjectStatusActionCode = Exclude; type StringIdResponse = string | number; export type ProjectLocalDateValue = string | number[] | null; export type LifecycleActionResponse = Partial> & { actionCode: ActionCode; }; export type ProjectExecutionResponse = Omit< Api.Project.ProjectExecution, | 'id' | 'projectId' | 'projectRequirementId' | 'ownerId' | 'availableActions' | 'plannedStartDate' | 'plannedEndDate' | 'actualStartDate' | 'actualEndDate' | 'progressRate' > & { id: StringIdResponse; projectId: StringIdResponse; projectRequirementId?: StringIdResponse | null; ownerId: StringIdResponse; availableActions?: LifecycleActionResponse[] | null; plannedStartDate?: ProjectLocalDateValue; plannedEndDate?: ProjectLocalDateValue; actualStartDate?: ProjectLocalDateValue; actualEndDate?: ProjectLocalDateValue; progressRate?: number | null; }; export type ExecutionMemberResponse = Omit & { id: StringIdResponse; executionId: StringIdResponse; userId: StringIdResponse; }; export type ExecutionMemberLogResponse = Omit< Api.Project.ExecutionMemberLog, 'id' | 'executionId' | 'userId' | 'operatorUserId' > & { id: StringIdResponse; executionId: StringIdResponse; userId: StringIdResponse; operatorUserId: StringIdResponse; }; export type ProjectTaskResponse = Omit< Api.Project.ProjectTask, | 'id' | 'projectId' | 'executionId' | 'parentTaskId' | 'ownerId' | 'availableActions' | 'plannedStartDate' | 'plannedEndDate' | 'actualStartDate' | 'actualEndDate' | 'progressRate' > & { id: StringIdResponse; projectId: StringIdResponse; executionId: StringIdResponse; parentTaskId?: StringIdResponse | null; ownerId: StringIdResponse; availableActions?: LifecycleActionResponse[] | null; plannedStartDate?: ProjectLocalDateValue; plannedEndDate?: ProjectLocalDateValue; actualStartDate?: ProjectLocalDateValue; actualEndDate?: ProjectLocalDateValue; progressRate?: number | null; }; export interface ProjectMemberResponse { id: string | number; userId: string | number; userNickname: string; roleId: string | number; roleName: string; roleCode: string; managerFlag: boolean; status: 0 | 1; joinedTime: string; leftTime?: string | null; remark?: string | null; } const projectLifecycleActionNameMap: Record = { pause: '暂停项目', resume: '恢复项目', complete: '完成项目', cancel: '取消项目', reopen: '重新开启', archive: '归档项目' }; const projectLifecycleActionReasonRequiredMap: Record = { pause: true, resume: false, complete: true, cancel: true, reopen: true, archive: false }; const projectLifecycleActionMap: Record = { pending: ['cancel'], active: ['pause', 'complete', 'cancel'], paused: ['resume', 'cancel'], completed: ['reopen', 'archive'], cancelled: [], archived: [] }; export function getProjectLifecycleActions(statusCode: ProjectStatusCode): Api.Project.ProjectLifecycleAction[] { return projectLifecycleActionMap[statusCode].map(actionCode => ({ actionCode, actionName: projectLifecycleActionNameMap[actionCode], needReason: projectLifecycleActionReasonRequiredMap[actionCode] })); } export function normalizeProjectLocalDate(value: ProjectLocalDateValue | undefined) { if (value === null || value === undefined || value === '') { return null; } if (Array.isArray(value)) { const [year, month, day] = value; if (!year || !month || !day) { return null; } return [year, month, day].map(item => String(item).padStart(2, '0')).join('-'); } return String(value); } export function normalizeLifecycleActions( actions: LifecycleActionResponse[] | null | undefined ): Api.Project.LifecycleAction[] { return (actions ?? []).map(action => ({ actionCode: action.actionCode, actionName: action.actionName ?? '', needReason: Boolean(action.needReason) })); } export function normalizeProjectMember(response: ProjectMemberResponse): Api.Project.ProjectMember { return { id: normalizeStringId(response.id), userId: normalizeStringId(response.userId), userNickname: response.userNickname || '', roleId: normalizeStringId(response.roleId), roleName: response.roleName || '', roleCode: response.roleCode || '', managerFlag: Boolean(response.managerFlag), status: response.status, joinedTime: response.joinedTime, leftTime: response.leftTime ?? null, remark: response.remark ?? null }; } export function normalizeProjectExecution(response: ProjectExecutionResponse): Api.Project.ProjectExecution { return { ...response, id: normalizeStringId(response.id), projectId: normalizeStringId(response.projectId), projectRequirementId: normalizeNullableStringId(response.projectRequirementId), ownerId: normalizeStringId(response.ownerId), ownerNickname: response.ownerNickname ?? null, statusName: response.statusName ?? null, terminal: Boolean(response.terminal), allowEdit: Boolean(response.allowEdit), availableActions: normalizeLifecycleActions(response.availableActions), plannedStartDate: normalizeProjectLocalDate(response.plannedStartDate), plannedEndDate: normalizeProjectLocalDate(response.plannedEndDate), actualStartDate: normalizeProjectLocalDate(response.actualStartDate), actualEndDate: normalizeProjectLocalDate(response.actualEndDate), progressRate: typeof response.progressRate === 'number' ? response.progressRate : 0, executionDesc: response.executionDesc ?? null, lastStatusReason: response.lastStatusReason ?? null }; } export function normalizeExecutionMember(response: ExecutionMemberResponse): Api.Project.ExecutionMember { return { ...response, id: normalizeStringId(response.id), executionId: normalizeStringId(response.executionId), userId: normalizeStringId(response.userId), userNickname: response.userNickname ?? null, joinedAt: response.joinedAt ?? null, removedAt: response.removedAt ?? null, removedReason: response.removedReason ?? null }; } export function normalizeExecutionMemberLog(response: ExecutionMemberLogResponse): Api.Project.ExecutionMemberLog { return { ...response, id: normalizeStringId(response.id), executionId: normalizeStringId(response.executionId), userId: normalizeStringId(response.userId), operatorUserId: normalizeStringId(response.operatorUserId), userNicknameSnapshot: response.userNicknameSnapshot ?? null, operatorNicknameSnapshot: response.operatorNicknameSnapshot ?? null, reason: response.reason ?? null }; } export function normalizeProjectTask(response: ProjectTaskResponse): Api.Project.ProjectTask { return { ...response, id: normalizeStringId(response.id), projectId: normalizeStringId(response.projectId), executionId: normalizeStringId(response.executionId), parentTaskId: normalizeNullableStringId(response.parentTaskId), ownerId: normalizeStringId(response.ownerId), ownerNickname: response.ownerNickname ?? null, statusName: response.statusName ?? null, terminal: Boolean(response.terminal), allowEdit: Boolean(response.allowEdit), availableActions: normalizeLifecycleActions(response.availableActions), progressRate: typeof response.progressRate === 'number' ? response.progressRate : 0, plannedStartDate: normalizeProjectLocalDate(response.plannedStartDate), plannedEndDate: normalizeProjectLocalDate(response.plannedEndDate), actualStartDate: normalizeProjectLocalDate(response.actualStartDate), actualEndDate: normalizeProjectLocalDate(response.actualEndDate), taskDesc: response.taskDesc ?? null, lastStatusReason: response.lastStatusReason ?? null }; }