feat(新增需求评审功能): 新增需求评审功能。

feat(动态切换对象域下的对象):对象域下的对象可以动态切换。
fix(产品需求、项目需求): 按照会议意见修改诸多细节。
fix(产品对象域的概览界面): 把假数据换成真实的需求统计数据。
This commit is contained in:
dk
2026-05-22 14:05:25 +08:00
parent ab882e085b
commit 13b74cfe97
36 changed files with 3764 additions and 771 deletions

View File

@@ -49,15 +49,6 @@ export interface ProductHomepageTimelineItem {
tone: 'sky' | 'emerald' | 'amber' | 'rose' | 'slate';
}
export interface ProductRequirementPoolSummarySource {
total: number;
todo: number;
analyzing: number;
planned: number;
done: number;
highPriorityTodo: number;
}
export interface ProductRequirementPoolSummary {
metrics: ProductHomepageMetric[];
distribution: Array<{
@@ -67,22 +58,16 @@ export interface ProductRequirementPoolSummary {
total: number;
todo: number;
highPriorityTodo: number;
}
export interface ProductRequirementPoolRecentChangeSource {
id: string;
title: string;
actionLabel: string;
time: string;
statusLabel: string;
completionRate: number;
}
export interface ProductRequirementPoolRecentChange {
id: string;
title: string;
actionType: Api.Product.ProductRequirementDashboardRecentChangeActionType;
actionLabel: string;
time: string;
statusLabel: string;
content: string;
}
export interface ProductHomepageExtensionModule {
@@ -182,19 +167,20 @@ function resolveLatestTimelineTime(
}
export function buildRequirementPoolSummary(
source: ProductRequirementPoolSummarySource | null | undefined
source: Api.Product.ProductRequirementDashboardSummary | null | undefined
): ProductRequirementPoolSummary {
const total = normalizeCount(source?.total);
const todo = normalizeCount(source?.todo);
const analyzing = normalizeCount(source?.analyzing);
const planned = normalizeCount(source?.planned);
const done = normalizeCount(source?.done);
const pendingClaim = normalizeCount(source?.pendingClaim);
const pendingReview = normalizeCount(source?.pendingReview);
const pendingDispatch = normalizeCount(source?.pendingDispatch);
const completionRate = Math.min(100, normalizeCount(source?.completionRate));
const highPriorityTodo = normalizeCount(source?.highPriorityTodo);
const distribution = [
{ label: '待处理', value: String(todo) },
{ label: '分析中', value: String(analyzing) },
{ label: '已规划', value: String(planned) },
{ label: '已完成', value: String(done) }
{ label: '待处理', value: String(todo) },
{ label: '等待认领', value: String(pendingClaim) },
{ label: '等待评审', value: String(pendingReview) },
{ label: '等待指派', value: String(pendingDispatch) }
];
return {
@@ -212,30 +198,35 @@ export function buildRequirementPoolSummary(
{
label: '待处理',
value: String(todo),
hint: '等待进入分析或分派的需求数量'
hint: '等待认领、评审、指派的需求,这些需求应该着重关注'
},
{
label: '高优先级待处理',
value: String(highPriorityTodo),
hint: '需要优先推进的待处理需求数量'
hint: '需要优先推进的待处理需求数量P0、P1类型的需求'
}
],
distribution,
total,
todo,
highPriorityTodo
highPriorityTodo,
completionRate
};
}
export function buildRequirementPoolRecentChanges(
source: readonly ProductRequirementPoolRecentChangeSource[] | null | undefined
source: readonly Api.Product.ProductRequirementDashboardRecentChange[] | null | undefined
) {
return [...(source || [])]
.filter(item => getTimeValue(item.time) > 0)
.sort((left, right) => getTimeValue(right.time) - getTimeValue(left.time))
.filter(item => getTimeValue(item.occurredAt) > 0)
.sort((left, right) => getTimeValue(right.occurredAt) - getTimeValue(left.occurredAt))
.map(item => ({
...item,
time: formatDateTime(item.time)
id: item.id,
title: item.title,
actionType: item.actionType,
actionLabel: item.actionLabel,
content: item.content,
time: formatDateTime(item.occurredAt)
})) satisfies ProductRequirementPoolRecentChange[];
}
@@ -368,7 +359,7 @@ function buildProductHomepageBannerMetrics(source: ProductHomepageBannerSource)
{
label: '待处理需求',
value: String(requirementSummary.todo),
hint: '等待进入分析或分派的需求数量'
hint: '需要进行认领、评审、指派的需求,这些需求应该着重关注'
},
{
label: '最近动态时间',