import dayjs from 'dayjs'; import type { WorkbenchActivityItemSource, WorkbenchKpiSource, WorkbenchMyWeekWorklogSource, WorkbenchProgressBarSource, WorkbenchProjectHealthCardSource, WorkbenchTeamLoadSource, WorkbenchTeamWorklogSource, WorkbenchTodoItemSource } from './homepage'; const now = dayjs(); const iso = (date: dayjs.Dayjs) => date.format('YYYY-MM-DD HH:mm:ss'); export const workbenchKpiMock = { todo: { count: 8, diffFromYesterday: 1 }, task: { count: 14, diffFromYesterday: -1 }, project: { count: 3, activeCount: 2 }, requirement: { count: 6, pendingReview: 2 } } satisfies WorkbenchKpiSource; export const workbenchTodoMock = [ { id: 'todo-1', category: 'task', title: '支付回调接口联调遗留问题处理', createdTime: iso(now.subtract(7, 'day').hour(9).minute(20)), deadline: iso(now.subtract(1, 'day').hour(17).minute(30)), source: '收银台 V3 · 后端联调', priority: 'high', overdue: true, routeKey: 'project_list' }, { id: 'todo-2', category: 'ticket', title: '工单 #1018 用户登录异常', createdTime: iso(now.subtract(6, 'day').hour(11).minute(0)), deadline: iso(now.subtract(2, 'day').hour(10).minute(0)), source: '客户支持 · 紧急', priority: 'mid', overdue: true, routeKey: 'ticket' }, { id: 'todo-3', category: 'approval', title: '李四 · 第 21 周周报待审批', createdTime: iso(now.subtract(2, 'day').hour(18).minute(20)), deadline: null, source: '周报 · 产品组', priority: 'mid', routeKey: 'workbench' }, { id: 'todo-4', category: 'personal', title: '提交昨日工时与本周计划', createdTime: iso(now.subtract(4, 'day').hour(8).minute(30)), deadline: iso(now.hour(18).minute(0)), source: '个人事项 · 工时', priority: 'mid', routeKey: 'personal-center_my-item' }, { id: 'todo-5', category: 'task', title: '会员等级提示文案最终校对', createdTime: iso(now.subtract(3, 'day').hour(10).minute(10)), deadline: iso(now.hour(20).minute(0)), source: '会员中心 · 文案', priority: 'high', routeKey: 'project_list' }, { id: 'todo-6', category: 'ticket', title: '工单 #1024 客户反馈待处理', createdTime: iso(now.subtract(3, 'day').hour(15).minute(0)), deadline: iso(now.add(2, 'day').hour(17).minute(0)), source: '王五 · 客户反馈', priority: 'mid', routeKey: 'ticket' }, { id: 'todo-7', category: 'personal', title: '复盘上周交付遗留并归档', createdTime: iso(now.subtract(2, 'day').hour(9).minute(0)), deadline: iso(now.add(4, 'day').hour(18).minute(0)), source: '个人事项 · 复盘', priority: 'low', routeKey: 'personal-center_my-item' }, { id: 'todo-8', category: 'task', title: '订单中心结算文档评审', createdTime: iso(now.subtract(2, 'day').hour(13).minute(20)), deadline: iso(now.add(5, 'day').hour(15).minute(0)), source: '订单中心 · 文档', priority: 'mid', routeKey: 'project_list' }, { id: 'todo-9', category: 'approval', title: '张三 · 5 月加班 12h 申请待审批', createdTime: iso(now.subtract(1, 'day').hour(17).minute(0)), deadline: null, source: '加班申请 · 研发组', priority: 'mid', routeKey: 'workbench' }, { id: 'todo-10', category: 'personal', title: '安排下周外出培训行程', createdTime: iso(now.subtract(1, 'day').hour(19).minute(40)), deadline: iso(now.add(10, 'day').hour(12).minute(0)), source: '个人事项 · 行程', priority: 'low', routeKey: 'personal-center_my-item' }, { id: 'todo-11', category: 'task', title: '会员中心首页骨架屏改造', createdTime: iso(now.subtract(20, 'hour')), deadline: iso(now.add(12, 'day').hour(18).minute(0)), source: '会员中心 · 前端', priority: 'low', routeKey: 'project_list' }, { id: 'todo-12', category: 'ticket', title: '工单 #1031 提示信息文案优化', createdTime: iso(now.subtract(8, 'hour')), deadline: iso(now.add(14, 'day').hour(17).minute(0)), source: '客户支持 · 普通', priority: 'low', routeKey: 'ticket' } ] satisfies WorkbenchTodoItemSource[]; export const workbenchActivityMock = [ { id: 'act-1', actor: '张三', action: '提交了需求评审申请', target: '订单导出 V2', targetKind: 'requirement', time: iso(now.subtract(10, 'minute')) }, { id: 'act-2', actor: '李四', action: '完成了任务', target: '支付回调接口联调', targetKind: 'task', time: iso(now.subtract(2, 'hour')) }, { id: 'act-3', actor: '李四', action: '在需求中 @ 了你', target: '会员等级', targetKind: 'requirement', time: iso(now.subtract(1, 'day').hour(17).minute(23)), mentioned: true }, { id: 'act-4', actor: '王五', action: '提交了工单', target: '#1024 · 客户反馈', targetKind: 'ticket', time: iso(now.subtract(1, 'day').hour(15).minute(8)) }, { id: 'act-5', actor: '赵六', action: '把项目状态调整为', target: '试运行(订单中心)', targetKind: 'project', time: iso(now.subtract(2, 'day').hour(10).minute(0)) }, { id: 'act-6', actor: '系统', action: '提醒:你有 1 项任务即将逾期', target: 'API 返回结构调整评审', targetKind: 'requirement', time: iso(now.subtract(3, 'day').hour(9).minute(30)) }, { id: 'act-7', actor: '钱七', action: '更新了产品资料', target: '收银台 V3 · 定位说明', targetKind: 'product', time: iso(now.subtract(4, 'day').hour(16).minute(45)) } ] satisfies WorkbenchActivityItemSource[]; const currentWeekStart = now.startOf('isoWeek').format('YYYY-MM-DD'); const previousWeekStart = now.subtract(1, 'week').startOf('isoWeek').format('YYYY-MM-DD'); export const workbenchMyWeekWorklogMock = { current: { weekStart: currentWeekStart, weeklyFilledHours: 5, dailyHours: [4, 7, 6, 8, 7.5], target: 40, distribution: [ { key: 'prj-mall-v2', label: '商城 V2 升级', hours: 12.5, kind: 'project', projectId: 'prj-mall-v2' }, { key: 'prj-risk', label: '风控引擎接入', hours: 8, kind: 'project', projectId: 'prj-risk' }, { key: 'prj-cashier', label: '收银台 V3', hours: 6, kind: 'project', projectId: 'prj-cashier' }, { key: 'prj-order', label: '订单中心', hours: 5, kind: 'project', projectId: 'prj-order' }, { key: 'prj-member', label: '会员中心', hours: 3, kind: 'project', projectId: 'prj-member' }, { key: 'prj-marketing', label: '营销中台', hours: 2, kind: 'project', projectId: 'prj-marketing' }, { key: 'personal', label: '个人事项', hours: 4, kind: 'personal' }, { key: 'other', label: '其他', hours: 2, kind: 'other' } ] }, previous: { weekStart: previousWeekStart, weeklyFilledHours: 0, dailyHours: [8, 8, 7, 8, 7], target: 40, distribution: [ { key: 'prj-mall-v2', label: '商城 V2 升级', hours: 15, kind: 'project', projectId: 'prj-mall-v2' }, { key: 'prj-risk', label: '风控引擎接入', hours: 9, kind: 'project', projectId: 'prj-risk' }, { key: 'prj-cashier', label: '收银台 V3', hours: 7, kind: 'project', projectId: 'prj-cashier' }, { key: 'personal', label: '个人事项', hours: 5, kind: 'personal' }, { key: 'other', label: '其他', hours: 2, kind: 'other' } ] } } satisfies WorkbenchMyWeekWorklogSource; // 团队工时口径约定:「团队 = 当前用户所在团队,含自己」。 // 后端 /workbench/team-worklog 接口返回的 members 必须包含当前用户自己—— // 这样没有下级的人(普通员工)切到「团队工时」tab 也至少有自己这一条数据, // 不会出现空白态。约定 members[0] = 当前用户,UI 用「(我)」后缀标识。 export const workbenchTeamWorklogMock = { current: { weekStart: currentWeekStart, expectedHoursPerMember: 40, members: [ { memberId: 'u-1', memberName: '张三(我)', items: [ { key: 'prj-cashier', label: '收银台 V3', hours: 22, kind: 'project' }, { key: 'prj-order', label: '订单中心', hours: 10, kind: 'project' }, { key: 'personal', label: '个人事项', hours: 4, kind: 'personal' }, { key: 'other', label: '其他', hours: 2, kind: 'other' } ] }, { memberId: 'u-2', memberName: '李四', items: [ { key: 'prj-cashier', label: '收银台 V3', hours: 18, kind: 'project' }, { key: 'prj-member', label: '会员中心', hours: 20, kind: 'project' }, { key: 'personal', label: '个人事项', hours: 3, kind: 'personal' }, { key: 'other', label: '其他', hours: 1, kind: 'other' } ] }, { memberId: 'u-3', memberName: '王五', items: [ { key: 'prj-member', label: '会员中心', hours: 14, kind: 'project' }, { key: 'prj-order', label: '订单中心', hours: 12, kind: 'project' }, { key: 'personal', label: '个人事项', hours: 2, kind: 'personal' }, { key: 'other', label: '其他', hours: 2, kind: 'other' } ] }, { memberId: 'u-4', memberName: '赵六', items: [ { key: 'prj-cashier', label: '收银台 V3', hours: 24, kind: 'project' }, { key: 'prj-order', label: '订单中心', hours: 18, kind: 'project' }, { key: 'prj-member', label: '会员中心', hours: 4, kind: 'project' }, { key: 'personal', label: '个人事项', hours: 2, kind: 'personal' } ] }, { memberId: 'u-5', memberName: '钱七', items: [ { key: 'prj-order', label: '订单中心', hours: 14, kind: 'project' }, { key: 'personal', label: '个人事项', hours: 6, kind: 'personal' }, { key: 'other', label: '其他', hours: 5, kind: 'other' } ] } ] }, previous: { weekStart: previousWeekStart, expectedHoursPerMember: 40, members: [ { memberId: 'u-1', memberName: '张三(我)', items: [ { key: 'prj-cashier', label: '收银台 V3', hours: 26, kind: 'project' }, { key: 'prj-order', label: '订单中心', hours: 8, kind: 'project' }, { key: 'personal', label: '个人事项', hours: 3, kind: 'personal' }, { key: 'other', label: '其他', hours: 3, kind: 'other' } ] }, { memberId: 'u-2', memberName: '李四', items: [ { key: 'prj-cashier', label: '收银台 V3', hours: 15, kind: 'project' }, { key: 'prj-member', label: '会员中心', hours: 22, kind: 'project' }, { key: 'personal', label: '个人事项', hours: 4, kind: 'personal' } ] }, { memberId: 'u-3', memberName: '王五', items: [ { key: 'prj-member', label: '会员中心', hours: 16, kind: 'project' }, { key: 'prj-order', label: '订单中心', hours: 10, kind: 'project' }, { key: 'personal', label: '个人事项', hours: 5, kind: 'personal' }, { key: 'other', label: '其他', hours: 3, kind: 'other' } ] }, { memberId: 'u-4', memberName: '赵六', items: [ { key: 'prj-cashier', label: '收银台 V3', hours: 20, kind: 'project' }, { key: 'prj-order', label: '订单中心', hours: 16, kind: 'project' }, { key: 'prj-member', label: '会员中心', hours: 6, kind: 'project' }, { key: 'personal', label: '个人事项', hours: 3, kind: 'personal' } ] }, { memberId: 'u-5', memberName: '钱七', items: [ { key: 'prj-order', label: '订单中心', hours: 16, kind: 'project' }, { key: 'personal', label: '个人事项', hours: 4, kind: 'personal' }, { key: 'other', label: '其他', hours: 4, kind: 'other' } ] } ] } } satisfies { current: WorkbenchTeamWorklogSource; previous: WorkbenchTeamWorklogSource }; // 项目 key 与 workbenchTeamWorklogMock 对齐,保证跨 widget 项目色一致 export const workbenchTeamLoadMock = { weekStart: now.startOf('isoWeek').format('YYYY-MM-DD'), members: [ // 高负载:进行中 7 或 临期+逾期 ≥ 2 { memberId: 'u-1', memberName: '张三', items: [ { key: 'prj-cashier', label: '收银台 V3', kind: 'project', count: 4 }, { key: 'prj-order', label: '订单中心', kind: 'project', count: 2 }, { key: 'personal', label: '个人事项', kind: 'personal', count: 1 } ], dueSoon: 2, overdue: 1 }, { memberId: 'u-4', memberName: '赵六', items: [ { key: 'prj-cashier', label: '收银台 V3', kind: 'project', count: 2 }, { key: 'prj-order', label: '订单中心', kind: 'project', count: 2 }, { key: 'prj-member', label: '会员中心', kind: 'project', count: 1 } ], dueSoon: 1, overdue: 2 }, // 中负载:进行中 ≥ 4 或 临期+逾期 ≥ 1 { memberId: 'u-2', memberName: '李四', items: [ { key: 'prj-cashier', label: '收银台 V3', kind: 'project', count: 2 }, { key: 'prj-member', label: '会员中心', kind: 'project', count: 2 } ], dueSoon: 1, overdue: 0 }, { memberId: 'u-3', memberName: '王五', items: [ { key: 'prj-member', label: '会员中心', kind: 'project', count: 2 }, { key: 'prj-order', label: '订单中心', kind: 'project', count: 1 } ], dueSoon: 1, overdue: 0 }, // 正常 { memberId: 'u-5', memberName: '钱七', items: [ { key: 'prj-order', label: '订单中心', kind: 'project', count: 1 }, { key: 'personal', label: '个人事项', kind: 'personal', count: 1 } ], dueSoon: 0, overdue: 0 } ] } satisfies WorkbenchTeamLoadSource; export const workbenchProjectHealthMock = [ { projectId: 'prj-1', projectName: '收银台 V3', code: 'CASHIER-V3', health: 'yellow', riskCount: 2, overdueTasks: 3, backlogRequirements: 2 }, { projectId: 'prj-2', projectName: '会员中心', code: 'MEMBER', health: 'green', riskCount: 0, overdueTasks: 0, backlogRequirements: 1 }, { projectId: 'prj-3', projectName: '订单中心', code: 'ORDER', health: 'red', riskCount: 4, overdueTasks: 5, backlogRequirements: 6 } ] satisfies WorkbenchProjectHealthCardSource[]; export const workbenchProgressChartMock = [ { projectId: 'prj-1', projectName: '收银台 V3', weekCompletionRate: 78 }, { projectId: 'prj-2', projectName: '会员中心', weekCompletionRate: 62 }, { projectId: 'prj-3', projectName: '订单中心', weekCompletionRate: 45 } ] satisfies WorkbenchProgressBarSource[];