feat(新增需求评审功能): 新增需求评审功能。
feat(动态切换对象域下的对象):对象域下的对象可以动态切换。 fix(产品需求、项目需求): 按照会议意见修改诸多细节。 fix(产品对象域的概览界面): 把假数据换成真实的需求统计数据。
This commit is contained in:
@@ -205,6 +205,41 @@ type RequirementResponse = Omit<
|
||||
};
|
||||
|
||||
type RequirementPageResponse = Api.Product.PageResult<RequirementResponse>;
|
||||
type RequirementReviewResponse = Omit<
|
||||
Api.Product.RequirementReview,
|
||||
'id' | 'requirementId' | 'operatorId' | 'attendees' | 'attachments'
|
||||
> & {
|
||||
id: string | number;
|
||||
requirementId: string | number;
|
||||
operatorId: string | number;
|
||||
attendees?: Array<{
|
||||
userId: string | number;
|
||||
nickname: string;
|
||||
}>;
|
||||
attachments?: AttachmentItemResponse[] | null;
|
||||
};
|
||||
type ProductRequirementDashboardSummaryResponse = {
|
||||
total?: number | string | null;
|
||||
todo?: number | string | null;
|
||||
pendingClaim?: number | string | null;
|
||||
pendingReview?: number | string | null;
|
||||
pendingDispatch?: number | string | null;
|
||||
completed?: number | string | null;
|
||||
completionRate?: number | string | null;
|
||||
highPriorityTodo?: number | string | null;
|
||||
};
|
||||
type ProductRequirementDashboardRecentChangeResponse = Omit<
|
||||
Api.Product.ProductRequirementDashboardRecentChange,
|
||||
'id' | 'requirementId' | 'operatorUserId'
|
||||
> & {
|
||||
id: string | number;
|
||||
requirementId?: string | number | null;
|
||||
operatorUserId?: string | number | null;
|
||||
};
|
||||
type ProductRequirementDashboardResponse = {
|
||||
summary?: ProductRequirementDashboardSummaryResponse | null;
|
||||
recentChanges?: ProductRequirementDashboardRecentChangeResponse[] | null;
|
||||
};
|
||||
|
||||
type AttachmentItemResponse = Omit<Api.Project.AttachmentItem, 'fileId'> & {
|
||||
fileId?: string | number;
|
||||
@@ -242,6 +277,51 @@ function normalizeRequirement(requirement: RequirementResponse): Api.Product.Req
|
||||
};
|
||||
}
|
||||
|
||||
function normalizeRequirementReview(review: RequirementReviewResponse): Api.Product.RequirementReview {
|
||||
return {
|
||||
...review,
|
||||
id: normalizeStringId(review.id),
|
||||
requirementId: normalizeStringId(review.requirementId),
|
||||
operatorId: normalizeStringId(review.operatorId),
|
||||
attendees: review.attendees?.map(item => ({
|
||||
...item,
|
||||
userId: normalizeStringId(item.userId)
|
||||
})),
|
||||
attachments: normalizeAttachments(review.attachments)
|
||||
};
|
||||
}
|
||||
|
||||
function normalizeDashboardCount(value: number | string | null | undefined) {
|
||||
const count = Number(value ?? 0);
|
||||
|
||||
return Number.isFinite(count) ? Math.max(0, count) : 0;
|
||||
}
|
||||
|
||||
function normalizeProductRequirementDashboard(
|
||||
data: ProductRequirementDashboardResponse
|
||||
): Api.Product.ProductRequirementDashboard {
|
||||
const summary = data.summary ?? {};
|
||||
|
||||
return {
|
||||
summary: {
|
||||
total: normalizeDashboardCount(summary.total),
|
||||
todo: normalizeDashboardCount(summary.todo),
|
||||
pendingClaim: normalizeDashboardCount(summary.pendingClaim),
|
||||
pendingReview: normalizeDashboardCount(summary.pendingReview),
|
||||
pendingDispatch: normalizeDashboardCount(summary.pendingDispatch),
|
||||
completed: normalizeDashboardCount(summary.completed),
|
||||
completionRate: Math.min(100, normalizeDashboardCount(summary.completionRate)),
|
||||
highPriorityTodo: normalizeDashboardCount(summary.highPriorityTodo)
|
||||
},
|
||||
recentChanges: (data.recentChanges ?? []).map(item => ({
|
||||
...item,
|
||||
id: normalizeStringId(item.id),
|
||||
requirementId: normalizeNullableStringId(item.requirementId),
|
||||
operatorUserId: normalizeNullableStringId(item.operatorUserId)
|
||||
}))
|
||||
};
|
||||
}
|
||||
|
||||
/** 获取需求分页列表 */
|
||||
export async function fetchGetRequirementPage(params?: Api.Product.RequirementSearchParams) {
|
||||
const result = await request<RequirementPageResponse>({
|
||||
@@ -337,17 +417,6 @@ export async function fetchSplitRequirement(data: Api.Product.SplitRequirementPa
|
||||
|
||||
return mapServiceResult(result as ServiceRequestResult<string | number>, normalizeStringId);
|
||||
}
|
||||
|
||||
/** 关闭需求 */
|
||||
export function fetchCloseRequirement(data: Api.Product.CloseRequirementParams) {
|
||||
return request<boolean>({
|
||||
...safeJsonRequestConfig,
|
||||
url: `${REQUIREMENT_PREFIX}/close`,
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
/** 获取需求可执行的状态动作列表 */
|
||||
export async function fetchGetRequirementAllowedTransitions(requirementId: string, productId: string) {
|
||||
const result = await request<Api.Product.RequirementLifecycleAction[]>({
|
||||
@@ -379,16 +448,43 @@ export async function fetchGetRequirementAllowedTransitionsBatch(data: Api.Produ
|
||||
);
|
||||
}
|
||||
|
||||
/** 获取需求生命周期信息 */
|
||||
export async function fetchGetRequirementLifecycle(requirementId: string, productId: string) {
|
||||
const result = await request<Api.Product.RequirementLifecycleInfo>({
|
||||
/** 提交产品需求评审 */
|
||||
export async function fetchSubmitProductRequirementReview(data: Api.Product.RequirementReviewSubmitParams) {
|
||||
const result = await request<string | number>({
|
||||
...safeJsonRequestConfig,
|
||||
url: `${REQUIREMENT_PREFIX}/lifecycle`,
|
||||
method: 'get',
|
||||
params: { requirementId, productId }
|
||||
url: `${REQUIREMENT_PREFIX}/review/submit`,
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
|
||||
return mapServiceResult(result as ServiceRequestResult<Api.Product.RequirementLifecycleInfo>, data => data);
|
||||
return mapServiceResult(result as ServiceRequestResult<string | number>, normalizeStringId);
|
||||
}
|
||||
|
||||
/** 获取产品需求评审记录 */
|
||||
export async function fetchGetProductRequirementReview(productId: string, requirementId: string) {
|
||||
const result = await request<RequirementReviewResponse>({
|
||||
...safeJsonRequestConfig,
|
||||
url: `${REQUIREMENT_PREFIX}/review/get`,
|
||||
method: 'get',
|
||||
params: { productId, requirementId }
|
||||
});
|
||||
|
||||
return mapServiceResult(result as ServiceRequestResult<RequirementReviewResponse>, normalizeRequirementReview);
|
||||
}
|
||||
|
||||
/** 获取产品概览需求池实时看板 */
|
||||
export async function fetchGetProductRequirementDashboard(productId: string) {
|
||||
const result = await request<ProductRequirementDashboardResponse>({
|
||||
...safeJsonRequestConfig,
|
||||
url: `${REQUIREMENT_PREFIX}/dashboard`,
|
||||
method: 'get',
|
||||
params: { productId }
|
||||
});
|
||||
|
||||
return mapServiceResult(
|
||||
result as ServiceRequestResult<ProductRequirementDashboardResponse>,
|
||||
normalizeProductRequirementDashboard
|
||||
);
|
||||
}
|
||||
|
||||
/** 获取需求所有状态字典 */
|
||||
@@ -402,18 +498,7 @@ export async function fetchGetRequirementStatusDict() {
|
||||
return mapServiceResult(result as ServiceRequestResult<Api.Product.RequirementStatusDict[]>, data => data);
|
||||
}
|
||||
|
||||
/** 获取需求终止态状态字典 */
|
||||
export async function fetchGetRequirementTerminalStatusDict() {
|
||||
const result = await request<Api.Product.RequirementStatusDict[]>({
|
||||
...safeJsonRequestConfig,
|
||||
url: `${REQUIREMENT_PREFIX}/status/dict/terminal`,
|
||||
method: 'get'
|
||||
});
|
||||
|
||||
return mapServiceResult(result as ServiceRequestResult<Api.Product.RequirementStatusDict[]>, data => data);
|
||||
}
|
||||
|
||||
/** 判断产品需求是否已分流生成项目需求 */
|
||||
/** 判断产品需求是否已指派并生成项目需求 */
|
||||
export async function fetchHasDispatchedProjectRequirement(requirementId: string, productId: string) {
|
||||
return request<boolean>({
|
||||
...safeJsonRequestConfig,
|
||||
@@ -423,7 +508,7 @@ export async function fetchHasDispatchedProjectRequirement(requirementId: string
|
||||
});
|
||||
}
|
||||
|
||||
/** 批量判断产品需求是否已分流生成项目需求 */
|
||||
/** 批量判断产品需求是否已指派并生成项目需求 */
|
||||
export async function fetchHasDispatchedProjectRequirementBatch(data: Api.Product.RequirementBatchReqVO) {
|
||||
const result = await request<Api.Product.RequirementHasDispatchedBatchRespVO[]>({
|
||||
...safeJsonRequestConfig,
|
||||
|
||||
@@ -832,6 +832,19 @@ type ProjectRequirementResponse = Omit<
|
||||
};
|
||||
|
||||
type ProjectRequirementPageResponse = Api.Project.PageResult<ProjectRequirementResponse>;
|
||||
type ProjectRequirementReviewResponse = Omit<
|
||||
Api.Project.ProjectRequirementReview,
|
||||
'id' | 'requirementId' | 'operatorId' | 'attendees' | 'attachments'
|
||||
> & {
|
||||
id: string | number;
|
||||
requirementId: string | number;
|
||||
operatorId: string | number;
|
||||
attendees?: Array<{
|
||||
userId: string | number;
|
||||
nickname: string;
|
||||
}>;
|
||||
attachments?: AttachmentItemResponse[] | null;
|
||||
};
|
||||
|
||||
type ProjectRequirementModuleResponse = Omit<Api.Project.ProjectRequirementModule, 'id' | 'parentId' | 'projectId'> & {
|
||||
id: string | number;
|
||||
@@ -876,6 +889,22 @@ function normalizeProjectRequirement(requirement: ProjectRequirementResponse): A
|
||||
};
|
||||
}
|
||||
|
||||
function normalizeProjectRequirementReview(
|
||||
review: ProjectRequirementReviewResponse
|
||||
): Api.Project.ProjectRequirementReview {
|
||||
return {
|
||||
...review,
|
||||
id: normalizeStringId(review.id),
|
||||
requirementId: normalizeStringId(review.requirementId),
|
||||
operatorId: normalizeStringId(review.operatorId),
|
||||
attendees: review.attendees?.map(item => ({
|
||||
...item,
|
||||
userId: normalizeStringId(item.userId)
|
||||
})),
|
||||
attachments: normalizeAttachments(review.attachments)
|
||||
};
|
||||
}
|
||||
|
||||
function normalizeProjectRequirementModule(
|
||||
module: ProjectRequirementModuleResponse
|
||||
): Api.Project.ProjectRequirementModule {
|
||||
@@ -1030,16 +1059,31 @@ export async function fetchGetProjectRequirementAllowedTransitionsBatch(
|
||||
);
|
||||
}
|
||||
|
||||
/** 获取项目需求生命周期信息 */
|
||||
export async function fetchGetProjectRequirementLifecycle(requirementId: string, projectId: string) {
|
||||
const result = await request<Api.Project.ProjectRequirementLifecycleInfo>({
|
||||
/** 提交项目需求评审 */
|
||||
export async function fetchSubmitProjectRequirementReview(data: Api.Project.ProjectRequirementReviewSubmitParams) {
|
||||
const result = await request<string | number>({
|
||||
...safeJsonRequestConfig,
|
||||
url: `${PROJECT_REQUIREMENT_PREFIX}/lifecycle`,
|
||||
method: 'get',
|
||||
params: { requirementId, projectId }
|
||||
url: `${PROJECT_REQUIREMENT_PREFIX}/review/submit`,
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
|
||||
return mapServiceResult(result as ServiceRequestResult<Api.Project.ProjectRequirementLifecycleInfo>, data => data);
|
||||
return mapServiceResult(result as ServiceRequestResult<string | number>, normalizeStringId);
|
||||
}
|
||||
|
||||
/** 获取项目需求评审记录 */
|
||||
export async function fetchGetProjectRequirementReview(projectId: string, requirementId: string) {
|
||||
const result = await request<ProjectRequirementReviewResponse>({
|
||||
...safeJsonRequestConfig,
|
||||
url: `${PROJECT_REQUIREMENT_PREFIX}/review/get`,
|
||||
method: 'get',
|
||||
params: { projectId, requirementId }
|
||||
});
|
||||
|
||||
return mapServiceResult(
|
||||
result as ServiceRequestResult<ProjectRequirementReviewResponse>,
|
||||
normalizeProjectRequirementReview
|
||||
);
|
||||
}
|
||||
|
||||
/** 获取项目需求状态字典 */
|
||||
@@ -1053,17 +1097,6 @@ export async function fetchGetProjectRequirementStatusDict() {
|
||||
return mapServiceResult(result as ServiceRequestResult<Api.Project.ProjectRequirementStatusDict[]>, data => data);
|
||||
}
|
||||
|
||||
/** 获取项目需求终态状态字典 */
|
||||
export async function fetchGetProjectRequirementTerminalStatusDict() {
|
||||
const result = await request<Api.Project.ProjectRequirementStatusDict[]>({
|
||||
...safeJsonRequestConfig,
|
||||
url: `${PROJECT_REQUIREMENT_PREFIX}/status/dict/terminal`,
|
||||
method: 'get'
|
||||
});
|
||||
|
||||
return mapServiceResult(result as ServiceRequestResult<Api.Project.ProjectRequirementStatusDict[]>, data => data);
|
||||
}
|
||||
|
||||
/** 获取项目需求模块树 */
|
||||
export async function fetchGetProjectRequirementModuleTree(projectId: string) {
|
||||
const result = await request<ProjectRequirementModuleResponse[]>({
|
||||
|
||||
@@ -445,7 +445,7 @@ export function fetchBatchDeletePost(ids: number[]) {
|
||||
}
|
||||
|
||||
/** 获取用户简单列表(用于用户选择下拉框) */
|
||||
export function fetchGetUserSimpleList() {
|
||||
export async function fetchGetUserSimpleList() {
|
||||
return request<UserSimpleResponse[]>({
|
||||
...safeJsonRequestConfig,
|
||||
url: `${USER_PREFIX}/simple-list`,
|
||||
|
||||
Reference in New Issue
Block a user