project-retrospective-ai.service.ts 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. import { Injectable } from '@angular/core';
  2. import { completionJSON } from 'fmode-ng/core/agent/chat/completion';
  3. @Injectable({ providedIn: 'root' })
  4. export class ProjectRetrospectiveAIService {
  5. constructor() {}
  6. async generate(options: {
  7. project: any; // FmodeObject (仅用于取标题/时间)
  8. data: any; // collectProjectData() 的结果
  9. onProgress?: (msg: string) => void;
  10. }): Promise<any> {
  11. const { project, data } = options;
  12. const safe = {
  13. title: project?.get?.('title') || '',
  14. createdAt: project?.get?.('createdAt') || '',
  15. products: (data?.products || []).map((p: any) => ({ id: p.id, name: p.name, type: p.type })),
  16. payments: {
  17. totalAmount: data?.finalPayment?.totalAmount || 0,
  18. paidAmount: data?.finalPayment?.paidAmount || 0,
  19. remainingAmount: data?.finalPayment?.remainingAmount || 0,
  20. status: data?.finalPayment?.status || 'pending'
  21. },
  22. feedback: {
  23. overallRating: data?.customerFeedback?.overallRating || 0,
  24. dimensionRatings: data?.customerFeedback?.dimensionRatings || {}
  25. }
  26. };
  27. const prompt = `你是一名项目复盘分析专家。请基于下面的项目数据,输出结构化复盘JSON:\n\n` +
  28. JSON.stringify(safe, null, 2) +
  29. `\n\n请严格输出为 JSON,字段含义如下:
  30. {
  31. "summary": string, // 100-200字项目摘要
  32. "highlights": string[], // 3-6条亮点
  33. "challenges": string[], // 3-6条挑战
  34. "recommendations": string[], // 3-6条可执行建议
  35. "efficiencyAnalysis": {
  36. "overallScore": number, // 0-100
  37. "grade": "A"|"B"|"C"|"D"|"F",
  38. "stageMetrics": [
  39. { "stage": string, "plannedDays": number, "actualDays": number, "efficiency": number, "status": "on-time"|"delayed"|"ahead" }
  40. ]
  41. },
  42. "financialAnalysis": { "revenueAnalysis": { "contracted": number, "received": number, "pending": number }, "profitMargin": number, "budgetVariance": number },
  43. "satisfactionAnalysis": { "overallScore": number, "nps": number },
  44. "risksAndOpportunities": { "risks": [{"type":"timeline"|"budget"|"quality"|"resource"|"scope","description":string,"severity":"high"|"medium"|"low"}], "opportunities": [{"area":string, "description":string, "priority":"high"|"medium"|"low"}] }
  45. }`;
  46. const outputSchema = `{
  47. "summary": "",
  48. "highlights": [""],
  49. "challenges": [""],
  50. "recommendations": [""],
  51. "efficiencyAnalysis": { "overallScore": 80, "grade": "B", "stageMetrics": [{"stage":"交付执行","plannedDays":10,"actualDays":11,"efficiency":91,"status":"delayed"}] },
  52. "financialAnalysis": { "revenueAnalysis": { "contracted": 0, "received": 0, "pending": 0 }, "profitMargin": 20, "budgetVariance": 0 },
  53. "satisfactionAnalysis": { "overallScore": 80, "nps": 20 },
  54. "risksAndOpportunities": { "risks": [{"type":"timeline","description":"进度波动","severity":"medium"}], "opportunities": [{"area":"复购","description":"客户满意度较高","priority":"high"}] }
  55. }`;
  56. options.onProgress?.('AI 正在生成复盘...');
  57. const result = await completionJSON(
  58. prompt,
  59. outputSchema,
  60. () => options.onProgress?.('分析中...'),
  61. 2,
  62. { model: 'doubao-1.6', vision: false }
  63. );
  64. return result || {};
  65. }
  66. }