refactor(projects): 1、新增执行任务,表单优化;2、删除逻辑丰富。3、修改已知问题
This commit is contained in:
@@ -345,3 +345,138 @@ export function getTodayLabel() {
|
||||
const weekdayMap = ['日', '一', '二', '三', '四', '五', '六'];
|
||||
return `今天 ${today.format('YYYY-MM-DD')} 星期${weekdayMap[today.day()]}`;
|
||||
}
|
||||
|
||||
export type WorkbenchMyTaskBucket = 'today' | 'week' | 'overdue' | 'all';
|
||||
|
||||
export interface WorkbenchMyTaskItemSource {
|
||||
id: string;
|
||||
title: string;
|
||||
statusCode: string;
|
||||
statusLabel: string;
|
||||
executionName: string;
|
||||
projectName: string;
|
||||
priority: 'high' | 'mid' | 'low';
|
||||
deadline: string | null;
|
||||
}
|
||||
|
||||
export interface WorkbenchMyTaskItem extends Omit<WorkbenchMyTaskItemSource, 'deadline'> {
|
||||
deadlineLabel: string;
|
||||
remainingDays: number | null;
|
||||
overdue: boolean;
|
||||
}
|
||||
|
||||
export function buildWorkbenchMyTaskItems(source: readonly WorkbenchMyTaskItemSource[]): WorkbenchMyTaskItem[] {
|
||||
return [...source]
|
||||
.sort((a, b) => {
|
||||
const av = a.deadline ? dayjs(a.deadline).valueOf() : Number.POSITIVE_INFINITY;
|
||||
const bv = b.deadline ? dayjs(b.deadline).valueOf() : Number.POSITIVE_INFINITY;
|
||||
return av - bv;
|
||||
})
|
||||
.map(item => {
|
||||
const remaining = getRemainingDays(item.deadline);
|
||||
return {
|
||||
...item,
|
||||
deadlineLabel: formatDeadline(item.deadline),
|
||||
remainingDays: remaining,
|
||||
overdue: remaining !== null && remaining < 0
|
||||
} satisfies WorkbenchMyTaskItem;
|
||||
});
|
||||
}
|
||||
|
||||
export function filterWorkbenchMyTaskItems(items: readonly WorkbenchMyTaskItem[], bucket: WorkbenchMyTaskBucket) {
|
||||
if (bucket === 'all') return [...items];
|
||||
if (bucket === 'overdue') return items.filter(i => i.overdue);
|
||||
if (bucket === 'today') return items.filter(i => i.remainingDays === 0);
|
||||
return items.filter(i => i.remainingDays !== null && i.remainingDays >= 0 && i.remainingDays <= 7);
|
||||
}
|
||||
|
||||
export interface WorkbenchMyRequirementGroupSource {
|
||||
statusCode: string;
|
||||
statusLabel: string;
|
||||
count: number;
|
||||
tone: 'sky' | 'amber' | 'emerald' | 'rose';
|
||||
}
|
||||
|
||||
export type WorkbenchMyRequirementGroup = WorkbenchMyRequirementGroupSource;
|
||||
|
||||
export function buildWorkbenchMyRequirementGroups(
|
||||
source: readonly WorkbenchMyRequirementGroupSource[]
|
||||
): WorkbenchMyRequirementGroup[] {
|
||||
return [...source];
|
||||
}
|
||||
|
||||
export interface WorkbenchTeamTodoRowSource {
|
||||
projectId: string;
|
||||
projectName: string;
|
||||
memberId: string;
|
||||
memberName: string;
|
||||
inProgress: number;
|
||||
overdue: number;
|
||||
weekDone: number;
|
||||
}
|
||||
|
||||
export type WorkbenchTeamTodoRow = WorkbenchTeamTodoRowSource;
|
||||
|
||||
export function buildWorkbenchTeamTodoRows(source: readonly WorkbenchTeamTodoRowSource[]): WorkbenchTeamTodoRow[] {
|
||||
return [...source].sort((a, b) => b.overdue - a.overdue);
|
||||
}
|
||||
|
||||
export type WorkbenchHealthLevel = 'green' | 'yellow' | 'red';
|
||||
|
||||
export interface WorkbenchProjectHealthCardSource {
|
||||
projectId: string;
|
||||
projectName: string;
|
||||
code: string;
|
||||
health: WorkbenchHealthLevel;
|
||||
riskCount: number;
|
||||
overdueTasks: number;
|
||||
backlogRequirements: number;
|
||||
}
|
||||
|
||||
export interface WorkbenchProjectHealthCard extends WorkbenchProjectHealthCardSource {
|
||||
healthLabel: string;
|
||||
}
|
||||
|
||||
export function buildWorkbenchProjectHealthCards(
|
||||
source: readonly WorkbenchProjectHealthCardSource[]
|
||||
): WorkbenchProjectHealthCard[] {
|
||||
const labelMap: Record<WorkbenchHealthLevel, string> = { green: '健康', yellow: '关注', red: '风险' };
|
||||
return source.map(s => ({ ...s, healthLabel: labelMap[s.health] }));
|
||||
}
|
||||
|
||||
export interface WorkbenchProgressBarSource {
|
||||
projectId: string;
|
||||
projectName: string;
|
||||
/** 完成率 0-100 */
|
||||
weekCompletionRate: number;
|
||||
}
|
||||
|
||||
export type WorkbenchProgressBar = WorkbenchProgressBarSource;
|
||||
|
||||
export function buildWorkbenchProgressBars(source: readonly WorkbenchProgressBarSource[]): WorkbenchProgressBar[] {
|
||||
return source.map(s => ({ ...s, weekCompletionRate: Math.min(100, Math.max(0, Math.round(s.weekCompletionRate))) }));
|
||||
}
|
||||
|
||||
export type WorkbenchFavoriteKind = 'product' | 'project' | 'requirement' | 'task';
|
||||
|
||||
export interface WorkbenchFavoriteItemSource {
|
||||
id: string;
|
||||
kind: WorkbenchFavoriteKind;
|
||||
title: string;
|
||||
source: string;
|
||||
}
|
||||
|
||||
export interface WorkbenchFavoriteItem extends WorkbenchFavoriteItemSource {
|
||||
kindLabel: string;
|
||||
kindTone: 'sky' | 'emerald' | 'amber' | 'rose';
|
||||
}
|
||||
|
||||
export function buildWorkbenchFavoriteItems(source: readonly WorkbenchFavoriteItemSource[]): WorkbenchFavoriteItem[] {
|
||||
const meta: Record<WorkbenchFavoriteKind, { label: string; tone: 'sky' | 'emerald' | 'amber' | 'rose' }> = {
|
||||
product: { label: '产品', tone: 'sky' },
|
||||
project: { label: '项目', tone: 'emerald' },
|
||||
requirement: { label: '需求', tone: 'amber' },
|
||||
task: { label: '任务', tone: 'rose' }
|
||||
};
|
||||
return source.map(s => ({ ...s, kindLabel: meta[s.kind].label, kindTone: meta[s.kind].tone }));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user