63 lines
2.8 KiB
TypeScript
63 lines
2.8 KiB
TypeScript
|
|
import { WEB_SERVICE_PREFIX } from '@/constants/service';
|
|||
|
|
import { request } from '../request';
|
|||
|
|
import {
|
|||
|
|
type ServiceRequestResult,
|
|||
|
|
mapServiceResult,
|
|||
|
|
normalizeNullableStringId,
|
|||
|
|
safeJsonRequestConfig
|
|||
|
|
} from './shared';
|
|||
|
|
import { type ProjectResponse, normalizeProject } from './project';
|
|||
|
|
|
|||
|
|
const PROJECT_PREFIX = `${WEB_SERVICE_PREFIX}/project/project`;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* group-page 原始响应。
|
|||
|
|
* 组级 managerUserId、productId:后端对小数值 Long(如 1001)仍按数字返回,需 String() 归一;
|
|||
|
|
* projects 字段与 page 接口项目行完全一致,复用 ProjectResponse / normalizeProject。
|
|||
|
|
*/
|
|||
|
|
type ProjectGroupResponse = Omit<Api.Project.ProjectGroup, 'productId' | 'managerUserId' | 'projects'> & {
|
|||
|
|
productId?: string | number | null;
|
|||
|
|
managerUserId?: string | number | null;
|
|||
|
|
projects: ProjectResponse[];
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
type ProjectGroupPageResponse = Omit<Api.Project.ProjectGroupPageResult, 'list'> & {
|
|||
|
|
list: ProjectGroupResponse[];
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/** 归一化分组:组级 ID String 化,组内项目复用 normalizeProject(id/managerUserId/productId/日期统一口径) */
|
|||
|
|
function normalizeProjectGroup(group: ProjectGroupResponse): Api.Project.ProjectGroup {
|
|||
|
|
return {
|
|||
|
|
...group,
|
|||
|
|
productId: normalizeNullableStringId(group.productId),
|
|||
|
|
managerUserId: normalizeNullableStringId(group.managerUserId),
|
|||
|
|
projects: Array.isArray(group.projects) ? group.projects.map(normalizeProject) : []
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 项目列表「按产品分组」分页。
|
|||
|
|
*
|
|||
|
|
* 后端契约见《项目列表产品分组-前端API-2026-06-10》:
|
|||
|
|
* - pageNo/pageSize 为产品组维度分页;statusCode 不传 = 「全部」口径(后端从状态机推导,
|
|||
|
|
* 当前等价 pending/active/paused/completed,不含 cancelled/archived)。
|
|||
|
|
* - 组内 projects 仅返前 topN 条(默认 5),projectTotal 为该口径组内全量计数;
|
|||
|
|
* 剩余项目由页面按 productId / orphanOnly + statusCodes 走 page 接口展开拉取。
|
|||
|
|
* - typeCounts / hasBaseline 现状恒按「全部」口径统计,不随 statusCode 变化;其中 typeCounts 已提需求
|
|||
|
|
* 改为与 projectTotal 同口径(见《2026-06-11-项目分组接口typeCounts口径-后端接口需求》),后端落地后更新本注释;
|
|||
|
|
* hasBaseline = 存在非已取消的主线项目(已归档/完成也算占坑),前端直接消费、不自行推导。
|
|||
|
|
*/
|
|||
|
|
export async function fetchGetProjectGroupPage(params?: Api.Project.ProjectGroupSearchParams) {
|
|||
|
|
const result = await request<ProjectGroupPageResponse>({
|
|||
|
|
...safeJsonRequestConfig,
|
|||
|
|
url: `${PROJECT_PREFIX}/group-page`,
|
|||
|
|
method: 'get',
|
|||
|
|
params
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
return mapServiceResult(result as ServiceRequestResult<ProjectGroupPageResponse>, data => ({
|
|||
|
|
...data,
|
|||
|
|
list: Array.isArray(data.list) ? data.list.map(normalizeProjectGroup) : []
|
|||
|
|
}));
|
|||
|
|
}
|