feat(workspace): 添加个人日报派生逻辑

This commit is contained in:
Script Generator
2026-06-26 14:40:37 +08:00
parent 914e6180c1
commit 6b965429ce
2 changed files with 186 additions and 0 deletions

View File

@@ -0,0 +1,123 @@
import test from 'node:test';
import assert from 'node:assert/strict';
import type { TaskWorklog } from './task-worklog';
import type { WorkItem } from './workspace-engine';
import { getWorkspaceDailyReport } from './workspace-daily-report';
const workItems: WorkItem[] = [
{
id: 'task-1',
type: 'devTask',
title: '实现登录接口',
status: 'in_progress',
completed: false,
productName: 'FTB',
projectName: '项目管理',
versionName: 'V1.0',
versionId: 'version-1',
raw: {} as any,
},
{
id: 'task-2',
type: 'bug',
title: '修复菜单错位',
status: 'fixing',
completed: false,
productName: 'FTB',
projectName: '项目管理',
versionName: 'V1.0',
versionId: 'version-1',
raw: {} as any,
},
];
const worklogs: TaskWorklog[] = [
{
id: 'wl-1',
taskId: 'task-1',
userId: '张三',
date: '2026-06-26',
hours: 1.5,
workContent: '完成登录接口联调',
createdAt: '2026-06-26T02:00:00.000Z',
},
{
id: 'wl-2',
taskId: 'task-2',
userId: '张三',
date: '2026-06-26',
hours: 0.5,
workContent: '定位菜单错位原因',
createdAt: '2026-06-26T03:00:00.000Z',
},
{
id: 'wl-other-user',
taskId: 'task-1',
userId: '李四',
date: '2026-06-26',
hours: 8,
workContent: '其他人的日报',
createdAt: '2026-06-26T04:00:00.000Z',
},
{
id: 'wl-other-date',
taskId: 'task-1',
userId: '张三',
date: '2026-06-25',
hours: 8,
workContent: '昨天的日报',
createdAt: '2026-06-25T04:00:00.000Z',
},
];
test('getWorkspaceDailyReport filters by current user and date', () => {
const report = getWorkspaceDailyReport({
worklogs,
workItems,
userId: '张三',
date: '2026-06-26',
});
assert.equal(report.totalHours, 2);
assert.equal(report.totalCount, 2);
assert.deepEqual(report.items.map((item) => item.id), ['wl-2', 'wl-1']);
});
test('getWorkspaceDailyReport resolves task title and workspace context', () => {
const report = getWorkspaceDailyReport({
worklogs,
workItems,
userId: '张三',
date: '2026-06-26',
});
assert.equal(report.items[0].taskTitle, '修复菜单错位');
assert.equal(report.items[0].productName, 'FTB');
assert.equal(report.items[0].projectName, '项目管理');
assert.equal(report.items[0].versionName, 'V1.0');
});
test('getWorkspaceDailyReport keeps logs whose task is no longer visible', () => {
const report = getWorkspaceDailyReport({
worklogs: [
{
id: 'wl-missing',
taskId: 'deleted-task',
userId: '张三',
date: '2026-06-26',
hours: 0.5,
workContent: '处理历史任务',
createdAt: '2026-06-26T01:00:00.000Z',
},
],
workItems: [],
userId: '张三',
date: '2026-06-26',
});
assert.equal(report.totalHours, 0.5);
assert.equal(report.totalCount, 1);
assert.equal(report.items[0].taskTitle, '未知任务');
assert.equal(report.items[0].workContent, '处理历史任务');
});

View File

@@ -0,0 +1,63 @@
import type { TaskWorklog } from './task-worklog';
import type { WorkItem } from './workspace-engine';
export interface WorkspaceDailyReportItem {
id: string;
taskId: string;
taskTitle: string;
workContent: string;
hours: number;
createdAt: string;
productName?: string;
projectName?: string;
versionName?: string;
}
export interface WorkspaceDailyReport {
date: string;
totalHours: number;
totalCount: number;
items: WorkspaceDailyReportItem[];
}
interface GetWorkspaceDailyReportInput {
worklogs: TaskWorklog[];
workItems: WorkItem[];
userId: string;
date: string;
}
export function getWorkspaceDailyReport({
worklogs,
workItems,
userId,
date,
}: GetWorkspaceDailyReportInput): WorkspaceDailyReport {
const workItemMap = new Map(workItems.map((item) => [item.id, item]));
const items = worklogs
.filter((log) => log.userId === userId && log.date === date)
.sort((a, b) => b.createdAt.localeCompare(a.createdAt))
.map((log) => {
const item = workItemMap.get(log.taskId);
return {
id: log.id,
taskId: log.taskId,
taskTitle: item?.title ?? '未知任务',
workContent: log.workContent,
hours: log.hours,
createdAt: log.createdAt,
productName: item?.productName,
projectName: item?.projectName,
versionName: item?.versionName,
};
});
return {
date,
totalHours: items.reduce((sum, item) => sum + item.hours, 0),
totalCount: items.length,
items,
};
}