You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
fu-hsi-service/src/main/java/com/supervision/police/service/impl/ExtractTripleInfoServiceImp...

101 lines
4.2 KiB
Java

10 months ago
package com.supervision.police.service.impl;
import cn.hutool.core.util.StrUtil;
import com.alibaba.druid.util.StringUtils;
import com.supervision.police.domain.NotePrompt;
import com.supervision.police.domain.NoteRecordSplit;
import com.supervision.police.domain.TripleInfo;
import com.supervision.police.mapper.NotePromptMapper;
import com.supervision.police.mapper.NoteRecordSplitMapper;
import com.supervision.police.mapper.TripleInfoMapper;
import com.supervision.police.service.*;
import com.supervision.thread.TripleExtractThread;
import com.supervision.thread.TripleExtractThreadPool;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.ai.chat.ChatResponse;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.ollama.OllamaChatClient;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.StopWatch;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.Future;
@Slf4j
@Service
@RequiredArgsConstructor
public class ExtractTripleInfoServiceImpl implements ExtractTripleInfoService {
private final NoteRecordSplitMapper noteRecordSplitMapper;
private final NotePromptService notePromptService;
private final TripleInfoService tripleInfoService;
private final OllamaChatClient chatClient;
@Async
public void extractTripleInfo(String caseId, String name, String recordId) {
// 首先获取所有切分后的笔录
List<NoteRecordSplit> recordSplitList = noteRecordSplitMapper.selectRecord(caseId, name, recordId);
List<TripleInfo> tripleInfos = new ArrayList<>();
List<Future<TripleInfo>> futures = new ArrayList<>();
// 对切分后的笔录进行遍历
for (NoteRecordSplit recordSplit : recordSplitList) {
// 根据笔录类型找到所有的提取三元组的提示词
List<NotePrompt> prompts = notePromptService.lambdaQuery().eq(NotePrompt::getTypeId, recordSplit.getRecordTypeId()).list();
// 遍历提示词进行提取
for (NotePrompt prompt : prompts) {
if (StringUtils.isEmpty(prompt.getPrompt())) {
continue;
}
try {
log.info("提交任务到线程池中进行三元组提取");
Future<TripleInfo> submit = TripleExtractThreadPool.chatExecutor.submit(new TripleExtractThread(chatClient, caseId, recordId, recordSplit.getId(), prompt.getPrompt(), recordSplit.getQuestion(), recordSplit.getAnswer()));
futures.add(submit);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
}
while (futures.size() > 0) {
Iterator<Future<TripleInfo>> iterator = futures.iterator();
while (iterator.hasNext()) {
Future<TripleInfo> future = iterator.next();
try {
// 如果提取到结果,且不为空,就进行保存
if (future.isDone()) {
TripleInfo tripleInfo = future.get();
if (tripleInfo != null) {
tripleInfos.add(tripleInfo);
}
iterator.remove();
}
} catch (Exception e) {
log.info("从线程中获取任务失败");
iterator.remove();
}
}
try {
log.info("检查一遍,休眠1s后继续检查");
Thread.sleep(1000);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
// 首先清除
tripleInfoService.lambdaUpdate().eq(TripleInfo::getRecordId, recordId).remove();
// 首先要把这个笔录已经提取过的三元组记录删除掉,删除掉之后才可以重新提取
tripleInfoService.saveBatch(tripleInfos);
}
}