Files
mp-java/src/main/java/com/gxwebsoft/ai/service/AiAnalyticsService.java
赵忠林 1c78fdbef4 feat(ai): 新增AI模块功能
- 添加Ollama配置参数,包括基础URL、模型设置、超时配置等
- 创建AI知识库相关数据库表(文档表和分段表)
- 实现AI数据分析服务,支持订单数据查询和分析
- 开发AI聊天控制器,提供模型列表、对话和流式对话功能
- 构建知识库RAG服务,支持文档上传、CMS同步和问答功能
- 添加多种AI相关的DTO类和实体类
- 实现AI嵌入向量计算和相似度匹配算法
- 集成Tika用于文档内容提取和解析
2026-02-28 08:30:48 +08:00

83 lines
2.9 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.gxwebsoft.ai.service;
import cn.hutool.core.util.StrUtil;
import com.gxwebsoft.ai.dto.*;
import com.gxwebsoft.ai.prompt.AiPrompts;
import com.gxwebsoft.common.core.exception.BusinessException;
import com.gxwebsoft.common.core.utils.JSONUtil;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.format.DateTimeParseException;
import java.util.Arrays;
@Service
public class AiAnalyticsService {
@Resource
private AiShopAnalyticsService shopAnalyticsService;
@Resource
private AiChatService aiChatService;
public AiShopMetricsQueryResult queryShopMetrics(Integer tenantId, AiShopMetricsQueryRequest request) {
if (tenantId == null) {
throw new BusinessException("tenantId 不能为空");
}
if (request == null) {
throw new BusinessException("请求不能为空");
}
LocalDate start = parseDate(request.getStartDate(), "startDate");
LocalDate end = parseDate(request.getEndDate(), "endDate");
if (end.isBefore(start)) {
throw new BusinessException("endDate 不能早于 startDate");
}
AiShopMetricsQueryResult r = new AiShopMetricsQueryResult();
r.setTenantId(tenantId);
r.setStartDate(start.toString());
r.setEndDate(end.toString());
r.setRows(shopAnalyticsService.queryTenantDaily(tenantId, start, end));
return r;
}
public AiAnalyticsAskResult askShopAnalytics(Integer tenantId, AiAnalyticsAskRequest request) {
if (request == null || StrUtil.isBlank(request.getQuestion())) {
throw new BusinessException("question 不能为空");
}
AiShopMetricsQueryRequest q = new AiShopMetricsQueryRequest();
q.setStartDate(request.getStartDate());
q.setEndDate(request.getEndDate());
q.setGroupByDay(true);
AiShopMetricsQueryResult data = queryShopMetrics(tenantId, q);
String userPrompt =
"用户问题:\n" + request.getQuestion() + "\n\n" +
"数据JSON字段含义order_cnt=订单数paid_order_cnt=已支付订单数gmv=已支付金额refund_amt=退款金额pay_user_cnt=支付用户数aov=客单价pay_rate=支付率):\n" +
JSONUtil.toJSONString(data, true);
AiChatRequest chat = new AiChatRequest();
chat.setMessages(Arrays.asList(
new AiMessage("system", AiPrompts.SYSTEM_ANALYTICS),
new AiMessage("user", userPrompt)
));
AiChatResult resp = aiChatService.chat(chat);
AiAnalyticsAskResult r = new AiAnalyticsAskResult();
r.setAnalysis(resp.getContent());
r.setData(data);
return r;
}
private static LocalDate parseDate(String s, String field) {
if (StrUtil.isBlank(s)) {
throw new BusinessException(field + " 不能为空,格式 YYYY-MM-DD");
}
try {
return LocalDate.parse(s.trim());
} catch (DateTimeParseException e) {
throw new BusinessException(field + " 格式错误,需 YYYY-MM-DD");
}
}
}