Files
cn-rdms-web/src/service/api/project.ts

533 lines
16 KiB
TypeScript
Raw Normal View History

import { WEB_SERVICE_PREFIX } from '@/constants/service';
import { request } from '../request';
import {
type ServiceRequestResult,
mapServiceResult,
normalizeNullableStringId,
normalizeStringId,
safeJsonRequestConfig
} from './shared';
import {
type ExecutionMemberLogResponse,
type ExecutionMemberResponse,
type ProjectExecutionResponse,
type ProjectLocalDateValue,
type ProjectMemberResponse,
type ProjectTaskResponse,
getProjectLifecycleActions,
normalizeExecutionMember,
normalizeExecutionMemberLog,
normalizeProjectExecution,
normalizeProjectLocalDate,
normalizeProjectMember,
normalizeProjectTask
} from './project-shared';
const PROJECT_PREFIX = `${WEB_SERVICE_PREFIX}/project/project`;
type ProjectResponse = Omit<
Api.Project.Project,
'id' | 'managerUserId' | 'productId' | 'plannedStartDate' | 'plannedEndDate' | 'actualStartDate' | 'actualEndDate'
> & {
id: string | number;
managerUserId?: string | number | null;
productId?: string | number | null;
plannedStartDate?: ProjectLocalDateValue;
plannedEndDate?: ProjectLocalDateValue;
actualStartDate?: ProjectLocalDateValue;
actualEndDate?: ProjectLocalDateValue;
};
type ProjectPageResponse = Api.Project.PageResult<ProjectResponse>;
type ProjectExecutionPageResponse = Api.Project.PageResult<ProjectExecutionResponse>;
type ProjectTaskPageResponse = Api.Project.PageResult<ProjectTaskResponse>;
type StatusBoardResponse = Api.Project.StatusBoard;
type ProjectContextResponse = Omit<Api.Project.ProjectContext, 'currentProject' | 'navs'> & {
currentProject: Omit<Api.Project.ProjectContext['currentProject'], 'id'> & { id: string | number };
navs: Array<Omit<Api.Project.ProjectContext['navs'][number], 'id'> & { id: string | number }>;
};
function getExecutionPrefix(projectId: string) {
return `${PROJECT_PREFIX}/${projectId}/executions`;
}
function getTaskPrefix(projectId: string, executionId: string) {
return `${getExecutionPrefix(projectId)}/${executionId}/tasks`;
}
/** 归一化项目数据 */
function normalizeProject(project: ProjectResponse): Api.Project.Project {
return {
...project,
id: normalizeStringId(project.id),
managerUserId: normalizeNullableStringId(project.managerUserId) ?? '',
productId: normalizeNullableStringId(project.productId),
plannedStartDate: normalizeProjectLocalDate(project.plannedStartDate),
plannedEndDate: normalizeProjectLocalDate(project.plannedEndDate),
actualStartDate: normalizeProjectLocalDate(project.actualStartDate),
actualEndDate: normalizeProjectLocalDate(project.actualEndDate)
};
}
/** 将项目详情组装为设置页数据 */
function createProjectSettings(project: Api.Project.Project): Api.Project.ProjectSettings {
return {
baseInfo: {
id: project.id,
projectCode: project.projectCode,
projectName: project.projectName,
directionCode: project.directionCode,
projectType: project.projectType,
productId: project.productId,
productName: project.productName ?? null,
managerUserId: project.managerUserId,
managerUserNickname: project.managerUserNickname ?? null,
statusCode: project.statusCode,
plannedStartDate: project.plannedStartDate,
plannedEndDate: project.plannedEndDate,
actualStartDate: project.actualStartDate,
actualEndDate: project.actualEndDate,
projectDesc: project.projectDesc,
lastStatusReason: project.lastStatusReason
},
lifecycle: {
statusCode: project.statusCode,
lastStatusReason: project.lastStatusReason,
availableActions: getProjectLifecycleActions(project.statusCode)
}
};
}
/** 获取项目分页 */
export async function fetchGetProjectPage(params?: Api.Project.ProjectSearchParams) {
const result = await request<ProjectPageResponse>({
...safeJsonRequestConfig,
url: `${PROJECT_PREFIX}/page`,
method: 'get',
params
});
return mapServiceResult(result as ServiceRequestResult<ProjectPageResponse>, data => ({
...data,
list: data.list.map(normalizeProject)
}));
}
/** 获取项目入口页概览统计 */
export function fetchGetProjectOverviewSummary() {
return request<Api.Project.ProjectOverviewSummary>({
...safeJsonRequestConfig,
url: `${PROJECT_PREFIX}/overview-summary`,
method: 'get'
});
}
/** 获取项目详情 */
export async function fetchGetProject(id: string) {
const result = await request<ProjectResponse>({
...safeJsonRequestConfig,
url: `${PROJECT_PREFIX}/get`,
method: 'get',
params: { id }
});
return mapServiceResult(result as ServiceRequestResult<ProjectResponse>, normalizeProject);
}
/** 创建项目 */
export async function fetchCreateProject(data: Api.Project.SaveProjectParams) {
const result = await request<string | number>({
...safeJsonRequestConfig,
url: `${PROJECT_PREFIX}/create`,
method: 'post',
data
});
return mapServiceResult(result as ServiceRequestResult<string | number>, normalizeStringId);
}
/** 更新项目 */
export function fetchUpdateProject(data: Api.Project.UpdateProjectParams) {
return request<boolean>({
url: `${PROJECT_PREFIX}/update`,
method: 'put',
data
});
}
/** 变更项目状态 */
export function fetchChangeProjectStatus(data: Api.Project.ChangeProjectStatusParams) {
return request<boolean>({
url: `${PROJECT_PREFIX}/change-status`,
method: 'post',
data
});
}
/** 删除项目 */
export function fetchDeleteProject(data: Api.Project.DeleteProjectParams) {
return request<boolean>({
url: `${PROJECT_PREFIX}/delete`,
method: 'post',
data
});
}
/** 获取项目上下文 */
export async function fetchGetProjectContext(id: string) {
const result = await request<ProjectContextResponse>({
...safeJsonRequestConfig,
url: `${PROJECT_PREFIX}/${id}/context`,
method: 'get'
});
return mapServiceResult(result as ServiceRequestResult<ProjectContextResponse>, data => ({
...data,
currentProject: {
...data.currentProject,
id: normalizeStringId(data.currentProject.id)
},
navs: data.navs.map(nav => ({
...nav,
id: normalizeStringId(nav.id)
}))
}));
}
/** 获取项目成员列表 */
export async function fetchGetProjectMembers(id: string) {
const result = await request<ProjectMemberResponse[]>({
...safeJsonRequestConfig,
url: `${PROJECT_PREFIX}/${id}/members`,
method: 'get'
});
return mapServiceResult(result as ServiceRequestResult<ProjectMemberResponse[]>, data =>
data.map(normalizeProjectMember)
);
}
/** 创建项目成员 */
export async function fetchCreateProjectMember(id: string, data: Api.Project.CreateProjectMemberParams) {
const result = await request<string | number>({
...safeJsonRequestConfig,
url: `${PROJECT_PREFIX}/${id}/members`,
method: 'post',
data
});
return mapServiceResult(result as ServiceRequestResult<string | number>, normalizeStringId);
}
/** 更新项目成员 */
export function fetchUpdateProjectMember(id: string, memberId: string, data: Api.Project.UpdateProjectMemberParams) {
return request<boolean>({
...safeJsonRequestConfig,
url: `${PROJECT_PREFIX}/${id}/members/${memberId}`,
method: 'put',
data
});
}
/** 移出项目成员 */
export function fetchInactiveProjectMember(
id: string,
memberId: string,
data: Api.Project.InactiveProjectMemberParams
) {
return request<boolean>({
...safeJsonRequestConfig,
url: `${PROJECT_PREFIX}/${id}/members/${memberId}/inactive`,
method: 'post',
data
});
}
/** 获取项目设置 */
export async function fetchGetProjectSettings(id: string) {
const result = await fetchGetProject(id);
if (result.error || !result.data) {
return result as ServiceRequestResult<Api.Project.ProjectSettings>;
}
return {
...result,
data: createProjectSettings(result.data)
};
}
/** 更新项目设置基础信息 */
export async function fetchUpdateProjectSettingBaseInfo(
id: string,
data: Api.Project.UpdateProjectSettingBaseInfoParams
) {
const detailResult = await fetchGetProject(id);
if (detailResult.error || !detailResult.data) {
return detailResult as ServiceRequestResult<boolean>;
}
return fetchUpdateProject({
id,
projectCode: detailResult.data.projectCode,
projectName: data.projectName,
directionCode: data.directionCode,
projectType: data.projectType,
productId: detailResult.data.productId,
managerUserId: detailResult.data.managerUserId,
plannedStartDate: data.plannedStartDate,
plannedEndDate: data.plannedEndDate,
actualStartDate: detailResult.data.actualStartDate,
actualEndDate: detailResult.data.actualEndDate,
projectDesc: data.projectDesc
});
}
/** 获取项目执行分页 */
export async function fetchGetProjectExecutionPage(
projectId: string,
params?: Api.Project.ProjectExecutionSearchParams
) {
const result = await request<ProjectExecutionPageResponse>({
...safeJsonRequestConfig,
url: `${getExecutionPrefix(projectId)}/page`,
method: 'get',
params
});
return mapServiceResult(result as ServiceRequestResult<ProjectExecutionPageResponse>, data => ({
...data,
list: data.list.map(normalizeProjectExecution)
}));
}
/** 获取项目执行状态看板 */
export function fetchGetProjectExecutionStatusBoard(
projectId: string,
params?: Api.Project.ProjectExecutionStatusBoardParams
) {
return request<StatusBoardResponse>({
...safeJsonRequestConfig,
url: `${getExecutionPrefix(projectId)}/status-board`,
method: 'get',
params
});
}
/** 获取项目执行详情 */
export async function fetchGetProjectExecution(projectId: string, executionId: string) {
const result = await request<ProjectExecutionResponse>({
...safeJsonRequestConfig,
url: `${getExecutionPrefix(projectId)}/${executionId}`,
method: 'get'
});
return mapServiceResult(result as ServiceRequestResult<ProjectExecutionResponse>, normalizeProjectExecution);
}
/** 创建项目执行 */
export async function fetchCreateProjectExecution(projectId: string, data: Api.Project.SaveProjectExecutionParams) {
const result = await request<string | number>({
...safeJsonRequestConfig,
url: getExecutionPrefix(projectId),
method: 'post',
data
});
return mapServiceResult(result as ServiceRequestResult<string | number>, normalizeStringId);
}
/** 更新项目执行 */
export function fetchUpdateProjectExecution(
projectId: string,
executionId: string,
data: Api.Project.SaveProjectExecutionParams
) {
return request<boolean>({
...safeJsonRequestConfig,
url: `${getExecutionPrefix(projectId)}/${executionId}`,
method: 'put',
data
});
}
/** 变更项目执行负责人 */
export function fetchChangeProjectExecutionOwner(
projectId: string,
executionId: string,
data: Api.Project.ChangeExecutionOwnerParams
) {
return request<boolean>({
...safeJsonRequestConfig,
url: `${getExecutionPrefix(projectId)}/${executionId}/change-owner`,
method: 'post',
data
});
}
/** 变更项目执行状态 */
export function fetchChangeProjectExecutionStatus(
projectId: string,
executionId: string,
data: Api.Project.ChangeExecutionStatusParams
) {
return request<boolean>({
...safeJsonRequestConfig,
url: `${getExecutionPrefix(projectId)}/${executionId}/change-status`,
method: 'post',
data
});
}
/** 获取项目执行成员 */
export async function fetchGetProjectExecutionMembers(projectId: string, executionId: string) {
const result = await request<ExecutionMemberResponse[]>({
...safeJsonRequestConfig,
url: `${getExecutionPrefix(projectId)}/${executionId}/members`,
method: 'get'
});
return mapServiceResult(result as ServiceRequestResult<ExecutionMemberResponse[]>, data =>
data.map(normalizeExecutionMember)
);
}
/** 创建项目执行成员 */
export async function fetchCreateProjectExecutionMember(
projectId: string,
executionId: string,
data: Api.Project.CreateExecutionMemberParams
) {
const result = await request<string | number>({
...safeJsonRequestConfig,
url: `${getExecutionPrefix(projectId)}/${executionId}/members`,
method: 'post',
data
});
return mapServiceResult(result as ServiceRequestResult<string | number>, normalizeStringId);
}
/** 移除项目执行成员 */
export function fetchInactiveProjectExecutionMember(
projectId: string,
executionId: string,
payload: { memberId: string; data: Api.Project.InactiveExecutionMemberParams }
) {
return request<boolean>({
...safeJsonRequestConfig,
url: `${getExecutionPrefix(projectId)}/${executionId}/members/${payload.memberId}/inactive`,
method: 'post',
data: payload.data
});
}
/** 获取项目执行成员变更历史分页 */
export async function fetchGetProjectExecutionMemberLogPage(
projectId: string,
executionId: string,
params?: Api.Project.ExecutionMemberLogSearchParams
) {
const result = await request<Api.Project.PageResult<ExecutionMemberLogResponse>>({
...safeJsonRequestConfig,
url: `${getExecutionPrefix(projectId)}/${executionId}/member-logs`,
method: 'get',
params
});
return mapServiceResult(result as ServiceRequestResult<Api.Project.PageResult<ExecutionMemberLogResponse>>, data => ({
...data,
list: data.list.map(normalizeExecutionMemberLog)
}));
}
/** 获取项目任务分页 */
export async function fetchGetProjectTaskPage(
projectId: string,
executionId: string,
params?: Api.Project.ProjectTaskSearchParams
) {
const result = await request<ProjectTaskPageResponse>({
...safeJsonRequestConfig,
url: `${getTaskPrefix(projectId, executionId)}/page`,
method: 'get',
params
});
return mapServiceResult(result as ServiceRequestResult<ProjectTaskPageResponse>, data => ({
...data,
list: data.list.map(normalizeProjectTask)
}));
}
/** 获取项目任务状态看板 */
export function fetchGetProjectTaskStatusBoard(
projectId: string,
executionId: string,
params?: Api.Project.ProjectTaskStatusBoardParams
) {
return request<StatusBoardResponse>({
...safeJsonRequestConfig,
url: `${getTaskPrefix(projectId, executionId)}/status-board`,
method: 'get',
params
});
}
/** 获取项目任务详情 */
export async function fetchGetProjectTask(projectId: string, executionId: string, taskId: string) {
const result = await request<ProjectTaskResponse>({
...safeJsonRequestConfig,
url: `${getTaskPrefix(projectId, executionId)}/${taskId}`,
method: 'get'
});
return mapServiceResult(result as ServiceRequestResult<ProjectTaskResponse>, normalizeProjectTask);
}
/** 创建项目任务 */
export async function fetchCreateProjectTask(
projectId: string,
executionId: string,
data: Api.Project.SaveProjectTaskParams
) {
const result = await request<string | number>({
...safeJsonRequestConfig,
url: getTaskPrefix(projectId, executionId),
method: 'post',
data
});
return mapServiceResult(result as ServiceRequestResult<string | number>, normalizeStringId);
}
/** 更新项目任务 */
export function fetchUpdateProjectTask(
projectId: string,
executionId: string,
payload: { taskId: string; data: Api.Project.SaveProjectTaskParams }
) {
return request<boolean>({
...safeJsonRequestConfig,
url: `${getTaskPrefix(projectId, executionId)}/${payload.taskId}`,
method: 'put',
data: payload.data
});
}
/** 变更项目任务状态 */
export function fetchChangeProjectTaskStatus(
projectId: string,
executionId: string,
payload: { taskId: string; data: Api.Project.ChangeTaskStatusParams }
) {
return request<boolean>({
...safeJsonRequestConfig,
url: `${getTaskPrefix(projectId, executionId)}/${payload.taskId}/change-status`,
method: 'post',
data: payload.data
});
}