Commit 72d8ca68 authored by alex yao's avatar alex yao

feat:Ai软著

parent a549be6d
...@@ -351,36 +351,7 @@ public class AiDialoguesServiceImpl implements AiDialoguesService { ...@@ -351,36 +351,7 @@ public class AiDialoguesServiceImpl implements AiDialoguesService {
long inputTimeStamp = System.currentTimeMillis(); long inputTimeStamp = System.currentTimeMillis();
try { try {
if (dialoguesType.equals(AiDialoguesTypeEnum.CAR_INSURANCE.getType()) || dialoguesType.equals(AiDialoguesTypeEnum.CAR_RECOMMEND.getType())) {//AppBuilder if (dialoguesType.equals(AiDialoguesTypeEnum.CAR_INSURANCE.getType()) || dialoguesType.equals(AiDialoguesTypeEnum.CAR_RECOMMEND.getType())) {//AppBuilder
BizAiDialogues3rdRelationEntity bizAiDialogues3rdRelationEntity = new BizAiDialogues3rdRelationEntity(); appbuilder(dialoguesId, input, contentBuilder, sseUtil);
bizAiDialogues3rdRelationEntity.setDialoguesId(dialoguesId);
bizAiDialogues3rdRelationEntity.setPlatform(DialoguesPlatformEnum.AppBuilder.getPlatform());
bizAiDialogues3rdRelationEntity.setIsDeleted(CommonConstant.IsDeleted.N);
List<BizAiDialogues3rdRelationEntity> relationEntities = bizAiDialogues3rdRelationService.findByExample(bizAiDialogues3rdRelationEntity, null);
if (CollectionUtils.isEmpty(relationEntities)) {
throw new BusinessException("获取会话配置异常");
}
AppBuilderClientIterator iterator = appBuilderService.communication(relationEntities.get(0).getRelationId(), input, null, true);
while (iterator.hasNext()) {
AppBuilderClientResult res = iterator.next();
LargeModelDemandResult largeModelDemandResult = new LargeModelDemandResult();
largeModelDemandResult.setCode("0");
if (ArrayUtils.isNotEmpty(res.getEvents())) {
Event event = res.getEvents()[0];
String eventType = event.getEventType();
if ("chatflow".equals(eventType)) {
Map<String, Object> detail = event.getDetail();
if (detail.containsKey("message")) {
String mess = detail.get("message").toString();
largeModelDemandResult.setMessage(mess);
contentBuilder.append(mess);
}
}
} else if (StringUtils.isNotEmpty(res.getAnswer())) {
largeModelDemandResult.setMessage(res.getAnswer());
contentBuilder.append(res.getAnswer());
}
sseUtil.send(JsonUtils.serialize(largeModelDemandResult));
}
} }
} catch (Exception e) { } catch (Exception e) {
logger.error(e.getMessage()); logger.error(e.getMessage());
...@@ -414,4 +385,39 @@ public class AiDialoguesServiceImpl implements AiDialoguesService { ...@@ -414,4 +385,39 @@ public class AiDialoguesServiceImpl implements AiDialoguesService {
} }
return contentBuilder.toString(); return contentBuilder.toString();
} }
private void appbuilder(String dialoguesId, String input, StringBuilder contentBuilder, SSEUtil sseUtil)
throws Exception {
BizAiDialogues3rdRelationEntity bizAiDialogues3rdRelationEntity = new BizAiDialogues3rdRelationEntity();
bizAiDialogues3rdRelationEntity.setDialoguesId(dialoguesId);
bizAiDialogues3rdRelationEntity.setPlatform(DialoguesPlatformEnum.AppBuilder.getPlatform());
bizAiDialogues3rdRelationEntity.setIsDeleted(CommonConstant.IsDeleted.N);
List<BizAiDialogues3rdRelationEntity> relationEntities = bizAiDialogues3rdRelationService.findByExample(bizAiDialogues3rdRelationEntity, null);
if (CollectionUtils.isEmpty(relationEntities)) {
throw new BusinessException("获取会话配置异常");
}
AppBuilderClientIterator iterator = appBuilderService.communication(relationEntities.get(0).getRelationId(),
input, null, true);
while (iterator.hasNext()) {
AppBuilderClientResult res = iterator.next();
LargeModelDemandResult largeModelDemandResult = new LargeModelDemandResult();
largeModelDemandResult.setCode("0");
if (ArrayUtils.isNotEmpty(res.getEvents())) {
Event event = res.getEvents()[0];
String eventType = event.getEventType();
if ("chatflow".equals(eventType)) {
Map<String, Object> detail = event.getDetail();
if (detail.containsKey("message")) {
String mess = detail.get("message").toString();
largeModelDemandResult.setMessage(mess);
contentBuilder.append(mess);
}
}
} else if (StringUtils.isNotEmpty(res.getAnswer())) {
largeModelDemandResult.setMessage(res.getAnswer());
contentBuilder.append(res.getAnswer());
}
sseUtil.send(JsonUtils.serialize(largeModelDemandResult));
}
}
} }
...@@ -5,44 +5,44 @@ import java.util.List; ...@@ -5,44 +5,44 @@ import java.util.List;
/** /**
* @author alex.yao * @author alex.yao
* @date 2025/6/19
*/ */
public enum AiDialoguesTypeEnum { public enum AiDialoguesTypeEnum {
PORTAL("portal", "门户页对话"), PORTAL("portal", "门户页对话", DialoguesPlatformEnum.ModelLink),
LONG_TEXT_DOCUMENT("long_text_document", "长文本文档"), LONG_TEXT_DOCUMENT("long_text_document", "长文本文档", DialoguesPlatformEnum.ModelLink),
AI_WRITING("ai_writing", "AI写作"), AI_WRITING("ai_writing", "AI写作", DialoguesPlatformEnum.ModelLink),
AI_BI("ai_bi", "智能问数"), AI_BI("ai_bi", "智能问数", DialoguesPlatformEnum.ModelLink),
AI_FINANCE("ai_finance", "AI财务"), AI_FINANCE("ai_finance", "AI财务", DialoguesPlatformEnum.ModelLink),
LEGAL_AFFAIRS("legal_affairs", "法务问答"), LEGAL_AFFAIRS("legal_affairs", "法务问答", DialoguesPlatformEnum.ModelLink),
LEGAL_DOCUMENT_WRITING("legal_document_writing", "智写-法律文书写作"), LEGAL_DOCUMENT_WRITING("legal_document_writing", "智写-法律文书写作", DialoguesPlatformEnum.ModelLink),
AI_LEGAL_DOCUMENT_WRITING("ai_legal_document_writing", "智写-法律文书ai写作"), AI_LEGAL_DOCUMENT_WRITING("ai_legal_document_writing", "智写-法律文书ai写作", DialoguesPlatformEnum.ModelLink),
TEMPLATE_LEGAL_DOCUMENT_WRITING("template_legal_document_writing", "智写-法律文书模板写作"), TEMPLATE_LEGAL_DOCUMENT_WRITING("template_legal_document_writing", "智写-法律文书模板写作",
DialoguesPlatformEnum.ModelLink),
TRAVEL_BUSINESS("travel_business", "旅游业务"), TRAVEL_BUSINESS("travel_business", "旅游业务", DialoguesPlatformEnum.ModelLink),
MEETING_ASSISTANT("meeting_assistant", "会议助手"), MEETING_ASSISTANT("meeting_assistant", "会议助手", DialoguesPlatformEnum.ModelLink),
LEGISLATIVE_DOCUMENT_WRITING("legislative_document_writing", "立案调查"), LEGISLATIVE_DOCUMENT_WRITING("legislative_document_writing", "立案调查", DialoguesPlatformEnum.ModelLink),
CAR_INSURANCE("car_insurance", "车辆保险"), CAR_INSURANCE("car_insurance", "车辆保险", DialoguesPlatformEnum.AppBuilder),
CAR_RECOMMEND("car_recommend", "车辆推荐"), CAR_RECOMMEND("car_recommend", "车辆推荐", DialoguesPlatformEnum.AppBuilder),
DATA_AUDIT("data_audit", "数据校验"), DATA_AUDIT("data_audit", "数据校验", DialoguesPlatformEnum.ModelLink),
AI_SOFTWARE_COPYRIGHT("ai_software_copyright", "AI软著"), AI_SOFTWARE_COPYRIGHT("ai_software_copyright", "AI软著", DialoguesPlatformEnum.Dify),
; ;
...@@ -50,9 +50,13 @@ public enum AiDialoguesTypeEnum { ...@@ -50,9 +50,13 @@ public enum AiDialoguesTypeEnum {
private final String desc; private final String desc;
AiDialoguesTypeEnum(String type, String desc) { private final DialoguesPlatformEnum platform;
// DialoguesPlatformEnum.ModelLink: modellink DialoguesPlatformEnum.AppBuilder: appbuilder DialoguesPlatformEnum.Dify: dify
AiDialoguesTypeEnum(String type, String desc, DialoguesPlatformEnum platform) {
this.type = type; this.type = type;
this.desc = desc; this.desc = desc;
this.platform = platform;
} }
public String getType() { public String getType() {
...@@ -63,6 +67,9 @@ public enum AiDialoguesTypeEnum { ...@@ -63,6 +67,9 @@ public enum AiDialoguesTypeEnum {
return desc; return desc;
} }
public DialoguesPlatformEnum getPlatform() {
return platform;
}
public static AiDialoguesTypeEnum getByType(String type) { public static AiDialoguesTypeEnum getByType(String type) {
for (AiDialoguesTypeEnum aiDialoguesTypeEnum : AiDialoguesTypeEnum.values()) { for (AiDialoguesTypeEnum aiDialoguesTypeEnum : AiDialoguesTypeEnum.values()) {
......
...@@ -3,7 +3,7 @@ package cn.com.poc.ai_software_copyright.agent; ...@@ -3,7 +3,7 @@ package cn.com.poc.ai_software_copyright.agent;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedHashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
...@@ -18,16 +18,26 @@ import cn.com.gsst.dify_client.enums.ResponseMode; ...@@ -18,16 +18,26 @@ import cn.com.gsst.dify_client.enums.ResponseMode;
import cn.com.gsst.dify_client.event.MessageEndEvent; import cn.com.gsst.dify_client.event.MessageEndEvent;
import cn.com.gsst.dify_client.event.MessageEvent; import cn.com.gsst.dify_client.event.MessageEvent;
import cn.com.gsst.dify_client.exception.DifyApiException; import cn.com.gsst.dify_client.exception.DifyApiException;
import cn.com.gsst.dify_client.model.DifyConfig;
import cn.com.gsst.dify_client.model.chat.ChatMessage; import cn.com.gsst.dify_client.model.chat.ChatMessage;
import cn.com.gsst.dify_client.model.chat.ChatMessageResponse; import cn.com.gsst.dify_client.model.chat.ChatMessageResponse;
import cn.com.gsst.dify_client.model.file.FileInfo; import cn.com.gsst.dify_client.model.file.FileInfo;
import cn.com.poc.ai_software_copyright.contant.AiSoftWareCopyRightEnum; import cn.com.poc.ai_software_copyright.contant.AiSoftWareCopyRightEnum;
import cn.com.poc.ai_software_copyright.contant.AiSoftWareCopyRightRedisKey;
import cn.com.poc.ai_software_copyright.domain.GeneratedDoc;
import cn.com.poc.ai_software_copyright.domian.BaseInfo;
import cn.com.poc.ai_software_copyright.domian.TechnicalContent;
import cn.com.poc.common.pool.CommonThreadPoolExecutor;
import cn.com.poc.common.utils.DateUtils;
import cn.com.poc.common.utils.JsonUtils; import cn.com.poc.common.utils.JsonUtils;
import cn.com.poc.common.utils.SSEUtil; import cn.com.poc.common.utils.SSEUtil;
import cn.com.poc.common.utils.StringUtils; import cn.com.poc.common.utils.StringUtils;
import cn.com.poc.thirdparty.resource.demand.ai.entity.largemodel.LargeModelDemandResult; import cn.com.poc.thirdparty.resource.demand.ai.entity.largemodel.LargeModelDemandResult;
import cn.com.yict.framemax.core.exception.BusinessException; import cn.com.yict.framemax.core.exception.BusinessException;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.context.request.ServletRequestAttributes;
...@@ -39,27 +49,73 @@ import org.springframework.web.context.request.ServletRequestAttributes; ...@@ -39,27 +49,73 @@ import org.springframework.web.context.request.ServletRequestAttributes;
@Component @Component
public class SoftwareCopyRightAgent { public class SoftwareCopyRightAgent {
private final Logger logger = LoggerFactory.getLogger(SoftwareCopyRightAgent.class);
@Value("${dify.base.url}")
private String DIFY_BASE_URL;
@Value("${dify.software_copyright.callball.url}")
private String CALL_BACK_URL;
/**
* 软著AI助手
*/
public void softwareCopyRightAssistant(List<String> fileUrls, String question, Map<String, Object> data)
throws DifyApiException, IOException, InterruptedException {
String API_KEY = "app-S3y8vmyX95cTa0sb9V9oBfSX";
streamChat(
fileUrls,
question,
data,
AiSoftWareCopyRightEnum.AI_ASSISTANT_TYPE.DEVELOPMENT_PURPOSE.name(),
API_KEY
);
}
/**
* 生成基础文档
*
* @param taskId
* @param files
* @param baseInfo
* @param technicalContent
*/
public void generatedBaseDoc(String taskId, List<String> files, BaseInfo baseInfo,
TechnicalContent technicalContent) {
String api_key = "app-VgynqQ7MDYW6CjUbtDu4osBf";
String ques = "执行";
String user = "generatedBaseDoc" + DateUtils.getCurrTime();
Map<String, Object> data = new HashMap<>();
data.put("task_id", taskId);
data.put("baseinfo", JsonUtils.serialize(baseInfo));
data.put("technical_content", JsonUtils.serialize(technicalContent));
data.put("callback_url", CALL_BACK_URL);
CommonThreadPoolExecutor.addTask(() -> blockingChat(files, ques, data, user, api_key));
}
private static String DIFY_BASE_URL = "https://dify.gsstcloud.com/v1";
/** /**
* 文件生成 * 文件生成
* *
* @param o * @param generatedDoc
* @param docType * @param docType
* @return * @return
*/ */
public Object generatedDocByType(Object o, AiSoftWareCopyRightEnum.DOC_TYPE docType) { public void generatedDocByType(GeneratedDoc generatedDoc, AiSoftWareCopyRightEnum.DOC_TYPE docType) {
switch (docType) { switch (docType) {
case source_code: case source_code:
return sourceCode(o); sourceCode(generatedDoc);
break;
case ph_operating_manual: case ph_operating_manual:
return phOperatingManual(o); phOperatingManual(generatedDoc);
break;
case pc_operating_manual: case pc_operating_manual:
return pcOperatingManual(o); pcOperatingManual(generatedDoc);
break;
case information: case information:
return information(o); information(generatedDoc);
break;
default: default:
throw new BusinessException("不支持的文档类型:" + docType); throw new BusinessException("不支持的文档类型:" + docType);
} }
...@@ -107,82 +163,73 @@ public class SoftwareCopyRightAgent { ...@@ -107,82 +163,73 @@ public class SoftwareCopyRightAgent {
} }
// 软著AI助手-源代码生成 // 软著AI助手-源代码生成
public Object sourceCode(Object o) { private void sourceCode(GeneratedDoc doc) {
return null; String api_key = "app-c0PWYmcythg7bIVxvt4d4kDM";
String q = "生成源代码";
Map<String, Object> data = new HashMap<>();
data.put("ui", doc.getUi());
data.put("structure", doc.getStructure());
data.put("demand", doc.getDemand());
data.put("code", "");
data.put("baseinfo", JsonUtils.serialize(doc.getBaseinfo()));
data.put("technical_content", JsonUtils.serialize(doc.getTechnical_content()));
data.put("callback_url", CALL_BACK_URL);
data.put("task_id", AiSoftWareCopyRightRedisKey.CALL_BACK + doc.getId());
String user = "phOperatingManual" + DateUtils.getCurrTime();
CommonThreadPoolExecutor.addTask(() -> blockingChat(doc.getFileURLs(), q, data, user, api_key));
} }
// 软著AI助手-手机端说明书 // 软著AI助手-手机端说明书
public Object phOperatingManual(Object o) { private void phOperatingManual(GeneratedDoc doc) {
return null; String api_key = "app-c0PWYmcythg7bIVxvt4d4kDM";
String q = "生成手机端使用说明书";
Map<String, Object> data = new HashMap<>();
data.put("ui", doc.getUi());
data.put("structure", doc.getStructure());
data.put("demand", doc.getDemand());
data.put("code", "");
data.put("baseinfo", JsonUtils.serialize(doc.getBaseinfo()));
data.put("technical_content", JsonUtils.serialize(doc.getTechnical_content()));
data.put("callback_url", CALL_BACK_URL);
data.put("task_id", AiSoftWareCopyRightRedisKey.CALL_BACK + doc.getId());
String user = "phOperatingManual" + DateUtils.getCurrTime();
CommonThreadPoolExecutor.addTask(() -> blockingChat(doc.getFileURLs(), q, data, user, api_key));
} }
// 软著AI助手-PC端说明书 // 软著AI助手-PC端说明书
public Object pcOperatingManual(Object o) { private void pcOperatingManual(GeneratedDoc doc) {
return null; String api_key = "app-c0PWYmcythg7bIVxvt4d4kDM";
String q = "生成电脑端使用说明书";
Map<String, Object> data = new HashMap<>();
data.put("ui", doc.getUi());
data.put("structure", doc.getStructure());
data.put("demand", doc.getDemand());
data.put("code", "");
data.put("baseinfo", JsonUtils.serialize(doc.getBaseinfo()));
data.put("technical_content", JsonUtils.serialize(doc.getTechnical_content()));
data.put("callback_url", CALL_BACK_URL);
data.put("task_id", AiSoftWareCopyRightRedisKey.CALL_BACK + doc.getId());
String user = "pcOperatingManual" + DateUtils.getCurrTime();
CommonThreadPoolExecutor.addTask(() -> blockingChat(doc.getFileURLs(), q, data, user, api_key));
} }
// 软著AI助手-信息采集表 // 软著AI助手-信息采集表
public Object information(Object o) { private void information(GeneratedDoc doc) {
return null;
} }
// ------------ // ------------
// 软著AI助手-开发目的
private final String API_KEY = "app-S3y8vmyX95cTa0sb9V9oBfSX";
public void developmentPurpose(List<String> fileUrls, String question, Map<String, Object> data)
throws InterruptedException, DifyApiException, IOException {
streamChat(
fileUrls,
question,
data,
AiSoftWareCopyRightEnum.AI_ASSISTANT_TYPE.DEVELOPMENT_PURPOSE.name(),
API_KEY
);
}
// 软著AI助手-面向行业/领域
public void targetIndustry(List<String> fileUrls, String question, Map<String, Object> data)
throws InterruptedException, DifyApiException, IOException {
streamChat(
fileUrls,
question,
data,
AiSoftWareCopyRightEnum.AI_ASSISTANT_TYPE.TARGET_INDUSTRY.name(),
API_KEY
);
}
// 软著AI助手-软件的主要功能
public void mainFunction(List<String> fileUrls, String question, Map<String, Object> data)
throws InterruptedException, DifyApiException, IOException {
streamChat(
fileUrls,
question,
data,
AiSoftWareCopyRightEnum.AI_ASSISTANT_TYPE.MAIN_FUNCTION.name(),
API_KEY
);
}
// 软著AI助手-该软件的技术特点
public void technicalFeatures(List<String> fileUrls, String question, Map<String, Object> data)
throws InterruptedException, DifyApiException, IOException {
streamChat(
fileUrls,
question,
data,
AiSoftWareCopyRightEnum.AI_ASSISTANT_TYPE.TECHNICAL_FEATURES.name(),
API_KEY
);
}
private String blockingChat(List<String> fileUrls, private String blockingChat(List<String> fileUrls,
String question, String question,
Map<String, Object> data, Map<String, Object> data,
String user, String user,
String apiKey) { String apiKey) {
DifyChatClient chatClient = DifyClientFactory.createChatClient(DIFY_BASE_URL, apiKey);
DifyConfig difyConfig = DifyConfig.builder()
.apiKey(apiKey)
.readTimeout(200 * 1000)
.baseUrl(DIFY_BASE_URL)
.build();
DifyChatClient chatClient = DifyClientFactory.createChatClient(difyConfig);
List<FileInfo> files = new ArrayList<>(); List<FileInfo> files = new ArrayList<>();
if (CollectionUtils.isNotEmpty(fileUrls)) { if (CollectionUtils.isNotEmpty(fileUrls)) {
...@@ -209,6 +256,7 @@ public class SoftwareCopyRightAgent { ...@@ -209,6 +256,7 @@ public class SoftwareCopyRightAgent {
ChatMessageResponse chatMessageResponse = chatClient.sendChatMessage(message); ChatMessageResponse chatMessageResponse = chatClient.sendChatMessage(message);
return chatMessageResponse.getAnswer(); return chatMessageResponse.getAnswer();
} catch (IOException | DifyApiException e) { } catch (IOException | DifyApiException e) {
logger.error(e.getMessage());
throw new BusinessException("执行" + user + "生成异常"); throw new BusinessException("执行" + user + "生成异常");
} }
} }
...@@ -217,9 +265,9 @@ public class SoftwareCopyRightAgent { ...@@ -217,9 +265,9 @@ public class SoftwareCopyRightAgent {
String question, String question,
Map<String, Object> data, Map<String, Object> data,
String user, String user,
String apiKey) throws InterruptedException, IOException, DifyApiException { String apiKey) throws IOException, DifyApiException, InterruptedException {
// 创建聊天客户端 // 创建聊天客户端
DifyChatClient chatClient = DifyClientFactory.createChatClient(DIFY_BASE_URL, apiKey); DifyChatClient chatClient = DifyClientFactory.createChatWorkflowClient(DIFY_BASE_URL, apiKey);
List<FileInfo> files = new ArrayList<>(); List<FileInfo> files = new ArrayList<>();
if (CollectionUtils.isNotEmpty(fileUrls)) { if (CollectionUtils.isNotEmpty(fileUrls)) {
...@@ -232,7 +280,6 @@ public class SoftwareCopyRightAgent { ...@@ -232,7 +280,6 @@ public class SoftwareCopyRightAgent {
} }
} }
// 创建聊天消息 // 创建聊天消息
ChatMessage message = ChatMessage.builder() ChatMessage message = ChatMessage.builder()
.query(question) .query(question)
...@@ -257,9 +304,9 @@ public class SoftwareCopyRightAgent { ...@@ -257,9 +304,9 @@ public class SoftwareCopyRightAgent {
LargeModelDemandResult largeModelDemandResult = new LargeModelDemandResult(); LargeModelDemandResult largeModelDemandResult = new LargeModelDemandResult();
largeModelDemandResult.setCode("0"); largeModelDemandResult.setCode("0");
largeModelDemandResult.setMessage(event.getAnswer()); largeModelDemandResult.setMessage(event.getAnswer());
sseUtil.send(JsonUtils.serialize(event.getAnswer())); sseUtil.send(JsonUtils.serialize(largeModelDemandResult));
} }
} catch (IOException e) { } catch (Exception e) {
sseUtil.completeByError(e.getMessage()); sseUtil.completeByError(e.getMessage());
throw new RuntimeException(e); throw new RuntimeException(e);
} }
...@@ -274,10 +321,10 @@ public class SoftwareCopyRightAgent { ...@@ -274,10 +321,10 @@ public class SoftwareCopyRightAgent {
throw new RuntimeException(e); throw new RuntimeException(e);
} finally { } finally {
sseUtil.complete(); sseUtil.complete();
countDownLatch.countDown();
} }
countDownLatch.countDown();
} }
}); });
countDownLatch.await(60, TimeUnit.SECONDS); countDownLatch.await(120, TimeUnit.SECONDS);
} }
} }
...@@ -8,9 +8,8 @@ import cn.com.gsst.dify_client.exception.DifyApiException; ...@@ -8,9 +8,8 @@ import cn.com.gsst.dify_client.exception.DifyApiException;
import cn.com.poc.ai_software_copyright.contant.AiSoftWareCopyRightEnum; import cn.com.poc.ai_software_copyright.contant.AiSoftWareCopyRightEnum;
import cn.com.poc.ai_software_copyright.domian.BaseInfo; import cn.com.poc.ai_software_copyright.domian.BaseInfo;
import cn.com.poc.ai_software_copyright.domian.TechnicalContent; import cn.com.poc.ai_software_copyright.domian.TechnicalContent;
import cn.com.poc.ai_software_copyright.dto.SoftwareCopyRightFilesDto;
import cn.com.poc.ai_software_copyright.entity.BizSoftwareCopyrightDocRecordEntity; import cn.com.poc.ai_software_copyright.entity.BizSoftwareCopyrightDocRecordEntity;
import org.springframework.web.bind.annotation.RequestParam; import cn.com.poc.ai_software_copyright.entity.CallbackEntity;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
/** /**
...@@ -52,7 +51,7 @@ public interface SoftwareCopyRightService { ...@@ -52,7 +51,7 @@ public interface SoftwareCopyRightService {
* *
* @param id biz_software_copyright 主键id * @param id biz_software_copyright 主键id
*/ */
BizSoftwareCopyrightDocRecordEntity listFile(Long id) throws Exception; BizSoftwareCopyrightDocRecordEntity listFile(Long id) ;
/** /**
* 获取下载地址 * 获取下载地址
...@@ -79,4 +78,13 @@ public interface SoftwareCopyRightService { ...@@ -79,4 +78,13 @@ public interface SoftwareCopyRightService {
*/ */
String zipFilesAndUpdateRecord(BizSoftwareCopyrightDocRecordEntity recordEntity); String zipFilesAndUpdateRecord(BizSoftwareCopyrightDocRecordEntity recordEntity);
/**
* 回调-生成基础文档
*
* @param taskId 回调任务ID
* @param type 回调类型
* @param callbackEntity 回调结果
*/
void callbackGeneratedBaseDoc(String taskId, String type, CallbackEntity callbackEntity);
} }
...@@ -6,10 +6,12 @@ import java.io.IOException; ...@@ -6,10 +6,12 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.file.Files; import java.nio.file.Files;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import cn.com.gsst.dify_client.exception.DifyApiException; import cn.com.gsst.dify_client.exception.DifyApiException;
...@@ -20,14 +22,18 @@ import cn.com.poc.ai_software_copyright.domian.BaseInfo; ...@@ -20,14 +22,18 @@ import cn.com.poc.ai_software_copyright.domian.BaseInfo;
import cn.com.poc.ai_software_copyright.domian.TechnicalContent; import cn.com.poc.ai_software_copyright.domian.TechnicalContent;
import cn.com.poc.ai_software_copyright.entity.BizSoftwareCopyrightDocRecordEntity; import cn.com.poc.ai_software_copyright.entity.BizSoftwareCopyrightDocRecordEntity;
import cn.com.poc.ai_software_copyright.entity.BizSoftwareCopyrightEntity; import cn.com.poc.ai_software_copyright.entity.BizSoftwareCopyrightEntity;
import cn.com.poc.ai_software_copyright.entity.CallbackEntity;
import cn.com.poc.ai_software_copyright.service.BizSoftwareCopyrightDocRecordService; import cn.com.poc.ai_software_copyright.service.BizSoftwareCopyrightDocRecordService;
import cn.com.poc.ai_software_copyright.service.BizSoftwareCopyrightService; import cn.com.poc.ai_software_copyright.service.BizSoftwareCopyrightService;
import cn.com.poc.common.constant.CommonConstant; import cn.com.poc.common.constant.CommonConstant;
import cn.com.poc.common.model.BizFileUploadRecordModel; import cn.com.poc.common.model.BizFileUploadRecordModel;
import cn.com.poc.common.service.BizFileUploadRecordService; import cn.com.poc.common.service.BizFileUploadRecordService;
import cn.com.poc.common.service.BosConfigService; import cn.com.poc.common.service.BosConfigService;
import cn.com.poc.common.service.RedisService;
import cn.com.poc.common.utils.DocumentLoad; import cn.com.poc.common.utils.DocumentLoad;
import cn.com.poc.common.utils.JsonUtils; import cn.com.poc.common.utils.JsonUtils;
import cn.com.poc.common.utils.MD5Util;
import cn.com.poc.common.utils.MD5Utils;
import cn.com.poc.common.utils.StringUtils; import cn.com.poc.common.utils.StringUtils;
import cn.com.yict.framemax.core.exception.BusinessException; import cn.com.yict.framemax.core.exception.BusinessException;
import cn.hutool.core.collection.ListUtil; import cn.hutool.core.collection.ListUtil;
...@@ -52,6 +58,9 @@ public class SoftwareCopyRightServiceImpl implements SoftwareCopyRightService { ...@@ -52,6 +58,9 @@ public class SoftwareCopyRightServiceImpl implements SoftwareCopyRightService {
@Resource @Resource
private BosConfigService bosConfigService; private BosConfigService bosConfigService;
@Resource
private RedisService redisService;
@Resource @Resource
private BizFileUploadRecordService bizFileUploadRecordService; private BizFileUploadRecordService bizFileUploadRecordService;
...@@ -74,51 +83,76 @@ public class SoftwareCopyRightServiceImpl implements SoftwareCopyRightService { ...@@ -74,51 +83,76 @@ public class SoftwareCopyRightServiceImpl implements SoftwareCopyRightService {
) throws InterruptedException, DifyApiException, IOException { ) throws InterruptedException, DifyApiException, IOException {
switch (type) { switch (type) {
case MAIN_FUNCTION: case MAIN_FUNCTION:
softwareCopyRightAgent.mainFunction(fileUrls, "生成[开发目的]", data); question = "生成[开发目的]";
break; break;
case TARGET_INDUSTRY: case TARGET_INDUSTRY:
softwareCopyRightAgent.targetIndustry(fileUrls, "生成[面向行业/领域]", data); question = "生成[面向行业/领域]";
break; break;
case TECHNICAL_FEATURES: case TECHNICAL_FEATURES:
softwareCopyRightAgent.technicalFeatures(fileUrls, "生成[软件的主要功能]", data); question = "生成[软件的主要功能]";
break; break;
case DEVELOPMENT_PURPOSE: case DEVELOPMENT_PURPOSE:
softwareCopyRightAgent.developmentPurpose(fileUrls, "生成[技术特点]", data); question = "生成[技术特点]";
break; break;
default: default:
throw new BusinessException("不支持的AI助手类型: " + type); throw new BusinessException("不支持的AI助手类型: " + type);
} }
softwareCopyRightAgent.softwareCopyRightAssistant(fileUrls, question, data);
} }
@Override @Override
public TechnicalContent createTechnicalContent(List<String> fileUrls, BaseInfo baseInfo) throws IOException { public TechnicalContent createTechnicalContent(List<String> fileUrls, BaseInfo baseInfo) throws IOException {
Map<String, Object> data = new HashMap<>(); Map<String, Object> data = new HashMap<>();
List<File> tempFiles = new ArrayList<>(); // 用于跟踪临时文件
try {
// 下载文件内容 // 下载文件内容
if (CollectionUtils.isNotEmpty(fileUrls)) { if (CollectionUtils.isNotEmpty(fileUrls)) {
StringBuilder stringBuilder = new StringBuilder(); StringBuilder stringBuilder = new StringBuilder();
StringBuilder codeBuilder = new StringBuilder(); StringBuilder codeBuilder = new StringBuilder();
for (String fileUrl : fileUrls) { for (String fileUrl : fileUrls) {
File file = DocumentLoad.downloadURLDocument(fileUrl); File file = DocumentLoad.downloadURLDocument(fileUrl);
tempFiles.add(file); // 添加到临时文件列表
// 判断是否为压缩文件并解压 // 判断是否为压缩文件并解压
if (isCompressedFile(file)) { if (isCompressedFile(file)) {
//todo 解压文件,获取解压后的文件列表 try {
//解压文件,获取解压后的文件列表
List<File> files = unGzip(file); List<File> files = unGzip(file);
if (files != null) { // 添加空值检查
for (File codeFiles : files) { for (File codeFiles : files) {
// String fileContent = DocumentLoad.documentToText(codeFiles); // 验证文件名安全性
// codeBuilder.append("##").append(file.getName()).append(StringUtils.LF); String fileName = sanitizeFileName(codeFiles.getName());
// codeBuilder.append(fileContent).append(StringUtils.LF); String fileContent = DocumentLoad.documentToText(codeFiles);
codeBuilder.append("##").append(fileName).append(StringUtils.LF);
codeBuilder.append(fileContent).append(StringUtils.LF);
// 添加到临时文件列表以便清理
tempFiles.add(codeFiles);
}
}
} catch (Exception e) {
logger.error("解压文件失败: {}", file.getAbsolutePath(), e);
throw new IOException("解压文件失败: " + file.getAbsolutePath(), e);
} }
} else { } else {
try {
// 验证文件名安全性
String fileName = sanitizeFileName(file.getName());
String fileContent = DocumentLoad.documentToText(file); String fileContent = DocumentLoad.documentToText(file);
stringBuilder.append("##").append(file.getName()).append(StringUtils.LF); stringBuilder.append("##").append(fileName).append(StringUtils.LF);
stringBuilder.append(fileContent).append(StringUtils.LF); stringBuilder.append(fileContent).append(StringUtils.LF);
} catch (Exception e) {
logger.error("读取文件内容失败: {}", file.getAbsolutePath(), e);
throw new IOException("读取文件内容失败: " + file.getAbsolutePath(), e);
}
} }
} }
data.put("files", stringBuilder.toString()); data.put("files", stringBuilder.toString());
data.put("code", codeBuilder.toString()); data.put("code", codeBuilder.toString());
} }
String baseInfoStr = JsonUtils.serialize(baseInfo); String baseInfoStr = JsonUtils.serialize(baseInfo);
String technicalContent = softwareCopyRightAgent.technicalContent(null, baseInfoStr, data); String technicalContent = softwareCopyRightAgent.technicalContent(null, baseInfoStr, data);
logger.info("【技术内容】 baseInfo:{},生成结果: {}", baseInfoStr, technicalContent); logger.info("【技术内容】 baseInfo:{},生成结果: {}", baseInfoStr, technicalContent);
...@@ -126,42 +160,24 @@ public class SoftwareCopyRightServiceImpl implements SoftwareCopyRightService { ...@@ -126,42 +160,24 @@ public class SoftwareCopyRightServiceImpl implements SoftwareCopyRightService {
throw new BusinessException("执行【技术内容】生成异常"); throw new BusinessException("执行【技术内容】生成异常");
} }
return JsonUtils.deSerialize(technicalContent, TechnicalContent.class); return JsonUtils.deSerialize(technicalContent, TechnicalContent.class);
} finally {
// 清理临时文件
for (File tempFile : tempFiles) {
if (tempFile != null && tempFile.exists()) {
try {
tempFile.delete();
} catch (Exception e) {
logger.warn("删除临时文件失败: {}", tempFile.getAbsolutePath(), e);
}
}
} }
/**
* 判断文件是否为压缩文件
*
* @param file 文件
* @return 是否为压缩文件
*/
private boolean isCompressedFile(File file) {
String fileName = file.getName().toLowerCase();
return fileName.endsWith(".zip") || fileName.endsWith(".tar") ||
fileName.endsWith(".tar.gz") || fileName.endsWith(".tgz") ||
fileName.endsWith(".rar") || fileName.endsWith(".7z");
} }
/**
* 解压文件
*
* @param gzipFile
* @return
* @throws IOException
*/
private List<File> unGzip(File gzipFile) throws IOException {
// 目标解压目录
String destDir = Files.createTempDirectory("gzip/temp/").toString();
// 确保目标目录存在
FileUtil.mkdir(destDir);
File[] extractedFiles = ZipUtil.unzip(gzipFile, new File(destDir)).listFiles();
return ListUtil.toList(extractedFiles);
} }
@Override @Override
public BizSoftwareCopyrightDocRecordEntity listFile(Long id) throws Exception { public BizSoftwareCopyrightDocRecordEntity listFile(Long id) {
checkTaskIsComplete(id); checkTaskIsComplete(id);
BizSoftwareCopyrightDocRecordEntity bizSoftwareCopyrightDocRecordEntity = BizSoftwareCopyrightDocRecordEntity bizSoftwareCopyrightDocRecordEntity =
new BizSoftwareCopyrightDocRecordEntity(); new BizSoftwareCopyrightDocRecordEntity();
bizSoftwareCopyrightDocRecordEntity.setRelationId(id); bizSoftwareCopyrightDocRecordEntity.setRelationId(id);
...@@ -172,7 +188,7 @@ public class SoftwareCopyRightServiceImpl implements SoftwareCopyRightService { ...@@ -172,7 +188,7 @@ public class SoftwareCopyRightServiceImpl implements SoftwareCopyRightService {
} }
@Override @Override
public String getDownloadUrl(Long id) throws Exception { public String getDownloadUrl(Long id) {
checkTaskIsComplete(id); checkTaskIsComplete(id);
BizSoftwareCopyrightDocRecordEntity bizSoftwareCopyrightDocRecordEntity = BizSoftwareCopyrightDocRecordEntity bizSoftwareCopyrightDocRecordEntity =
new BizSoftwareCopyrightDocRecordEntity(); new BizSoftwareCopyrightDocRecordEntity();
...@@ -191,31 +207,19 @@ public class SoftwareCopyRightServiceImpl implements SoftwareCopyRightService { ...@@ -191,31 +207,19 @@ public class SoftwareCopyRightServiceImpl implements SoftwareCopyRightService {
} }
private void checkTaskIsComplete(Long id) {
BizSoftwareCopyrightEntity bizSoftwareCopyrightEntity = bizSoftwareCopyrightService.get(id);
if (bizSoftwareCopyrightEntity == null) {
throw new BusinessException("查询任务失败");
}
String generatedStatus = bizSoftwareCopyrightEntity.getGeneratedStatus();
if (!generatedStatus.equals(AiSoftWareCopyRightEnum.GENERATED_STATUS.Complete.name())) {
throw new BusinessException("任务未完成");
}
}
@Override @Override
public String upload(MultipartFile file) throws IOException { public String upload(MultipartFile file) throws IOException {
String md5 = MD5Util.fileToMD5(file.getInputStream());
BizFileUploadRecordModel fileUploadRecordModel = bizFileUploadRecordService.getByMD5(md5);
if (fileUploadRecordModel != null) {
return fileUploadRecordModel.getFileUrl();
}
String contentType = file.getContentType(); String contentType = file.getContentType();
String originalFilename = file.getOriginalFilename(); String originalFilename = file.getOriginalFilename();
String prefix = originalFilename.substring(originalFilename.lastIndexOf(".")).replaceAll("\\.", ""); String prefix = originalFilename.substring(originalFilename.lastIndexOf(".")).replaceAll("\\.", "");
String upload = bosConfigService.upload(file.getInputStream(), prefix, contentType); String upload = bosConfigService.upload(file.getInputStream(), prefix, contentType);
//计算文件MD5值
InputStream inputStream = file.getInputStream();
byte[] bytes = new byte[inputStream.available()];
inputStream.read(bytes);
String md5 = MD5.create().digestHex(bytes);
BizFileUploadRecordModel bizFileUploadRecordModel = new BizFileUploadRecordModel(); BizFileUploadRecordModel bizFileUploadRecordModel = new BizFileUploadRecordModel();
bizFileUploadRecordModel.setFileName(file.getOriginalFilename()); bizFileUploadRecordModel.setFileName(file.getOriginalFilename());
bizFileUploadRecordModel.setFileUrl(upload); bizFileUploadRecordModel.setFileUrl(upload);
...@@ -225,7 +229,23 @@ public class SoftwareCopyRightServiceImpl implements SoftwareCopyRightService { ...@@ -225,7 +229,23 @@ public class SoftwareCopyRightServiceImpl implements SoftwareCopyRightService {
return upload; return upload;
} }
@Override
public void callbackGeneratedBaseDoc(String taskId, String type, CallbackEntity callbackEntity) {
if (redisService.hasKey(taskId)) {
if (type.equals("success")) {
redisService.set(taskId, "success");
} else if (type.equals("error")) {
redisService.set(taskId, "error");
} else {
redisService.set(taskId + ":" + type, JsonUtils.serialize(callbackEntity));
}
} else {
logger.error("-------------------任务不存在: {}---------------------", taskId);
throw new BusinessException("任务不存在");
}
}
@Override
public String zipFilesAndUpdateRecord(BizSoftwareCopyrightDocRecordEntity recordEntity) { public String zipFilesAndUpdateRecord(BizSoftwareCopyrightDocRecordEntity recordEntity) {
String pcOperatingManualUrl = recordEntity.getPcOperatingManual(); String pcOperatingManualUrl = recordEntity.getPcOperatingManual();
String informationUrl = recordEntity.getInformation(); String informationUrl = recordEntity.getInformation();
...@@ -236,20 +256,39 @@ public class SoftwareCopyRightServiceImpl implements SoftwareCopyRightService { ...@@ -236,20 +256,39 @@ public class SoftwareCopyRightServiceImpl implements SoftwareCopyRightService {
// 添加所有有效的文件URL到文件列表,使用异步并行下载 // 添加所有有效的文件URL到文件列表,使用异步并行下载
CompletableFuture<Void> pcOperatingManualUrlFuture = CompletableFuture.runAsync(() -> { CompletableFuture<Void> pcOperatingManualUrlFuture = CompletableFuture.runAsync(() -> {
addFileIfNotBlank(pcOperatingManualUrl, files); addFileIfNotBlank(pcOperatingManualUrl, files);
}).exceptionally(throwable -> {
logger.error("下载PC操作手册失败: {}", pcOperatingManualUrl, throwable);
return null;
}); });
CompletableFuture<Void> informationUrlFuture = CompletableFuture.runAsync(() -> { CompletableFuture<Void> informationUrlFuture = CompletableFuture.runAsync(() -> {
addFileIfNotBlank(informationUrl, files); addFileIfNotBlank(informationUrl, files);
}).exceptionally(throwable -> {
logger.error("下载信息文件失败: {}", informationUrl, throwable);
return null;
}); });
CompletableFuture<Void> phOperatingManualUrlFuture = CompletableFuture.runAsync(() -> { CompletableFuture<Void> phOperatingManualUrlFuture = CompletableFuture.runAsync(() -> {
addFileIfNotBlank(phOperatingManualUrl, files); addFileIfNotBlank(phOperatingManualUrl, files);
}).exceptionally(throwable -> {
logger.error("下载手机操作手册失败: {}", phOperatingManualUrl, throwable);
return null;
}); });
CompletableFuture<Void> sourceCodeUrlFuture = CompletableFuture.runAsync(() -> { CompletableFuture<Void> sourceCodeUrlFuture = CompletableFuture.runAsync(() -> {
addFileIfNotBlank(sourceCodeUrl, files); addFileIfNotBlank(sourceCodeUrl, files);
}).exceptionally(throwable -> {
logger.error("下载源码失败: {}", sourceCodeUrl, throwable);
return null;
}); });
// 等待所有文件下载完成后再执行压缩和上传 // 等待所有文件下载完成后再执行压缩和上传
try {
CompletableFuture.allOf(pcOperatingManualUrlFuture, informationUrlFuture, CompletableFuture.allOf(pcOperatingManualUrlFuture, informationUrlFuture,
phOperatingManualUrlFuture, sourceCodeUrlFuture).join(); phOperatingManualUrlFuture, sourceCodeUrlFuture).join();
} catch (CompletionException e) {
throw new BusinessException("文件下载过程中发生错误", e.getCause());
}
if (CollectionUtils.isEmpty(files)) { if (CollectionUtils.isEmpty(files)) {
throw new BusinessException("文档下载失败"); throw new BusinessException("文档下载失败");
...@@ -257,19 +296,26 @@ public class SoftwareCopyRightServiceImpl implements SoftwareCopyRightService { ...@@ -257,19 +296,26 @@ public class SoftwareCopyRightServiceImpl implements SoftwareCopyRightService {
File zipFile = null; File zipFile = null;
try { try {
// 创建临时文件用于存放压缩包 // 创建临时文件用于存放压缩包,对文件名进行安全处理
zipFile = File.createTempFile("aggregation_" + recordEntity.getId(), ".zip"); String safeFileName = sanitizeFileName(String.valueOf(recordEntity.getId()));
zipFile = File.createTempFile("aggregation_" + safeFileName, ".zip");
// 将所有文件打包成zip // 将所有文件打包成zip
ZipUtil.zip(zipFile, Charset.defaultCharset(), false, files.toArray(new File[0])); ZipUtil.zip(zipFile, Charset.defaultCharset(), false, files.toArray(new File[0]));
// 使用try-with-resources确保流被正确关闭
try (InputStream zipInputStream = Files.newInputStream(zipFile.toPath())) {
// 上传压缩包到BOS并获取URL // 上传压缩包到BOS并获取URL
String aggregationUrl = bosConfigService.upload(Files.newInputStream(zipFile.toPath()), "zip", String aggregationUrl = bosConfigService.upload(zipInputStream, "zip",
"application/zip"); "application/zip");
// 更新数据库中的聚合URL // 更新数据库中的聚合URL
recordEntity.setAggregationUrl(aggregationUrl); recordEntity.setAggregationUrl(aggregationUrl);
bizSoftwareCopyrightDocRecordService.update(recordEntity); bizSoftwareCopyrightDocRecordService.update(recordEntity);
return aggregationUrl; return aggregationUrl;
} catch (Exception e) { }
} catch (IOException e) {
throw new BusinessException("压缩包创建或上传失败", e); throw new BusinessException("压缩包创建或上传失败", e);
} catch (Exception e) {
throw new BusinessException("压缩包处理失败", e);
} finally { } finally {
// 清理临时文件 // 清理临时文件
files.forEach(file -> { files.forEach(file -> {
...@@ -290,6 +336,7 @@ public class SoftwareCopyRightServiceImpl implements SoftwareCopyRightService { ...@@ -290,6 +336,7 @@ public class SoftwareCopyRightServiceImpl implements SoftwareCopyRightService {
} }
} }
/** /**
* 如果URL不为空白,则下载文件并添加到文件列表 * 如果URL不为空白,则下载文件并添加到文件列表
* *
...@@ -302,4 +349,63 @@ public class SoftwareCopyRightServiceImpl implements SoftwareCopyRightService { ...@@ -302,4 +349,63 @@ public class SoftwareCopyRightServiceImpl implements SoftwareCopyRightService {
files.add(file); files.add(file);
} }
} }
/**
* 判断文件是否为压缩文件
*
* @param file 文件
* @return 是否为压缩文件
*/
private boolean isCompressedFile(File file) {
String fileName = file.getName().toLowerCase();
return fileName.endsWith(".zip") || fileName.endsWith(".tar") ||
fileName.endsWith(".tar.gz") || fileName.endsWith(".tgz") ||
fileName.endsWith(".rar") || fileName.endsWith(".7z");
}
/**
* 解压文件
*
* @param gzipFile
* @return
* @throws IOException
*/
private List<File> unGzip(File gzipFile) throws IOException {
// 目标解压目录
String destDir = Files.createTempDirectory("gzip/temp/").toString();
// 确保目标目录存在
FileUtil.mkdir(destDir);
File[] extractedFiles = ZipUtil.unzip(gzipFile, new File(destDir)).listFiles();
return ListUtil.toList(extractedFiles);
}
private void checkTaskIsComplete(Long id) {
BizSoftwareCopyrightEntity bizSoftwareCopyrightEntity = bizSoftwareCopyrightService.get(id);
if (bizSoftwareCopyrightEntity == null) {
throw new BusinessException("查询任务失败");
}
String generatedStatus = bizSoftwareCopyrightEntity.getGeneratedStatus();
if (!generatedStatus.equals(AiSoftWareCopyRightEnum.GENERATED_STATUS.Complete.name())) {
throw new BusinessException("任务未完成");
}
}
/**
* 验证并清理文件名,防止路径遍历攻击
*/
private String sanitizeFileName(String fileName) {
if (fileName == null) {
return "unknown";
}
// 移除路径分隔符,防止路径遍历
fileName = fileName.replace("../", "").replace("..\\", "").replace("..", "");
// 只保留文件名部分
int lastSeparatorIndex = Math.max(fileName.lastIndexOf('/'), fileName.lastIndexOf('\\'));
if (lastSeparatorIndex >= 0) {
fileName = fileName.substring(lastSeparatorIndex + 1);
}
return fileName.isEmpty() ? "unknown" : fileName;
}
} }
\ No newline at end of file
package cn.com.poc.ai_software_copyright.contant;
/**
* @author alex.yao
* @date 2026/1/5
*/
public class AiSoftWareCopyRightRedisKey {
public static final String CALL_BACK = "SOFT_WARE_COPY_RIGHT_CALL_BACK:";
}
package cn.com.poc.ai_software_copyright.domain;
import java.util.List;
import cn.com.poc.ai_software_copyright.domian.BaseInfo;
import cn.com.poc.ai_software_copyright.domian.TechnicalContent;
/**
* @author alex.yao
* @date 2026/1/7
*/
public class GeneratedDoc {
private Long id;
private String ui;
private String structure;
private String demand;
private String code;
private BaseInfo baseinfo;
private TechnicalContent technical_content;
private List<String> fileURLs;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public List<String> getFileURLs() {
return fileURLs;
}
public void setFileURLs(List<String> fileURLs) {
this.fileURLs = fileURLs;
}
public String getUi() {
return ui;
}
public void setUi(String ui) {
this.ui = ui;
}
public String getStructure() {
return structure;
}
public void setStructure(String structure) {
this.structure = structure;
}
public String getDemand() {
return demand;
}
public void setDemand(String demand) {
this.demand = demand;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public BaseInfo getBaseinfo() {
return baseinfo;
}
public void setBaseinfo(BaseInfo baseinfo) {
this.baseinfo = baseinfo;
}
public TechnicalContent getTechnical_content() {
return technical_content;
}
public void setTechnical_content(TechnicalContent technical_content) {
this.technical_content = technical_content;
}
}
package cn.com.poc.ai_software_copyright.domian;
import java.util.Map;
/**
* @author alex.yao
* @date 2026/1/5
*/
public class BaseDocTask {
private String taskId;
private String status;
private Map<String, Object> result;
public String getTaskId() {
return taskId;
}
public void setTaskId(String taskId) {
this.taskId = taskId;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Map<String, Object> getResult() {
return result;
}
public void setResult(Map<String, Object> result) {
this.result = result;
}
}
package cn.com.poc.ai_software_copyright.entity;
/**
* @author alex.yao
* @date 2026/1/5
*/
public class CallbackEntity {
private Object result;
public Object getResult() {
return result;
}
public void setResult(Object result) {
this.result = result;
}
}
...@@ -12,4 +12,5 @@ where ...@@ -12,4 +12,5 @@ where
is_deleted = 'N' is_deleted = 'N'
<< and LOCATE(:query,JSON_EXTRACT(base_info, '$.softwareFullName'))>> << and LOCATE(:query,JSON_EXTRACT(base_info, '$.softwareFullName'))>>
<< and generated_status = :generatedStatus >> << and generated_status = :generatedStatus >>
<< and generated_status in (:generatedStatusList) >>
order by CREATED_TIME desc order by CREATED_TIME desc
\ No newline at end of file
package cn.com.poc.ai_software_copyright.query; package cn.com.poc.ai_software_copyright.query;
import java.io.Serializable; import java.io.Serializable;
import java.util.List;
/** /**
* Query Condition class for SoftwareCopyrightQuery * Query Condition class for SoftwareCopyrightQuery
*/ */
public class SoftwareCopyrightQueryCondition implements Serializable{ public class SoftwareCopyrightQueryCondition implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private java.lang.String query; private java.lang.String query;
public java.lang.String getQuery(){ public java.lang.String getQuery() {
return this.query; return this.query;
} }
public void setQuery(java.lang.String query){ public void setQuery(java.lang.String query) {
this.query = query; this.query = query;
} }
private java.lang.String generatedStatus; private java.lang.String generatedStatus;
public java.lang.String getGeneratedStatus(){
public java.lang.String getGeneratedStatus() {
return this.generatedStatus; return this.generatedStatus;
} }
public void setGeneratedStatus(java.lang.String generatedStatus){ public void setGeneratedStatus(java.lang.String generatedStatus) {
this.generatedStatus = generatedStatus; this.generatedStatus = generatedStatus;
} }
private List<String> generatedStatusList;
public List<String> getGeneratedStatusList() {
return generatedStatusList;
}
public void setGeneratedStatusList(List<String> generatedStatusList) {
this.generatedStatusList = generatedStatusList;
}
} }
\ No newline at end of file
...@@ -2,6 +2,7 @@ package cn.com.poc.ai_software_copyright.rest.impl; ...@@ -2,6 +2,7 @@ package cn.com.poc.ai_software_copyright.rest.impl;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
...@@ -16,12 +17,14 @@ import cn.com.poc.ai_software_copyright.dto.SoftwareCopyRightAssistantDto; ...@@ -16,12 +17,14 @@ import cn.com.poc.ai_software_copyright.dto.SoftwareCopyRightAssistantDto;
import cn.com.poc.ai_software_copyright.dto.SoftwareCopyRightDto; import cn.com.poc.ai_software_copyright.dto.SoftwareCopyRightDto;
import cn.com.poc.ai_software_copyright.dto.SoftwareCopyRightFilesDto; import cn.com.poc.ai_software_copyright.dto.SoftwareCopyRightFilesDto;
import cn.com.poc.ai_software_copyright.entity.BizSoftwareCopyrightEntity; import cn.com.poc.ai_software_copyright.entity.BizSoftwareCopyrightEntity;
import cn.com.poc.ai_software_copyright.entity.CallbackEntity;
import cn.com.poc.ai_software_copyright.query.SoftwareCopyrightQueryCondition; import cn.com.poc.ai_software_copyright.query.SoftwareCopyrightQueryCondition;
import cn.com.poc.ai_software_copyright.query.SoftwareCopyrightQueryItem; import cn.com.poc.ai_software_copyright.query.SoftwareCopyrightQueryItem;
import cn.com.poc.ai_software_copyright.rest.BizSoftwareCopyrightRest; import cn.com.poc.ai_software_copyright.rest.BizSoftwareCopyrightRest;
import cn.com.poc.ai_software_copyright.service.BizSoftwareCopyrightService; import cn.com.poc.ai_software_copyright.service.BizSoftwareCopyrightService;
import cn.com.poc.common.service.RedisService; import cn.com.poc.common.service.RedisService;
import cn.com.poc.common.utils.JsonUtils; import cn.com.poc.common.utils.JsonUtils;
import cn.com.poc.common.utils.StringUtils;
import cn.com.yict.framemax.data.model.PagingInfo; import cn.com.yict.framemax.data.model.PagingInfo;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.Assert; import org.springframework.util.Assert;
...@@ -31,6 +34,9 @@ import org.springframework.web.multipart.MultipartFile; ...@@ -31,6 +34,9 @@ import org.springframework.web.multipart.MultipartFile;
public class BizSoftwareCopyrightRestImpl implements BizSoftwareCopyrightRest { public class BizSoftwareCopyrightRestImpl implements BizSoftwareCopyrightRest {
@Resource
private RedisService redisService;
@Resource @Resource
private SoftwareCopyRightService softwareCopyRightService; private SoftwareCopyRightService softwareCopyRightService;
...@@ -58,10 +64,24 @@ public class BizSoftwareCopyrightRestImpl implements BizSoftwareCopyrightRest { ...@@ -58,10 +64,24 @@ public class BizSoftwareCopyrightRestImpl implements BizSoftwareCopyrightRest {
@Override @Override
public List<SoftwareCopyRightDto> querySoftwareCopyRight(String query, String generatedStatus, public List<SoftwareCopyRightDto> querySoftwareCopyRight(String query, String generatedStatus,
PagingInfo pagingInfo) {
PagingInfo pagingInfo) {
SoftwareCopyrightQueryCondition condition = new SoftwareCopyrightQueryCondition(); SoftwareCopyrightQueryCondition condition = new SoftwareCopyrightQueryCondition();
List<String> generatedStatusList = null;
if (StringUtils.isNotBlank(generatedStatus)) {
if (generatedStatus.equals(AiSoftWareCopyRightEnum.GENERATED_STATUS.Daft.name())
|| generatedStatus.equals(AiSoftWareCopyRightEnum.GENERATED_STATUS.Pending.name())
|| generatedStatus.equals(AiSoftWareCopyRightEnum.GENERATED_STATUS.Running.name())
) {
generatedStatusList = new ArrayList<>();
generatedStatusList.add(AiSoftWareCopyRightEnum.GENERATED_STATUS.Daft.name());
generatedStatusList.add(AiSoftWareCopyRightEnum.GENERATED_STATUS.Pending.name());
generatedStatusList.add(AiSoftWareCopyRightEnum.GENERATED_STATUS.Running.name());
condition.setGeneratedStatusList(generatedStatusList);
} else {
condition.setGeneratedStatus(generatedStatus); condition.setGeneratedStatus(generatedStatus);
}
}
condition.setQuery(query); condition.setQuery(query);
List<SoftwareCopyrightQueryItem> softwareCopyrightQueryItems = List<SoftwareCopyrightQueryItem> softwareCopyrightQueryItems =
bizSoftwareCopyrightService.softwareCopyrightQuery(condition, pagingInfo); bizSoftwareCopyrightService.softwareCopyrightQuery(condition, pagingInfo);
...@@ -107,21 +127,15 @@ public class BizSoftwareCopyrightRestImpl implements BizSoftwareCopyrightRest { ...@@ -107,21 +127,15 @@ public class BizSoftwareCopyrightRestImpl implements BizSoftwareCopyrightRest {
return softwareCopyRightService.getDownloadUrl(id); return softwareCopyRightService.getDownloadUrl(id);
} }
@Resource
private RedisService redisService;
@Override @Override
public void callbackGeneratedBaseDoc(String taskId, public void callbackGeneratedBaseDoc(String taskId,
String type, String type,
CallbackDto callbackDto) { CallbackDto callbackDto) {
if (redisService.hasKey(taskId)) { CallbackEntity callbackEntity = new CallbackEntity();
if (type.equals("success")) { if (callbackDto != null && callbackDto.getResult() != null) {
redisService.set(taskId, type); callbackEntity.setResult(callbackDto.getResult());
} else if (type.equals("error")) {
redisService.set(taskId, type);
} else {
redisService.set(taskId + ":" + type, JsonUtils.serialize(callbackDto));
}
} }
softwareCopyRightService.callbackGeneratedBaseDoc(taskId, type, callbackEntity);
} }
} }
\ No newline at end of file
package cn.com.poc.ai_software_copyright.scheduler; package cn.com.poc.ai_software_copyright.scheduler;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import static cn.com.poc.ai_software_copyright.contant.AiSoftWareCopyRightRedisKey.CALL_BACK;
import cn.com.poc.ai_software_copyright.agent.SoftwareCopyRightAgent;
import cn.com.poc.ai_software_copyright.contant.AiSoftWareCopyRightEnum; import cn.com.poc.ai_software_copyright.contant.AiSoftWareCopyRightEnum;
import cn.com.poc.ai_software_copyright.convert.BizSoftwareCopyrightConvert;
import cn.com.poc.ai_software_copyright.convert.BizSoftwareCopyrightDocRecordConvert;
import cn.com.poc.ai_software_copyright.domian.BaseInfo;
import cn.com.poc.ai_software_copyright.domian.TechnicalContent;
import cn.com.poc.ai_software_copyright.dto.SoftwareCopyRightDto;
import cn.com.poc.ai_software_copyright.entity.BizSoftwareCopyrightDocRecordEntity;
import cn.com.poc.ai_software_copyright.entity.BizSoftwareCopyrightEntity; import cn.com.poc.ai_software_copyright.entity.BizSoftwareCopyrightEntity;
import cn.com.poc.ai_software_copyright.service.BizSoftwareCopyrightDocRecordService;
import cn.com.poc.ai_software_copyright.service.BizSoftwareCopyrightService; import cn.com.poc.ai_software_copyright.service.BizSoftwareCopyrightService;
import cn.com.poc.common.constant.CommonConstant; import cn.com.poc.common.constant.CommonConstant;
import cn.com.poc.common.service.BosConfigService;
import cn.com.poc.common.service.RedisService;
import cn.com.poc.common.utils.JsonUtils;
import cn.com.poc.common.utils.ListUtils;
import cn.com.poc.common.utils.StringUtils;
import cn.com.poc.message.entity.SoftwareCopyRightMessage; import cn.com.poc.message.entity.SoftwareCopyRightMessage;
import cn.com.poc.message.service.SoftwareCopyRightProduceService; import cn.com.poc.message.service.SoftwareCopyRightProduceService;
import cn.com.poc.thirdparty.resource.demand.ai.aggregate.LegalService;
import cn.com.poc.thirdparty.resource.demand.ai.entity.legal.Item;
import cn.com.poc.thirdparty.resource.demand.ai.entity.legal.LegalFileResponse;
import cn.com.poc.thirdparty.resource.demand.ai.entity.legal.LegalFileResult;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
...@@ -20,30 +47,351 @@ import org.springframework.stereotype.Component; ...@@ -20,30 +47,351 @@ import org.springframework.stereotype.Component;
@Component @Component
public class SoftwareCopyRightScheduler { public class SoftwareCopyRightScheduler {
private static final String DOCX_EXTENSION = ".docx";
private static final String DOCX_FILE_TYPE = "docx";
private static final String INFORMATION_TEMPLATE_FILE_URL =
"https://gsst-poe-sit.gz.bcebos.com/v1/software-copyright/%E6%A8%A1%E6%9D%BF.docx";
@Resource @Resource
private SoftwareCopyRightProduceService produceService; private SoftwareCopyRightProduceService produceService;
@Resource
private RedisService redisService;
@Resource @Resource
private BizSoftwareCopyrightService bizSoftwareCopyrightService; private BizSoftwareCopyrightService bizSoftwareCopyrightService;
@Scheduled(cron = "0 0 0/30 * * ?") @Resource
public void checkSoftwareCopyRightTask() { private SoftwareCopyRightAgent softwareCopyRightAgent;
@Resource
private BizSoftwareCopyrightDocRecordService bizSoftwareCopyrightDocRecordService;
@Resource
private BosConfigService bosConfigService;
@Resource
private LegalService legalService;
@Scheduled(fixedDelay = 1000 * 30)
public void checkDeftSoftwareCopyRightTask() {
BizSoftwareCopyrightEntity bizSoftwareCopyrightEntity = new BizSoftwareCopyrightEntity(); BizSoftwareCopyrightEntity bizSoftwareCopyrightEntity = new BizSoftwareCopyrightEntity();
bizSoftwareCopyrightEntity.setGeneratedStatus(AiSoftWareCopyRightEnum.GENERATED_STATUS.Daft.name()); bizSoftwareCopyrightEntity.setGeneratedStatus(AiSoftWareCopyRightEnum.GENERATED_STATUS.Daft.name());
bizSoftwareCopyrightEntity.setIsDeleted(CommonConstant.IsDeleted.N); bizSoftwareCopyrightEntity.setIsDeleted(CommonConstant.IsDeleted.N);
List<BizSoftwareCopyrightEntity> bizSoftwareCopyrightEntities = List<BizSoftwareCopyrightEntity> bizSoftwareCopyrightEntities =
bizSoftwareCopyrightService.findByExample(bizSoftwareCopyrightEntity, null); bizSoftwareCopyrightService.findByExample(bizSoftwareCopyrightEntity, null);
if (CollectionUtils.isNotEmpty(bizSoftwareCopyrightEntities)) { if (CollectionUtils.isNotEmpty(bizSoftwareCopyrightEntities)) {
for (BizSoftwareCopyrightEntity softwareCopyrightEntity : bizSoftwareCopyrightEntities) { for (BizSoftwareCopyrightEntity softwareCopyrightEntity : bizSoftwareCopyrightEntities) {
String redisKey = CALL_BACK + softwareCopyrightEntity.getId();
if (redisService.hasKey(redisKey)) {
Object res = redisService.get(redisKey);
if (ObjectUtil.isEmpty(res)) {
continue;
}
String resStr = res.toString();
if (resStr.equals("error")) { // 失败
SoftwareCopyRightMessage message = new SoftwareCopyRightMessage();
message.setStatus(AiSoftWareCopyRightEnum.GENERATED_STATUS.Error);
produceService.updateStatus(message);
} else if (resStr.equals("success")) {
SoftwareCopyRightMessage message = new SoftwareCopyRightMessage(); SoftwareCopyRightMessage message = new SoftwareCopyRightMessage();
message.setId(softwareCopyrightEntity.getId()); message.setId(softwareCopyrightEntity.getId());
message.setStatus(AiSoftWareCopyRightEnum.GENERATED_STATUS.Pending); message.setStatus(AiSoftWareCopyRightEnum.GENERATED_STATUS.Pending);
message.setBaseInfo(bizSoftwareCopyrightEntity.getBaseInfo()); message.setBaseInfo(softwareCopyrightEntity.getBaseInfo());
message.setTechnicalContent(bizSoftwareCopyrightEntity.getTechnicalContent()); message.setTechnicalContent(softwareCopyrightEntity.getTechnicalContent());
message.setReferenceDocumentFileUrl(bizSoftwareCopyrightEntity.getReferenceDocumentFileUrl()); message.setReferenceDocumentFileUrl(softwareCopyrightEntity.getReferenceDocumentFileUrl());
message.setGeneratedDocType(bizSoftwareCopyrightEntity.getGeneratedDocType()); message.setGeneratedDocType(softwareCopyrightEntity.getGeneratedDocType());
produceService.submitTask(message); produceService.submitTask(message);
} }
} else {
// 设置Redis键值,避免重复处理
redisService.set(redisKey, null);
SoftwareCopyRightDto softwareCopyRightDto =
BizSoftwareCopyrightConvert.entityToDto(softwareCopyrightEntity);
List<String> files = softwareCopyRightDto.getReferenceDocumentFileUrl();
BaseInfo baseInfo = softwareCopyRightDto.getBaseInfo();
TechnicalContent technicalContent = softwareCopyRightDto.getTechnicalContent();
softwareCopyRightAgent.generatedBaseDoc(redisKey, files, baseInfo, technicalContent);
}
}
}
}
@Scheduled(fixedDelay = 1000 * 30)
public void checkRunningSoftwareCopyRightTask() {
BizSoftwareCopyrightEntity bizSoftwareCopyrightEntity = new BizSoftwareCopyrightEntity();
bizSoftwareCopyrightEntity.setGeneratedStatus(AiSoftWareCopyRightEnum.GENERATED_STATUS.Running.name());
bizSoftwareCopyrightEntity.setIsDeleted(CommonConstant.IsDeleted.N);
List<BizSoftwareCopyrightEntity> bizSoftwareCopyrightEntities =
bizSoftwareCopyrightService.findByExample(bizSoftwareCopyrightEntity, null);
if (CollectionUtils.isNotEmpty(bizSoftwareCopyrightEntities)) {
bizSoftwareCopyrightEntities.parallelStream().forEach(softwareCopyrightEntity -> {
after(softwareCopyrightEntity);
});
}
}
private void after(BizSoftwareCopyrightEntity softwareCopyrightEntity) {
BizSoftwareCopyrightDocRecordEntity recordEntity =
bizSoftwareCopyrightDocRecordService.getByRelationId(softwareCopyrightEntity.getId());
if (recordEntity == null) {
recordEntity = new BizSoftwareCopyrightDocRecordEntity();
recordEntity.setRelationId(softwareCopyrightEntity.getId());
}
String generatedDocType = softwareCopyrightEntity.getGeneratedDocType();
if (StringUtils.isBlank(generatedDocType)) {
return;
}
List<String> docTypes;
try {
docTypes = JsonUtils.deSerialize(generatedDocType, new TypeReference<List<String>>() {
}.getType());
} catch (Exception e) {
throw new IllegalArgumentException("Invalid generatedDocType format", e);
}
if (docTypes == null || docTypes.isEmpty()) {
return;
}
String redisKey = CALL_BACK + softwareCopyrightEntity.getId();
boolean allDone = true;
boolean isChange = false;
for (String docType : docTypes) {
AiSoftWareCopyRightEnum.DOC_TYPE type;
try {
type = AiSoftWareCopyRightEnum.DOC_TYPE.valueOf(docType);
} catch (IllegalArgumentException e) {
// 跳过无效的枚举值
continue;
}
if (type.equals(AiSoftWareCopyRightEnum.DOC_TYPE.source_code)) {
String sourceCode = recordEntity.getSourceCode();
if (StringUtils.isBlank(sourceCode)) {
Object obj = redisService.get(redisKey + ":" + type.name());
if (ObjectUtil.isEmpty(obj)) {
allDone = false;
continue;
}
try {
JSONObject jsonObject = JSONObject.parseObject(obj.toString());
JSONArray jsonArray = jsonObject.getJSONArray("result");
if (jsonArray != null) {
byte[] documentBytes = createSourceCodeDocument(jsonArray);
String url =
uploadDocument(documentBytes, "source_code_" + softwareCopyrightEntity.getId());
recordEntity.setSourceCode(url);
isChange = true;
}
} catch (Exception e) {
// 记录错误但继续处理其他类型
continue;
}
}
} else if (type.equals(AiSoftWareCopyRightEnum.DOC_TYPE.pc_operating_manual)) {
String pcOperatingManual = recordEntity.getPcOperatingManual();
if (StringUtils.isBlank(pcOperatingManual)) {
Object obj = redisService.get(redisKey + ":" + type.name());
if (ObjectUtil.isEmpty(obj)) {
allDone = false;
continue;
}
try {
JSONObject jsonObject = JSONObject.parseObject(obj.toString());
String result = jsonObject.getString("result");
if (result != null) {
byte[] documentBytes = createSimpleDocument(result);
String url = uploadDocument(documentBytes,
AiSoftWareCopyRightEnum.DOC_TYPE.pc_operating_manual.name() + "_" +
softwareCopyrightEntity.getId());
recordEntity.setPcOperatingManual(url);
isChange = true;
}
} catch (Exception e) {
// 记录错误但继续处理其他类型
continue;
}
}
} else if (type.equals(AiSoftWareCopyRightEnum.DOC_TYPE.ph_operating_manual)) {
String phOperatingManual = recordEntity.getPhOperatingManual();
if (StringUtils.isBlank(phOperatingManual)) { // 修复:使用正确的变量名
Object obj = redisService.get(redisKey + ":" + type.name());
if (ObjectUtil.isEmpty(obj)) {
allDone = false;
continue;
}
try {
JSONObject jsonObject = JSONObject.parseObject(obj.toString());
String result = jsonObject.getString("result");
if (result != null) {
byte[] documentBytes = createSimpleDocument(result);
String url = uploadDocument(documentBytes,
AiSoftWareCopyRightEnum.DOC_TYPE.ph_operating_manual.name() + "_" +
softwareCopyrightEntity.getId());
recordEntity.setPhOperatingManual(url);
isChange = true;
}
} catch (Exception e) {
// 记录错误但继续处理其他类型
continue;
}
}
} else if (type.equals(AiSoftWareCopyRightEnum.DOC_TYPE.information)) {
if (StringUtils.isBlank(recordEntity.getInformation())) {
SoftwareCopyRightDto softwareCopyRightDto =
BizSoftwareCopyrightConvert.entityToDto(softwareCopyrightEntity);
BaseInfo baseInfo = softwareCopyRightDto.getBaseInfo();
TechnicalContent technicalContent = softwareCopyRightDto.getTechnicalContent();
List<Item> items = new ArrayList<>();
buildItem(baseInfo, items, technicalContent);
LegalFileResponse legalFileResponse = new LegalFileResponse();
legalFileResponse.setItems(items);
legalFileResponse.setFilePath(INFORMATION_TEMPLATE_FILE_URL);
LegalFileResult legalFileResult = legalService.legalFile(legalFileResponse);
recordEntity.setInformation(legalFileResult.getFilePath());
isChange = true;
}
}
}
if (isChange) {
recordEntity = recordEntity.getId() != null ?
bizSoftwareCopyrightDocRecordService.update(recordEntity) :
bizSoftwareCopyrightDocRecordService.save(recordEntity);
}
//检查是否文档全部生成
if (allDone) {
softwareCopyrightEntity.setGeneratedStatus(AiSoftWareCopyRightEnum.GENERATED_STATUS.Complete.name());
bizSoftwareCopyrightService.update(softwareCopyrightEntity);
}
}
private void buildItem(BaseInfo baseInfo, List<Item> items, TechnicalContent technicalContent) {
// 处理baseInfo的所有字段
java.lang.reflect.Field[] baseInfoFields = baseInfo.getClass().getDeclaredFields();
for (java.lang.reflect.Field field : baseInfoFields) {
field.setAccessible(true);
try {
Object value = field.get(baseInfo);
List<String> values = new ArrayList<>();
if (value == null) {
values.add(" ");
}
if (value != null) {
values.add(value.toString());
}
Item item = new Item();
item.setKey(field.getName());
item.setValue(values);
item.setType("text");
items.add(item);
} catch (IllegalAccessException e) {
// 记录错误但继续处理其他字段
continue;
}
}
// 处理technicalContent的所有字段
java.lang.reflect.Field[] technicalContentFields = technicalContent.getClass().getDeclaredFields();
for (java.lang.reflect.Field field : technicalContentFields) {
field.setAccessible(true);
try {
Object value = field.get(technicalContent);
List<String> values = new ArrayList<>();
if (value == null) {
values.add(" ");
}
if (value != null) {
values.add(value.toString());
}
Item item = new Item();
item.setKey(field.getName());
item.setValue(values);
item.setType("text");
items.add(item);
} catch (IllegalAccessException e) {
// 记录错误但继续处理其他字段
continue;
}
}
}
private byte[] createSourceCodeDocument(JSONArray jsonArray) throws Exception {
org.apache.poi.xwpf.usermodel.XWPFDocument document =
new org.apache.poi.xwpf.usermodel.XWPFDocument();
try {
for (int i = 0; i < jsonArray.size(); i++) {
String content = jsonArray.getString(i);
org.apache.poi.xwpf.usermodel.XWPFParagraph contentParagraph = document.createParagraph();
org.apache.poi.xwpf.usermodel.XWPFRun contentRun = contentParagraph.createRun();
String[] split = content.split("\n");
for (String line : split) {
contentRun.setText(line);
contentRun.addBreak();
}
}
java.io.ByteArrayOutputStream out = new java.io.ByteArrayOutputStream();
document.write(out);
return out.toByteArray();
} finally {
document.close();
}
}
private byte[] createSimpleDocument(String content) throws Exception {
org.apache.poi.xwpf.usermodel.XWPFDocument document =
new org.apache.poi.xwpf.usermodel.XWPFDocument();
try {
org.apache.poi.xwpf.usermodel.XWPFParagraph contentParagraph = document.createParagraph();
org.apache.poi.xwpf.usermodel.XWPFRun contentRun = contentParagraph.createRun();
String[] split = content.split("\n");
for (String line : split) {
contentRun.setText(line);
contentRun.addBreak();
}
java.io.ByteArrayOutputStream out = new java.io.ByteArrayOutputStream();
document.write(out);
return out.toByteArray();
} finally {
document.close();
}
}
private String uploadDocument(byte[] documentBytes, String fileName) throws Exception {
File tempFile = null;
try {
tempFile = File.createTempFile(fileName, DOCX_EXTENSION);
FileUtil.writeBytes(documentBytes, tempFile);
try (FileInputStream fileInputStream = new FileInputStream(tempFile)) {
return bosConfigService.upload(fileInputStream, DOCX_FILE_TYPE, "");
}
} finally {
if (tempFile != null && tempFile.exists()) {
tempFile.delete();
}
} }
} }
} }
\ No newline at end of file
...@@ -4,19 +4,21 @@ import cn.com.yict.framemax.core.service.BaseService; ...@@ -4,19 +4,21 @@ import cn.com.yict.framemax.core.service.BaseService;
import cn.com.poc.ai_software_copyright.entity.BizSoftwareCopyrightDocRecordEntity; import cn.com.poc.ai_software_copyright.entity.BizSoftwareCopyrightDocRecordEntity;
import cn.com.yict.framemax.data.model.PagingInfo; import cn.com.yict.framemax.data.model.PagingInfo;
import java.util.Collection;
import java.util.List; import java.util.List;
public interface BizSoftwareCopyrightDocRecordService extends BaseService { public interface BizSoftwareCopyrightDocRecordService extends BaseService {
BizSoftwareCopyrightDocRecordEntity get(java.lang.Long id) throws Exception; BizSoftwareCopyrightDocRecordEntity get(java.lang.Long id) throws Exception;
BizSoftwareCopyrightDocRecordEntity getByRelationId(java.lang.Long relationId);
List<BizSoftwareCopyrightDocRecordEntity> findByExample(BizSoftwareCopyrightDocRecordEntity example, List<BizSoftwareCopyrightDocRecordEntity> findByExample(BizSoftwareCopyrightDocRecordEntity example,
PagingInfo pagingInfo) throws Exception; PagingInfo pagingInfo);
BizSoftwareCopyrightDocRecordEntity save(BizSoftwareCopyrightDocRecordEntity entity) throws Exception; BizSoftwareCopyrightDocRecordEntity save(BizSoftwareCopyrightDocRecordEntity entity);
BizSoftwareCopyrightDocRecordEntity update(BizSoftwareCopyrightDocRecordEntity entity) throws Exception; BizSoftwareCopyrightDocRecordEntity update(BizSoftwareCopyrightDocRecordEntity entity);
void deletedById(java.lang.Long id) throws Exception; void deletedById(java.lang.Long id) throws Exception;
......
package cn.com.poc.ai_software_copyright.service.impl; package cn.com.poc.ai_software_copyright.service.impl;
import cn.com.yict.framemax.core.exception.BusinessException; import cn.com.poc.common.constant.CommonConstant;
import cn.com.yict.framemax.core.service.impl.BaseServiceImpl; import cn.com.yict.framemax.core.service.impl.BaseServiceImpl;
import cn.com.poc.ai_software_copyright.service.BizSoftwareCopyrightDocRecordService; import cn.com.poc.ai_software_copyright.service.BizSoftwareCopyrightDocRecordService;
import cn.com.poc.ai_software_copyright.model.BizSoftwareCopyrightDocRecordModel; import cn.com.poc.ai_software_copyright.model.BizSoftwareCopyrightDocRecordModel;
...@@ -8,18 +8,11 @@ import cn.com.poc.ai_software_copyright.entity.BizSoftwareCopyrightDocRecordEnti ...@@ -8,18 +8,11 @@ import cn.com.poc.ai_software_copyright.entity.BizSoftwareCopyrightDocRecordEnti
import cn.com.poc.ai_software_copyright.convert.BizSoftwareCopyrightDocRecordConvert; import cn.com.poc.ai_software_copyright.convert.BizSoftwareCopyrightDocRecordConvert;
import cn.com.poc.ai_software_copyright.repository.BizSoftwareCopyrightDocRecordRepository; import cn.com.poc.ai_software_copyright.repository.BizSoftwareCopyrightDocRecordRepository;
import cn.com.yict.framemax.data.model.PagingInfo; import cn.com.yict.framemax.data.model.PagingInfo;
import cn.hutool.core.util.ZipUtil;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.List; import java.util.List;
import javax.annotation.Resource; import javax.annotation.Resource;
...@@ -45,9 +38,20 @@ public class BizSoftwareCopyrightDocRecordServiceImpl extends BaseServiceImpl ...@@ -45,9 +38,20 @@ public class BizSoftwareCopyrightDocRecordServiceImpl extends BaseServiceImpl
return BizSoftwareCopyrightDocRecordConvert.modelToEntity(model); return BizSoftwareCopyrightDocRecordConvert.modelToEntity(model);
} }
@Override
public BizSoftwareCopyrightDocRecordEntity getByRelationId(Long relationId) {
BizSoftwareCopyrightDocRecordModel model = new BizSoftwareCopyrightDocRecordModel();
model.setRelationId(relationId);
model.setIsDeleted(CommonConstant.IsDeleted.N);
List<BizSoftwareCopyrightDocRecordModel> models = this.repository.findByExample(model, null);
if (CollectionUtils.isNotEmpty(models)) {
return BizSoftwareCopyrightDocRecordConvert.modelToEntity(models.get(0));
}
return null;
}
public List<BizSoftwareCopyrightDocRecordEntity> findByExample(BizSoftwareCopyrightDocRecordEntity example, public List<BizSoftwareCopyrightDocRecordEntity> findByExample(BizSoftwareCopyrightDocRecordEntity example,
PagingInfo pagingInfo) throws Exception { PagingInfo pagingInfo) {
List<BizSoftwareCopyrightDocRecordEntity> result = new ArrayList<BizSoftwareCopyrightDocRecordEntity>(); List<BizSoftwareCopyrightDocRecordEntity> result = new ArrayList<BizSoftwareCopyrightDocRecordEntity>();
BizSoftwareCopyrightDocRecordModel model = new BizSoftwareCopyrightDocRecordModel(); BizSoftwareCopyrightDocRecordModel model = new BizSoftwareCopyrightDocRecordModel();
if (example != null) { if (example != null) {
...@@ -62,7 +66,7 @@ public class BizSoftwareCopyrightDocRecordServiceImpl extends BaseServiceImpl ...@@ -62,7 +66,7 @@ public class BizSoftwareCopyrightDocRecordServiceImpl extends BaseServiceImpl
return result; return result;
} }
public BizSoftwareCopyrightDocRecordEntity save(BizSoftwareCopyrightDocRecordEntity entity) throws Exception { public BizSoftwareCopyrightDocRecordEntity save(BizSoftwareCopyrightDocRecordEntity entity) {
Assert.notNull(entity); Assert.notNull(entity);
entity.setId(null); entity.setId(null);
entity.setIsDeleted("N"); entity.setIsDeleted("N");
...@@ -71,7 +75,7 @@ public class BizSoftwareCopyrightDocRecordServiceImpl extends BaseServiceImpl ...@@ -71,7 +75,7 @@ public class BizSoftwareCopyrightDocRecordServiceImpl extends BaseServiceImpl
return BizSoftwareCopyrightDocRecordConvert.modelToEntity(saveModel); return BizSoftwareCopyrightDocRecordConvert.modelToEntity(saveModel);
} }
public BizSoftwareCopyrightDocRecordEntity update(BizSoftwareCopyrightDocRecordEntity entity) throws Exception { public BizSoftwareCopyrightDocRecordEntity update(BizSoftwareCopyrightDocRecordEntity entity) {
Assert.notNull(entity); Assert.notNull(entity);
Assert.notNull(entity.getId(), "update pk can not be null"); Assert.notNull(entity.getId(), "update pk can not be null");
BizSoftwareCopyrightDocRecordModel model = this.repository.get(entity.getId()); BizSoftwareCopyrightDocRecordModel model = this.repository.get(entity.getId());
......
...@@ -13,6 +13,8 @@ public interface BizFileUploadRecordService extends BaseService { ...@@ -13,6 +13,8 @@ public interface BizFileUploadRecordService extends BaseService {
BizFileUploadRecordModel get(Long id) throws Exception; BizFileUploadRecordModel get(Long id) throws Exception;
BizFileUploadRecordModel getByMD5(String md5);
List<BizFileUploadRecordModel> findByExample(BizFileUploadRecordModel example,PagingInfo pagingInfo) throws Exception; List<BizFileUploadRecordModel> findByExample(BizFileUploadRecordModel example,PagingInfo pagingInfo) throws Exception;
List<BizFileUploadRecordModel> findByFileLink(List<String> fileLink) throws Exception; List<BizFileUploadRecordModel> findByFileLink(List<String> fileLink) throws Exception;
......
...@@ -45,7 +45,19 @@ public class BizFileUploadRecordServiceImpl extends BaseServiceImpl ...@@ -45,7 +45,19 @@ public class BizFileUploadRecordServiceImpl extends BaseServiceImpl
return this.repository.get(id); return this.repository.get(id);
} }
public List<BizFileUploadRecordModel> findByExample(BizFileUploadRecordModel example, PagingInfo pagingInfo) throws Exception { @Override
public BizFileUploadRecordModel getByMD5(String md5) {
BizFileUploadRecordModel bizFileUploadRecordModel = new BizFileUploadRecordModel();
bizFileUploadRecordModel.setMd5(md5);
List<BizFileUploadRecordModel> models = this.repository.findByExample(bizFileUploadRecordModel);
if (CollectionUtils.isEmpty(models)) {
return null;
}
return models.get(0);
}
public List<BizFileUploadRecordModel> findByExample(BizFileUploadRecordModel example, PagingInfo pagingInfo)
throws Exception {
if (example == null) { if (example == null) {
example = new BizFileUploadRecordModel(); example = new BizFileUploadRecordModel();
} }
...@@ -60,13 +72,14 @@ public class BizFileUploadRecordServiceImpl extends BaseServiceImpl ...@@ -60,13 +72,14 @@ public class BizFileUploadRecordServiceImpl extends BaseServiceImpl
FileUploadQueryCondition fileUploadQueryCondition = new FileUploadQueryCondition(); FileUploadQueryCondition fileUploadQueryCondition = new FileUploadQueryCondition();
fileUploadQueryCondition.setFileUrlList(fileLinks); fileUploadQueryCondition.setFileUrlList(fileLinks);
List<FileUploadQueryItem> fileUploadQueryItems = this.sqlDao.query(fileUploadQueryCondition, FileUploadQueryItem.class); List<FileUploadQueryItem> fileUploadQueryItems =
this.sqlDao.query(fileUploadQueryCondition, FileUploadQueryItem.class);
List<BizFileUploadRecordModel> bizFileUploadRecordModels = new ArrayList<>(); List<BizFileUploadRecordModel> bizFileUploadRecordModels = new ArrayList<>();
if(CollectionUtils.isNotEmpty(fileUploadQueryItems)){ if (CollectionUtils.isNotEmpty(fileUploadQueryItems)) {
for (FileUploadQueryItem fileUploadQueryItem : fileUploadQueryItems) { for (FileUploadQueryItem fileUploadQueryItem : fileUploadQueryItems) {
BizFileUploadRecordModel bizFileUploadRecordModel = new BizFileUploadRecordModel(); BizFileUploadRecordModel bizFileUploadRecordModel = new BizFileUploadRecordModel();
BeanUtils.copyProperties(fileUploadQueryItem,bizFileUploadRecordModel); BeanUtils.copyProperties(fileUploadQueryItem, bizFileUploadRecordModel);
bizFileUploadRecordModels.add(bizFileUploadRecordModel); bizFileUploadRecordModels.add(bizFileUploadRecordModel);
} }
} }
......
...@@ -82,7 +82,8 @@ public class DocumentLoad { ...@@ -82,7 +82,8 @@ public class DocumentLoad {
List<HSLFSlide> slides = hslfSlideShow.getSlides(); List<HSLFSlide> slides = hslfSlideShow.getSlides();
SlideShowExtractor slideShowExtractor = new SlideShowExtractor(hslfSlideShow); SlideShowExtractor slideShowExtractor = new SlideShowExtractor(hslfSlideShow);
for (HSLFSlide slide : slides) { for (HSLFSlide slide : slides) {
sb.append("Page:").append(slide.getSlideNumber()).append(StringUtils.LF).append(slideShowExtractor.getText(slide)).append(StringUtils.LF); sb.append("Page:").append(slide.getSlideNumber()).append(StringUtils.LF)
.append(slideShowExtractor.getText(slide)).append(StringUtils.LF);
} }
slideShowExtractor.close(); slideShowExtractor.close();
is.close(); is.close();
...@@ -106,7 +107,8 @@ public class DocumentLoad { ...@@ -106,7 +107,8 @@ public class DocumentLoad {
for (CTTextParagraph textParagraph : pList) { for (CTTextParagraph textParagraph : pList) {
List<CTRegularTextRun> textRuns = textParagraph.getRList(); List<CTRegularTextRun> textRuns = textParagraph.getRList();
for (CTRegularTextRun textRun : textRuns) { for (CTRegularTextRun textRun : textRuns) {
sb.append("Page:").append(slide.getSlideNumber()).append(StringUtils.LF).append(textRun.getT()).append(StringUtils.LF); sb.append("Page:").append(slide.getSlideNumber()).append(StringUtils.LF)
.append(textRun.getT()).append(StringUtils.LF);
} }
} }
} }
...@@ -192,6 +194,41 @@ public class DocumentLoad { ...@@ -192,6 +194,41 @@ public class DocumentLoad {
case "xls": case "xls":
case "csv": case "csv":
return excelToMarkdown(file); return excelToMarkdown(file);
// 添加对代码文件的支持
case "java":
case "py":
case "js":
case "ts":
case "cpp":
case "c":
case "h":
case "cs":
case "go":
case "rb":
case "php":
case "html":
case "css":
case "vue":
case "jsx":
case "tsx":
case "sql":
case "xml":
case "json":
case "yaml":
case "yml":
case "sh":
case "bash":
case "pl":
case "pm":
case "r":
case "scala":
case "kt":
case "kts":
case "swift":
case "dart":
case "rs":
case "lua":
return loadCodeFile(file, type);
default: default:
throw new BusinessException(type + " format is not yet supported"); throw new BusinessException(type + " format is not yet supported");
} }
...@@ -274,4 +311,51 @@ public class DocumentLoad { ...@@ -274,4 +311,51 @@ public class DocumentLoad {
throw new I18nMessageException("exception/file.load.error"); throw new I18nMessageException("exception/file.load.error");
} }
} }
/**
* 读取代码文件内容
*
* @param file 代码文件
* @param type 文件类型扩展名
* @return 代码文件内容
* @throws IOException
*/
public static String loadCodeFile(File file, String type) throws IOException {
// 验证文件类型
if (!isValidCodeFileType(type)) {
throw new BusinessException("Unsupported code file type: " + type);
}
// 使用 UTF-8 编码读取代码文件
StringBuilder content = new StringBuilder();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(
new FileInputStream(file), "UTF-8"))) {
String line;
while ((line = reader.readLine()) != null) {
content.append(line).append(StringUtils.LF);
}
}
return content.toString();
}
/**
* 验证是否为支持的代码文件类型
*
* @param type 文件扩展名
* @return 是否为支持的代码文件类型
*/
private static boolean isValidCodeFileType(String type) {
String[] supportedTypes = {
"java", "py", "js", "ts", "cpp", "c", "h", "cs", "go", "rb",
"php", "html", "css", "vue", "jsx", "tsx", "sql", "xml", "json",
"yaml", "yml", "sh", "bash", "pl", "pm", "r", "scala", "kt",
"kts", "swift", "dart", "rs", "lua"
};
for (String supportedType : supportedTypes) {
if (supportedType.equalsIgnoreCase(type)) {
return true;
}
}
return false;
}
} }
package cn.com.poc.common.utils; package cn.com.poc.common.utils;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest; import java.security.MessageDigest;
import cn.com.yict.framemax.core.exception.BusinessException;
import cn.hutool.crypto.digest.MD5;
import jdk.internal.util.xml.impl.Input;
public class MD5Util { public class MD5Util {
private static String byteArrayToHexString(byte b[]) { private static String byteArrayToHexString(byte b[]) {
...@@ -42,4 +48,15 @@ public class MD5Util { ...@@ -42,4 +48,15 @@ public class MD5Util {
private static final String hexDigits[] = {"0", "1", "2", "3", "4", "5", private static final String hexDigits[] = {"0", "1", "2", "3", "4", "5",
"6", "7", "8", "9", "a", "b", "c", "d", "e", "f"}; "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};
public static String fileToMD5(InputStream inputStream) {
try {
byte[] bytes = new byte[inputStream.available()];
inputStream.read(bytes);
String md5 = MD5.create().digestHex(bytes);
return md5;
} catch (IOException e) {
throw new BusinessException(e);
}
}
} }
...@@ -2,21 +2,34 @@ package cn.com.poc.message.service.impl; ...@@ -2,21 +2,34 @@ package cn.com.poc.message.service.impl;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import cn.com.poc.ai_software_copyright.agent.SoftwareCopyRightAgent; import cn.com.poc.ai_software_copyright.agent.SoftwareCopyRightAgent;
import cn.com.poc.ai_software_copyright.contant.AiSoftWareCopyRightEnum; import cn.com.poc.ai_software_copyright.contant.AiSoftWareCopyRightEnum;
import cn.com.poc.ai_software_copyright.contant.AiSoftWareCopyRightRedisKey;
import cn.com.poc.ai_software_copyright.domain.GeneratedDoc;
import cn.com.poc.ai_software_copyright.domian.BaseInfo;
import cn.com.poc.ai_software_copyright.domian.TechnicalContent;
import cn.com.poc.ai_software_copyright.entity.BizSoftwareCopyrightEntity; import cn.com.poc.ai_software_copyright.entity.BizSoftwareCopyrightEntity;
import cn.com.poc.ai_software_copyright.service.BizSoftwareCopyrightService; import cn.com.poc.ai_software_copyright.service.BizSoftwareCopyrightService;
import cn.com.poc.common.service.RedisService;
import cn.com.poc.common.utils.JsonUtils; import cn.com.poc.common.utils.JsonUtils;
import cn.com.poc.common.utils.StringUtils;
import cn.com.poc.message.entity.SoftwareCopyRightMessage; import cn.com.poc.message.entity.SoftwareCopyRightMessage;
import cn.com.poc.message.service.SoftwareCopyRightConsumerService; import cn.com.poc.message.service.SoftwareCopyRightConsumerService;
import cn.com.poc.message.service.SoftwareCopyRightProduceService; import cn.com.poc.message.service.SoftwareCopyRightProduceService;
import cn.com.poc.message.topic.SoftwareCopyRightTopic; import cn.com.poc.message.topic.SoftwareCopyRightTopic;
import cn.com.yict.framemax.core.exception.BusinessException;
import cn.com.yict.framemax.tumbleweed.client.annotation.Consumer; import cn.com.yict.framemax.tumbleweed.client.annotation.Consumer;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
/** /**
...@@ -26,6 +39,8 @@ import org.springframework.stereotype.Service; ...@@ -26,6 +39,8 @@ import org.springframework.stereotype.Service;
@Service @Service
public class SoftwareCopyRightConsumerServiceImpl implements SoftwareCopyRightConsumerService { public class SoftwareCopyRightConsumerServiceImpl implements SoftwareCopyRightConsumerService {
private Logger logger = LoggerFactory.getLogger(SoftwareCopyRightConsumerService.class);
@Resource @Resource
private BizSoftwareCopyrightService bizSoftwareCopyrightService; private BizSoftwareCopyrightService bizSoftwareCopyrightService;
...@@ -35,6 +50,9 @@ public class SoftwareCopyRightConsumerServiceImpl implements SoftwareCopyRightCo ...@@ -35,6 +50,9 @@ public class SoftwareCopyRightConsumerServiceImpl implements SoftwareCopyRightCo
@Resource @Resource
private SoftwareCopyRightAgent agent; private SoftwareCopyRightAgent agent;
@Resource
private RedisService redisService;
/** /**
* 提交生成文档任务 * 提交生成文档任务
* *
...@@ -44,32 +62,39 @@ public class SoftwareCopyRightConsumerServiceImpl implements SoftwareCopyRightCo ...@@ -44,32 +62,39 @@ public class SoftwareCopyRightConsumerServiceImpl implements SoftwareCopyRightCo
@Override @Override
@Consumer(topic = SoftwareCopyRightTopic.SUBMIT_SOFTWARE_COPYRIGHT_TASK, scale = 2) @Consumer(topic = SoftwareCopyRightTopic.SUBMIT_SOFTWARE_COPYRIGHT_TASK, scale = 2)
public void submitTask(SoftwareCopyRightMessage message) { public void submitTask(SoftwareCopyRightMessage message) {
logger.info("submit task:{}", JsonUtils.serialize(message));
message.setStatus(AiSoftWareCopyRightEnum.GENERATED_STATUS.Running); message.setStatus(AiSoftWareCopyRightEnum.GENERATED_STATUS.Running);
produceService.updateStatus(message); produceService.updateStatus(message);
//todo 实现提交生成文档任务
String generatedDocType = message.getGeneratedDocType(); String generatedDocType = message.getGeneratedDocType();
List<String> docTypes = JsonUtils.deSerialize(generatedDocType, new TypeReference<List<String>>() { List<String> docTypes = JsonUtils.deSerialize(generatedDocType, new TypeReference<List<String>>() {
}.getType()); }.getType());
List<String> fileURLS = new ArrayList<>();
// 创建一个CompletableFuture数组来存储所有任务 if (StringUtils.isNotBlank(message.getReferenceDocumentFileUrl())) {
List<CompletableFuture<Object>> futures = docTypes.stream() fileURLS = JsonUtils.deSerialize(message.getReferenceDocumentFileUrl(), new TypeReference<List<String>>() {
.map(docType -> }.getType());
CompletableFuture.supplyAsync(() -> }
agent.generatedDocByType(message, AiSoftWareCopyRightEnum.DOC_TYPE.valueOf(docType))) String ui = redisService.get(AiSoftWareCopyRightRedisKey.CALL_BACK + message.getId() + ":ui").toString();
) String demand =
.collect(Collectors.toList()); redisService.get(AiSoftWareCopyRightRedisKey.CALL_BACK + message.getId() + ":demand").toString();
String structure =
// 等待所有任务完成 redisService.get(AiSoftWareCopyRightRedisKey.CALL_BACK + message.getId() + ":structure").toString();
CompletableFuture<Void> allFutures = CompletableFuture.allOf( JSONObject jsonObject = JSONObject.parseObject(structure);
futures.toArray(new CompletableFuture[0]) JSONObject result = jsonObject.getJSONObject("result");
); structure = result.toJSONString();
allFutures.thenRun(() -> { GeneratedDoc generatedDoc = new GeneratedDoc();
//todo 处理完成逻辑 generatedDoc.setId(message.getId());
generatedDoc.setFileURLs(fileURLS);
}).exceptionally(throwable -> { generatedDoc.setUi(ui);
generatedDoc.setDemand(demand);
return null; generatedDoc.setStructure(structure);
}); generatedDoc.setBaseinfo(StringUtils.isNotBlank(message.getBaseInfo()) ?
JsonUtils.deSerialize(message.getBaseInfo(), BaseInfo.class) : null);
generatedDoc.setTechnical_content(StringUtils.isNotBlank(message.getTechnicalContent()) ?
JsonUtils.deSerialize(message.getTechnicalContent(), TechnicalContent.class) : null);
for (String docType : docTypes) {
agent.generatedDocByType(generatedDoc, AiSoftWareCopyRightEnum.DOC_TYPE.valueOf(docType));
}
} }
@Override @Override
......
...@@ -29,3 +29,5 @@ pay.domain.callback.url=https://poc-sit.gsstcloud.com/api/rest/payCallBackRest/p ...@@ -29,3 +29,5 @@ pay.domain.callback.url=https://poc-sit.gsstcloud.com/api/rest/payCallBackRest/p
google.client.id=867985016759-n9qj00k174n9bibrtrqngvt89vbmnjrp.apps.googleusercontent.com google.client.id=867985016759-n9qj00k174n9bibrtrqngvt89vbmnjrp.apps.googleusercontent.com
google.custom.search.key=AIzaSyCV8PTQ10rG5wo4E004dR3mcGD1RM_PrBw google.custom.search.key=AIzaSyCV8PTQ10rG5wo4E004dR3mcGD1RM_PrBw
google.custom.search.cx=049026ecb26e840ed google.custom.search.cx=049026ecb26e840ed
dify.software_copyright.callball.url=https://super-modellink-sit.gsstcloud.com/api/rest/bizSoftwareCopyrightRest/callbackGeneratedBaseDoc.json
\ No newline at end of file
...@@ -29,3 +29,5 @@ pay.domain.callback.url=https://model-link.gsstcloud.com/api/rest/payCallBackRes ...@@ -29,3 +29,5 @@ pay.domain.callback.url=https://model-link.gsstcloud.com/api/rest/payCallBackRes
google.client.id=867985016759-n9qj00k174n9bibrtrqngvt89vbmnjrp.apps.googleusercontent.com google.client.id=867985016759-n9qj00k174n9bibrtrqngvt89vbmnjrp.apps.googleusercontent.com
google.custom.search.key=AIzaSyCV8PTQ10rG5wo4E004dR3mcGD1RM_PrBw google.custom.search.key=AIzaSyCV8PTQ10rG5wo4E004dR3mcGD1RM_PrBw
google.custom.search.cx=049026ecb26e840ed google.custom.search.cx=049026ecb26e840ed
dify.software_copyright.callball.url=https://super-modellink.gsstcloud.com/api/rest/bizSoftwareCopyrightRest/callbackGeneratedBaseDoc.json
\ No newline at end of file
...@@ -29,3 +29,5 @@ pay.domain.callback.url=https://poc-sit.gsstcloud.com/api/rest/payCallBackRest/p ...@@ -29,3 +29,5 @@ pay.domain.callback.url=https://poc-sit.gsstcloud.com/api/rest/payCallBackRest/p
google.client.id=867985016759-n9qj00k174n9bibrtrqngvt89vbmnjrp.apps.googleusercontent.com google.client.id=867985016759-n9qj00k174n9bibrtrqngvt89vbmnjrp.apps.googleusercontent.com
google.custom.search.key=AIzaSyCV8PTQ10rG5wo4E004dR3mcGD1RM_PrBw google.custom.search.key=AIzaSyCV8PTQ10rG5wo4E004dR3mcGD1RM_PrBw
google.custom.search.cx=049026ecb26e840ed google.custom.search.cx=049026ecb26e840ed
dify.software_copyright.callball.url=https://super-modellink-sit.gsstcloud.com/api/rest/bizSoftwareCopyrightRest/callbackGeneratedBaseDoc.json
\ No newline at end of file
...@@ -29,3 +29,6 @@ pay.domain.callback.url=https://model-link.gsstcloud.com/api/rest/payCallBackRes ...@@ -29,3 +29,6 @@ pay.domain.callback.url=https://model-link.gsstcloud.com/api/rest/payCallBackRes
google.client.id=867985016759-n9qj00k174n9bibrtrqngvt89vbmnjrp.apps.googleusercontent.com google.client.id=867985016759-n9qj00k174n9bibrtrqngvt89vbmnjrp.apps.googleusercontent.com
google.custom.search.key=AIzaSyCV8PTQ10rG5wo4E004dR3mcGD1RM_PrBw google.custom.search.key=AIzaSyCV8PTQ10rG5wo4E004dR3mcGD1RM_PrBw
google.custom.search.cx=049026ecb26e840ed google.custom.search.cx=049026ecb26e840ed
dify.software_copyright.callball.url=https://super-modellink.gsstcloud.com/api/rest/bizSoftwareCopyrightRest/callbackGeneratedBaseDoc.json
\ No newline at end of file
...@@ -72,3 +72,6 @@ framemax-frame.job.disable=false ...@@ -72,3 +72,6 @@ framemax-frame.job.disable=false
#pay #pay
pay.config.acctId=16653311814572 pay.config.acctId=16653311814572
pay.config.wxAppId=wxea3470b5d2d97eca pay.config.wxAppId=wxea3470b5d2d97eca
#dify
dify.base.url=https://dify.gsstcloud.com/v1
package cn.com.poc.softwareCopyRight;
import javax.annotation.Resource;
import java.io.IOException;
import java.util.Collections;
import java.util.Set;
import cn.com.gsst.dify_client.exception.DifyApiException;
import cn.com.poc.ai_software_copyright.agent.SoftwareCopyRightAgent;
import cn.com.poc.ai_software_copyright.contant.AiSoftWareCopyRightRedisKey;
import cn.com.poc.ai_software_copyright.convert.BizSoftwareCopyrightConvert;
import cn.com.poc.ai_software_copyright.dto.SoftwareCopyRightDto;
import cn.com.poc.ai_software_copyright.entity.BizSoftwareCopyrightEntity;
import cn.com.poc.ai_software_copyright.service.BizSoftwareCopyrightService;
import cn.com.poc.common.service.RedisService;
import cn.com.yict.framemax.core.spring.SingleContextInitializer;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
/**
* @author alex.yao
* @date 2026/1/5
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(initializers = SingleContextInitializer.class)
@WebAppConfiguration
public class AgentTest {
@Resource
private RedisService redisService;
@Resource
private BizSoftwareCopyrightService bizSoftwareCopyrightService;
@Resource
private SoftwareCopyRightAgent softwareCopyRightAgent;
@Test
public void test_agent() throws DifyApiException, IOException, InterruptedException {
BizSoftwareCopyrightEntity bizSoftwareCopyrightEntity = bizSoftwareCopyrightService.get(6L);
SoftwareCopyRightDto softwareCopyRightDto = BizSoftwareCopyrightConvert.entityToDto(bizSoftwareCopyrightEntity);
softwareCopyRightAgent.generatedBaseDoc("SOFT_WARE_COPY_RIGHT_CALL_BACK:6", Collections.emptyList(),
softwareCopyRightDto.getBaseInfo(),
softwareCopyRightDto.getTechnicalContent());
}
@Test
public void test() {
String string = redisService.get(AiSoftWareCopyRightRedisKey.CALL_BACK + "6:structure").toString();
JSONObject jsonObject = JSONObject.parseObject(string);
JSONObject result = jsonObject.getJSONObject("result");
System.out.println(result.toJSONString());
}
}
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