引入AI分析 生成Echarts代码和分析结果

This commit is contained in:
brian 2023-07-14 16:57:13 +08:00
parent 876e98e765
commit a1dcd7572e
10 changed files with 214 additions and 43 deletions

View File

@ -121,6 +121,11 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.yucongming</groupId>
<artifactId>yucongming-java-sdk</artifactId>
<version>0.0.3</version>
</dependency>
</dependencies>
<build>

View File

@ -0,0 +1,21 @@
/*
* @(#)BiConstant.java
*
* Copyright © 2023 YunPeng Corporation.
*/
package top.peng.answerbi.constant;
/**
* BiConstant Bi常量
*
* @author yunpeng
* @version 1.0 2023/7/14
*/
public interface BiConstant {
/**
* Bi模型id
*/
Long BI_MODEL_ID = 1679729045626982402L;
String BI_RESULT_SEPARATOR = "【【【【【";
}

View File

@ -13,10 +13,12 @@ import top.peng.answerbi.common.CommonResponse;
import top.peng.answerbi.common.DeleteRequest;
import top.peng.answerbi.common.ErrorCode;
import top.peng.answerbi.common.ResultUtils;
import top.peng.answerbi.constant.BiConstant;
import top.peng.answerbi.constant.FileConstant;
import top.peng.answerbi.constant.UserConstant;
import top.peng.answerbi.exception.BusinessException;
import top.peng.answerbi.exception.ThrowUtils;
import top.peng.answerbi.manager.AiManager;
import top.peng.answerbi.model.dto.chart.ChartAddRequest;
import top.peng.answerbi.model.dto.chart.ChartEditRequest;
import top.peng.answerbi.model.dto.chart.ChartQueryRequest;
@ -26,6 +28,7 @@ import top.peng.answerbi.model.dto.file.UploadFileRequest;
import top.peng.answerbi.model.entity.Chart;
import top.peng.answerbi.model.entity.User;
import top.peng.answerbi.model.enums.FileUploadBizEnum;
import top.peng.answerbi.model.vo.BiResponse;
import top.peng.answerbi.service.ChartService;
import top.peng.answerbi.service.UserService;
import javax.annotation.Resource;
@ -56,6 +59,9 @@ public class ChartController {
@Resource
private UserService userService;
@Resource
private AiManager aiManager;
private final static Gson GSON = new Gson();
// region 增删改查
@ -228,7 +234,7 @@ public class ChartController {
* @return
*/
@PostMapping("/gen")
public CommonResponse<String> genChartByAi(@RequestPart("file") MultipartFile multipartFile,
public CommonResponse<BiResponse> genChartByAi(@RequestPart("file") MultipartFile multipartFile,
GenChartByAiRequest genChartByAiRequest, HttpServletRequest request) {
String chartName = genChartByAiRequest.getChartName();
String goal = genChartByAiRequest.getGoal();
@ -240,36 +246,38 @@ public class ChartController {
//如果名称不为空并且名称长度大于100就抛出异常并给出提示
ThrowUtils.throwIf(StringUtils.isNotBlank(chartName) && chartName.length() > 100,ErrorCode.PARAMS_ERROR,"图表名称过长");
//通过request对象拿到用户id(必须登录才能使用)
User loginUser = userService.getLoginUser(request);
//用户输入
StringBuilder userInput = new StringBuilder();
userInput.append("你是一个数据分析师,接下来我会给你我的分析目标和原始数据,请告诉我分析结论。").append("\n");
userInput.append("分析目标:").append(goal).append("\n");
userInput.append("分析需求:").append("\n");
//拼接分析目标
String userGoal = goal;
if (StringUtils.isNotBlank(chartType)){
userGoal += ",请使用" + chartType;
}
userInput.append(userGoal).append("\n");
userInput.append("原始数据:").append("\n");
//压缩后的数据
String result = ExcelUtils.excelToCsv(multipartFile);
userInput.append("数据:").append(result).append("\n");
return ResultUtils.success(userInput.toString());
/*//读取用户上传的excel文件进行处理
User loginUser = userService.getLoginUser(request);
// 文件目录根据业务用户来划分
String uuid = RandomStringUtils.randomAlphanumeric(8);
String filename = uuid + "-" + multipartFile.getOriginalFilename();
File file = null;
try {
// 返回可访问地址
return ResultUtils.success("");
}catch (Exception e){
//log.error("file upload error, filepath = " + filepath, e);
throw new BusinessException(ErrorCode.SYSTEM_ERROR, "上传失败");
}finally {
if (file != null) {
// 删除临时文件
boolean delete = file.delete();
if (!delete) {
//log.error("file delete error, filepath = {}", filepath);
}
}
}*/
String csvData = ExcelUtils.excelToCsv(multipartFile);
userInput.append(csvData).append("\n");
String aiResult = aiManager.doChat(BiConstant.BI_MODEL_ID, userInput.toString());
BiResponse biResponse = aiManager.aiAnsToBiResp(aiResult);
//插入数据库
Chart chart = new Chart();
BeanUtils.copyProperties(biResponse,chart);
chart.setChartName(chartName);
chart.setGoal(goal);
chart.setChartType(chartType);
chart.setChartData(csvData);
chart.setUserId(loginUser.getId());
boolean saveResult = chartService.save(chart);
ThrowUtils.throwIf(!saveResult, ErrorCode.SYSTEM_ERROR, "图表保存失败");
biResponse.setChartId(chart.getId());
return ResultUtils.success(biResponse);
}
}

View File

@ -0,0 +1,63 @@
/*
* @(#)AiManager.java
*
* Copyright © 2023 YunPeng Corporation.
*/
package top.peng.answerbi.manager;
import com.yupi.yucongming.dev.client.YuCongMingClient;
import com.yupi.yucongming.dev.common.BaseResponse;
import com.yupi.yucongming.dev.model.DevChatRequest;
import com.yupi.yucongming.dev.model.DevChatResponse;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import top.peng.answerbi.common.ErrorCode;
import top.peng.answerbi.constant.BiConstant;
import top.peng.answerbi.exception.ThrowUtils;
import top.peng.answerbi.model.vo.BiResponse;
/**
* AiManager AI对话
*
* @author yunpeng
* @version 1.0 2023/7/14
*/
@Service
public class AiManager {
@Resource
private YuCongMingClient yuCongMingClient;
/**
* AI 对话
*
* @param modelId 模型id
* @param message 提问
* @return 结果
*/
public String doChat(long modelId, String message){
DevChatRequest devChatRequest = new DevChatRequest();
devChatRequest.setModelId(modelId);
devChatRequest.setMessage(message);
BaseResponse<DevChatResponse> response = yuCongMingClient.doChat(devChatRequest);
ThrowUtils.throwIf(response == null, ErrorCode.SYSTEM_ERROR,"AI响应错误");
return response.getData().getContent();
}
/**
* 将AI生成的结果转换为 BiResponse
* @param aiAnswer AI 对话 结果
* @return BiResponse对象
*/
public BiResponse aiAnsToBiResp(String aiAnswer){
String[] aiResultSplit = aiAnswer.split(BiConstant.BI_RESULT_SEPARATOR);
ThrowUtils.throwIf(aiResultSplit.length < 3,ErrorCode.SYSTEM_ERROR,"AI 生成错误");
BiResponse biResponse = new BiResponse();
biResponse.setGenChart(aiResultSplit[1].trim());
biResponse.setGenResult(aiResultSplit[2].trim());
return biResponse;
}
}

View File

@ -20,14 +20,9 @@ public class UserQueryRequest extends PageRequest implements Serializable {
private Long id;
/**
* 开放平台id
* 用户账号
*/
private String unionId;
/**
* 公众号openId
*/
private String mpOpenId;
private String userAccount;
/**
* 用户昵称

View File

@ -0,0 +1,33 @@
/*
* @(#)BiResponse.java
*
* Copyright © 2023 YunPeng Corporation.
*/
package top.peng.answerbi.model.vo;
import lombok.Data;
/**
* BiResponse Bi 的返回结果
*
* @author yunpeng
* @version 1.0 2023/7/14
*/
@Data
public class BiResponse {
/**
* 生成的图表数据
*/
private String genChart;
/**
* 生成的分析结论
*/
private String genResult;
/**
* 新生成的图表Id
*/
private Long chartId;
}

View File

@ -23,6 +23,11 @@ public class UserVO implements Serializable {
*/
private String userName;
/**
* 用户账号
*/
private String userAccount;
/**
* 用户头像
*/

View File

@ -217,20 +217,18 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数为空");
}
Long id = userQueryRequest.getId();
String unionId = userQueryRequest.getUnionId();
String mpOpenId = userQueryRequest.getMpOpenId();
String userName = userQueryRequest.getUserName();
String userAccount = userQueryRequest.getUserAccount();
String userProfile = userQueryRequest.getUserProfile();
String userRole = userQueryRequest.getUserRole();
String sortField = userQueryRequest.getSortField();
String sortOrder = userQueryRequest.getSortOrder();
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq(id != null, "id", id);
queryWrapper.eq(StringUtils.isNotBlank(unionId), "unionId", unionId);
queryWrapper.eq(StringUtils.isNotBlank(mpOpenId), "mpOpenId", mpOpenId);
queryWrapper.eq(StringUtils.isNotBlank(userRole), "userRole", userRole);
queryWrapper.like(StringUtils.isNotBlank(userProfile), "userProfile", userProfile);
queryWrapper.like(StringUtils.isNotBlank(userName), "userName", userName);
queryWrapper.eq(StringUtils.isNotBlank(userAccount), "user_account", userAccount);
queryWrapper.eq(StringUtils.isNotBlank(userRole), "user_role", userRole);
queryWrapper.like(StringUtils.isNotBlank(userProfile), "user_profile", userProfile);
queryWrapper.like(StringUtils.isNotBlank(userName), "user_name", userName);
queryWrapper.orderBy(SqlUtils.validSortField(sortField), sortOrder.equals(CommonConstant.SORT_ORDER_ASC),
sortField);
return queryWrapper;

View File

@ -86,4 +86,9 @@ cos:
accessKey: xxx
secretKey: xxx
region: xxx
bucket: xxx
bucket: xxx
yuapi:
client:
access-key: xyjjaiosvyjxfk4t98g0qlrplfijigrz
secret-key: q6lppq8sdz587jggbttg35nrsj1iyofl

View File

@ -0,0 +1,38 @@
package top.peng.answerbi.manager;
import static org.junit.jupiter.api.Assertions.*;
import java.util.Arrays;
import javax.annotation.Resource;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import top.peng.answerbi.constant.BiConstant;
/**
* AiManagerTest
*
* @author yunpeng
* @version 1.0 2023/7/14
*/
@SpringBootTest
class AiManagerTest {
@Resource
private AiManager aiManager;
@Test
void doChat() {
String answer = aiManager.doChat(1679729045626982402L, "分析需求:\n"
+ "分析网站用户的增长情况\n"
+ "原始数据:\n"
+ "日期,用户数\n"
+ "1号,10\n"
+ "2号,20\n"
+ "3号,30");
String[] aiResultSplit = answer.split(BiConstant.BI_RESULT_SEPARATOR);
System.out.println(aiResultSplit[0]);
System.out.println(aiResultSplit[1]);
System.out.println(aiResultSplit[2]);
}
}