data.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. /* ==========================================================================
  2. 静态示例数据 —— 字段与 src/app/core/api/models.ts 对齐,便于日后替换为 service
  3. (演示版不发起任何写操作)
  4. ========================================================================== */
  5. window.DEMO = (function () {
  6. const me = { id: 'me-1', name: '林一舟', mobile: '138****0210', companyName: '北美数字科技', roles: ['member'] };
  7. // Agent.status: running | idle | error | offline | stopped(blocked 展示见 agentPresence)
  8. const agents = [
  9. { id: 'a-nova', name: 'Nova', specialty: '数据分析 · 报告', status: 'running', currentTask: '季度经营复盘报告',
  10. usage: 68, usageSessions: 42, host: { cpuPercent: 37, memPercent: 52, diskPercent: 21 },
  11. balance: { remainCny: 186.4, pageUrl: '#' }, channels: ['钉钉', '飞书'], unread: 3,
  12. matrixReady: true, sessionStatus: 'ok', heartbeatAt: '刚刚' },
  13. { id: 'a-orbit', name: 'Orbit', specialty: '前端工程 · 交付', status: 'running', currentTask: '移动端首页改版',
  14. usage: 54, usageSessions: 30, host: { cpuPercent: 61, memPercent: 44, diskPercent: 33 },
  15. balance: { remainCny: 92.1, pageUrl: '#' }, channels: ['企业微信'], unread: 2,
  16. matrixReady: true, sessionStatus: 'ok', heartbeatAt: '1 分钟前' },
  17. { id: 'a-echo', name: 'Echo', specialty: '文案 · 内容运营', status: 'idle', currentTask: '等待新指令',
  18. usage: 31, usageSessions: 12, host: { cpuPercent: 6, memPercent: 18, diskPercent: 12 },
  19. balance: { remainCny: 240.0, pageUrl: '#' }, channels: ['邮件'], unread: 0,
  20. matrixReady: true, sessionStatus: 'ok', heartbeatAt: '12 分钟前' },
  21. { id: 'a-pilot', name: 'Pilot', specialty: '运维 · 监控', status: 'error', currentTask: '镜像构建失败',
  22. usage: 22, usageSessions: 7, host: { cpuPercent: 4, memPercent: 22, diskPercent: 15 },
  23. balance: { remainCny: 12.6, pageUrl: '#' }, channels: ['钉钉'], unread: 1,
  24. matrixReady: false, sessionStatus: 'expired', heartbeatAt: '2 小时前' },
  25. { id: 'a-atlas', name: 'Atlas', specialty: '项目管理 · 排期', status: 'running', currentTask: 'Q3 里程碑对齐',
  26. usage: 45, usageSessions: 25, host: { cpuPercent: 28, memPercent: 39, diskPercent: 27 },
  27. balance: { remainCny: 158.9, pageUrl: '#' }, channels: ['飞书'], unread: 0,
  28. matrixReady: true, sessionStatus: 'ok', heartbeatAt: '刚刚' },
  29. { id: 'a-lyra', name: 'Lyra', specialty: '设计 · 视觉规范', status: 'offline', currentTask: '—',
  30. usage: 9, usageSessions: 3, host: { cpuPercent: 0, memPercent: 0, diskPercent: 10 },
  31. balance: { remainCny: 0, pageUrl: '#' }, channels: [], unread: 0,
  32. matrixReady: false, sessionStatus: 'unknown', heartbeatAt: '昨天' },
  33. ];
  34. const people = [
  35. { id: 'p-zhou', name: '周敏', mobile: '139****5521', agents: ['a-nova', 'a-echo'] },
  36. { id: 'p-chen', name: '陈默', mobile: '136****8830', agents: ['a-orbit'] },
  37. { id: 'p-xu', name: '许嘉禾', mobile: '137****2094', agents: ['a-atlas', 'a-pilot'] },
  38. ];
  39. // 会话:group = workspace | daily | archived
  40. const sessions = [
  41. { id: 's-1', agentId: 'a-nova', title: '季度经营复盘报告', group: 'workspace', projectId: 'pr-1',
  42. lastPreview: '已生成 12 页 PPT 与数据附录', lastAt: '09:42', unread: 3, active: true },
  43. { id: 's-2', agentId: 'a-orbit', title: '移动端首页改版', group: 'workspace', projectId: 'pr-2',
  44. lastPreview: '首页骨架已完成,等待你确认配色', lastAt: '09:15', unread: 2 },
  45. { id: 's-3', agentId: 'a-atlas', title: 'Q3 里程碑对齐', group: 'daily',
  46. lastPreview: '本周 3 个阻塞项需要人工确认', lastAt: '昨天', unread: 0 },
  47. { id: 's-4', agentId: 'a-echo', title: '产品发布会通稿润色', group: 'daily',
  48. lastPreview: '已按「克制、专业」语气重写第二段', lastAt: '昨天', unread: 0 },
  49. { id: 's-5', agentId: 'a-pilot', title: '构建流水线排障', group: 'daily',
  50. lastPreview: '镜像拉取超时,疑似网络策略变更', lastAt: '周二', unread: 1 },
  51. { id: 's-6', agentId: 'a-nova', title: '上半年客户满意度分析', group: 'workspace', projectId: 'pr-1',
  52. lastPreview: '交叉分析完成,结论见表格', lastAt: '周一', unread: 0 },
  53. { id: 's-7', agentId: 'a-atlas', title: '旧版排期迁移', group: 'archived',
  54. lastPreview: '已归档', lastAt: '上周', unread: 0 },
  55. { id: 's-8', agentId: 'a-echo', title: '公众号选题池整理', group: 'archived',
  56. lastPreview: '已归档', lastAt: '上周', unread: 0 },
  57. ];
  58. // 完整对话(仅 s-1 / s-2 有历史消息)
  59. const messages = {
  60. 's-1': [
  61. { id: 'm1', sender: 'me', kind: 'text', text: '帮我做一份 2026Q2 的季度经营复盘,输出 PPT,附数据附录。', ts: '09:20' },
  62. { id: 'm2', sender: 'agent', kind: 'rich', ts: '09:42',
  63. processes: [
  64. { label: '拉取 Q2 经营数据(4 张表)', state: 'done' },
  65. { label: '拆解为 6 个分析步骤', state: 'done' },
  66. { label: '生成图表与页面草图', state: 'done' },
  67. ],
  68. markdown: [
  69. { type: 'p', text: '已完成 Q2 复盘。核心结论如下,完整数据见附录表:' },
  70. { type: 'table', head: ['指标', '数值'], rows: [
  71. ['营收', '¥ 4,820 万(环比 +12.4%)'],
  72. ['毛利率', '46.1%(同比 +2.3pt)'],
  73. ['活跃客户', '1,284(净增 96)'],
  74. ['项目交付准时率', '93.8%'],
  75. ] },
  76. { type: 'p', text: '需要我把其中「利润率下滑的 3 个事业部」单独展开一页吗?' },
  77. ] },
  78. { id: 'm3', sender: 'me', kind: 'text', text: '要,单独一页,加上原因分析。', ts: '09:50' },
  79. { id: 'm4', sender: 'agent', kind: 'rich', ts: '09:58',
  80. processes: [{ label: '定位 3 个事业部并归因', state: 'running' }],
  81. markdown: [{ type: 'p', text: '正在整理……' }] },
  82. ],
  83. 's-2': [
  84. { id: 'm1', sender: 'me', kind: 'text', text: '移动端首页骨架先出一版,参考 WorkBuddy 的居中式结构。', ts: '08:40' },
  85. { id: 'm2', sender: 'agent', kind: 'rich', ts: '09:15',
  86. processes: [{ label: '读取设计令牌与组件规范', state: 'done' },
  87. { label: '生成页面骨架', state: 'done' }],
  88. markdown: [{ type: 'p', text: '骨架已完成,配色仍走项目 4 套整体配色。附上本次输出的文件:' }],
  89. files: [{ name: 'mobile-home-spec.pdf', meta: 'PDF · 860 KB · v0.3' },
  90. { name: 'home-layout.md', meta: 'Markdown · 12 KB' }] },
  91. ],
  92. };
  93. const projects = [
  94. { id: 'pr-1', name: 'Q2 经营复盘', code: 'OPS-2026-Q2', owner: '周敏', status: '进行中', due: '2026-11-15',
  95. description: '汇总 3 个事业部 Q2 经营数据,输出复盘报告与会议材料。', hasBlocked: true,
  96. agentIds: ['a-nova'], deliverableIds: ['d-1', 'd-2'], sessionIds: ['s-1', 's-6'] },
  97. { id: 'pr-2', name: '移动端改版', code: 'APP-M-02', owner: '陈默', status: '进行中', due: '2026-12-01',
  98. description: '按新设计令牌重做移动端首页与会话列表,统一 WorkBuddy 式骨架。', hasBlocked: false,
  99. agentIds: ['a-orbit'], deliverableIds: ['d-3'], sessionIds: ['s-2'] },
  100. { id: 'pr-3', name: '发布会准备', code: 'MKT-LAUNCH', owner: '许嘉禾', status: '待启动', due: '2026-12-20',
  101. description: '产品发布会通稿、演示脚本与场地彩排。', hasBlocked: false,
  102. agentIds: ['a-echo', 'a-atlas'], deliverableIds: [], sessionIds: ['s-4'] },
  103. ];
  104. // 任务七态:triage | todo | scheduled | ready | running | blocked | done
  105. const tasks = [
  106. { id: 't-1', title: '导出 Q2 事业部明细表', agentId: 'a-nova', projectId: 'pr-1', status: 'blocked',
  107. blockKind: '数据权限', blockedHours: 6, updatedAt: '今天 08:10',
  108. body: '需要财务系统中「事业部明细」视图的只读权限,当前账号无权限。',
  109. runs: [{ at: '08:02', text: '开始拉取', state: 'done' }, { at: '08:10', text: '权限被拒绝,任务阻塞', state: 'blocked' }],
  110. comments: [{ who: '周敏', at: '08:30', text: '已提工单,预计今天下午开通。' }],
  111. attachments: [] },
  112. { id: 't-2', title: '生成复盘 PPT 第 1-6 页', agentId: 'a-nova', projectId: 'pr-1', status: 'running',
  113. updatedAt: '09:58', body: '按确认的大纲生成 6 页:概览、营收、毛利、客户、交付、结论。',
  114. runs: [{ at: '09:40', text: '大纲确认', state: 'done' }, { at: '09:55', text: '生成第 3 页中', state: 'running' }],
  115. comments: [], attachments: [{ name: 'outline.md', meta: '12 KB' }] },
  116. { id: 't-3', title: '首页骨架代码生成', agentId: 'a-orbit', projectId: 'pr-2', status: 'done',
  117. updatedAt: '昨天 18:20', body: '生成 index / 会话列表两屏骨架。',
  118. runs: [{ at: '昨天 17:40', text: '开始生成', state: 'done' }, { at: '昨天 18:20', text: '完成,等待评审', state: 'done' }],
  119. comments: [{ who: '陈默', at: '昨天 18:40', text: '骨架结构没问题,配色按 4 套来。' }],
  120. attachments: [{ name: 'mobile-home-spec.pdf', meta: '860 KB' }] },
  121. { id: 't-4', title: '新闻发布会通稿初稿', agentId: 'a-echo', projectId: 'pr-3', status: 'ready',
  122. updatedAt: '昨天 15:02', body: '按产品定位写通稿初稿。', runs: [], comments: [], attachments: [] },
  123. { id: 't-5', title: '排期表与风险清单', agentId: 'a-atlas', projectId: 'pr-3', status: 'scheduled',
  124. updatedAt: '周一', body: '汇总 3 个项目排期,标注风险。', runs: [], comments: [], attachments: [] },
  125. { id: 't-6', title: '构建流水线排障', agentId: 'a-pilot', projectId: 'pr-2', status: 'triage',
  126. updatedAt: '周二', body: '镜像拉取超时,需定位网络策略。', runs: [], comments: [], attachments: [] },
  127. { id: 't-7', title: '旧版页面清单归档', agentId: 'a-atlas', projectId: 'pr-2', status: 'todo',
  128. updatedAt: '上周', body: '整理旧版页面,标注下线时间。', runs: [], comments: [], attachments: [] },
  129. ];
  130. const deliverables = [
  131. { id: 'd-1', agentId: 'a-nova', projectId: 'pr-1', title: 'Q2 经营复盘 PPT', version: 'v0.4',
  132. state: 'delivered', deliveredAt: '今天 09:42', fileType: 'pdf', filename: 'Q2-复盘-v0.4.pdf', size: '3.2 MB',
  133. artifacts: [{ name: 'Q2-复盘-v0.4.pdf', type: 'pdf' }, { name: '数据附录.xlsx', type: 'xlsx' }] },
  134. { id: 'd-2', agentId: 'a-nova', projectId: 'pr-1', title: '客户满意度交叉分析', version: 'v1.0',
  135. state: 'delivered', deliveredAt: '周一 16:20', fileType: 'xlsx', filename: '满意度交叉分析.xlsx', size: '640 KB',
  136. artifacts: [{ name: '满意度交叉分析.xlsx', type: 'xlsx' }] },
  137. { id: 'd-3', agentId: 'a-orbit', projectId: 'pr-2', title: '移动端首页骨架', version: 'v0.3',
  138. state: 'delivered', deliveredAt: '昨天 18:20', fileType: 'pdf', filename: 'mobile-home-spec.pdf', size: '860 KB',
  139. artifacts: [{ name: 'mobile-home-spec.pdf', type: 'pdf' }, { name: 'home-layout.md', type: 'md' }] },
  140. { id: 'd-4', agentId: 'a-echo', projectId: 'pr-3', title: '发布会通稿', version: 'v0.1',
  141. state: 'failed', deliveredAt: '昨天 15:02', fileType: 'doc', filename: '通稿-v0.1.docx', size: '—',
  142. artifacts: [] },
  143. ];
  144. // category: delivery | execution | alert
  145. const events = [
  146. { id: 'e-1', category: 'delivery', title: 'Nova 交付《Q2 经营复盘 PPT》', description: 'v0.4 · 12 页', time: '09:42', day: '今天', agentId: 'a-nova', deliverableId: 'd-1' },
  147. { id: 'e-2', category: 'execution', title: 'Nova 执行中:生成复盘 PPT 第 3 页', time: '09:55', day: '今天', agentId: 'a-nova', taskId: 't-2' },
  148. { id: 'e-3', category: 'alert', title: 'Pilot 镜像构建失败', description: '镜像拉取超时,疑似网络策略变更', time: '08:10', day: '今天', agentId: 'a-pilot', taskId: 't-6' },
  149. { id: 'e-4', category: 'delivery', title: 'Orbit 交付《移动端首页骨架》', description: 'v0.3 · PDF + Markdown', time: '18:20', day: '昨天', agentId: 'a-orbit', deliverableId: 'd-3' },
  150. { id: 'e-5', category: 'alert', title: '任务阻塞超过 6 小时:导出事业部明细表', time: '08:10', day: '今天', agentId: 'a-nova', taskId: 't-1' },
  151. { id: 'e-6', category: 'delivery', title: 'Nova 交付《客户满意度交叉分析》', description: 'v1.0 · Excel', time: '16:20', day: '周一', agentId: 'a-nova', deliverableId: 'd-2' },
  152. ];
  153. const navMenu = [
  154. { key: 'projects', label: '项目', icon: 'folder' },
  155. { key: 'tasks', label: '任务', icon: 'check-square' },
  156. { key: 'contacts', label: '通讯录', icon: 'users' },
  157. { key: 'events', label: '事件', icon: 'activity' },
  158. { key: 'deliverables', label: '成果', icon: 'package' },
  159. { key: 'workbench', label: '工作台', icon: 'grid' },
  160. ];
  161. const STATUS_TEXT = {
  162. running: '运行中', idle: '空闲', error: '异常', offline: '离线', stopped: '已停止',
  163. };
  164. const TASK_STATUS_TEXT = {
  165. triage: '待分类', todo: '待办', scheduled: '已排期', ready: '就绪',
  166. running: '执行中', blocked: '阻塞', done: '已完成',
  167. };
  168. const TASK_TONE = {
  169. running: 'info', blocked: 'danger', done: 'success',
  170. triage: '', todo: '', scheduled: '', ready: '',
  171. };
  172. // 与《设计令牌.md》§5.1 一致:running/idle 走语义色;error/offline/stopped 走 danger
  173. const AGENT_TONE = { running: 'success', idle: 'warning', error: 'danger', offline: 'danger', stopped: 'danger' };
  174. const agentById = id => agents.find(a => a.id === id);
  175. const sessionById = id => sessions.find(s => s.id === id);
  176. const taskById = id => tasks.find(t => t.id === id);
  177. const projectById = id => projects.find(p => p.id === id);
  178. const deliverableById = id => deliverables.find(d => d.id === id);
  179. return {
  180. me, agents, people, sessions, messages, projects, tasks, deliverables, events, navMenu,
  181. STATUS_TEXT, TASK_STATUS_TEXT, TASK_TONE, AGENT_TONE,
  182. agentById, sessionById, taskById, projectById, deliverableById,
  183. };
  184. })();