|
@@ -1,6 +1,8 @@
|
|
|
package space.anyi.server.service.impl;
|
|
package space.anyi.server.service.impl;
|
|
|
|
|
|
|
|
|
|
+import org.springframework.ai.chat.client.ChatClient;
|
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
+import reactor.core.publisher.Flux;
|
|
|
import space.anyi.common.dto.*;
|
|
import space.anyi.common.dto.*;
|
|
|
import space.anyi.server.service.AiService;
|
|
import space.anyi.server.service.AiService;
|
|
|
import space.anyi.server.service.StatisticsService;
|
|
import space.anyi.server.service.StatisticsService;
|
|
@@ -10,9 +12,11 @@ import java.util.List;
|
|
|
public class AiServiceImpl implements AiService {
|
|
public class AiServiceImpl implements AiService {
|
|
|
|
|
|
|
|
private final StatisticsService statisticsService;
|
|
private final StatisticsService statisticsService;
|
|
|
|
|
+ private final ChatClient chatClient;
|
|
|
|
|
|
|
|
- public AiServiceImpl(StatisticsService statisticsService) {
|
|
|
|
|
|
|
+ public AiServiceImpl(StatisticsService statisticsService, ChatClient.Builder chatClientBuilder) {
|
|
|
this.statisticsService = statisticsService;
|
|
this.statisticsService = statisticsService;
|
|
|
|
|
+ this.chatClient = chatClientBuilder.build();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
@@ -83,4 +87,67 @@ public class AiServiceImpl implements AiService {
|
|
|
report.append("\n================================================");
|
|
report.append("\n================================================");
|
|
|
return report.toString();
|
|
return report.toString();
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public Flux<String> streamAnalysis() {
|
|
|
|
|
+ StatisticsSummary summary = statisticsService.getSummary();
|
|
|
|
|
+ List<DeptSalesDTO> topDepts = statisticsService.getTopDepartments();
|
|
|
|
|
+ List<HotBookDTO> topBooks = statisticsService.getTopBooks();
|
|
|
|
|
+ List<DeptDiscountDTO> discounts = statisticsService.getDeptDiscountRates();
|
|
|
|
|
+ String prompt = buildPrompt(summary, topDepts, topBooks, discounts);
|
|
|
|
|
+ return chatClient.prompt().user(prompt).stream().content();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private String buildPrompt(StatisticsSummary summary, List<DeptSalesDTO> topDepts,
|
|
|
|
|
+ List<HotBookDTO> topBooks, List<DeptDiscountDTO> discounts) {
|
|
|
|
|
+ StringBuilder sb = new StringBuilder();
|
|
|
|
|
+ sb.append("你是一位校园二手书交易平台的数据分析师。请根据以下平台运营数据,撰写一份运营分析报告。\n\n");
|
|
|
|
|
+
|
|
|
|
|
+ sb.append("【交易总览】交易总金额:¥").append(summary.getTotalAmount())
|
|
|
|
|
+ .append(",总笔数:").append(summary.getTotalCount()).append("笔\n\n");
|
|
|
|
|
+
|
|
|
|
|
+ sb.append("【热门院系 TOP3(按交易额)】\n");
|
|
|
|
|
+ if (topDepts.isEmpty()) {
|
|
|
|
|
+ sb.append("暂无数据\n");
|
|
|
|
|
+ } else {
|
|
|
|
|
+ for (int i = 0; i < topDepts.size(); i++) {
|
|
|
|
|
+ DeptSalesDTO d = topDepts.get(i);
|
|
|
|
|
+ sb.append(i + 1).append(". ").append(d.getDept())
|
|
|
|
|
+ .append(" - ¥").append(d.getSalesAmount()).append("\n");
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ sb.append("\n");
|
|
|
|
|
+
|
|
|
|
|
+ sb.append("【热门书籍 TOP5(按销量)】\n");
|
|
|
|
|
+ if (topBooks.isEmpty()) {
|
|
|
|
|
+ sb.append("暂无数据\n");
|
|
|
|
|
+ } else {
|
|
|
|
|
+ for (int i = 0; i < topBooks.size(); i++) {
|
|
|
|
|
+ HotBookDTO b = topBooks.get(i);
|
|
|
|
|
+ sb.append(i + 1).append(". 《").append(b.getTitle())
|
|
|
|
|
+ .append("》").append(b.getAuthor())
|
|
|
|
|
+ .append(" - 销量 ").append(b.getTotalSold()).append("本\n");
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ sb.append("\n");
|
|
|
|
|
+
|
|
|
|
|
+ sb.append("【各院系平均折扣率】\n");
|
|
|
|
|
+ if (discounts.isEmpty()) {
|
|
|
|
|
+ sb.append("暂无数据\n");
|
|
|
|
|
+ } else {
|
|
|
|
|
+ for (DeptDiscountDTO d : discounts) {
|
|
|
|
|
+ sb.append(d.getDept()).append(":").append(String.format("%.1f", d.getAvgDiscountRate())).append("%\n");
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ sb.append("\n");
|
|
|
|
|
+
|
|
|
|
|
+ sb.append("请从以下5个维度分析(中文,800字内):\n");
|
|
|
|
|
+ sb.append("1. 整体运营评估:基于交易规模和活跃度,判断平台处于什么阶段(起步期/成长期/成熟期),概括当前运营状况。\n");
|
|
|
|
|
+ sb.append("2. 院系推广建议:针对不同表现的院系,提出差异化的推广策略。\n");
|
|
|
|
|
+ sb.append("3. 书籍选品与库存建议:分析热门书籍特点,给出库存建议。\n");
|
|
|
|
|
+ sb.append("4. 定价策略优化:分析折扣率分布,给出合理折扣区间建议。\n");
|
|
|
|
|
+ sb.append("5. 具体行动建议:列举3-5条下周可执行的具体运营动作。\n\n");
|
|
|
|
|
+ sb.append("要求:基于数据,不空泛,专业客观。");
|
|
|
|
|
+ return sb.toString();
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|