引入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>
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.yucongming</groupId>
|
||||||
|
<artifactId>yucongming-java-sdk</artifactId>
|
||||||
|
<version>0.0.3</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<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.DeleteRequest;
|
||||||
import top.peng.answerbi.common.ErrorCode;
|
import top.peng.answerbi.common.ErrorCode;
|
||||||
import top.peng.answerbi.common.ResultUtils;
|
import top.peng.answerbi.common.ResultUtils;
|
||||||
|
import top.peng.answerbi.constant.BiConstant;
|
||||||
import top.peng.answerbi.constant.FileConstant;
|
import top.peng.answerbi.constant.FileConstant;
|
||||||
import top.peng.answerbi.constant.UserConstant;
|
import top.peng.answerbi.constant.UserConstant;
|
||||||
import top.peng.answerbi.exception.BusinessException;
|
import top.peng.answerbi.exception.BusinessException;
|
||||||
import top.peng.answerbi.exception.ThrowUtils;
|
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.ChartAddRequest;
|
||||||
import top.peng.answerbi.model.dto.chart.ChartEditRequest;
|
import top.peng.answerbi.model.dto.chart.ChartEditRequest;
|
||||||
import top.peng.answerbi.model.dto.chart.ChartQueryRequest;
|
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.Chart;
|
||||||
import top.peng.answerbi.model.entity.User;
|
import top.peng.answerbi.model.entity.User;
|
||||||
import top.peng.answerbi.model.enums.FileUploadBizEnum;
|
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.ChartService;
|
||||||
import top.peng.answerbi.service.UserService;
|
import top.peng.answerbi.service.UserService;
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
@ -56,6 +59,9 @@ public class ChartController {
|
|||||||
@Resource
|
@Resource
|
||||||
private UserService userService;
|
private UserService userService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private AiManager aiManager;
|
||||||
|
|
||||||
private final static Gson GSON = new Gson();
|
private final static Gson GSON = new Gson();
|
||||||
|
|
||||||
// region 增删改查
|
// region 增删改查
|
||||||
@ -228,7 +234,7 @@ public class ChartController {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@PostMapping("/gen")
|
@PostMapping("/gen")
|
||||||
public CommonResponse<String> genChartByAi(@RequestPart("file") MultipartFile multipartFile,
|
public CommonResponse<BiResponse> genChartByAi(@RequestPart("file") MultipartFile multipartFile,
|
||||||
GenChartByAiRequest genChartByAiRequest, HttpServletRequest request) {
|
GenChartByAiRequest genChartByAiRequest, HttpServletRequest request) {
|
||||||
String chartName = genChartByAiRequest.getChartName();
|
String chartName = genChartByAiRequest.getChartName();
|
||||||
String goal = genChartByAiRequest.getGoal();
|
String goal = genChartByAiRequest.getGoal();
|
||||||
@ -240,36 +246,38 @@ public class ChartController {
|
|||||||
//如果名称不为空,并且名称长度大于100,就抛出异常,并给出提示
|
//如果名称不为空,并且名称长度大于100,就抛出异常,并给出提示
|
||||||
ThrowUtils.throwIf(StringUtils.isNotBlank(chartName) && chartName.length() > 100,ErrorCode.PARAMS_ERROR,"图表名称过长");
|
ThrowUtils.throwIf(StringUtils.isNotBlank(chartName) && chartName.length() > 100,ErrorCode.PARAMS_ERROR,"图表名称过长");
|
||||||
|
|
||||||
|
//通过request对象拿到用户id(必须登录才能使用)
|
||||||
|
User loginUser = userService.getLoginUser(request);
|
||||||
|
|
||||||
//用户输入
|
//用户输入
|
||||||
StringBuilder userInput = new StringBuilder();
|
StringBuilder userInput = new StringBuilder();
|
||||||
userInput.append("你是一个数据分析师,接下来我会给你我的分析目标和原始数据,请告诉我分析结论。").append("\n");
|
userInput.append("分析需求:").append("\n");
|
||||||
userInput.append("分析目标:").append(goal).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);
|
String csvData = ExcelUtils.excelToCsv(multipartFile);
|
||||||
userInput.append("数据:").append(result).append("\n");
|
userInput.append(csvData).append("\n");
|
||||||
return ResultUtils.success(userInput.toString());
|
|
||||||
/*//读取用户上传的excel文件,进行处理
|
String aiResult = aiManager.doChat(BiConstant.BI_MODEL_ID, userInput.toString());
|
||||||
User loginUser = userService.getLoginUser(request);
|
BiResponse biResponse = aiManager.aiAnsToBiResp(aiResult);
|
||||||
// 文件目录:根据业务、用户来划分
|
|
||||||
String uuid = RandomStringUtils.randomAlphanumeric(8);
|
//插入数据库
|
||||||
String filename = uuid + "-" + multipartFile.getOriginalFilename();
|
Chart chart = new Chart();
|
||||||
File file = null;
|
BeanUtils.copyProperties(biResponse,chart);
|
||||||
try {
|
chart.setChartName(chartName);
|
||||||
// 返回可访问地址
|
chart.setGoal(goal);
|
||||||
return ResultUtils.success("");
|
chart.setChartType(chartType);
|
||||||
}catch (Exception e){
|
chart.setChartData(csvData);
|
||||||
//log.error("file upload error, filepath = " + filepath, e);
|
chart.setUserId(loginUser.getId());
|
||||||
throw new BusinessException(ErrorCode.SYSTEM_ERROR, "上传失败");
|
boolean saveResult = chartService.save(chart);
|
||||||
}finally {
|
ThrowUtils.throwIf(!saveResult, ErrorCode.SYSTEM_ERROR, "图表保存失败");
|
||||||
if (file != null) {
|
biResponse.setChartId(chart.getId());
|
||||||
// 删除临时文件
|
return ResultUtils.success(biResponse);
|
||||||
boolean delete = file.delete();
|
|
||||||
if (!delete) {
|
|
||||||
//log.error("file delete error, filepath = {}", filepath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
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;
|
private Long id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 开放平台id
|
* 用户账号
|
||||||
*/
|
*/
|
||||||
private String unionId;
|
private String userAccount;
|
||||||
|
|
||||||
/**
|
|
||||||
* 公众号openId
|
|
||||||
*/
|
|
||||||
private String mpOpenId;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户昵称
|
* 用户昵称
|
||||||
|
|||||||
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 userName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户账号
|
||||||
|
*/
|
||||||
|
private String userAccount;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户头像
|
* 用户头像
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -217,20 +217,18 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
|
|||||||
throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数为空");
|
throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数为空");
|
||||||
}
|
}
|
||||||
Long id = userQueryRequest.getId();
|
Long id = userQueryRequest.getId();
|
||||||
String unionId = userQueryRequest.getUnionId();
|
|
||||||
String mpOpenId = userQueryRequest.getMpOpenId();
|
|
||||||
String userName = userQueryRequest.getUserName();
|
String userName = userQueryRequest.getUserName();
|
||||||
|
String userAccount = userQueryRequest.getUserAccount();
|
||||||
String userProfile = userQueryRequest.getUserProfile();
|
String userProfile = userQueryRequest.getUserProfile();
|
||||||
String userRole = userQueryRequest.getUserRole();
|
String userRole = userQueryRequest.getUserRole();
|
||||||
String sortField = userQueryRequest.getSortField();
|
String sortField = userQueryRequest.getSortField();
|
||||||
String sortOrder = userQueryRequest.getSortOrder();
|
String sortOrder = userQueryRequest.getSortOrder();
|
||||||
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
|
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
|
||||||
queryWrapper.eq(id != null, "id", id);
|
queryWrapper.eq(id != null, "id", id);
|
||||||
queryWrapper.eq(StringUtils.isNotBlank(unionId), "unionId", unionId);
|
queryWrapper.eq(StringUtils.isNotBlank(userAccount), "user_account", userAccount);
|
||||||
queryWrapper.eq(StringUtils.isNotBlank(mpOpenId), "mpOpenId", mpOpenId);
|
queryWrapper.eq(StringUtils.isNotBlank(userRole), "user_role", userRole);
|
||||||
queryWrapper.eq(StringUtils.isNotBlank(userRole), "userRole", userRole);
|
queryWrapper.like(StringUtils.isNotBlank(userProfile), "user_profile", userProfile);
|
||||||
queryWrapper.like(StringUtils.isNotBlank(userProfile), "userProfile", userProfile);
|
queryWrapper.like(StringUtils.isNotBlank(userName), "user_name", userName);
|
||||||
queryWrapper.like(StringUtils.isNotBlank(userName), "userName", userName);
|
|
||||||
queryWrapper.orderBy(SqlUtils.validSortField(sortField), sortOrder.equals(CommonConstant.SORT_ORDER_ASC),
|
queryWrapper.orderBy(SqlUtils.validSortField(sortField), sortOrder.equals(CommonConstant.SORT_ORDER_ASC),
|
||||||
sortField);
|
sortField);
|
||||||
return queryWrapper;
|
return queryWrapper;
|
||||||
|
|||||||
@ -87,3 +87,8 @@ cos:
|
|||||||
secretKey: xxx
|
secretKey: xxx
|
||||||
region: 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