feat(projects): 工作台接口切换为真实数据
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import dayjs from 'dayjs';
|
||||
import { normalizeNullableStringId, normalizeStringId } from './shared';
|
||||
|
||||
type ProjectStatusCode = Api.Project.ProjectStatusCode;
|
||||
@@ -76,6 +77,60 @@ export type MyOwnedProjectResponse = Omit<Api.Project.MyOwnedProjectItem, 'id' |
|
||||
members?: MyOwnedProjectMemberResponse[] | null;
|
||||
};
|
||||
|
||||
export type MyTaskResponse = Omit<
|
||||
Api.Project.MyTaskItem,
|
||||
| 'id'
|
||||
| 'projectId'
|
||||
| 'executionId'
|
||||
| 'priority'
|
||||
| 'plannedEndDate'
|
||||
| 'progressRate'
|
||||
| 'createTime'
|
||||
| 'parentTaskId'
|
||||
| 'availableActions'
|
||||
> & {
|
||||
id: StringIdResponse;
|
||||
projectId: StringIdResponse;
|
||||
executionId?: StringIdResponse | null;
|
||||
priority?: string | number | null;
|
||||
plannedEndDate?: ProjectLocalDateValue;
|
||||
progressRate?: number | string | null;
|
||||
createTime?: string | number | null;
|
||||
parentTaskId?: StringIdResponse | null;
|
||||
availableActions?: LifecycleActionResponse<Api.Project.ProjectTaskActionCode>[] | null;
|
||||
};
|
||||
|
||||
export type TeamLoadDistributionItemResponse = Omit<Api.Project.TeamLoadDistributionItem, 'projectId'> & {
|
||||
projectId?: StringIdResponse | null;
|
||||
};
|
||||
|
||||
export type TeamLoadMemberResponse = Omit<Api.Project.TeamLoadMember, 'userId' | 'items'> & {
|
||||
userId: StringIdResponse;
|
||||
items?: TeamLoadDistributionItemResponse[] | null;
|
||||
};
|
||||
|
||||
export type TeamLoadResponse = {
|
||||
members?: TeamLoadMemberResponse[] | null;
|
||||
};
|
||||
|
||||
export type WorklogDistributionItemResponse = Omit<Api.Project.WorklogDistributionItem, 'projectId'> & {
|
||||
projectId?: StringIdResponse | null;
|
||||
};
|
||||
|
||||
export type MyWorklogWeekResponse = Omit<Api.Project.MyWorklogWeekResult, 'dailyHours' | 'distribution'> & {
|
||||
dailyHours?: number[] | null;
|
||||
distribution?: WorklogDistributionItemResponse[] | null;
|
||||
};
|
||||
|
||||
export type TeamWorklogWeekMemberResponse = Omit<Api.Project.TeamWorklogWeekMember, 'userId' | 'items'> & {
|
||||
userId: StringIdResponse;
|
||||
items?: WorklogDistributionItemResponse[] | null;
|
||||
};
|
||||
|
||||
export type TeamWorklogWeekResponse = Omit<Api.Project.TeamWorklogWeekResult, 'members'> & {
|
||||
members?: TeamWorklogWeekMemberResponse[] | null;
|
||||
};
|
||||
|
||||
export type ExecutionAssigneeResponse = Omit<Api.Project.ExecutionAssignee, 'id' | 'executionId' | 'userId'> & {
|
||||
id: StringIdResponse;
|
||||
executionId: StringIdResponse;
|
||||
@@ -263,6 +318,28 @@ export function normalizeProjectLocalDate(value: ProjectLocalDateValue | undefin
|
||||
return String(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 后端 LocalDateTime 统一序列化为毫秒时间戳(也可能是数字字符串/格式化字符串),
|
||||
* 归一为 'YYYY-MM-DD HH:mm:ss' 供展示与 dayjs 解析。
|
||||
*/
|
||||
export function normalizeProjectDateTime(value: string | number | null | undefined): string {
|
||||
if (value === null || value === undefined || value === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
let parsed: dayjs.Dayjs;
|
||||
if (typeof value === 'number') {
|
||||
parsed = dayjs(value);
|
||||
} else if (/^\d+$/.test(value)) {
|
||||
// 字符串形态的毫秒时间戳:dayjs 无法直接解析,先转数值(时间值非 ID,安全整数范围内)
|
||||
parsed = dayjs(Number(value));
|
||||
} else {
|
||||
parsed = dayjs(value);
|
||||
}
|
||||
|
||||
return parsed.isValid() ? parsed.format('YYYY-MM-DD HH:mm:ss') : '';
|
||||
}
|
||||
|
||||
export function normalizeLifecycleActions<ActionCode extends string>(
|
||||
actions: LifecycleActionResponse<ActionCode>[] | null | undefined
|
||||
): Api.Project.LifecycleAction<ActionCode>[] {
|
||||
@@ -296,6 +373,15 @@ function normalizePriority(value: string | number | null | undefined): string {
|
||||
return String(value);
|
||||
}
|
||||
|
||||
function normalizeProgressRate(value: number | string | null | undefined) {
|
||||
if (value === null || value === undefined || value === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
const numeric = typeof value === 'number' ? value : Number(value ?? 0);
|
||||
return Number.isFinite(numeric) ? numeric : null;
|
||||
}
|
||||
|
||||
export function normalizeProjectExecution(response: ProjectExecutionResponse): Api.Project.ProjectExecution {
|
||||
return {
|
||||
...response,
|
||||
@@ -366,6 +452,75 @@ export function normalizeMyOwnedProject(response: MyOwnedProjectResponse): Api.P
|
||||
};
|
||||
}
|
||||
|
||||
export function normalizeMyTask(response: MyTaskResponse): Api.Project.MyTaskItem {
|
||||
return {
|
||||
...response,
|
||||
id: normalizeStringId(response.id),
|
||||
projectId: normalizeStringId(response.projectId),
|
||||
executionId: normalizeNullableStringId(response.executionId),
|
||||
executionName: response.executionName ?? null,
|
||||
statusName: response.statusName ?? null,
|
||||
priority: normalizePriority(response.priority),
|
||||
plannedEndDate: normalizeProjectLocalDate(response.plannedEndDate),
|
||||
progressRate: normalizeProgressRate(response.progressRate) ?? 0,
|
||||
createTime: normalizeProjectDateTime(response.createTime),
|
||||
parentTaskId: normalizeNullableStringId(response.parentTaskId),
|
||||
terminal: Boolean(response.terminal),
|
||||
allowEdit: Boolean(response.allowEdit),
|
||||
availableActions: normalizeLifecycleActions(response.availableActions)
|
||||
};
|
||||
}
|
||||
|
||||
function normalizeWorklogDistributionItem(
|
||||
response: WorklogDistributionItemResponse | TeamLoadDistributionItemResponse
|
||||
): { projectId: string | null; projectName: string | null; kind: 'project' | 'personal' | 'other' } {
|
||||
return {
|
||||
projectId: normalizeNullableStringId(response.projectId),
|
||||
projectName: response.projectName ?? null,
|
||||
kind: response.kind
|
||||
};
|
||||
}
|
||||
|
||||
export function normalizeTeamLoad(response: TeamLoadResponse): Api.Project.TeamLoadResult {
|
||||
return {
|
||||
members: (response.members ?? []).map(member => ({
|
||||
userId: normalizeStringId(member.userId),
|
||||
userNickname: member.userNickname ?? '',
|
||||
items: (member.items ?? []).map(item => ({
|
||||
...normalizeWorklogDistributionItem(item),
|
||||
count: typeof item.count === 'number' ? item.count : 0
|
||||
})),
|
||||
dueSoonCount: typeof member.dueSoonCount === 'number' ? member.dueSoonCount : 0,
|
||||
overdueCount: typeof member.overdueCount === 'number' ? member.overdueCount : 0
|
||||
}))
|
||||
};
|
||||
}
|
||||
|
||||
export function normalizeMyWorklogWeek(response: MyWorklogWeekResponse): Api.Project.MyWorklogWeekResult {
|
||||
return {
|
||||
weekStart: response.weekStart ?? '',
|
||||
dailyHours: response.dailyHours ?? [0, 0, 0, 0, 0],
|
||||
distribution: (response.distribution ?? []).map(item => ({
|
||||
...normalizeWorklogDistributionItem(item),
|
||||
hours: typeof item.hours === 'number' ? item.hours : 0
|
||||
}))
|
||||
};
|
||||
}
|
||||
|
||||
export function normalizeTeamWorklogWeek(response: TeamWorklogWeekResponse): Api.Project.TeamWorklogWeekResult {
|
||||
return {
|
||||
weekStart: response.weekStart ?? '',
|
||||
members: (response.members ?? []).map(member => ({
|
||||
userId: normalizeStringId(member.userId),
|
||||
userNickname: member.userNickname ?? '',
|
||||
items: (member.items ?? []).map(item => ({
|
||||
...normalizeWorklogDistributionItem(item),
|
||||
hours: typeof item.hours === 'number' ? item.hours : 0
|
||||
}))
|
||||
}))
|
||||
};
|
||||
}
|
||||
|
||||
export function normalizeExecutionAssignee(response: ExecutionAssigneeResponse): Api.Project.ExecutionAssignee {
|
||||
return {
|
||||
...response,
|
||||
|
||||
Reference in New Issue
Block a user