引入AI分析 生成Echarts代码和分析结果
This commit is contained in:
parent
876e98e765
commit
a1dcd7572e
5
pom.xml
5
pom.xml
@ -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>
|
||||
|
||||
21
src/main/java/top/peng/answerbi/constant/BiConstant.java
Normal file
21
src/main/java/top/peng/answerbi/constant/BiConstant.java
Normal 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 = "【【【【【";
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
63
src/main/java/top/peng/answerbi/manager/AiManager.java
Normal file
63
src/main/java/top/peng/answerbi/manager/AiManager.java
Normal 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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
|
||||
/**
|
||||
* 用户昵称
|
||||
|
||||
33
src/main/java/top/peng/answerbi/model/vo/BiResponse.java
Normal file
33
src/main/java/top/peng/answerbi/model/vo/BiResponse.java
Normal 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;
|
||||
}
|
||||
@ -23,6 +23,11 @@ public class UserVO implements Serializable {
|
||||
*/
|
||||
private String userName;
|
||||
|
||||
/**
|
||||
* 用户账号
|
||||
*/
|
||||
private String userAccount;
|
||||
|
||||
/**
|
||||
* 用户头像
|
||||
*/
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -86,4 +86,9 @@ cos:
|
||||
accessKey: xxx
|
||||
secretKey: xxx
|
||||
region: xxx
|
||||
bucket: xxx
|
||||
bucket: xxx
|
||||
|
||||
yuapi:
|
||||
client:
|
||||
access-key: xyjjaiosvyjxfk4t98g0qlrplfijigrz
|
||||
secret-key: q6lppq8sdz587jggbttg35nrsj1iyofl
|
||||
38
src/test/java/top/peng/answerbi/manager/AiManagerTest.java
Normal file
38
src/test/java/top/peng/answerbi/manager/AiManagerTest.java
Normal 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]);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user