Commit 3deea40c authored by alex yao's avatar alex yao

feat(annual-report): 添加年度商业报告AI助手功能

parent 5c402aa7
......@@ -44,6 +44,8 @@ public enum AiDialoguesTypeEnum {
AI_SOFTWARE_COPYRIGHT("ai_software_copyright", "AI软著", DialoguesPlatformEnum.Dify),
ANNUAL_REPORT("annual_report","年度商业",DialoguesPlatformEnum.Dify),
;
private final String type;
......
package cn.com.poc.annual_eport.agent;
import java.util.List;
import java.util.Map;
import cn.com.poc.ai_dialogues.constant.AiDialoguesTypeEnum;
import cn.com.poc.common.config.DifyConfigProperties;
import cn.com.poc.common.service.impl.DifyChatServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* @author alex.yao
* @date 2026/2/5
*/
@Component
public class AnnualReportAgent {
@Autowired
private DifyConfigProperties difyConfigProperties;
@Autowired
private DifyChatServiceImpl difyChatService;
public String agent(String dialoguesId, List<String> fileUrls, String question, Map<String, Object> data)
throws Exception {
String apiKey = difyConfigProperties.getApiKeys().get(AiDialoguesTypeEnum.ANNUAL_REPORT.getType());
return difyChatService.streamChat(
fileUrls,
question,
data,
dialoguesId,
apiKey
);
}
}
\ No newline at end of file
package cn.com.poc.annual_eport.dto;
import java.util.List;
import java.util.Map;
/**
* @author alex.yao
* @date 2026/2/5
*/
public class AnnualReportAssistantDto {
private String input;
private List<String> fileUrls;
private String dialoguesId;
private Map<String, Object> data;
public String getInput() {
return input;
}
public void setInput(String input) {
this.input = input;
}
public List<String> getFileUrls() {
return fileUrls;
}
public void setFileUrls(List<String> fileUrls) {
this.fileUrls = fileUrls;
}
public String getDialoguesId() {
return dialoguesId;
}
public void setDialoguesId(String dialoguesId) {
this.dialoguesId = dialoguesId;
}
public Map<String, Object> getData() {
return data;
}
public void setData(Map<String, Object> data) {
this.data = data;
}
}
package cn.com.poc.annual_eport.rest;
import cn.com.poc.annual_eport.dto.AnnualReportAssistantDto;
import cn.com.yict.framemax.core.rest.BaseRest;
import cn.com.yict.framemax.web.permission.Access;
import cn.com.yict.framemax.web.permission.Permission;
import org.springframework.web.bind.annotation.RequestBody;
/**
* @author alex.yao
* @date 2026/2/5
*/
@Permission(Access.Anonymous)
public interface AnnualReportAssistantRest extends BaseRest {
/**
* 对话助手
*/
void call(@RequestBody AnnualReportAssistantDto dto) throws Exception;
}
package cn.com.poc.annual_eport.rest.impl;
import javax.annotation.Resource;
import cn.com.poc.annual_eport.dto.AnnualReportAssistantDto;
import cn.com.poc.annual_eport.rest.AnnualReportAssistantRest;
import cn.com.poc.annual_eport.service.AnnualReportService;
import org.springframework.stereotype.Component;
/**
* @author alex.yao
* @date 2026/2/5
*/
@Component
public class AnnualReportAssistantRestImpl implements AnnualReportAssistantRest {
@Resource
private AnnualReportService annualReportService;
@Override
public void call(AnnualReportAssistantDto dto) throws Exception {
annualReportService.call(dto.getInput(), dto.getFileUrls(), dto.getDialoguesId(), dto.getData());
}
}
package cn.com.poc.annual_eport.service;
import java.util.List;
import java.util.Map;
/**
* @author alex.yao
* @date 2026/2/5
*/
public interface AnnualReportService {
void call(String input, List<String> fileUrls, String dialoguesId, Map<String, Object> data) throws Exception;
}
package cn.com.poc.annual_eport.service.impl;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import cn.com.poc.agent_application.constant.AgentApplicationDialoguesRecordConstants;
import cn.com.poc.agent_application.entity.BizAgentApplicationDialoguesRecordEntity;
import cn.com.poc.agent_application.service.BizAgentApplicationDialoguesRecordService;
import cn.com.poc.ai_dialogues.aggregate.AiDialoguesService;
import cn.com.poc.ai_dialogues.entity.BizAiDialoguesEntity;
import cn.com.poc.ai_dialogues.service.BizAiDialoguesService;
import cn.com.poc.annual_eport.agent.AnnualReportAgent;
import cn.com.poc.annual_eport.service.AnnualReportService;
import cn.com.poc.common.constant.CommonConstant;
import cn.com.poc.common.utils.JsonUtils;
import cn.com.yict.framemax.core.exception.BusinessException;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
/**
* @author alex.yao
* @date 2026/2/5
*/
@Component
public class AnnualReportServiceImpl implements AnnualReportService {
private final Logger logger = LoggerFactory.getLogger(AnnualReportService.class);
@Resource
private AnnualReportAgent annualReportAgent;
@Resource
private BizAiDialoguesService bizAiDialoguesService;
@Resource
private BizAgentApplicationDialoguesRecordService bizAgentApplicationDialoguesRecordService;
@Override
public void call(String input, List<String> fileUrls, String dialoguesId, Map<String, Object> data)
throws Exception {
String result = new String();
long inputTimeStamp = System.currentTimeMillis();
BizAiDialoguesEntity bizAiDialoguesEntity = new BizAiDialoguesEntity();
bizAiDialoguesEntity.setDialoguesId(dialoguesId);
bizAiDialoguesEntity.setMemberId(null);
bizAiDialoguesEntity.setIsDeleted(CommonConstant.IsDeleted.N);
List<BizAiDialoguesEntity> bizAiDialoguesEntities =
bizAiDialoguesService.findByExample(bizAiDialoguesEntity, null);
if (CollectionUtils.isEmpty(bizAiDialoguesEntities)) {
throw new BusinessException("对话ID不存在");
}
BizAiDialoguesEntity aiDialoguesEntity = bizAiDialoguesEntities.get(0);
//更新标题
if (org.apache.commons.lang3.StringUtils.isBlank(aiDialoguesEntity.getTitle())) { // 标题
aiDialoguesEntity.setTitle(input.substring(0, Math.min(input.length(), 150)));
bizAiDialoguesService.update(aiDialoguesEntity);
}
try {
result = annualReportAgent.agent(dialoguesId, fileUrls, input, data);
} catch (Exception e) {
logger.error(e.getMessage());
throw new BusinessException("对话异常");
} finally {
//保存对话记录
//用户输入记录
BizAgentApplicationDialoguesRecordEntity inputRecord = new BizAgentApplicationDialoguesRecordEntity();
inputRecord.setAgentId(null);
inputRecord.setMemberId(null);
inputRecord.setContent(input);
inputRecord.setDialogsId(dialoguesId);
inputRecord.setRole(AgentApplicationDialoguesRecordConstants.ROLE.USER);
inputRecord.setTimestamp(inputTimeStamp);
bizAgentApplicationDialoguesRecordService.save(inputRecord);
//AI输出记录
BizAgentApplicationDialoguesRecordEntity outputRecord = new BizAgentApplicationDialoguesRecordEntity();
outputRecord.setRole(AgentApplicationDialoguesRecordConstants.ROLE.ASSISTANT);
outputRecord.setAgentId(null);
outputRecord.setDialogsId(dialoguesId);
outputRecord.setMemberId(null);
outputRecord.setTimestamp(System.currentTimeMillis());
outputRecord.setContent(result);
outputRecord.setReasoningContent(null);
bizAgentApplicationDialoguesRecordService.save(outputRecord);
}
}
}
......@@ -20,10 +20,10 @@ public interface DifyChatService {
String apiKey);
void streamChat(List<String> fileUrls,
String question,
Map<String, Object> data,
String user,
String apiKey) throws IOException, DifyApiException, InterruptedException;
String streamChat(List<String> fileUrls,
String question,
Map<String, Object> data,
String user,
String apiKey) throws IOException, DifyApiException, InterruptedException;
}
......@@ -102,12 +102,12 @@ public class DifyChatServiceImpl implements DifyChatService {
/**
* 流式聊天请求
*/
public void streamChat(List<String> fileUrls,
String question,
Map<String, Object> data,
String user,
String apiKey) throws IOException, DifyApiException, InterruptedException {
public String streamChat(List<String> fileUrls,
String question,
Map<String, Object> data,
String user,
String apiKey) throws IOException, DifyApiException, InterruptedException {
StringBuilder stringBuilder = new StringBuilder();
// 从配置中获取API密钥,如果传入的apiKey为null或空,则从配置中查找
String actualApiKey = apiKey;
if (StringUtils.isEmpty(actualApiKey)) {
......@@ -154,6 +154,7 @@ public class DifyChatServiceImpl implements DifyChatService {
largeModelDemandResult.setCode("0");
largeModelDemandResult.setMessage(event.getAnswer());
sseUtil.send(JsonUtils.serialize(largeModelDemandResult));
stringBuilder.append(event.getAnswer());
}
} catch (Exception e) {
logger.error("发送SSE消息时出错: {}", e.getMessage(), e);
......@@ -177,5 +178,6 @@ public class DifyChatServiceImpl implements DifyChatService {
}
});
countDownLatch.await(120, TimeUnit.SECONDS);
return stringBuilder.toString();
}
}
\ No newline at end of file
......@@ -7,3 +7,4 @@ dify.config.apiKeys.technical-content=app-VuwhZGr7UqFb2gkg7jOmibGM
dify.config.apiKeys.source-code=app-c0PWYmcythg7bIVxvt4d4kDM
dify.config.apiKeys.ph-operating-manual=app-c0PWYmcythg7bIVxvt4d4kDM
dify.config.apiKeys.pc-operating-manual=app-c0PWYmcythg7bIVxvt4d4kDM
dify.config.apiKeys.annual_report=app-9WQWeRVC0wyVDvBXqaVjvj3M
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment