Compare commits

...

13 Commits

Author SHA1 Message Date
xueqingkun 923063dcf2 1. 优化代码 4 months ago
xueqingkun 53efc04e71 1. 优化代码 4 months ago
xueqingkun a8c9e84cbd 1. 修复新增案件知识图谱保存不进去问题 4 months ago
xueqingkun b759955f5b 1. 修复新增案件创建知识库报错问题 4 months ago
xueqingkun c19fc37e35 1. 添加removeCaseDataSet 4 months ago
yaxin 37ed83a12a 任务、案件任务状态管理,code format 4 months ago
xueqingkun a5611ec313 1. 添加单个提示词分析笔录功能 4 months ago
xueqingkun 55076f376b 1. 添加单个提示词分析笔录功能 4 months ago
yaxin 90b4e1f792 方法提取
异常处理
4 months ago
longbao 0e7c6e6b4d [事务管理器]
primary mysql dataSourceTransactionManager
4 months ago
longbao 95b5736221 [长文本方案] 4 months ago
longbao 00f85c8dc9 代码生成器 4 months ago
longbao 51dc2cb9d7 本地测试 4 months ago

@ -65,6 +65,24 @@
<version>3.5.5</version> <version>3.5.5</version>
</dependency> </dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.9</version>
</dependency>
<!-- 添加模板引擎thymeleaf 还有freemarker都是模板引擎 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<!--mybatis-plus 代码生成器的模板引擎-->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.3</version>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
@ -231,6 +249,13 @@
</excludes> </excludes>
</configuration> </configuration>
</plugin> </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<testFailureIgnore>true</testFailureIgnore>
</configuration>
</plugin>
</plugins> </plugins>
</build> </build>
<repositories> <repositories>

@ -2,6 +2,7 @@ package com.supervision.config;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.transaction.annotation.EnableTransactionManagement;
@ -19,6 +20,7 @@ public class TransactionManagerConfig {
* @param dataSource * @param dataSource
* @return * @return
*/ */
@Primary
@Bean("dataSourceTransactionManager") @Bean("dataSourceTransactionManager")
public DataSourceTransactionManager transactionManager(DataSource dataSource) { public DataSourceTransactionManager transactionManager(DataSource dataSource) {
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(); DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();

@ -0,0 +1,96 @@
package com.supervision.constant;
import lombok.Getter;
/**
* @Authorlongbao
* @Date2024/12/10 13:37
* @Description:
*/
@Getter
public enum PromptsEnum {
LONG_TEXT_SINGLE_SENTENCE_SUMMARY("长文本单句总结提示词", """
: 2
:
: (1)
---
:
1 2
:{"result": {"id": "1","llmGenA":"冒充"},{"id": "2","llmGenA":"欺诈"}}
---
:
1.
2. 2
3.
4.
5. idllmGenA
6.
7.
---
:
{noteRecordSplitList}
---
json,:{"result": [{"id": "","llmGenA":""}]}
"""),
LONG_TEXT_SINGLE_STATEMENT_WITH_SEMANTIC_JUDGMENT_PROMPT_WORD("长文本单语句同语义判断提示词", """
:
:
:
---
:
{"result":false}
---
1.
3.
4.
5. truefalse
6. 2
---
:
{encCombinedSentence}
{currentSentence}
---
json:
{"result":xxxx}
"""),
LONG_TEXT_TRIPLE_INFO("长文本三元组信息提取", """
:
1.
2.
3.
4.
5. 使
6.
{requirement}
"{headEntityType}";"{tailEntityType}","{relation}"
json:{"result":[]}
---
:
{"result":[{"headEntity": {"type": "{headEntityType}","name":"小明"},"relation": "{relation}","tailEntity": {"type": "{tailEntityType}","name": "光缆承揽合同"}}]}
---
{contentChuckSummary}
---
json:
{"result":[{"headEntity": {"type": "{headEntityType}","name":"提取到的头实体内容1"},"relation": "{relation}","tailEntity": {"type": "{tailEntityType}","name": "提取到的尾实体内容1"}}]}
""");
private String description;
private String content;
PromptsEnum(String description, String content) {
this.description = description;
this.content = content;
}
}

@ -0,0 +1,27 @@
package com.supervision.handler;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.util.List;
public class StringListTypeHandler extends JacksonTypeHandler {
private static final ObjectMapper objectMapper = new ObjectMapper();
public StringListTypeHandler(Class<Object> type) {
super(type);
}
@Override
protected Object parse(String json) {
try {
return objectMapper.readValue(json, new TypeReference<List<String>>() {});
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}

@ -1,18 +1,20 @@
package com.supervision.job; package com.supervision.job;
import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.supervision.neo4j.service.Neo4jService; import com.supervision.common.constant.XxlJobConstants;
import com.supervision.police.domain.NotePrompt; import com.supervision.police.domain.NotePrompt;
import com.supervision.police.domain.TaskCaseRecord; import com.supervision.police.domain.TaskCaseRecord;
import com.supervision.police.domain.TaskRecord; import com.supervision.police.domain.TaskRecord;
import com.supervision.police.domain.TripleInfo; import com.supervision.police.service.CaseEvidenceService;
import com.supervision.police.service.*; import com.supervision.police.service.NotePromptService;
import com.supervision.police.service.TaskCaseRecordService;
import com.supervision.police.service.TaskRecordService;
import com.xxl.job.core.context.XxlJobHelper; import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob; import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -28,22 +30,15 @@ public class XxlJobTask {
private final CaseEvidenceService caseEvidenceService; private final CaseEvidenceService caseEvidenceService;
private final TaskRecordService taskRecordService; private final TaskRecordService taskRecordService;
private TaskCaseRecordService taskCaseRecordService;
private final ModelCaseService modelCaseService; private final TaskCaseRecordService taskCaseRecordService;
private final NotePromptService notePromptService; private final NotePromptService notePromptService;
private final ExtractTripleInfoService extractTripleInfoService;
private final Neo4jService neo4jService;
private final TripleInfoService tripleInfoService;
/** /**
* *
*/ */
@XxlJob("evidenceAnalysis") @XxlJob(XxlJobConstants.TASK_NAME_EVIDENCE_ANALYSIS)
public void evidenceAnalysis() { public void evidenceAnalysis() {
String param = XxlJobHelper.getJobParam(); String param = XxlJobHelper.getJobParam();
log.info("【证据解析】任务开始。ID: 【{}】", param); log.info("【证据解析】任务开始。ID: 【{}】", param);
@ -59,15 +54,16 @@ public class XxlJobTask {
/** /**
* *
*/ */
@XxlJob("promptExtractTask") @XxlJob(XxlJobConstants.TASK_NAME_PROMPT_EXTRACT_TASK)
public void promptExtractTask() { public void promptExtractTask() {
String jobParam = XxlJobHelper.getJobParam(); String jobParam = XxlJobHelper.getJobParam();
log.info("【提取任务】任务开始。参数: {}", jobParam); log.info("【提取任务】任务开始。参数: {}", jobParam);
try {
Map<String, String> map = JSON.parseObject(XxlJobHelper.getJobParam(), Map.class); Map<String, String> map = JSON.parseObject(XxlJobHelper.getJobParam(), Map.class);
try {
String taskId = map.get("taskId"); String taskId = map.get("taskId");
String caseId = map.get("caseId"); String caseId = map.get("caseId");
String promptId = map.get("promptId"); String promptId = map.get("promptId");
String executeId = map.get("executeId");
NotePrompt prompt = notePromptService.getById(promptId); NotePrompt prompt = notePromptService.getById(promptId);
boolean executable = true; boolean executable = true;
TaskRecord taskRecord = taskRecordService.getById(taskId); TaskRecord taskRecord = taskRecordService.getById(taskId);
@ -85,6 +81,11 @@ public class XxlJobTask {
break; break;
case TASK_STATUS_CANCELED: case TASK_STATUS_CANCELED:
log.info("任务状态为已取消任务不可执行任务ID: 【{}】", taskId); log.info("任务状态为已取消任务不可执行任务ID: 【{}】", taskId);
taskCaseRecordService.updateStatus(taskId, List.of(TASK_STATUS_WAITING, TASK_STATUS_PROCESSING), TASK_STATUS_CANCELED);
executable = false;
break;
case TASK_STATUS_FAIL:
log.info("任务状态为失败任务不可执行任务ID: 【{}】", taskId);
executable = false; executable = false;
break; break;
default: default:
@ -99,30 +100,23 @@ public class XxlJobTask {
} }
switch (prompt.getType()) { switch (prompt.getType()) {
case TYPE_GRAPH_REASONING: case TYPE_GRAPH_REASONING:
List<TripleInfo> tripleInfos = extractTripleInfoService.extractTripleInfo(prompt, caseId, map.get("executeId"));
for (TripleInfo tripleInfo : tripleInfos) {
neo4jService.saveTripleInfo(tripleInfo);
}
if (CollUtil.isNotEmpty(tripleInfos)){
tripleInfoService.updateNeo4jFlag(tripleInfos.stream().map(TripleInfo::getId).toList(), "1");
}
log.info("【图推理】任务开始。任务ID: 【{}】", taskId); log.info("【图推理】任务开始。任务ID: 【{}】", taskId);
// TODO: 笔录处理 taskRecordService.graphExtract(prompt, caseId, executeId);
break; break;
case TYPE_STRUCTURAL_REASONING: case TYPE_STRUCTURAL_REASONING:
log.info("【结构推理】任务开始。任务ID: 【{}】", taskId); log.info("【结构推理】任务开始。任务ID: 【{}】", taskId);
// TODO: 证据处理 taskRecordService.structureExtract(executeId);
break; break;
default: default:
log.error("未知的任务类型"); log.error("未知的任务类型");
break; break;
} }
//TODO:更新案件状态、任务状态 taskRecordService.completeTask(taskId, map.get("executeId"), true);
log.info("【提取任务】任务结束。任务ID: 【{}】", taskId); log.info("【提取任务】任务结束。任务ID: 【{}】", taskId);
} }
} catch (Exception e) { } catch (Exception e) {
log.error("任务执行失败", e); log.error("任务执行失败", e);
taskRecordService.completeTask(map.get("taskId"), map.get("executeId"), false);
} finally { } finally {
log.info("【提取任务】任务结束。"); log.info("【提取任务】任务结束。");
} }

@ -0,0 +1,32 @@
package com.supervision.police.controller;
import com.supervision.common.domain.R;
import com.supervision.police.service.LongTextService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @Authorlongbao
* @Date2024/12/10 10:20
* @Description: QA
*/
@Slf4j
@RestController
@RequestMapping("/answerLongText")
public class LongTextController {
@Autowired
private LongTextService longTextService;
@Operation(summary = "笔录长文本三元组提取")
@GetMapping("/tripletExtraction")
public R<Object> answerLongTextTripletExtraction(String noteRecordId) {
return longTextService.qaAnswerLongTextTripletExtractionByNoteRecordId(noteRecordId);
}
}

@ -0,0 +1,18 @@
package com.supervision.police.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* <p>
*
* </p>
*
* @author longbao
* @since 2024-12-11
*/
@RestController
@RequestMapping("/police/model-piece-record-type")
public class ModelPieceRecordTypeController {
}

@ -0,0 +1,18 @@
package com.supervision.police.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* <p>
*
* </p>
*
* @author longbao
* @since 2024-12-12
*/
@RestController
@RequestMapping("/police/note-piece-prompt")
public class NotePiecePromptController {
}

@ -0,0 +1,18 @@
package com.supervision.police.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* <p>
*
* </p>
*
* @author longbao
* @since 2024-12-12
*/
@RestController
@RequestMapping("/police/note-piece-prompt-type-rel")
public class NotePiecePromptTypeRelController {
}

@ -0,0 +1,18 @@
package com.supervision.police.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* <p>
*
* </p>
*
* @author longbao
* @since 2024-12-11
*/
@RestController
@RequestMapping("/police/note-record-split-piece-sentence")
public class NoteRecordSplitPieceSentenceController {
}

@ -0,0 +1,18 @@
package com.supervision.police.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* <p>
*
* </p>
*
* @author longbao
* @since 2024-12-10
*/
@RestController
@RequestMapping("/police/note-record-split-sentence")
public class NoteRecordSplitSentenceController {
}

@ -0,0 +1,18 @@
package com.supervision.police.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* <p>
*
* </p>
*
* @author longbao
* @since 2024-12-12
*/
@RestController
@RequestMapping("/police/piece-triple-info")
public class PieceTripleInfoController {
}

@ -0,0 +1,56 @@
package com.supervision.police.domain;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.time.LocalDateTime;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
/**
* <p>
*
* </p>
*
* @author longbao
* @since 2024-12-11
*/
@Getter
@Setter
@Accessors(chain = true)
@TableName("model_piece_record_type")
@ApiModel(value = "ModelPieceRecordType对象", description = "笔录同语义类型表")
public class ModelPieceRecordType implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("主键")
@TableId(value = "id")
private String id;
@ApiModelProperty("笔录语句段类型(总结)")
@TableField("record_type")
private String recordType;
@ApiModelProperty("创建人ID")
@TableField("create_user_id")
private String createUserId;
@ApiModelProperty("创建时间")
@TableField(value = "create_time", fill = FieldFill.INSERT)
private LocalDateTime createTime;
@ApiModelProperty("更新人")
@TableField("update_user_id")
private String updateUserId;
@ApiModelProperty("更新时间")
@TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
}

@ -0,0 +1,85 @@
package com.supervision.police.domain;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Date;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
/**
* <p>
*
* </p>
*
* @author longbao
* @since 2024-12-12
*/
@Getter
@Setter
@Accessors(chain = true)
@TableName("note_piece_prompt")
@ApiModel(value = "NotePiecePrompt对象", description = "长文本提示词表")
public class NotePiecePrompt implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("主键id")
@TableId(value = "id")
private String id;
@ApiModelProperty("提示词")
@TableField("prompt")
private String prompt;
@ApiModelProperty("开始节点类型")
@TableField("start_entity_type")
private String startEntityType;
@ApiModelProperty("开始节点占位符")
@TableField("start_entity_template")
private String startEntityTemplate;
@ApiModelProperty("关系类型")
@TableField("rel_type")
private String relType;
@ApiModelProperty("名称")
@TableField("name")
private String name;
@ApiModelProperty("关系占位符")
@TableField("rel_template")
private String relTemplate;
@ApiModelProperty("结束节点类型")
@TableField("end_entity_type")
private String endEntityType;
@ApiModelProperty("结束节点占位符")
@TableField("end_entity_template")
private String endEntityTemplate;
@ApiModelProperty("创建人ID")
@TableField("create_user_id")
private String createUserId;
@ApiModelProperty("创建时间")
@TableField(value = "create_time", fill = FieldFill.INSERT)
private LocalDateTime createTime;
@ApiModelProperty("更新人")
@TableField("update_user_id")
private String updateUserId;
@ApiModelProperty("更新时间")
@TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
}

@ -0,0 +1,42 @@
package com.supervision.police.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
/**
* <p>
*
* </p>
*
* @author longbao
* @since 2024-12-12
*/
@Getter
@Setter
@Accessors(chain = true)
@TableName("note_piece_prompt_type_rel")
@ApiModel(value = "NotePiecePromptTypeRel对象", description = "句子三元组提示词和分类关系表")
public class NotePiecePromptTypeRel implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("主键id")
@TableId(value = "id")
private String id;
@ApiModelProperty("note_piece_prompt表ID")
@TableField("prompt_id")
private String promptId;
@ApiModelProperty("id(model_piece_record_type)")
@TableField("type_id")
private String typeId;
}

@ -0,0 +1,77 @@
package com.supervision.police.domain;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import com.supervision.handler.StringListTypeHandler;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
/**
* <p>
*
* </p>
*
* @author longbao
* @since 2024-12-11
*/
@Getter
@Setter
@Accessors(chain = true)
@TableName("note_record_split_piece_sentence")
@ApiModel(value = "NoteRecordSplitPieceSentence对象", description = "笔录相同语义片段表")
public class NoteRecordSplitPieceSentence implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("主键id")
@TableId(value = "id")
private String id;
@ApiModelProperty("笔录片段表id")
@TableField("record_split_id")
private String recordSplitId;
// @ApiModelProperty("同语义片段")
// @TableField(value = "content_chuck", typeHandler = StringListTypeHandler.class)
// private List<String> contentChuck;
@ApiModelProperty("同语义片段")
@TableField(value = "content_chuck")
private String contentChuck;
@ApiModelProperty("片段内容总结")
@TableField("content_chuck_summary")
private String contentChuckSummary;
@ApiModelProperty("备用字段")
@TableField("extend")
private String extend;
@ApiModelProperty("创建人ID")
@TableField("create_user_id")
private String createUserId;
@ApiModelProperty("创建时间")
@TableField(value = "create_time", fill = FieldFill.INSERT)
private LocalDateTime createTime;
@ApiModelProperty("更新人")
@TableField("update_user_id")
private String updateUserId;
@ApiModelProperty("更新时间")
@TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
}

@ -0,0 +1,73 @@
package com.supervision.police.domain;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Date;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
/**
* <p>
*
* </p>
*
* @author longbao
* @since 2024-12-10
*/
@Getter
@Setter
@Accessors(chain = true)
@TableName("note_record_split_sentence")
@ApiModel(value = "NoteRecordSplitSentence对象", description = "长文本单句表")
public class NoteRecordSplitSentence implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("主键id")
@TableId(value = "id", type = IdType.AUTO)
private Long id;
@ApiModelProperty("笔录片段表id")
@TableField("record_split_id")
private String recordSplitId;
@ApiModelProperty("笔录相同语义片段表id")
@TableField("piece_record_split_id")
private String pieceRecordSplitId;
@ApiModelProperty("回答")
@TableField("answer")
private String answer;
@ApiModelProperty("句子模型总结内容")
@TableField("llm_gen_a")
private String llmGenA;
@ApiModelProperty("备用字段")
@TableField("extend_one")
private String extendOne;
@ApiModelProperty("创建人ID")
@TableField("create_user_id")
private String createUserId;
@ApiModelProperty("创建时间")
@TableField(value = "create_time", fill = FieldFill.INSERT)
private LocalDateTime createTime;
@ApiModelProperty("更新人")
@TableField("update_user_id")
private String updateUserId;
@ApiModelProperty("更新时间")
@TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
}

@ -0,0 +1,102 @@
package com.supervision.police.domain;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Date;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
/**
* <p>
*
* </p>
*
* @author longbao
* @since 2024-12-12
*/
@Getter
@Setter
@Accessors(chain = true)
@TableName("piece_triple_info")
@ApiModel(value = "PieceTripleInfo对象", description = "长文本三元组信息表")
public class PieceTripleInfo implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("主键id")
@TableId(value = "id")
private String id;
@ApiModelProperty("开始节点")
@TableField("start_node")
private String startNode;
@ApiModelProperty("结束节点")
@TableField("end_node")
private String endNode;
@ApiModelProperty("关系")
@TableField("relation")
private String relation;
@ApiModelProperty("笔录片段id")
@TableField("record_split_id")
private String recordSplitId;
@ApiModelProperty("同语义片段id")
@TableField("piece_record_split_id")
private String pieceRecordSplitId;
@ApiModelProperty("实际提交给大模型的提示词")
@TableField("submit_prompt")
private String submitPrompt;
@ApiModelProperty("是否生成图谱")
@TableField("add_neo4j")
private String addNeo4j;
@ApiModelProperty("创建时间")
@TableField(value = "create_time", fill = FieldFill.INSERT)
private LocalDateTime createTime;
@ApiModelProperty("起始节点图ID")
@TableField("start_node_graph_id")
private Long startNodeGraphId;
@ApiModelProperty("关系ID(neo4j关系id)")
@TableField("rel_graph_id")
private Long relGraphId;
@ApiModelProperty("结束节点图ID")
@TableField("end_node_graph_id")
private Long endNodeGraphId;
@ApiModelProperty("开始节点类型(neo4j节点类型)")
@TableField("start_node_type")
private String startNodeType;
@ApiModelProperty("结束节点类型(neo4j节点类型)")
@TableField("end_node_type")
private String endNodeType;
@ApiModelProperty("创建人ID")
@TableField("create_user_id")
private String createUserId;
@ApiModelProperty("更新人")
@TableField("update_user_id")
private String updateUserId;
@ApiModelProperty("更新时间")
@TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
}

@ -1,5 +1,6 @@
package com.supervision.police.domain; package com.supervision.police.domain;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
@ -7,7 +8,7 @@ import lombok.Data;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import java.util.Date; import java.time.LocalDateTime;
/** /**
* @TableName task_case_record * @TableName task_case_record
@ -59,7 +60,8 @@ public class TaskCaseRecord implements Serializable {
/** /**
* *
*/ */
private Date createTime; @TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
/** /**
* ID * ID
@ -69,7 +71,8 @@ public class TaskCaseRecord implements Serializable {
/** /**
* *
*/ */
private Date updateTime; @TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
@Serial @Serial
@TableField(exist = false) @TableField(exist = false)

@ -1,11 +1,13 @@
package com.supervision.police.domain; package com.supervision.police.domain;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data; import lombok.Data;
import java.io.Serializable; import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Date; import java.util.Date;
/** /**
@ -69,7 +71,8 @@ public class TaskRecord implements Serializable {
/** /**
* *
*/ */
private Date createTime; @TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
/** /**
* ID * ID
@ -79,7 +82,8 @@ public class TaskRecord implements Serializable {
/** /**
* *
*/ */
private Date updateTime; @TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
@TableField(exist = false) @TableField(exist = false)
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;

@ -0,0 +1,20 @@
package com.supervision.police.dto;
import lombok.Data;
import java.util.List;
/**
* @Authorlongbao
* @Date2024/12/10 14:19
* @Description:
*/
@Data
public class LongTextPieceSentenceDto {
// 笔录片段 长文本单句 id
private List<String> noteRecordSplitSentenceId;
// 笔录片段 长文本同语义id
private String noteRecordSplitPieceSentenceId;
}

@ -0,0 +1,21 @@
package com.supervision.police.dto;
import com.supervision.police.domain.NoteRecordSplitSentence;
import lombok.Data;
import java.util.List;
/**
* @Authorlongbao
* @Date2024/12/10 14:19
* @Description:
*/
@Data
public class LongTextSingleSentenceSummaryDto {
// 笔录片段id
private String noteRecordSplitId;
// 笔录片段单句集合
private List<NoteRecordSplitSentence> noteRecordSplitSentences;
}

@ -0,0 +1,29 @@
package com.supervision.police.dto;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
/**
* @Authorlongbao
* @Date2024/12/10 14:19
* @Description: 使 id
*/
@Data
public class PieceSentenceIdDto {
// 同语义句id
private String noteRecordSplitPieceSentenceId;
// 单语句 id集合
private List<Long> noteRecordSplitSentenceId;
public PieceSentenceIdDto() {
}
public PieceSentenceIdDto(String noteRecordSplitPieceSentenceId, List<Long> noteRecordSplitSentenceId) {
this.noteRecordSplitPieceSentenceId = noteRecordSplitPieceSentenceId;
this.noteRecordSplitSentenceId = noteRecordSplitSentenceId;
}
}

@ -9,5 +9,4 @@ public class TaskRecordVo {
private String evidenceId; private String evidenceId;
private String promptId; private String promptId;
private String type; private String type;
private String status;
} }

@ -0,0 +1,18 @@
package com.supervision.police.mapper;
import com.supervision.police.domain.ModelPieceRecordType;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* Mapper
* </p>
*
* @author longbao
* @since 2024-12-11
*/
@Mapper
public interface ModelPieceRecordTypeMapper extends BaseMapper<ModelPieceRecordType> {
}

@ -0,0 +1,18 @@
package com.supervision.police.mapper;
import com.supervision.police.domain.NotePiecePrompt;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* Mapper
* </p>
*
* @author longbao
* @since 2024-12-12
*/
@Mapper
public interface NotePiecePromptMapper extends BaseMapper<NotePiecePrompt> {
}

@ -0,0 +1,18 @@
package com.supervision.police.mapper;
import com.supervision.police.domain.NotePiecePromptTypeRel;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* Mapper
* </p>
*
* @author longbao
* @since 2024-12-12
*/
@Mapper
public interface NotePiecePromptTypeRelMapper extends BaseMapper<NotePiecePromptTypeRel> {
}

@ -0,0 +1,18 @@
package com.supervision.police.mapper;
import com.supervision.police.domain.NoteRecordSplitPieceSentence;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* Mapper
* </p>
*
* @author longbao
* @since 2024-12-11
*/
@Mapper
public interface NoteRecordSplitPieceSentenceMapper extends BaseMapper<NoteRecordSplitPieceSentence> {
}

@ -0,0 +1,26 @@
package com.supervision.police.mapper;
import com.supervision.police.domain.NoteRecordSplitSentence;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* <p>
* Mapper
* </p>
*
* @author longbao
* @since 2024-12-10
*/
@Mapper
public interface NoteRecordSplitSentenceMapper extends BaseMapper<NoteRecordSplitSentence> {
void saveBatchList(List<NoteRecordSplitSentence> noteRecordSplitList);
void updateBatchList(@Param("ids") List<Long> ids, @Param("noteRecordSplitPieceSentences") Long noteRecordSplitPieceSentences);
}

@ -0,0 +1,18 @@
package com.supervision.police.mapper;
import com.supervision.police.domain.PieceTripleInfo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* Mapper
* </p>
*
* @author longbao
* @since 2024-12-12
*/
@Mapper
public interface PieceTripleInfoMapper extends BaseMapper<PieceTripleInfo> {
}

@ -0,0 +1,139 @@
package com.supervision.police.mybatis;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.baomidou.mybatisplus.generator.fill.Column;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* @Authorlongbao
* @Date2024/11/19 13:03
* @Description:
*/
public class MySqlCodeGenerator {
public static void main(String[] args) {
String projectPath = System.getProperty("user.dir"); //获取当前项目路径
List<String> tables = new ArrayList<>();
//添加 表 到集合中,可以添加多个表
tables.add("transcription_triple_info");
FastAutoGenerator.create("jdbc:mysql://192.168.1.101:42415/nx_llm?useUnicode=true&characterEncoding=utf-8&useSSL=true&allowMultiQueries=true",
"root",
"llm@984573~!eda")
// 全局配置
.globalConfig(builder -> {
builder
.enableSwagger() // 是否启用swagger注解
.author("longbao") // 作者名称
.dateType(DateType.ONLY_DATE) // 时间策略
.commentDate("yyyy-MM-dd") // 注释日期
.outputDir(projectPath + "/src/main/java") // 输出目录
.disableOpenDir(); // 生成后禁止打开所生成的系统目录
})
//java和数据库字段的类型转换
.dataSourceConfig(builder -> builder.typeConvertHandler((globalConfig, typeRegistry, metaInfo) -> {
int typeCode = metaInfo.getJdbcType().TYPE_CODE;
if (typeCode == Types.SMALLINT || typeCode == Types.TINYINT) {
// 自定义类型转换
return DbColumnType.INTEGER;
}
return typeRegistry.getColumnType(metaInfo);
}))
// 包配置
.packageConfig(builder -> {
builder
.parent("com.supervision") // 父包名
.moduleName("police") // 模块包名
.controller("controller")
.entity("domain") // 实体类包名
.service("service") // service包名
.serviceImpl("service.impl") // serviceImpl包名
.mapper("mapper") // mapper包名
.xml("mapper.xml");
})
// 策略配置
.strategyConfig(builder -> {
builder.enableCapitalMode()//驼峰
.enableSkipView()//跳过视图
.disableSqlFilter()
// .addTablePrefix("t_") // 增加过滤表前缀
// .addTableSuffix("_db") // 增加过滤表后缀
// .addFieldPrefix("t_") // 增加过滤字段前缀
// .addFieldSuffix("_field") // 增加过滤字段后缀
.addInclude(tables) // 表匹配
// Entity 策略配置
.entityBuilder()
.enableFileOverride()
.enableLombok() // 开启lombok
.enableChainModel() // 链式
.enableRemoveIsPrefix() // 开启boolean类型字段移除is前缀
.enableTableFieldAnnotation() //开启生成实体时生成的字段注解
.versionColumnName("version") // 乐观锁数据库字段
.versionPropertyName("version") // 乐观锁实体类名称
.logicDeleteColumnName("delflag") // 逻辑删除数据库中字段名
.logicDeletePropertyName("delFlag") // 逻辑删除实体类中的字段名
.naming(NamingStrategy.underline_to_camel) // 表名 下划线 -》 驼峰命名
.columnNaming(NamingStrategy.underline_to_camel) // 字段名 下划线 -》 驼峰命名
.idType(IdType.ASSIGN_ID) // 主键生成策略 雪花算法生成id
.formatFileName("%s") // Entity 文件名称
.addTableFills(new Column("create_time", FieldFill.INSERT)) // 表字段填充
.addTableFills(new Column("update_time", FieldFill.INSERT_UPDATE)) // 表字段填充
//.enableColumnConstant()
//.enableActiveRecord()//MPlus中启用ActiveRecord模式生成的实体类会继承activerecord.Model类直接进行数据库操作
// Controller 策略配置
.controllerBuilder()
.enableFileOverride()
.enableHyphenStyle()
.enableRestStyle() // 开启@RestController
.formatFileName("%sController") // Controller 文件名称
// Service 策略配置
.serviceBuilder()
.enableFileOverride()
.formatServiceFileName("%sService") // Service 文件名称
.formatServiceImplFileName("%sServiceImpl") // ServiceImpl 文件名称
// Mapper 策略配置
.mapperBuilder()
.enableFileOverride()
.enableMapperAnnotation() // 开启@Mapper
.enableBaseColumnList() // 启用 columnList (通用查询结果列)
.enableBaseResultMap() // 启动resultMap
.formatMapperFileName("%sMapper") // Mapper 文件名称
.formatXmlFileName("%sMapper"); // Xml 文件名称
})
.templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板默认的是Velocity引擎模板
.templateConfig(builder -> {
builder.controller("/templates/controller.java")
.service("/templates/service.java")
.serviceImpl("/templates/serviceImpl.java")
//.mapper()
.build();
})
.execute(); // 执行
}
}

@ -0,0 +1,22 @@
package com.supervision.police.service;
import com.supervision.common.domain.R;
import java.sql.SQLException;
/**
* @Authorlongbao
* @Date2024/12/10 10:21
* @Description: id
*/
public interface LongTextService {
/**
* id
*
* @param noteRecordId id
* @return
*/
public R<Object> qaAnswerLongTextTripletExtractionByNoteRecordId(String noteRecordId);
}

@ -0,0 +1,16 @@
package com.supervision.police.service;
import com.supervision.police.domain.ModelPieceRecordType;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
*
* </p>
*
* @author longbao
* @since 2024-12-11
*/
public interface ModelPieceRecordTypeService extends IService<ModelPieceRecordType> {
}

@ -0,0 +1,29 @@
package com.supervision.police.service;
import com.supervision.police.domain.NotePiecePrompt;
import com.baomidou.mybatisplus.extension.service.IService;
import com.supervision.police.domain.NotePrompt;
import com.supervision.police.domain.NoteRecordSplitPieceSentence;
import java.util.List;
/**
* <p>
*
* </p>
*
* @author longbao
* @since 2024-12-12
*/
public interface NotePiecePromptService extends IService<NotePiecePrompt> {
/**
*
* @param recordSplitId
* @return
*/
List<NotePiecePrompt> listPiecePromptBySplitId(NoteRecordSplitPieceSentence recordSplitId);
}

@ -0,0 +1,16 @@
package com.supervision.police.service;
import com.supervision.police.domain.NotePiecePromptTypeRel;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
*
* </p>
*
* @author longbao
* @since 2024-12-12
*/
public interface NotePiecePromptTypeRelService extends IService<NotePiecePromptTypeRel> {
}

@ -0,0 +1,16 @@
package com.supervision.police.service;
import com.supervision.police.domain.NoteRecordSplitPieceSentence;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
*
* </p>
*
* @author longbao
* @since 2024-12-11
*/
public interface NoteRecordSplitPieceSentenceService extends IService<NoteRecordSplitPieceSentence> {
}

@ -0,0 +1,32 @@
package com.supervision.police.service;
import com.supervision.police.domain.NoteRecordSplitSentence;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* <p>
*
* </p>
*
* @author longbao
* @since 2024-12-10
*/
public interface NoteRecordSplitSentenceService extends IService<NoteRecordSplitSentence> {
/**
*
* @param noteRecordSplitList
*/
public void saveBatchList(List<NoteRecordSplitSentence> noteRecordSplitList);
/**
* llmGenA
* @param ids id
* @param noteRecordSplitPieceSentences id
*/
void updateBatchList(List<Long> ids,Long noteRecordSplitPieceSentences);
}

@ -0,0 +1,16 @@
package com.supervision.police.service;
import com.supervision.police.domain.PieceTripleInfo;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
*
* </p>
*
* @author longbao
* @since 2024-12-12
*/
public interface PieceTripleInfoService extends IService<PieceTripleInfo> {
}

@ -17,4 +17,23 @@ public interface TaskCaseRecordService extends IService<TaskCaseRecord> {
* @return * @return
*/ */
List<TaskCaseRecord> queryProcessingTaskList(); List<TaskCaseRecord> queryProcessingTaskList();
List<TaskCaseRecord> queryByTaskId(String taskId);
/**
*
* @param taskCaseRecord
* @return
*/
String getActuallyStatus(TaskCaseRecord taskCaseRecord);
TaskCaseRecord updateStatus(String taskId, String executeId,boolean isSuccess);
TaskCaseRecord updateStatus(String taskId, String executeId,boolean isSuccess,List<TaskCaseRecord> taskCaseRecordList);
Boolean updateStatus(String taskId,List<String> olderStatus,String nowStatus);
Boolean removeByTaskId(List<String> taskIds);
} }

@ -1,28 +1,41 @@
package com.supervision.police.service; package com.supervision.police.service;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.supervision.police.domain.TaskRecord;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.supervision.police.domain.NotePrompt;
import com.supervision.police.domain.TaskCaseRecord;
import com.supervision.police.domain.TaskRecord;
import com.supervision.police.dto.TaskInfoDTO; import com.supervision.police.dto.TaskInfoDTO;
import com.supervision.police.dto.taskRecord.TaskRecordVo; import com.supervision.police.dto.taskRecord.TaskRecordVo;
import com.supervision.police.vo.TaskInfoReqVO; import com.supervision.police.vo.TaskInfoReqVO;
import java.util.List; import java.util.List;
/** /**
* @author dxy * @author dxy
* @description task_recordService * @description task_recordService
* @createDate 2024-12-24 14:44:43 * @createDate 2024-12-24 14:44:43
*/ */
public interface TaskRecordService extends IService<TaskRecord> { public interface TaskRecordService extends IService<TaskRecord> {
void executePromptExtractTask(TaskRecordVo taskRecordVo); void executePromptExtractTask(TaskRecordVo taskRecordVo);
void graphExtract(NotePrompt prompt, String caseId, String executeId);
/**
*
*
* @param evidenceId id
*/
void structureExtract(String evidenceId);
IPage<TaskInfoDTO> queryTaskList(TaskInfoReqVO taskInfoReqVO, Integer page, Integer size); IPage<TaskInfoDTO> queryTaskList(TaskInfoReqVO taskInfoReqVO, Integer page, Integer size);
/** /**
* *
*
* @param status * @param status
* @return true false * @return true false
*/ */
@ -30,6 +43,7 @@ public interface TaskRecordService extends IService<TaskRecord> {
/** /**
* *
*
* @param status * @param status
* @return true false * @return true false
*/ */
@ -40,4 +54,15 @@ public interface TaskRecordService extends IService<TaskRecord> {
void deleteTask(List<String> taskIds); void deleteTask(List<String> taskIds);
/**
*
*
* @param taskId id
* @param executeId id
*/
void completeTask(String taskId, String executeId, boolean isSuccess);
String determineStatus(List<TaskCaseRecord> taskCaseRecords);
} }

@ -0,0 +1,750 @@
package com.supervision.police.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator;
import com.supervision.common.domain.R;
import com.supervision.common.utils.StringUtils;
import com.supervision.constant.PromptsEnum;
import com.supervision.police.domain.*;
import com.supervision.police.dto.LongTextSingleSentenceSummaryDto;
import com.supervision.police.dto.PieceSentenceIdDto;
import com.supervision.police.service.*;
import com.supervision.thread.*;
import com.supervision.utils.UserUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
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.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StopWatch;
import java.util.*;
import java.util.concurrent.*;
import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @Authorlongbao
* @Date2024/12/10 10:22
* @Description: QA
*/
@Slf4j
@Service
public class LongTextServiceImpl implements LongTextService {
private static final String HEAD_ENTITY_TYPE_ACTOR = "行为人";
@Autowired
private NoteRecordService noteRecordService;
@Autowired
private NoteRecordSplitService noteRecordSplitService;
@Autowired
private NoteRecordSplitSentenceService noteRecordSplitSentenceService;
@Autowired
private OllamaChatClient chatClient;
@Autowired
private NoteRecordSplitPieceSentenceService noteRecordSplitPieceSentenceService;
@Autowired
private ModelPieceRecordTypeService modelPieceRecordTypeService;
@Autowired
private NotePiecePromptTypeRelService notePiecePromptTypeRelService;
@Autowired
private NotePiecePromptService notePiecePromptService;
@Autowired
private CasePersonService casePersonService;
@Autowired
private PieceTripleInfoService pieceTripleInfoService;
/**
* id
*
* @param noteRecordId id
* @return
*/
@Override
@Transactional(transactionManager = "dataSourceTransactionManager", rollbackFor = Exception.class)
public R<Object> qaAnswerLongTextTripletExtractionByNoteRecordId(String noteRecordId) {
log.info("[QaAnswerLongTextTripletExtraction]开始");
StopWatch stopWatch = new StopWatch();
stopWatch.start();
// 校验参数
if (StringUtils.isNull(noteRecordId)) {
stopWatch.stop();
log.error("[QaAnswerLongTextTripletExtraction]笔录id不存在{}", noteRecordId);
log.warn("[QaAnswerLongTextTripletExtraction]主线程程序总耗时:{}", stopWatch.getTotalTimeSeconds());
return R.fail("笔录id不可为空");
}
// 查询笔录是否存在
NoteRecord noteRecord = noteRecordService
.lambdaQuery()
.select(NoteRecord::getId)
.eq(NoteRecord::getId, noteRecordId)
.one();
if (null == noteRecord) {
stopWatch.stop();
log.error("[QaAnswerLongTextTripletExtraction]笔录不存在{}", noteRecordId);
log.warn("[QaAnswerLongTextTripletExtraction]主线程程序总耗时:{}", stopWatch.getTotalTimeSeconds());
return R.fail("该笔录不存在");
}
// 笔录是否已拆分QA
List<NoteRecordSplit> noteRecordSplits = noteRecordSplitService
.lambdaQuery()
.select(NoteRecordSplit::getId, NoteRecordSplit::getAnswer)
.eq(NoteRecordSplit::getNoteRecordId, noteRecordId)
.list();
if (null == noteRecordSplits || noteRecordSplits.isEmpty()) {
stopWatch.stop();
log.error("[QaAnswerLongTextTripletExtraction]笔录未拆分{}", noteRecordId);
log.warn("[QaAnswerLongTextTripletExtraction]主线程程序总耗时:{}", stopWatch.getTotalTimeSeconds());
return R.fail("该笔录未拆分QA对");
}
R<Object> threadPoolExecutorCheck = singlePointCheck();
if (null != threadPoolExecutorCheck) {
stopWatch.stop();
return threadPoolExecutorCheck;
}
// 获取笔录片段中回答中的长文本
List<NoteRecordSplitSentence> noteRecordSplitList = matcherLongText(noteRecordSplits);
if (noteRecordSplitList.isEmpty()) {
stopWatch.stop();
log.error("[QaAnswerLongTextTripletExtraction]笔录无长文本{}", noteRecordId);
log.warn("[QaAnswerLongTextTripletExtraction]主线程程序总耗时:{}", stopWatch.getTotalTimeSeconds());
return R.fail("该笔录QA对未查询到长文本");
}
log.info("[QaAnswerLongTextTripletExtraction]校验通过");
// 保存长文本单句
noteRecordSplitSentenceService.saveBatch(noteRecordSplitList);
log.info("[QaAnswerLongTextTripletExtraction]保存长文本单句成功");
// 长文本单句总结
List<String> noteRecordSplitAnswerList = new ArrayList<>();
for (NoteRecordSplitSentence noteRecordSplitSentence : noteRecordSplitList) {
Long noteRecordSplitSentenceId = noteRecordSplitSentence.getId();
String answer = noteRecordSplitSentence.getAnswer();
noteRecordSplitAnswerList.add(noteRecordSplitSentenceId + "、" + answer);
}
log.info("[QaAnswerLongTextTripletExtraction]长文本单句总结开始");
List<NoteRecordSplitSentence> noteRecordSplitSentences = chatAiLongTextSingleSentenceSummary(PromptsEnum.LONG_TEXT_SINGLE_SENTENCE_SUMMARY, noteRecordSplitAnswerList);
log.info("[QaAnswerLongTextTripletExtraction]长文本单句总结结束");
// 更新长文本单句
noteRecordSplitSentenceService.updateBatchById(noteRecordSplitSentences);
log.info("[QaAnswerLongTextTripletExtraction]更新长文本单句成功");
// 获取answer片段对应的单句集合
List<Long> noteRecordSplitSentenceIdList = noteRecordSplitList
.stream()
.map(NoteRecordSplitSentence::getId)
.toList();
List<LongTextSingleSentenceSummaryDto> longTextSingleSentenceSummaryDtoList = new ArrayList<>();
List<NoteRecordSplitSentence> splitSentences = noteRecordSplitSentenceService
.lambdaQuery()
.select(NoteRecordSplitSentence::getRecordSplitId)
.in(NoteRecordSplitSentence::getId, noteRecordSplitSentenceIdList)
.groupBy(NoteRecordSplitSentence::getRecordSplitId)
.list();
// 遍历长文本单句
for (NoteRecordSplitSentence noteRecordSplit : splitSentences) {
String noteRecordSplitId = noteRecordSplit.getRecordSplitId();
List<NoteRecordSplitSentence> recordSplitSentenceList = noteRecordSplitSentenceService
.lambdaQuery()
.eq(NoteRecordSplitSentence::getRecordSplitId, noteRecordSplitId)
.in(NoteRecordSplitSentence::getId, noteRecordSplitSentenceIdList)
.orderByAsc(NoteRecordSplitSentence::getId)
.list();
LongTextSingleSentenceSummaryDto longTextSingleSentenceSummaryDto = new LongTextSingleSentenceSummaryDto();
longTextSingleSentenceSummaryDto.setNoteRecordSplitId(noteRecordSplitId);
longTextSingleSentenceSummaryDto.setNoteRecordSplitSentences(recordSplitSentenceList);
longTextSingleSentenceSummaryDtoList.add(longTextSingleSentenceSummaryDto);
}
if (longTextSingleSentenceSummaryDtoList.isEmpty()) {
log.warn("[QaAnswerLongTextTripletExtraction]当前回答下的单句集合不可为空");
return R.fail("当前回答下的长文本单句集合为空");
}
log.info("[QaAnswerLongTextTripletExtraction]当前回答下的单句集合查询成功");
try {
// 遍历单句集合-同语义归纳
List<Future<Map<String, Object>>> futureList = new ArrayList<>();
for (LongTextSingleSentenceSummaryDto longTextSingleSentenceSummaryDto : longTextSingleSentenceSummaryDtoList) {
LongTextTask longTextTask = new LongTextTask(chatClient, longTextSingleSentenceSummaryDto, pieceSentenceSave());
Future<Map<String, Object>> submit = LongtextThreadPool.executorService.submit(longTextTask);
futureList.add(submit);
}
log.info("[QaAnswerLongTextTripletExtraction]:同语义归纳任务成功提交{}个任务....", futureList.size());
} catch (Exception e) {
log.error("[QaAnswerLongTextTripletExtraction]未知异常:", e);
return R.fail("长文本接口未知异常");
} finally {
stopWatch.stop();
log.warn("[QaAnswerLongTextTripletExtraction]主线程程序总耗时:{}", stopWatch.getTotalTimeSeconds());
}
return null;
}
/**
*
*
* @param noteRecordSplitPieceSentence
* @return person- notePromptList-
*/
private Map<String, Object> queryPromptByType(NoteRecordSplitPieceSentence noteRecordSplitPieceSentence) {
log.info("longTextExtractTripleInfo:同语义句类型查询开始");
Map<String, Object> returnMap = new HashMap<>();
// 判断同语义类型是否存在
String pieceSentenceId = noteRecordSplitPieceSentence.getId();
String contentChuck = noteRecordSplitPieceSentence.getContentChuckSummary();
if (null == contentChuck || contentChuck.isEmpty()) {
log.warn("longTextExtractTripleInfo:同语义片段片段:{} 不存在任何分类信息,不进行后续操作...", pieceSentenceId);
return null;
}
// 查询 同语义类型 对应的 提示词集合
List<NotePiecePrompt> notePromptList = notePiecePromptService.listPiecePromptBySplitId(noteRecordSplitPieceSentence);
if (CollUtil.isEmpty(notePromptList)) {
log.warn("longTextExtractTripleInfo:同语义片段:{},分类:{} 不属于任何提示词,不进行后续操作...", pieceSentenceId, contentChuck);
return null;
}
// 查询笔录的案件信息
String recordSplitId = noteRecordSplitPieceSentence.getRecordSplitId();
NoteRecordSplit recordSplit = noteRecordSplitService.lambdaQuery().select(NoteRecordSplit::getCaseId).eq(NoteRecordSplit::getId, recordSplitId).one();
QueryWrapper<CasePerson> wrapper = new QueryWrapper<>();
wrapper.eq("case_id", recordSplit.getCaseId());
wrapper.eq("case_actor_flag", 1);
CasePerson personServiceOne = casePersonService.getOne(wrapper);
returnMap.put("person", personServiceOne);
returnMap.put("notePromptList", notePromptList);
return returnMap;
}
/**
*
*
* @return
*/
private Consumer<Map<String, Object>> pieceSentenceSave() throws Exception {
return (noteMap) -> {
log.info("[QaAnswerLongTextTripletExtraction-Pool-pieceSentenceSave]同语义保存,当前线程是:{}", Thread.currentThread().getName());
String contentChuck;
List<NoteRecordSplitPieceSentence> recordSplitPieceSentences = (List<NoteRecordSplitPieceSentence>) noteMap.get("recordSplitPieceSentences");
List<PieceSentenceIdDto> noteRecordSplitPieceSentenceBySingle = (List<PieceSentenceIdDto>) noteMap.get("noteRecordSplitPieceSentenceBySingle");
// 保存同语义集合
noteRecordSplitPieceSentenceService.saveBatch(recordSplitPieceSentences);
// 更新单语句 的 长语句id
for (PieceSentenceIdDto pieceSentenceIdDto : noteRecordSplitPieceSentenceBySingle) {
List<NoteRecordSplitSentence> recordSplitSentences = getNoteRecordSplitSentences(pieceSentenceIdDto);
noteRecordSplitSentenceService.updateBatchById(recordSplitSentences);
}
// 保存 提示词
NotePiecePrompt piecePrompt = notePiecePromptService.lambdaQuery().eq(NotePiecePrompt::getName, "行为人-担保-xxxx").one();
if (null == piecePrompt) {
NotePiecePrompt notePiecePrompt = getNotePiecePrompt();
notePiecePromptService.save(notePiecePrompt);
piecePrompt = notePiecePrompt;
}
// 更新同语义总结
List<NoteRecordSplitPieceSentence> noteRecordSplitPieceSentences = new ArrayList<>();
List<ModelPieceRecordType> modelPieceRecordTypes = new ArrayList<>();
List<NotePiecePromptTypeRel> notePiecePromptTypeRels = new ArrayList<>();
for (NoteRecordSplitPieceSentence noteRecordSplitPieceSentence : recordSplitPieceSentences) {
String splitPieceSentenceId = noteRecordSplitPieceSentence.getId();
List<NoteRecordSplitSentence> splitSentence = noteRecordSplitSentenceService.lambdaQuery()
.select(NoteRecordSplitSentence::getLlmGenA)
.isNotNull(NoteRecordSplitSentence::getLlmGenA)
.ne(NoteRecordSplitSentence::getLlmGenA, "无")
.eq(NoteRecordSplitSentence::getPieceRecordSplitId, splitPieceSentenceId)
.list();
if (null != splitSentence && !splitSentence.isEmpty()) {
// 更新同语义总结
contentChuck = splitSentence.get(0).getLlmGenA();
} else {
// 重新请求模型生成同语义句子的语义
List<String> noteRecordSplitAnswerList = new ArrayList<>();
noteRecordSplitAnswerList.add(noteRecordSplitPieceSentence.getContentChuck());
contentChuck = ((chatAiLongTextSingleSentenceSummary(PromptsEnum.LONG_TEXT_SINGLE_SENTENCE_SUMMARY, noteRecordSplitAnswerList).get(0)) == null) ? "无"
: (chatAiLongTextSingleSentenceSummary(PromptsEnum.LONG_TEXT_SINGLE_SENTENCE_SUMMARY, noteRecordSplitAnswerList).get(0).getLlmGenA());
}
NoteRecordSplitPieceSentence splitPieceSentence = new NoteRecordSplitPieceSentence();
splitPieceSentence.setId(splitPieceSentenceId);
splitPieceSentence.setContentChuckSummary(contentChuck);
noteRecordSplitPieceSentences.add(splitPieceSentence);
// 类型
String modelPieceRecordTypeId = DefaultIdentifierGenerator.getInstance().nextId(null).toString();
ModelPieceRecordType modelPieceRecordType = new ModelPieceRecordType();
modelPieceRecordType.setId(modelPieceRecordTypeId);
modelPieceRecordType.setRecordType(contentChuck);
modelPieceRecordType.setCreateUserId(UserUtil.getUser().getId());
modelPieceRecordType.setUpdateUserId(UserUtil.getUser().getId());
modelPieceRecordTypes.add(modelPieceRecordType);
// 保存 类型 提示词关系
String notePiecePromptTypeRelId = DefaultIdentifierGenerator.getInstance().nextId(null).toString();
NotePiecePromptTypeRel notePiecePromptTypeRel = new NotePiecePromptTypeRel();
notePiecePromptTypeRel.setId(notePiecePromptTypeRelId);
notePiecePromptTypeRel.setPromptId(piecePrompt.getId());
notePiecePromptTypeRel.setTypeId(modelPieceRecordType.getId());
notePiecePromptTypeRels.add(notePiecePromptTypeRel);
}
// 更新同语义句的总结(类型)
noteRecordSplitPieceSentenceService.updateBatchById(noteRecordSplitPieceSentences);
// 保存同语义总结(类型)
modelPieceRecordTypeService.saveBatch(modelPieceRecordTypes);
// 保存 类型 提示词关系
notePiecePromptTypeRelService.saveBatch(notePiecePromptTypeRels);
log.info("[QaAnswerLongTextTripletExtraction-Pool-pieceSentenceSave]保存类型+总结+提示词成功,当前线程是:{}", Thread.currentThread().getName());
// 12.三元组提取
// 查询同语义句
log.info("[QaAnswerLongTextTripletExtraction-Pool-pieceSentenceSave]开始同语义三元组提取。当前线程是:{}", Thread.currentThread().getName());
List<String> notePieceSentencesIdList = recordSplitPieceSentences.stream().map(NoteRecordSplitPieceSentence::getId).toList();
List<NoteRecordSplitPieceSentence> notePieceSentences = noteRecordSplitPieceSentenceService
.lambdaQuery()
.select(NoteRecordSplitPieceSentence::getId, NoteRecordSplitPieceSentence::getRecordSplitId, NoteRecordSplitPieceSentence::getContentChuck, NoteRecordSplitPieceSentence::getContentChuckSummary)
.in(NoteRecordSplitPieceSentence::getId, notePieceSentencesIdList)
.list();
// 遍历同语义句
for (NoteRecordSplitPieceSentence noteRecordSplitPieceSentence : notePieceSentences) {
Map<String, Object> queryPromptByType = queryPromptByType(noteRecordSplitPieceSentence);
if (null == queryPromptByType) {
log.warn("[QaAnswerLongTextTripletExtraction-Pool-pieceSentenceSave]同语义查询案件信息或提示词为null,noteRecordSplitPieceSentenceId:{},当前线程是:{}", noteRecordSplitPieceSentence.getId(), Thread.currentThread().getName());
continue;
}
CasePerson mainActor = (CasePerson) queryPromptByType.get("person");
List<NotePiecePrompt> notePromptList = (List<NotePiecePrompt>) queryPromptByType.get("notePromptList");
if (null == mainActor || CollUtil.isEmpty(notePromptList)) {
log.warn("[QaAnswerLongTextTripletExtraction-Pool-pieceSentenceSave]该同语义句三元组提示词或案件信息缺失,noteRecordSplitPieceSentenceId:{},当前线程是:{}", noteRecordSplitPieceSentence.getId(), Thread.currentThread().getName());
continue;
}
List<Future<PieceTripleInfo>> futures = new ArrayList<>();
for (NotePiecePrompt notePiecePrompt : notePromptList) {
PieceTripleExtractTask pieceTripleExtractTask = new PieceTripleExtractTask(chatClient, mainActor, notePiecePrompt, noteRecordSplitPieceSentence);
Future<PieceTripleInfo> submit = PieceTripleThreadPool.executorService.submit(pieceTripleExtractTask);
futures.add(submit);
}
List<PieceTripleInfo> tripleInfos = new ArrayList<>();
try {
log.info("[QaAnswerLongTextTripletExtraction-Pool-pieceSentenceSave]当前线程{},同语义片段:{}三元组抽取任务成功提交{}个任务....", Thread.currentThread().getName(), noteRecordSplitPieceSentence.getId(), futures.size());
for (Future<PieceTripleInfo> future : futures) {
PieceTripleInfo tripleInfo = future.get();
if (Objects.nonNull(tripleInfo)) {
tripleInfos.add(tripleInfo);
}
}
// 如果有提取到三元组信息
if (CollUtil.isNotEmpty(tripleInfos)) {
log.info("[QaAnswerLongTextTripletExtraction-Pool-pieceSentenceSave]当前线程{},同语义片段:{}三元组提取任务执行结束...,三元组信息入库:{}", Thread.currentThread().getName(), noteRecordSplitPieceSentence.getId(), JSONUtil.toJsonStr(tripleInfos));
pieceTripleInfoService.saveBatch(tripleInfos);
} else {
log.info("[QaAnswerLongTextTripletExtraction-Pool-pieceSentenceSave]当前线程{},同语义片段:{}三元组提取任务执行结束...,未提取到任何三元组信息...", Thread.currentThread().getName(), noteRecordSplitPieceSentence.getId());
}
} catch (InterruptedException | ExecutionException e) {
log.error("[QaAnswerLongTextTripletExtraction-Pool-pieceSentenceSave]当前线程{},同语义片段:{}三元组提取任务提交失败...", Thread.currentThread().getName(), noteRecordSplitPieceSentence.getId(), e);
throw new RuntimeException(e);
}
}
};
}
/**
*
*
* @param longTextSingleSentenceSummaryDto
*/
private void pieceSentenceNormal(LongTextSingleSentenceSummaryDto longTextSingleSentenceSummaryDto) {
log.info("[pieceSentenceNormal]开始同语义归纳方法");
String contentChuck = "";
// 同语义集合
List<NoteRecordSplitPieceSentence> recordSplitPieceSentences = new ArrayList<>();
// 同语义使用单句id集合
List<PieceSentenceIdDto> noteRecordSplitPieceSentenceBySingle = new ArrayList<>();
// 笔录片段id
String noteRecordSplitId = longTextSingleSentenceSummaryDto.getNoteRecordSplitId();
// 单语句集合
List<NoteRecordSplitSentence> noteRecordSplitSentences = longTextSingleSentenceSummaryDto.getNoteRecordSplitSentences();
int noteRecordSplitSentencesSize = noteRecordSplitSentences.size();
// 获取末尾单句 N+1
NoteRecordSplitSentence endCombinedSentence = noteRecordSplitSentences.get(noteRecordSplitSentencesSize - 1);
Long endCombinedSentenceId = endCombinedSentence.getId();
ConcurrentLinkedDeque<Long> noteRecordSplitPieceSentenceDeque = new ConcurrentLinkedDeque<>();
noteRecordSplitPieceSentenceDeque.add(endCombinedSentenceId);
ConcurrentLinkedDeque<String> endCombinedSentenceDeque = new ConcurrentLinkedDeque<>();
endCombinedSentenceDeque.addLast(endCombinedSentence.getAnswer());
// 遍历单句集合
for (int i = noteRecordSplitSentencesSize - 2; i >= 0; i--) {
PieceSentenceIdDto pieceSentenceIdDto = new PieceSentenceIdDto();
// 获取第N句
NoteRecordSplitSentence currentSentence = noteRecordSplitSentences.get(i);
Long currentSentenceId = currentSentence.getId();
String currentSentenceAnswer = currentSentence.getAnswer();
// 对比句子语义
boolean inductionFlag = chatAiLongTextHomoSemanticInduction(String.valueOf(endCombinedSentenceDeque), currentSentenceAnswer);
if (inductionFlag) {
endCombinedSentenceDeque.addFirst(currentSentenceAnswer);
noteRecordSplitPieceSentenceDeque.addFirst(currentSentenceId);
} else {
NoteRecordSplitPieceSentence pieceSentence = setNotePieceRecordSentence(noteRecordSplitId, endCombinedSentenceDeque);
endCombinedSentenceDeque.remove();
endCombinedSentenceDeque.addLast(currentSentenceAnswer);
List<Long> longList = noteRecordSplitPieceSentenceDeque.stream().toList();
noteRecordSplitPieceSentenceDeque.remove();
noteRecordSplitPieceSentenceDeque.addLast(currentSentenceId);
pieceSentenceIdDto.setNoteRecordSplitPieceSentenceId(pieceSentence.getId());
pieceSentenceIdDto.setNoteRecordSplitSentenceId(longList);
recordSplitPieceSentences.add(pieceSentence);
noteRecordSplitPieceSentenceBySingle.add(pieceSentenceIdDto);
}
}
NoteRecordSplitPieceSentence pieceSentence = setNotePieceRecordSentence(noteRecordSplitId, endCombinedSentenceDeque);
recordSplitPieceSentences.add(pieceSentence);
noteRecordSplitPieceSentenceBySingle.add(new PieceSentenceIdDto(pieceSentence.getId(), noteRecordSplitPieceSentenceDeque.stream().toList()));
// 保存同语义集合
noteRecordSplitPieceSentenceService.saveBatch(recordSplitPieceSentences);
// 更新单语句 的 长语句id
for (PieceSentenceIdDto pieceSentenceIdDto : noteRecordSplitPieceSentenceBySingle) {
List<NoteRecordSplitSentence> recordSplitSentences = getNoteRecordSplitSentences(pieceSentenceIdDto);
noteRecordSplitSentenceService.updateBatchById(recordSplitSentences);
}
// 保存 提示词
NotePiecePrompt piecePrompt = notePiecePromptService.lambdaQuery().eq(NotePiecePrompt::getName, "行为人-担保-xxxx").one();
if (null == piecePrompt) {
NotePiecePrompt notePiecePrompt = getNotePiecePrompt();
notePiecePromptService.save(notePiecePrompt);
piecePrompt = notePiecePrompt;
}
// 更新同语义总结
List<NoteRecordSplitPieceSentence> noteRecordSplitPieceSentences = new ArrayList<>();
List<ModelPieceRecordType> modelPieceRecordTypes = new ArrayList<>();
List<NotePiecePromptTypeRel> notePiecePromptTypeRels = new ArrayList<>();
for (NoteRecordSplitPieceSentence noteRecordSplitPieceSentence : recordSplitPieceSentences) {
String splitPieceSentenceId = noteRecordSplitPieceSentence.getId();
List<NoteRecordSplitSentence> splitSentence = noteRecordSplitSentenceService.lambdaQuery()
.select(NoteRecordSplitSentence::getLlmGenA)
.isNotNull(NoteRecordSplitSentence::getLlmGenA)
.ne(NoteRecordSplitSentence::getLlmGenA, "无")
.eq(NoteRecordSplitSentence::getPieceRecordSplitId, splitPieceSentenceId)
.list();
if (null != splitSentence && !splitSentence.isEmpty()) {
// 更新同语义总结
contentChuck = splitSentence.get(0).getLlmGenA();
} else {
// 重新请求模型生成同语义句子的语义
List<String> noteRecordSplitAnswerList = new ArrayList<>();
noteRecordSplitAnswerList.add(noteRecordSplitPieceSentence.getContentChuck());
contentChuck = ((chatAiLongTextSingleSentenceSummary(PromptsEnum.LONG_TEXT_SINGLE_SENTENCE_SUMMARY, noteRecordSplitAnswerList).get(0)) == null) ? "无"
: (chatAiLongTextSingleSentenceSummary(PromptsEnum.LONG_TEXT_SINGLE_SENTENCE_SUMMARY, noteRecordSplitAnswerList).get(0).getLlmGenA());
}
NoteRecordSplitPieceSentence splitPieceSentence = new NoteRecordSplitPieceSentence();
splitPieceSentence.setId(splitPieceSentenceId);
splitPieceSentence.setContentChuckSummary(contentChuck);
noteRecordSplitPieceSentences.add(splitPieceSentence);
// 类型
String modelPieceRecordTypeId = DefaultIdentifierGenerator.getInstance().nextId(null).toString();
ModelPieceRecordType modelPieceRecordType = new ModelPieceRecordType();
modelPieceRecordType.setId(modelPieceRecordTypeId);
modelPieceRecordType.setRecordType(contentChuck);
modelPieceRecordType.setCreateUserId(UserUtil.getUser().getId());
modelPieceRecordType.setUpdateUserId(UserUtil.getUser().getId());
modelPieceRecordTypes.add(modelPieceRecordType);
// 保存 类型 提示词关系
String notePiecePromptTypeRelId = DefaultIdentifierGenerator.getInstance().nextId(null).toString();
NotePiecePromptTypeRel notePiecePromptTypeRel = new NotePiecePromptTypeRel();
notePiecePromptTypeRel.setId(notePiecePromptTypeRelId);
notePiecePromptTypeRel.setPromptId(piecePrompt.getId());
notePiecePromptTypeRel.setTypeId(modelPieceRecordType.getId());
notePiecePromptTypeRels.add(notePiecePromptTypeRel);
}
// 更新同语义句的总结(类型)
noteRecordSplitPieceSentenceService.updateBatchById(noteRecordSplitPieceSentences);
// 保存同语义总结(类型)
modelPieceRecordTypeService.saveBatch(modelPieceRecordTypes);
// 保存 类型 提示词关系
notePiecePromptTypeRelService.saveBatch(notePiecePromptTypeRels);
log.info("[pieceSentenceNormal]关系已保存");
}
/**
*
*
* @return
*/
private NotePiecePrompt getNotePiecePrompt() {
NotePiecePrompt notePiecePrompt = new NotePiecePrompt();
notePiecePrompt.setStartEntityType("行为人");
notePiecePrompt.setRelType("担保");
notePiecePrompt.setEndEntityType("xxxx");
notePiecePrompt.setPrompt(PromptsEnum.LONG_TEXT_TRIPLE_INFO.getContent());
notePiecePrompt.setStartEntityTemplate("headEntityType");
notePiecePrompt.setRelTemplate("relation");
notePiecePrompt.setEndEntityTemplate("tailEntityType");
notePiecePrompt.setName("行为人-担保-xxxx");
notePiecePrompt.setCreateUserId(UserUtil.getUser().getId());
notePiecePrompt.setUpdateUserId(UserUtil.getUser().getId());
return notePiecePrompt;
}
/**
* @param prompt
* @param noteRecordSplitAnswerList
* @return
*/
public List<NoteRecordSplitSentence> chatAiLongTextSingleSentenceSummary(PromptsEnum prompt, List<String> noteRecordSplitAnswerList) {
List<NoteRecordSplitSentence> noteRecordSplitSentenceArrayList = new ArrayList<>();
StopWatch stopWatch = new StopWatch();
// 分析同语义集合
stopWatch.start();
HashMap<String, Object> paramMap = new HashMap<>();
paramMap.put("noteRecordSplitList", noteRecordSplitAnswerList);
String format = StrUtil.format(prompt.getContent(), paramMap);
ChatResponse call = chatClient.call(new Prompt(new UserMessage(format)));
stopWatch.stop();
log.warn("[QaAnswerLongTextTripletExtraction-chatAiLongTextSingleSentenceSummary]长文本单句总结集合模型耗时:{}", stopWatch.getTotalTimeSeconds());
String content = call.getResult().getOutput().getContent();
JSONObject jsonObject = JSON.parseObject(content);
Object object = jsonObject.get("result");
JSONArray jsonArray = JSONArray.parseArray(object.toString());
List<Object> list = jsonArray.stream().toList();
try {
for (Object listObject : list) {
NoteRecordSplitSentence noteRecordSplitSentence = JSONUtil.toBean(String.valueOf(listObject), NoteRecordSplitSentence.class);
noteRecordSplitSentenceArrayList.add(noteRecordSplitSentence);
}
} catch (Exception e) {
log.error("[QaAnswerLongTextTripletExtraction-chatAiLongTextSingleSentenceSummary]长文本单句总结集合模型转换错误");
throw new RuntimeException(e);
}
return noteRecordSplitSentenceArrayList;
}
/**
*
*
* @param noteRecordSplits
* @return
*/
private List<NoteRecordSplitSentence> matcherLongText(List<NoteRecordSplit> noteRecordSplits) {
// 定义正则表达式,匹配“:”,“:”
String regexSplit = "[:]";
// 长文本段落集合
List<NoteRecordSplitSentence> noteRecordSplitList = new ArrayList<>();
// 回答中匹配的长文本段落
String paragraph = null;
for (NoteRecordSplit noteRecordSplit : noteRecordSplits) {
String noteRecordSplitId = noteRecordSplit.getId();
String answer = noteRecordSplit.getAnswer();
if (StringUtils.isEmpty(answer)) {
continue;
}
// 使用 Pattern 和 Matcher 类进行匹配
Pattern pattern = Pattern.compile(regexSplit);
Matcher matcher = pattern.matcher(answer);
boolean isMatch = matcher.find();
if (isMatch) {
String[] answerSplit = answer.split(regexSplit);
paragraph = answerSplit[1];
if (StringUtils.isEmpty(paragraph)) {
continue;
}
}
List<String> splitSentences = splitSentences(paragraph);
int paragraphChar = paragraph.replace("\n", "")
.replace("\t", "")
.replace("\s", "")
.trim().length();
if (splitSentences.size() > 5 || paragraphChar > 100) {
// 长文本
for (String sentence : splitSentences) {
NoteRecordSplitSentence noteRecordSplitSentence = new NoteRecordSplitSentence();
noteRecordSplitSentence.setRecordSplitId(noteRecordSplitId);
noteRecordSplitSentence.setAnswer(sentence);
noteRecordSplitSentence.setCreateUserId(UserUtil.getUser().getId());
noteRecordSplitSentence.setUpdateUserId(UserUtil.getUser().getId());
noteRecordSplitList.add(noteRecordSplitSentence);
}
}
}
return noteRecordSplitList;
}
/**
*
*
* @param paragraph
* @return
*/
private List<String> splitSentences(String paragraph) {
List<String> sentences = new ArrayList<>();
StringBuilder currentSentence = new StringBuilder();
for (char c : paragraph.toCharArray()) {
if (c == '。' || c == '' || c == '' || c == '.' || c == '?' || c == '!') {
sentences.add(currentSentence.append(c).toString().trim());
currentSentence.setLength(0);
} else {
currentSentence.append(c);
}
}
// 处理段落末尾可能没有标点符号的情况
if (!currentSentence.isEmpty()) {
sentences.add(currentSentence.toString().trim());
}
return sentences;
}
/**
* @param encCombinedSentence N+1
* @param currentSentence N
* @return
*/
private boolean chatAiLongTextHomoSemanticInduction(String encCombinedSentence, String currentSentence) {
StopWatch stopWatch = new StopWatch();
// 分析同语义集合
stopWatch.start();
HashMap<String, Object> paramMap = new HashMap<>();
paramMap.put("encCombinedSentence", encCombinedSentence);
paramMap.put("currentSentence", currentSentence);
String format = StrUtil.format(PromptsEnum.LONG_TEXT_SINGLE_STATEMENT_WITH_SEMANTIC_JUDGMENT_PROMPT_WORD.getContent(), paramMap);
ChatResponse call = chatClient.call(new Prompt(new UserMessage(format)));
stopWatch.stop();
String content = call.getResult().getOutput().getContent();
JSONObject jsonObject = JSON.parseObject(content);
boolean result = (boolean) jsonObject.get("result");
return result;
}
/**
*
*
* @param noteRecordSplitId id
* @param endSentenceDequeStringDeque
* @return
*/
public NoteRecordSplitPieceSentence setNotePieceRecordSentence(String noteRecordSplitId, ConcurrentLinkedDeque<String> endSentenceDequeStringDeque) {
StringBuilder endSentenceDequeStringBuilder = new StringBuilder();
for (String endSentenceDeque : endSentenceDequeStringDeque) {
endSentenceDequeStringBuilder.append(endSentenceDeque);
}
String endSentenceDequeStringBuilderString = String.valueOf(endSentenceDequeStringBuilder);
String noteRecordSplitPieceSentenceId = DefaultIdentifierGenerator.getInstance().nextId(null).toString();
NoteRecordSplitPieceSentence noteRecordSplitPieceSentence = new NoteRecordSplitPieceSentence();
noteRecordSplitPieceSentence.setId(noteRecordSplitPieceSentenceId);
noteRecordSplitPieceSentence.setCreateUserId(UserUtil.getUser().getId());
noteRecordSplitPieceSentence.setUpdateUserId(UserUtil.getUser().getId());
noteRecordSplitPieceSentence.setRecordSplitId(noteRecordSplitId);
noteRecordSplitPieceSentence.setContentChuck(endSentenceDequeStringBuilderString);
return noteRecordSplitPieceSentence;
}
/**
*
*
* @return
*/
public R<Object> singlePointCheck() {
// 检测上个线程池中是否有未完成的任务
ThreadPoolExecutor longTextExecutorService = LongtextThreadPool.executorService;
ThreadPoolExecutor pieceTripleExecutorService = PieceTripleThreadPool.executorService;
int longTextActiveCount = longTextExecutorService.getActiveCount();
boolean longTextEmpty = longTextExecutorService.getQueue().isEmpty();
int pieceTripleActiveCount = pieceTripleExecutorService.getActiveCount();
boolean pieceTripleTextEmpty = longTextExecutorService.getQueue().isEmpty();
if ((longTextActiveCount != 0 || !longTextEmpty) || (pieceTripleActiveCount != 0 || !pieceTripleTextEmpty)) {
log.error("[QaAnswerLongTextTripletExtraction-threadPoolExecutorCheck]线程池中有未完成的任务,请稍后再试");
return R.fail("操作过快,请稍后再试");
}
return null;
}
/**
*
*
* @param pieceSentenceIdDto
* @return
*/
private List<NoteRecordSplitSentence> getNoteRecordSplitSentences(PieceSentenceIdDto pieceSentenceIdDto) {
String noteRecordSplitPieceSentenceId = pieceSentenceIdDto.getNoteRecordSplitPieceSentenceId();
List<Long> noteRecordSplitSentenceId = pieceSentenceIdDto.getNoteRecordSplitSentenceId();
List<NoteRecordSplitSentence> recordSplitSentences = new ArrayList<>();
for (Long recordSplitSentenceId : noteRecordSplitSentenceId) {
NoteRecordSplitSentence noteRecordSplitSentence = new NoteRecordSplitSentence();
noteRecordSplitSentence.setId(recordSplitSentenceId);
noteRecordSplitSentence.setPieceRecordSplitId(noteRecordSplitPieceSentenceId);
recordSplitSentences.add(noteRecordSplitSentence);
}
return recordSplitSentences;
}
}

@ -168,16 +168,18 @@ public class ModelCaseServiceImpl extends ServiceImpl<ModelCaseMapper, ModelCase
Long count = super.lambdaQuery().eq(ModelCase::getCaseNo, modelCase.getCaseNo()).count(); Long count = super.lambdaQuery().eq(ModelCase::getCaseNo, modelCase.getCaseNo()).count();
Assert.isTrue(count == 0, "案件编号已存在,请更换案件编号!"); Assert.isTrue(count == 0, "案件编号已存在,请更换案件编号!");
Long num = modelCaseMapper.selectCount(null);
modelCase.setIndexNum(Integer.parseInt(num.toString()) + 1);
i = modelCaseMapper.insert(modelCase);
// 这里需要调用知识库的接口,去保存知识库 // 这里需要调用知识库的接口,去保存知识库
String databaseId = difyApiUtil.createDataset(modelCase.getCaseName(), modelCase.getCaseDetail()); String databaseId = difyApiUtil.createDataset(
StrUtil.join("_", "case", modelCase.getId()), modelCase.getCaseDetail());
if (StrUtil.isEmpty(databaseId)) { if (StrUtil.isEmpty(databaseId)) {
throw new BusinessException("保存知识库失败"); throw new BusinessException("保存知识库失败");
} }
modelCase.setKnowledgeBaseId(databaseId); modelCase.setKnowledgeBaseId(databaseId);
Long num = modelCaseMapper.selectCount(null); modelCaseMapper.updateById(modelCase);
modelCase.setIndexNum(Integer.parseInt(num.toString()) + 1);
i = modelCaseMapper.insert(modelCase);
// 保存案件行为人 // 保存案件行为人
casePersonService.saveCaseActor(modelCase.getId(), modelCaseBase.getCaseActorName(), modelCaseBase.getCaseActorIdCard()); casePersonService.saveCaseActor(modelCase.getId(), modelCaseBase.getCaseActorName(), modelCaseBase.getCaseActorIdCard());

@ -0,0 +1,20 @@
package com.supervision.police.service.impl;
import com.supervision.police.domain.ModelPieceRecordType;
import com.supervision.police.mapper.ModelPieceRecordTypeMapper;
import com.supervision.police.service.ModelPieceRecordTypeService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* <p>
*
* </p>
*
* @author longbao
* @since 2024-12-11
*/
@Service
public class ModelPieceRecordTypeServiceImpl extends ServiceImpl<ModelPieceRecordTypeMapper, ModelPieceRecordType> implements ModelPieceRecordTypeService {
}

@ -41,7 +41,7 @@ public class MroServiceImpl implements MroService {
.like(StrUtil.isNotEmpty(caseProcessReqVO.getCaseName()), ModelCase::getCaseName, caseProcessReqVO.getCaseName()) .like(StrUtil.isNotEmpty(caseProcessReqVO.getCaseName()), ModelCase::getCaseName, caseProcessReqVO.getCaseName())
.in(CollUtil.isNotEmpty(caseProcessReqVO.getIdentifyResult()), ModelCase::getIdentifyResult, caseProcessReqVO.getIdentifyResult()) .in(CollUtil.isNotEmpty(caseProcessReqVO.getIdentifyResult()), ModelCase::getIdentifyResult, caseProcessReqVO.getIdentifyResult())
.in(CollUtil.isNotEmpty(caseProcessReqVO.getAnalysisStatus()), ModelCase::getCaseAnalysisStatus, caseProcessReqVO.getAnalysisStatus()) .in(CollUtil.isNotEmpty(caseProcessReqVO.getAnalysisStatus()), ModelCase::getCaseAnalysisStatus, caseProcessReqVO.getAnalysisStatus())
.orderBy(true, StrUtil.equalsIgnoreCase(caseProcessReqVO.getSort(), "asc"), ModelCase::getCaseAnalysisSuccessTime) .orderBy(true, StrUtil.equalsIgnoreCase(caseProcessReqVO.getSort(), "desc"), ModelCase::getCaseAnalysisSuccessTime)
.page(Page.of(page, size)); .page(Page.of(page, size));
final Set<String> processCaseIds = new HashSet<>(); final Set<String> processCaseIds = new HashSet<>();

@ -0,0 +1,94 @@
package com.supervision.police.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.supervision.police.domain.*;
import com.supervision.police.mapper.NotePiecePromptMapper;
import com.supervision.police.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
/**
* <p>
*
* </p>
*
* @author longbao
* @since 2024-12-12
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class NotePiecePromptServiceImpl extends ServiceImpl<NotePiecePromptMapper, NotePiecePrompt> implements NotePiecePromptService {
private final NotePiecePromptTypeRelService notePiecePromptTypeRelService;
private final ModelPieceRecordTypeService modelPieceRecordTypeService;
@Override
public List<NotePiecePrompt> listPiecePromptBySplitId(NoteRecordSplitPieceSentence noteRecordSplitPieceSentence) {
List<NotePiecePrompt> notePromptList = new ArrayList<>();
// 同语义片段是否为空
if (null == noteRecordSplitPieceSentence) {
log.warn("listPiecePromptBySplitId根据同语义片段id{}未找到切分笔录数据...", noteRecordSplitPieceSentence.getId());
return notePromptList;
}
// 查询同语义片段分类
String recordType = noteRecordSplitPieceSentence.getContentChuckSummary();
if (StrUtil.isBlank(recordType)) {
log.info("listPiecePromptBySplitId:同语义片段:{} 不属于任何分类...", noteRecordSplitPieceSentence.getId());
return notePromptList;
}
// todo 这里是用全部分类还是用当前笔录生成的分类,暂定全部分类
// 获取所有的分类
List<ModelPieceRecordType> allTypeList = modelPieceRecordTypeService
.lambdaQuery()
.select(ModelPieceRecordType::getId, ModelPieceRecordType::getRecordType)
.list();
Map<String, String> allTypeMap = allTypeList.stream().collect(Collectors.toMap(ModelPieceRecordType::getRecordType, ModelPieceRecordType::getId, (k1, k2) -> k1));
// 对切分后的笔录进行遍历
String[] split = recordType.split(";");
for (String typeName : split) {
String typeId = allTypeMap.get(typeName);
if (null == typeId) {
log.info("listPiecePromptBySplitId:同语义片段id:{} typeName:{}未在全局分类中找到数据...", noteRecordSplitPieceSentence.getId(), typeName);
continue;
}
// 根据同语义类型找到所有的提取三元组的提示词
// 一个提示词可能关联多个类型,要进行拆分操作
List<NotePiecePromptTypeRel> promptTypeRelList = notePiecePromptTypeRelService.lambdaQuery().eq(NotePiecePromptTypeRel::getTypeId, typeId).select(NotePiecePromptTypeRel::getPromptId).list();
if (CollUtil.isEmpty(promptTypeRelList)) {
log.info("listPiecePromptBySplitId:同语义片段:{}根据typeId:{},typeName:{},未找到对应的提示词信息...", noteRecordSplitPieceSentence.getId(), typeId, typeName);
continue;
}
List<String> promptIdList = promptTypeRelList.stream().map(NotePiecePromptTypeRel::getPromptId).toList();
List<NotePiecePrompt> list = super.lambdaQuery().in(NotePiecePrompt::getId, promptIdList).list();
if (CollUtil.isEmpty(list)) {
log.info("listPiecePromptBySplitId:根据 promptIdList:{},未找到对应的提示词信息...", CollUtil.join(promptIdList, ","));
continue;
}
notePromptList.addAll(list);
}
return notePromptList;
}
}

@ -0,0 +1,20 @@
package com.supervision.police.service.impl;
import com.supervision.police.domain.NotePiecePromptTypeRel;
import com.supervision.police.mapper.NotePiecePromptTypeRelMapper;
import com.supervision.police.service.NotePiecePromptTypeRelService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* <p>
*
* </p>
*
* @author longbao
* @since 2024-12-12
*/
@Service
public class NotePiecePromptTypeRelServiceImpl extends ServiceImpl<NotePiecePromptTypeRelMapper, NotePiecePromptTypeRel> implements NotePiecePromptTypeRelService {
}

@ -0,0 +1,20 @@
package com.supervision.police.service.impl;
import com.supervision.police.domain.NoteRecordSplitPieceSentence;
import com.supervision.police.mapper.NoteRecordSplitPieceSentenceMapper;
import com.supervision.police.service.NoteRecordSplitPieceSentenceService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* <p>
*
* </p>
*
* @author longbao
* @since 2024-12-11
*/
@Service
public class NoteRecordSplitPieceSentenceServiceImpl extends ServiceImpl<NoteRecordSplitPieceSentenceMapper, NoteRecordSplitPieceSentence> implements NoteRecordSplitPieceSentenceService {
}

@ -0,0 +1,42 @@
package com.supervision.police.service.impl;
import com.supervision.police.domain.NoteRecordSplitSentence;
import com.supervision.police.mapper.NoteRecordSplitSentenceMapper;
import com.supervision.police.service.NoteRecordSplitSentenceService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* <p>
*
* </p>
*
* @author longbao
* @since 2024-12-10
*/
@Service
public class NoteRecordSplitSentenceServiceImpl extends ServiceImpl<NoteRecordSplitSentenceMapper, NoteRecordSplitSentence> implements NoteRecordSplitSentenceService {
/**
*
* @param noteRecordSplitList
*/
@Override
public void saveBatchList(List<NoteRecordSplitSentence> noteRecordSplitList) {
this.baseMapper.saveBatchList(noteRecordSplitList);
}
/**
* llmGenA
* @param ids id
* @param noteRecordSplitPieceSentences id
*/
@Override
public void updateBatchList(List<Long> ids,Long noteRecordSplitPieceSentences){
this.baseMapper.updateBatchList(ids,noteRecordSplitPieceSentences);
}
}

@ -0,0 +1,20 @@
package com.supervision.police.service.impl;
import com.supervision.police.domain.PieceTripleInfo;
import com.supervision.police.mapper.PieceTripleInfoMapper;
import com.supervision.police.service.PieceTripleInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* <p>
*
* </p>
*
* @author longbao
* @since 2024-12-12
*/
@Service
public class PieceTripleInfoServiceImpl extends ServiceImpl<PieceTripleInfoMapper, PieceTripleInfo> implements PieceTripleInfoService {
}

@ -1,12 +1,17 @@
package com.supervision.police.service.impl; package com.supervision.police.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.supervision.common.constant.TaskRecordConstants; import com.supervision.common.constant.TaskRecordConstants;
import com.supervision.police.domain.TaskCaseRecord; import com.supervision.police.domain.TaskCaseRecord;
import com.supervision.police.service.TaskCaseRecordService; import com.supervision.police.service.TaskCaseRecordService;
import com.supervision.police.mapper.TaskCaseRecordMapper; import com.supervision.police.mapper.TaskCaseRecordMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.List; import java.util.List;
/** /**
@ -14,6 +19,7 @@ import java.util.List;
* @description task_case_recordService * @description task_case_recordService
* @createDate 2024-12-25 09:57:08 * @createDate 2024-12-25 09:57:08
*/ */
@Slf4j
@Service @Service
public class TaskCaseRecordServiceImpl extends ServiceImpl<TaskCaseRecordMapper, TaskCaseRecord> public class TaskCaseRecordServiceImpl extends ServiceImpl<TaskCaseRecordMapper, TaskCaseRecord>
implements TaskCaseRecordService{ implements TaskCaseRecordService{
@ -21,6 +27,82 @@ public class TaskCaseRecordServiceImpl extends ServiceImpl<TaskCaseRecordMapper,
public List<TaskCaseRecord> queryProcessingTaskList() { public List<TaskCaseRecord> queryProcessingTaskList() {
return super.lambdaQuery().eq(TaskCaseRecord::getStatus, TaskRecordConstants.TASK_STATUS_PROCESSING).list(); return super.lambdaQuery().eq(TaskCaseRecord::getStatus, TaskRecordConstants.TASK_STATUS_PROCESSING).list();
} }
@Override
public List<TaskCaseRecord> queryByTaskId(String taskId) {
return super.lambdaQuery().eq(TaskCaseRecord::getTaskRecordId, taskId).list();
}
@Override
public String getActuallyStatus(TaskCaseRecord taskCaseRecord) {
String waitingId = taskCaseRecord.getWaitingId();
if (StrUtil.isNotEmpty(waitingId)) {
return TaskRecordConstants.TASK_STATUS_PROCESSING;
}
return TaskRecordConstants.TASK_STATUS_SUCCESS;
}
@Override
public TaskCaseRecord updateStatus(String taskId, String executeId, boolean isSuccess) {
List<TaskCaseRecord> taskCaseRecords = this.queryByTaskId(taskId);
return updateStatus(taskId, executeId, isSuccess, taskCaseRecords);
}
@Override
public TaskCaseRecord updateStatus(String taskId, String executeId, boolean isSuccess, List<TaskCaseRecord> taskCaseRecords) {
// 理论上只能存在一个taskCase信息
List<TaskCaseRecord> taskCaseRecordList = taskCaseRecords.stream()
.filter(taskCaseRecord -> StrUtil.isNotEmpty(taskCaseRecord.getWaitingId()))
.filter(taskCaseRecord -> Arrays.asList(taskCaseRecord.getWaitingId().split(",")).contains(executeId))
.toList();
log.info("updateStatus:任务【{}】当前执行ID【{}】,当前任务案件执行列表长度:{}", taskId, executeId, taskCaseRecordList.size());
TaskCaseRecord taskCaseRecord = CollUtil.getFirst(taskCaseRecordList);
taskCaseRecord.setWaitingId(removeSingle(taskCaseRecord.getWaitingId(), executeId));
if (isSuccess){
taskCaseRecord.setProcessedId(appendSingle(taskCaseRecord.getProcessedId(), executeId));
}else {
taskCaseRecord.setExceptionId(appendSingle(taskCaseRecord.getExceptionId(), executeId));
}
taskCaseRecord.setStatus(this.getActuallyStatus(taskCaseRecord));
// 更新任务案件执行记录
this.updateById(taskCaseRecord);
return taskCaseRecord;
}
@Override
public Boolean updateStatus(String taskId, List<String> oldStatus, String nowStatus) {
return super.lambdaUpdate()
.eq(TaskCaseRecord::getTaskRecordId, taskId)
.in(CollUtil.isNotEmpty(oldStatus),TaskCaseRecord::getStatus, oldStatus)
.set(TaskCaseRecord::getStatus, nowStatus)
.update();
}
@Override
public Boolean removeByTaskId(List<String> taskIds) {
return super.lambdaUpdate().in(TaskCaseRecord::getTaskRecordId, taskIds).remove();
}
private String appendSingle(String longString, String single) {
if (StrUtil.isEmpty(longString)){
return single;
}
return String.join(",", longString, single);
}
private String removeSingle(String longString, String single) {
if (StrUtil.isEmpty(longString)){
return longString;
}
String[] split = longString.split(",");
split = ArrayUtil.remove(split, ArrayUtil.indexOf(split, single));
return ArrayUtil.join(split, ",");
}
} }

@ -10,6 +10,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.supervision.common.constant.TaskRecordConstants; import com.supervision.common.constant.TaskRecordConstants;
import com.supervision.constant.DataStatus; import com.supervision.constant.DataStatus;
import com.supervision.neo4j.service.Neo4jService;
import com.supervision.police.domain.*; import com.supervision.police.domain.*;
import com.supervision.police.dto.TaskInfoDTO; import com.supervision.police.dto.TaskInfoDTO;
import com.supervision.police.dto.taskRecord.TaskRecordVo; import com.supervision.police.dto.taskRecord.TaskRecordVo;
@ -18,6 +19,7 @@ import com.supervision.police.service.*;
import com.supervision.police.vo.TaskInfoReqVO; import com.supervision.police.vo.TaskInfoReqVO;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -41,15 +43,25 @@ import static com.supervision.common.constant.XxlJobConstants.TASK_NAME_PROMPT_E
@Slf4j @Slf4j
@Service @Service
@RequiredArgsConstructor @RequiredArgsConstructor
public class TaskRecordServiceImpl extends ServiceImpl<TaskRecordMapper, TaskRecord> public class TaskRecordServiceImpl extends ServiceImpl<TaskRecordMapper, TaskRecord> implements TaskRecordService {
implements TaskRecordService {
final TaskCaseRecordService taskCaseRecordService; private final TaskCaseRecordService taskCaseRecordService;
final ModelCaseService modelCaseService;
final NoteRecordService noteRecordService; private final ModelCaseService modelCaseService;
final CaseEvidenceService caseEvidenceService;
final NotePromptService notePromptService; private final NoteRecordService noteRecordService;
final XxlJobService xxlJobService;
private final CaseEvidenceService caseEvidenceService;
private final NotePromptService notePromptService;
private final XxlJobService xxlJobService;
private final ExtractTripleInfoService extractTripleInfoService;
private final Neo4jService neo4jService;
private final TripleInfoService tripleInfoService;
@Override @Override
public void executePromptExtractTask(TaskRecordVo taskRecordVo) { public void executePromptExtractTask(TaskRecordVo taskRecordVo) {
@ -57,20 +69,55 @@ public class TaskRecordServiceImpl extends ServiceImpl<TaskRecordMapper, TaskRec
TaskRecord taskRecord = new TaskRecord(); TaskRecord taskRecord = new TaskRecord();
BeanUtils.copyProperties(taskRecordVo, taskRecord); BeanUtils.copyProperties(taskRecordVo, taskRecord);
super.save(taskRecord); super.save(taskRecord);
try {
NotePrompt prompt = notePromptService.getById(taskRecordVo.getPromptId()); NotePrompt prompt = notePromptService.getById(taskRecordVo.getPromptId());
List<ModelCase> modelCases; List<ModelCase> modelCases = this.getModelCases(taskRecordVo, taskRecord);
LambdaQueryWrapper<ModelCase> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(ModelCase::getDataStatus, DataStatus.AVAILABLE.getCode());
//根据任务类型查找案件
if (TASK_TYPE_SPECIFIED_CASE.equals(taskRecord.getType())) {
queryWrapper.in(ModelCase::getId, List.of(taskRecordVo.getCaseId().split(",")));
} else if (TASK_TYPE_SPECIFIED_RECORD.equals(taskRecord.getType()) || TASK_TYPE_SPECIFIED_EVIDENCE.equals(taskRecord.getType())) {
queryWrapper.eq(ModelCase::getId, taskRecord.getCaseId());
}
modelCases = modelCaseService.list(queryWrapper);
if (!CollUtil.isEmpty(modelCases)) { if (!CollUtil.isEmpty(modelCases)) {
for (ModelCase modelCase : modelCases) { for (ModelCase modelCase : modelCases) {
String caseId = modelCase.getId(); String caseId = modelCase.getId();
List<String> ids = this.getIds(taskRecordVo, taskRecord, prompt, caseId);
if (!ids.isEmpty()) {
this.invokeXxlJob(taskRecordVo, taskRecord, caseId, ids);
} else {
log.info("案件【{}】没有笔录", caseId);
}
}
} else {
log.info("查无案件");
}
} catch (Exception e) {
taskRecord.setStatus(TASK_STATUS_FAIL);
super.updateById(taskRecord);
log.error("任务执行失败", e);
}
}
@Override
public void graphExtract(NotePrompt prompt, String caseId, String executeId) {
List<TripleInfo> tripleInfos = extractTripleInfoService.extractTripleInfo(prompt, caseId, executeId);
for (TripleInfo tripleInfo : tripleInfos) {
neo4jService.saveTripleInfo(tripleInfo);
}
if (CollUtil.isNotEmpty(tripleInfos)) {
tripleInfoService.updateNeo4jFlag(tripleInfos.stream().map(TripleInfo::getId).toList(), "1");
}
}
@Override
public void structureExtract(String evidenceId) {
caseEvidenceService.evidenceAnalysis(evidenceId);
}
/**
* ID
*
* @param taskRecordVo
* @param taskRecord
* @param prompt
* @param caseId ID
* @return ID
*/
private @NotNull List<String> getIds(TaskRecordVo taskRecordVo, TaskRecord taskRecord, NotePrompt prompt, String caseId) {
//查出当前案件相关笔录或证据 //查出当前案件相关笔录或证据
List<String> ids = new ArrayList<>(); List<String> ids = new ArrayList<>();
//如果类型为指定笔录或证据直接取传入的id //如果类型为指定笔录或证据直接取传入的id
@ -86,7 +133,18 @@ public class TaskRecordServiceImpl extends ServiceImpl<TaskRecordMapper, TaskRec
ids = caseEvidenceService.lambdaQuery().eq(CaseEvidence::getCaseId, caseId).list().stream().map(CaseEvidence::getId).toList(); ids = caseEvidenceService.lambdaQuery().eq(CaseEvidence::getCaseId, caseId).list().stream().map(CaseEvidence::getId).toList();
} }
} }
if (!ids.isEmpty()) { return ids;
}
/**
* xxl-job
*
* @param taskRecordVo
* @param taskRecord
* @param caseId ID
* @param ids ID
*/
private void invokeXxlJob(TaskRecordVo taskRecordVo, TaskRecord taskRecord, String caseId, List<String> ids) {
TaskCaseRecord taskCaseRecord = new TaskCaseRecord(); TaskCaseRecord taskCaseRecord = new TaskCaseRecord();
taskCaseRecord.setTaskRecordId(taskRecord.getId()); taskCaseRecord.setTaskRecordId(taskRecord.getId());
taskCaseRecord.setCaseId(caseId); taskCaseRecord.setCaseId(caseId);
@ -102,17 +160,33 @@ public class TaskRecordServiceImpl extends ServiceImpl<TaskRecordMapper, TaskRec
//map转String作为参数 //map转String作为参数
xxlJobService.executeTaskByJobHandler(TASK_NAME_PROMPT_EXTRACT_TASK, new JSONObject(params).toString()); xxlJobService.executeTaskByJobHandler(TASK_NAME_PROMPT_EXTRACT_TASK, new JSONObject(params).toString());
} }
} else {
log.info("案件【{}】没有笔录", caseId);
}
} }
} else {
log.info("没有找到案件"); /**
*
*
* @param taskRecordVo
* @param taskRecord
* @return
*/
private List<ModelCase> getModelCases(TaskRecordVo taskRecordVo, TaskRecord taskRecord) {
List<ModelCase> modelCases;
LambdaQueryWrapper<ModelCase> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(ModelCase::getDataStatus, DataStatus.AVAILABLE.getCode());
//根据任务类型查找案件
if (TASK_TYPE_SPECIFIED_CASE.equals(taskRecord.getType())) {
queryWrapper.in(ModelCase::getId, List.of(taskRecordVo.getCaseId().split(",")));
} else if (TASK_TYPE_SPECIFIED_RECORD.equals(taskRecord.getType()) || TASK_TYPE_SPECIFIED_EVIDENCE.equals(taskRecord.getType())) {
queryWrapper.eq(ModelCase::getId, taskRecord.getCaseId());
} }
modelCases = modelCaseService.list(queryWrapper);
return modelCases;
} }
@Override @Override
public IPage<TaskInfoDTO> queryTaskList(TaskInfoReqVO taskInfo, Integer page, Integer size) { public IPage<TaskInfoDTO> queryTaskList(TaskInfoReqVO taskInfo, Integer page, Integer size) {
taskInfo.checkSorted();
return super.getBaseMapper().queryTaskList(taskInfo, Page.of(page, size)); return super.getBaseMapper().queryTaskList(taskInfo, Page.of(page, size));
} }
@ -162,7 +236,63 @@ public class TaskRecordServiceImpl extends ServiceImpl<TaskRecordMapper, TaskRec
Assert.isTrue(CollUtil.isEmpty(list), "删除任务失败,存在不可删除的任务"); Assert.isTrue(CollUtil.isEmpty(list), "删除任务失败,存在不可删除的任务");
super.removeBatchByIds(taskIds); super.removeBatchByIds(taskIds);
// 删除task_case中的关联数据
Boolean success = taskCaseRecordService.removeByTaskId(taskIds);
log.info("deleteTask:删除任务成功删除task_case中的关联数据:{}", success);
}
@Override
@Transactional(transactionManager = "dataSourceTransactionManager", rollbackFor = Exception.class)
public void completeTask(String taskId, String executeId, boolean isSuccess) {
if (StrUtil.isEmpty(taskId)) {
log.info("completeTask:任务ID为空");
return;
}
if (StrUtil.isEmpty(executeId)) {
log.info("completeTask:执行ID为空");
return;
}
TaskRecord taskRecord = super.getById(taskId);
if (null == taskRecord) {
log.info("completeTask:任务不存在任务ID:【{}】", taskId);
return;
}
TaskCaseRecord taskCaseRecord = taskCaseRecordService.updateStatus(taskId, executeId, isSuccess);
log.info("completeTask:任务ID:【{}】执行ID:【{}】,任务状态:【{}】", taskId, executeId, taskCaseRecord.getStatus());
// 校验总体任务是否是取消中
if (StrUtil.equalsAny(taskRecord.getStatus(), TASK_STATUS_CANCELLING, TASK_STATUS_CANCELED)) {
log.info("completeTask:任务状态为取消中,任务状态更新即将更新为【{}】任务ID: 【{}】", taskId, taskRecord.getStatus());
Boolean success = taskCaseRecordService.updateStatus(taskId, List.of(TASK_STATUS_WAITING, TASK_STATUS_PROCESSING), TASK_STATUS_CANCELED);
log.info("completeTask:任务状态更新完成,task_case数据任务状态【{}】变动任务ID: 【{}】", taskId, success ? "产生" : "无");
taskRecord.setStatus(TASK_STATUS_CANCELED);
this.updateById(taskRecord);
return;
} }
if (StrUtil.equalsAny(taskRecord.getStatus(), TASK_STATUS_WAITING, TASK_STATUS_PROCESSING)) {
List<TaskCaseRecord> taskCaseRecords = taskCaseRecordService.queryByTaskId(taskId);
String taskStatus = this.determineStatus(taskCaseRecords);
log.info("completeTask:任务ID:【{}】,初始任务状态:【{}】,计算后任务状态:【{}】", taskId, taskCaseRecord.getStatus(), taskStatus);
if (!StrUtil.equals(taskStatus, taskRecord.getStatus())) {
taskRecord.setStatus(taskStatus);
super.updateById(taskRecord);
}
}
}
@Override
public String determineStatus(List<TaskCaseRecord> taskCaseRecords) {
if (CollUtil.isEmpty(taskCaseRecords)) {
return TASK_STATUS_SUCCESS;
}
// 所有任务状态都是终止状态,则任务状态为成功
boolean finished = taskCaseRecords.stream().allMatch(taskCaseRecord ->
StrUtil.equalsAny(taskCaseRecord.getStatus(), TASK_STATUS_CANCELED, TASK_STATUS_SUCCESS, TASK_STATUS_FAIL));
return finished ? TASK_STATUS_SUCCESS : TASK_STATUS_PROCESSING;
}
} }

@ -32,10 +32,7 @@ public class TripleInfoServiceImpl extends ServiceImpl<TripleInfoMapper, TripleI
.eq(TripleInfo::getStartNodeType, tripleInfo.getStartNodeType()) .eq(TripleInfo::getStartNodeType, tripleInfo.getStartNodeType())
.eq(TripleInfo::getEndNodeType, tripleInfo.getEndNodeType()) .eq(TripleInfo::getEndNodeType, tripleInfo.getEndNodeType())
.eq(TripleInfo::getRecordSplitId, tripleInfo.getRecordSplitId()).one(); .eq(TripleInfo::getRecordSplitId, tripleInfo.getRecordSplitId()).one();
if (null != one) { if (null == one) {
tripleInfo.setId(one.getId());
super.updateById(tripleInfo);
} else {
super.save(tripleInfo); super.save(tripleInfo);
} }
} }

@ -1,7 +1,10 @@
package com.supervision.police.vo; package com.supervision.police.vo;
import cn.hutool.core.util.StrUtil;
import lombok.Data; import lombok.Data;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Data @Data
public class TaskInfoReqVO { public class TaskInfoReqVO {
@ -26,4 +29,18 @@ public class TaskInfoReqVO {
* *
*/ */
private String cancelTimeSorted = "desc"; private String cancelTimeSorted = "desc";
/**
* sql
*/
public void checkSorted(){
if (!StrUtil.equalsAnyIgnoreCase(createTimeSorted, "desc", "asc")){
log.warn("checkSorted:createTimeSorted参数校验失败输入值:{},已重置为默认值:{}", createTimeSorted,"desc");
this.cancelTimeSorted = "desc";
}
if (!StrUtil.equalsAnyIgnoreCase(cancelTimeSorted, "desc", "asc")){
log.warn("checkSorted:cancelTimeSorted参数校验失败输入值:{},已重置为默认值:{}", cancelTimeSorted,"desc");
this.cancelTimeSorted = "desc";
}
}
} }

@ -0,0 +1,178 @@
package com.supervision.thread;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator;
import com.supervision.constant.PromptsEnum;
import com.supervision.police.domain.*;
import com.supervision.police.dto.LongTextSingleSentenceSummaryDto;
import com.supervision.police.dto.PieceSentenceIdDto;
import com.supervision.utils.UserUtil;
import lombok.extern.slf4j.Slf4j;
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.util.StopWatch;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.function.Consumer;
/**
* <p>
*
* </p>
*
* @author longbao
* @since 2024-12-12
*/
@Slf4j
public class LongTextTask implements Callable<Map<String, Object>> {
private final LongTextSingleSentenceSummaryDto longTextSingleSentenceSummaryDto;
private final OllamaChatClient chatClient;
private final Consumer<Map<String, Object>> consumer;
public LongTextTask(OllamaChatClient chatClient, LongTextSingleSentenceSummaryDto longTextSingleSentenceSummaryDto, Consumer<Map<String, Object>> consumer) {
this.longTextSingleSentenceSummaryDto = longTextSingleSentenceSummaryDto;
this.chatClient = chatClient;
this.consumer = consumer;
}
@Override
public Map<String, Object> call() throws Exception {
return pieceSentenceNormal(longTextSingleSentenceSummaryDto);
}
/**
*
*
* @param longTextSingleSentenceSummaryDto
*/
private Map<String, Object> pieceSentenceNormal(LongTextSingleSentenceSummaryDto longTextSingleSentenceSummaryDto) throws Exception {
log.info("[QaAnswerLongTextTripletExtraction-Pool-PieceSentenceNormal]开始同语义归纳方法,当前线程是:{}", Thread.currentThread().getName());
Map<String, Object> map = new HashMap<>();
// 同语义集合
List<NoteRecordSplitPieceSentence> recordSplitPieceSentences = new ArrayList<>();
// 同语义使用单句id集合
List<PieceSentenceIdDto> noteRecordSplitPieceSentenceBySingle = new ArrayList<>();
// 笔录片段id
String noteRecordSplitId = longTextSingleSentenceSummaryDto.getNoteRecordSplitId();
// 单语句集合
List<NoteRecordSplitSentence> noteRecordSplitSentences = longTextSingleSentenceSummaryDto.getNoteRecordSplitSentences();
int noteRecordSplitSentencesSize = noteRecordSplitSentences.size();
// 获取末尾单句 N+1
NoteRecordSplitSentence endCombinedSentence = noteRecordSplitSentences.get(noteRecordSplitSentencesSize - 1);
Long endCombinedSentenceId = endCombinedSentence.getId();
ConcurrentLinkedDeque<Long> noteRecordSplitPieceSentenceDeque = new ConcurrentLinkedDeque<>();
noteRecordSplitPieceSentenceDeque.add(endCombinedSentenceId);
ConcurrentLinkedDeque<String> endCombinedSentenceDeque = new ConcurrentLinkedDeque<>();
endCombinedSentenceDeque.addLast(endCombinedSentence.getAnswer());
// 遍历单句集合
for (int i = noteRecordSplitSentencesSize - 2; i >= 0; i--) {
PieceSentenceIdDto pieceSentenceIdDto = new PieceSentenceIdDto();
// 获取第N句
NoteRecordSplitSentence currentSentence = noteRecordSplitSentences.get(i);
Long currentSentenceId = currentSentence.getId();
String currentSentenceAnswer = currentSentence.getAnswer();
// 对比句子语义
boolean inductionFlag = chatAiLongTextHomoSemanticInduction(String.valueOf(endCombinedSentenceDeque), currentSentenceAnswer);
if (inductionFlag) {
endCombinedSentenceDeque.addFirst(currentSentenceAnswer);
noteRecordSplitPieceSentenceDeque.addFirst(currentSentenceId);
} else {
NoteRecordSplitPieceSentence pieceSentence = setNotePieceRecordSentence(noteRecordSplitId, endCombinedSentenceDeque);
endCombinedSentenceDeque.remove();
endCombinedSentenceDeque.addLast(currentSentenceAnswer);
List<Long> longList = noteRecordSplitPieceSentenceDeque.stream().toList();
noteRecordSplitPieceSentenceDeque.remove();
noteRecordSplitPieceSentenceDeque.addLast(currentSentenceId);
pieceSentenceIdDto.setNoteRecordSplitPieceSentenceId(pieceSentence.getId());
pieceSentenceIdDto.setNoteRecordSplitSentenceId(longList);
recordSplitPieceSentences.add(pieceSentence);
noteRecordSplitPieceSentenceBySingle.add(pieceSentenceIdDto);
}
}
NoteRecordSplitPieceSentence pieceSentence = setNotePieceRecordSentence(noteRecordSplitId, endCombinedSentenceDeque);
recordSplitPieceSentences.add(pieceSentence);
noteRecordSplitPieceSentenceBySingle.add(new PieceSentenceIdDto(pieceSentence.getId(), noteRecordSplitPieceSentenceDeque.stream().toList()));
map.put("recordSplitPieceSentences", recordSplitPieceSentences);
map.put("noteRecordSplitPieceSentenceBySingle", noteRecordSplitPieceSentenceBySingle);
consumer.accept(map);
log.info("[QaAnswerLongTextTripletExtraction-Pool-PieceSentenceNormal]同语义归纳结束,当前线程是:{}", Thread.currentThread().getName());
return map;
}
/**
* @param encCombinedSentence N+1
* @param currentSentence N
* @return
*/
private boolean chatAiLongTextHomoSemanticInduction(String encCombinedSentence, String currentSentence) {
StopWatch stopWatch = new StopWatch();
// 分析同语义集合
stopWatch.start();
HashMap<String, Object> paramMap = new HashMap<>();
paramMap.put("encCombinedSentence", encCombinedSentence);
paramMap.put("currentSentence", currentSentence);
String format = StrUtil.format(PromptsEnum.LONG_TEXT_SINGLE_STATEMENT_WITH_SEMANTIC_JUDGMENT_PROMPT_WORD.getContent(), paramMap);
ChatResponse call = chatClient.call(new Prompt(new UserMessage(format)));
stopWatch.stop();
String content = call.getResult().getOutput().getContent();
JSONObject jsonObject = JSON.parseObject(content);
boolean result = (boolean) jsonObject.get("result");
return result;
}
/**
*
*
* @param noteRecordSplitId id
* @param endSentenceDequeStringDeque
* @return
*/
public NoteRecordSplitPieceSentence setNotePieceRecordSentence(String noteRecordSplitId, ConcurrentLinkedDeque<String> endSentenceDequeStringDeque) {
StringBuilder endSentenceDequeStringBuilder = new StringBuilder();
for (String endSentenceDeque : endSentenceDequeStringDeque) {
endSentenceDequeStringBuilder.append(endSentenceDeque);
}
String endSentenceDequeStringBuilderString = String.valueOf(endSentenceDequeStringBuilder);
String noteRecordSplitPieceSentenceId = DefaultIdentifierGenerator.getInstance().nextId(null).toString();
NoteRecordSplitPieceSentence noteRecordSplitPieceSentence = new NoteRecordSplitPieceSentence();
noteRecordSplitPieceSentence.setId(noteRecordSplitPieceSentenceId);
noteRecordSplitPieceSentence.setCreateUserId(UserUtil.getUser().getId());
noteRecordSplitPieceSentence.setUpdateUserId(UserUtil.getUser().getId());
noteRecordSplitPieceSentence.setRecordSplitId(noteRecordSplitId);
noteRecordSplitPieceSentence.setContentChuck(endSentenceDequeStringBuilderString);
return noteRecordSplitPieceSentence;
}
}

@ -0,0 +1,30 @@
package com.supervision.thread;
import cn.hutool.core.thread.ThreadUtil;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* 线
*/
@Slf4j
@Component
public class LongtextThreadPool {
@Value("${fu-hsi-config.thread-pool.type.core:2}")
private int core;
public static ThreadPoolExecutor executorService;
@PostConstruct
public void init() {
log.info("LongtextThreadPool线程池初始化。线程数{}", core);
executorService = new ThreadPoolExecutor(1, 10000, 100L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());
}
}

@ -0,0 +1,154 @@
package com.supervision.thread;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator;
import com.supervision.police.domain.*;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
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.util.StopWatch;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.Callable;
/**
* <p>
*
* </p>
*
* @author longbao
* @since 2024-12-12
*/
@Slf4j
public class PieceTripleExtractTask implements Callable<PieceTripleInfo> {
private static final String HEAD_ENTITY_TYPE_ACTOR = "行为人";
private final NotePiecePrompt notePiecePrompt;
private final NoteRecordSplitPieceSentence noteRecordSplitPieceSentence;
private final CasePerson mainActor;
private final OllamaChatClient chatClient;
public PieceTripleExtractTask(OllamaChatClient chatClient,
CasePerson mainActor,
NotePiecePrompt notePiecePrompt,
NoteRecordSplitPieceSentence noteRecordSplitPieceSentence) {
this.chatClient = chatClient;
this.mainActor = mainActor;
this.notePiecePrompt = notePiecePrompt;
this.noteRecordSplitPieceSentence = noteRecordSplitPieceSentence;
}
/**
*
*
* @return
*/
@Override
public PieceTripleInfo call() throws Exception {
TripleRecord tripleRecord = chat4Triple(mainActor, notePiecePrompt, noteRecordSplitPieceSentence);
// 获取从提示词中提取到的三元组信息
TripleExtractResult extractResult = JSONUtil.toBean(tripleRecord.answer, TripleExtractResult.class);
if (ObjectUtil.isEmpty(extractResult) || CollUtil.isEmpty(extractResult.getResult())) {
log.warn("[QaAnswerLongTextTripletExtraction-call]提取三元组信息为空,忽略.提取的内容为:{}", tripleRecord.answer);
return null;
}
for (TripleExtractNode tripleExtractNode : extractResult.getResult()) {
TripleEntity headEntity = tripleExtractNode.getHeadEntity();
TripleEntity tailEntity = tripleExtractNode.getTailEntity();
String relation = tripleExtractNode.getRelation();
if (StrUtil.hasEmpty(headEntity.getName(), relation, tailEntity.getName())) {
log.warn("[QaAnswerLongTextTripletExtraction-call]提取三元组信息出现空值,忽略,主体:{},关系:{},客体:{}", headEntity.getName(), relation, tailEntity.getName());
return null;
}
// 构建三元组信息
PieceTripleInfo tripleInfo = new PieceTripleInfo();
tripleInfo.setId(DefaultIdentifierGenerator.getInstance().nextId(null).toString());
tripleInfo.setStartNode(headEntity.getName());
tripleInfo.setEndNode(tailEntity.getName());
tripleInfo.setRelation(relation);
tripleInfo.setPieceRecordSplitId(noteRecordSplitPieceSentence.getId());
tripleInfo.setRecordSplitId(noteRecordSplitPieceSentence.getRecordSplitId());
tripleInfo.setSubmitPrompt(tripleRecord.question);
tripleInfo.setStartNodeType(notePiecePrompt.getStartEntityType());
tripleInfo.setEndNodeType(notePiecePrompt.getEndEntityType());
return tripleInfo;
}
return null;
}
/**
* ollama
*
* @param mainActor
* @param prompt
* @param noteRecordSplitPieceSentence
* @return
*/
private TripleRecord chat4Triple(CasePerson mainActor, NotePiecePrompt prompt, NoteRecordSplitPieceSentence noteRecordSplitPieceSentence) {
String pieceSentenceContentChuck = noteRecordSplitPieceSentence.getContentChuck();
StopWatch stopWatch = new StopWatch();
// 分析三元组
stopWatch.start();
HashMap<String, String> paramMap = new HashMap<>();
paramMap.put("headEntityType", prompt.getStartEntityType());
paramMap.put("relation", prompt.getRelType());
paramMap.put("tailEntityType", prompt.getEndEntityType());
paramMap.put("contentChuckSummary", pieceSentenceContentChuck);
log.info("[QaAnswerLongTextTripletExtraction-call-chat4Triple]开始尝试提取三元组:{}-{}-{},mainActor:{}", prompt.getStartEntityType(), prompt.getRelType(), prompt.getEndEntityType(), mainActor == null ? "" : mainActor.getName());
if (mainActor != null && HEAD_ENTITY_TYPE_ACTOR.equals(prompt.getStartEntityType())) {
paramMap.put("requirement", "当前案件的行为人是" + mainActor.getName() + ",只尝试提取" + mainActor.getName() + "为头结点的三元组。");
} else {
paramMap.put("requirement", "");
}
String format = StrUtil.format(prompt.getPrompt(), paramMap);
log.info("[QaAnswerLongTextTripletExtraction-call-chat4Triple]三元组提取提示词:{}", format);
ChatResponse call = chatClient.call(new Prompt(new UserMessage(format)));
stopWatch.stop();
String content = call.getResult().getOutput().getContent();
log.info("问题:{}耗时:{},三元组提取结果是:{}", pieceSentenceContentChuck, stopWatch.getTotalTimeSeconds(), content);
return new TripleRecord(format, content);
}
record TripleRecord(String question, String answer) {
}
@Data
public static class TripleExtractResult {
private List<TripleExtractNode> result;
}
@Data
public static class TripleExtractNode {
private TripleEntity headEntity;
private String relation;
private TripleEntity tailEntity;
}
@Data
public static class TripleEntity {
private String name;
private String type;
}
}

@ -0,0 +1,30 @@
package com.supervision.thread;
import cn.hutool.core.thread.ThreadUtil;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* 线
*/
@Slf4j
@Component
public class PieceTripleThreadPool {
@Value("${fu-hsi-config.thread-pool.type.core:2}")
private int core;
public static ThreadPoolExecutor executorService;
@PostConstruct
public void init() {
log.info("LongtextThreadPool线程池初始化。线程数{}", core);
executorService = new ThreadPoolExecutor(1, 10000, 100L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());
}
}

@ -4,9 +4,9 @@ spring:
ai: ai:
# 文档地址 https://docs.spring.io/spring-ai/reference/1.0-SNAPSHOT/api/chat/ollama-chat.html # 文档地址 https://docs.spring.io/spring-ai/reference/1.0-SNAPSHOT/api/chat/ollama-chat.html
ollama: ollama:
# base-url: http://113.128.242.110:11434 base-url: http://113.128.242.110:11434
# base-url: http://112.81.86.50:11434 # base-url: http://112.81.86.50:11434
base-url: http://192.168.10.70:11434 # base-url: http://192.168.10.70:11434
chat: chat:
enabled: true enabled: true
options: options:
@ -26,10 +26,10 @@ spring:
type: com.alibaba.druid.pool.DruidDataSource type: com.alibaba.druid.pool.DruidDataSource
druid: druid:
driver-class-name: com.mysql.cj.jdbc.Driver driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.10.137:3306/nx_llm?useUnicode=true&characterEncoding=utf-8&useSSL=true&nullCatalogMeansCurrent=true&serverTimezone=GMT%2B8 # url: jdbc:mysql://192.168.10.137:3306/nx_llm?useUnicode=true&characterEncoding=utf-8&useSSL=true&nullCatalogMeansCurrent=true&serverTimezone=GMT%2B8
#url: jdbc:mysql://113.128.242.110:3306/nx_llm?useUnicode=true&characterEncoding=utf-8&useSSL=true&nullCatalogMeansCurrent=true&serverTimezone=GMT%2B8 url: jdbc:mysql://192.168.1.101:42415/nx_llm?useUnicode=true&characterEncoding=utf-8&useSSL=true&nullCatalogMeansCurrent=true&serverTimezone=GMT%2B8
username: root username: root
password: '123456' password: 'llm@984573~!eda'
initial-size: 5 # 初始化大小 initial-size: 5 # 初始化大小
min-idle: 10 # 最小连接数 min-idle: 10 # 最小连接数
max-active: 20 # 最大连接数 max-active: 20 # 最大连接数
@ -56,15 +56,15 @@ spring:
neo4j: neo4j:
database: neo4j database: neo4j
neo4j: neo4j:
uri: bolt://192.168.10.137:7687 uri: bolt://192.168.1.101:42418
authentication: authentication:
username: neo4j username: neo4j
password: 123456 password: llm@984573~!eda
minio: minio:
endpoint: http:192.168.10.137:9002 endpoint: http:192.168.1.101:42417
accessKey: admin accessKey: admin
secretKey: 12345678 secretKey: llm@984573~!eda
bucketName: nxfuhsi bucketName: nxfuhsi
logging: logging:
@ -72,10 +72,10 @@ logging:
org.springframework.ai: TRACE org.springframework.ai: TRACE
langChain-chat: langChain-chat:
url: http://113.128.242.110:7861 url: http://192.168.1.101:7861
ocr: ocr:
url: http://192.168.10.137:8866/ url: http://192.168.1.101:8866/
pool: pool:
max-size: 20 max-size: 20
@ -84,7 +84,7 @@ xxl:
admin: admin:
username: admin username: admin
password: 123456 password: 123456
addresses: http://192.168.10.137:8080/xxl-job-admin addresses: http://192.168.1.101:8081/xxl-job-admin
accessToken: default_token accessToken: default_token
executor: executor:
address: address:

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.supervision.police.mapper.ModelPieceRecordTypeMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.supervision.police.domain.ModelPieceRecordType">
<id column="id" property="id" />
<result column="record_type" property="recordType" />
<result column="create_user_id" property="createUserId" />
<result column="create_time" property="createTime" />
<result column="update_user_id" property="updateUserId" />
<result column="update_time" property="updateTime" />
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id, record_type, create_user_id, create_time, update_user_id, update_time
</sql>
</mapper>

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.supervision.police.mapper.NotePiecePromptMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.supervision.police.domain.NotePiecePrompt">
<id column="id" property="id"/>
<result column="prompt" property="prompt"/>
<result column="start_entity_type" property="startEntityType"/>
<result column="start_entity_template" property="startEntityTemplate"/>
<result column="rel_type" property="relType"/>
<result column="rel_template" property="relTemplate"/>
<result column="name" property="name"/>
<result column="end_entity_type" property="endEntityType"/>
<result column="end_entity_template" property="endEntityTemplate"/>
<result column="create_user_id" property="createUserId"/>
<result column="create_time" property="createTime"/>
<result column="update_user_id" property="updateUserId"/>
<result column="update_time" property="updateTime"/>
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id
, prompt, start_entity_type, start_entity_template, rel_type, rel_template,name, end_entity_type, end_entity_template, create_user_id, create_time, update_user_id, update_time
</sql>
</mapper>

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.supervision.police.mapper.NotePiecePromptTypeRelMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.supervision.police.domain.NotePiecePromptTypeRel">
<id column="id" property="id" />
<result column="prompt_id" property="promptId" />
<result column="type_id" property="typeId" />
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id, prompt_id, type_id
</sql>
</mapper>

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.supervision.police.mapper.NoteRecordSplitPieceSentenceMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.supervision.police.domain.NoteRecordSplitPieceSentence">
<id column="id" property="id" />
<result column="record_split_id" property="recordSplitId" />
<!-- <result column="content_chuck" property="contentChuck" jdbcType="ARRAY"-->
<!-- typeHandler="com.supervision.handler.StringListTypeHandler"/>-->
<result column="content_chuck" property="contentChuck" />
<result column="content_chuck_summary" property="contentChuckSummary" />
<result column="extend" property="extend" />
<result column="create_user_id" property="createUserId" />
<result column="create_time" property="createTime" />
<result column="update_user_id" property="updateUserId" />
<result column="update_time" property="updateTime" />
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id, record_split_id, content_chuck, content_chuck_summary, extend, create_user_id, create_time, update_user_id, update_time
</sql>
</mapper>

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.supervision.police.mapper.NoteRecordSplitSentenceMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.supervision.police.domain.NoteRecordSplitSentence">
<id column="id" property="id"/>
<result column="record_split_id" property="recordSplitId"/>
<result column="piece_record_split_id" property="pieceRecordSplitId"/>
<result column="answer" property="answer"/>
<result column="llm_gen_a" property="llmGenA"/>
<result column="extend_one" property="extendOne"/>
<result column="create_user_id" property="createUserId"/>
<result column="create_time" property="createTime"/>
<result column="update_user_id" property="updateUserId"/>
<result column="update_time" property="updateTime"/>
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id
, record_split_id, piece_record_split_id, answer, llm_gen_a, extend_one, create_user_id, create_time, update_user_id, update_time
</sql>
<insert id="saveBatchList" parameterType="java.util.List">
insert into note_record_split_sentence (record_split_id, answer,create_user_id,update_user_id)
values
<foreach collection="noteRecordSplitList" item="entity" index="index" separator=",">
(
#{entity.recordSplitId}, #{entity.answer},#{entity.createUserId},#{entity.updateUserId}
)
</foreach>
</insert>
<update id="updateBatchList" parameterType="map">
UPDATE note_record_split_sentence
SET piece_record_split_id = #{noteRecordSplitPieceSentences}
WHERE id IN
<foreach item="id" index="index" collection="ids" open="(" separator="," close=")">
#{id}
</foreach>
</update>
</mapper>

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.supervision.police.mapper.PieceTripleInfoMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.supervision.police.domain.PieceTripleInfo">
<id column="id" property="id" />
<result column="start_node" property="startNode" />
<result column="end_node" property="endNode" />
<result column="relation" property="relation" />
<result column="record_split_id" property="recordSplitId" />
<result column="piece_record_split_id" property="pieceRecordSplitId" />
<result column="submit_prompt" property="submitPrompt" />
<result column="add_neo4j" property="addNeo4j" />
<result column="create_time" property="createTime" />
<result column="start_node_graph_id" property="startNodeGraphId" />
<result column="rel_graph_id" property="relGraphId" />
<result column="end_node_graph_id" property="endNodeGraphId" />
<result column="start_node_type" property="startNodeType" />
<result column="end_node_type" property="endNodeType" />
<result column="create_user_id" property="createUserId" />
<result column="update_user_id" property="updateUserId" />
<result column="update_time" property="updateTime" />
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id, start_node, end_node, relation, record_split_id, piece_record_split_id, submit_prompt, add_neo4j, create_time, start_node_graph_id, rel_graph_id, end_node_graph_id, start_node_type, end_node_type, create_user_id, update_user_id, update_time
</sql>
</mapper>

@ -40,13 +40,13 @@
left join model_case c on t.case_id = c.id left join model_case c on t.case_id = c.id
left join case_person p on t.create_user_id = p.id left join case_person p on t.create_user_id = p.id
<where> <where>
<if test="caseName != null and caseName != ''"> <if test="taskInfo.caseName != null and taskInfo.caseName != ''">
and c.case_name like concat('%',#{taskInfo.caseName},'%') and c.case_name like concat('%',#{taskInfo.caseName},'%')
</if> </if>
<if test="taskStatus != null and taskStatus != ''"> <if test="taskInfo.taskStatus != null and taskInfo.taskStatus != ''">
and t.status = #{taskInfo.taskStatus} and t.status = #{taskInfo.taskStatus}
</if> </if>
</where> </where>
order by c.create_time #{taskInfo.createTimeSorted} ,t.create_time #{taskInfo.cancelTimeSorted} order by c.create_time ${taskInfo.createTimeSorted} ,t.create_time ${taskInfo.cancelTimeSorted}
</select> </select>
</mapper> </mapper>

@ -0,0 +1,85 @@
package ${package.Controller};
import ${package.Entity}.${entity};
import ${package.Service}.${table.serviceName};
import io.swagger.annotations.ApiOperation;
<#--import org.apache.shiro.authz.annotation.Logical;-->
<#--import org.apache.shiro.authz.annotation.RequiresPermissions;-->
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.validation.constraints.NotBlank;
import javax.validation.Valid;
import java.util.List;
<#--import com.common.res.DataResult;-->
<#if restControllerStyle>
<#else>
import org.springframework.stereotype.Controller;
</#if>
<#if superControllerClassPackage??>
import ${superControllerClassPackage};
</#if>
/**
* @author ${author}
* @since ${date}
*/
<#if restControllerStyle>
@RestController
<#else>
@Controller
</#if>
@RequestMapping("/<#if controllerMappingHyphenStyle>${controllerMappingHyphen}<#else>${table.entityPath}</#if>")
<#if kotlin>
class ${table.controllerName}<#if superControllerClass??> : ${superControllerClass}()</#if>
<#else>
<#if superControllerClass??>
public class ${table.controllerName} extends ${superControllerClass} {
<#else>
public class ${table.controllerName} {
</#if>
@Autowired
private ${table.serviceName} ${table.serviceName?uncap_first};
@GetMapping("/selectOne")
<#-- @RequiresPermissions("sys:${table.entityName?uncap_first}:list")-->
@ApiOperation("${table.entityName}查询单个")
public ${table.entityName} get${table.entityName}(@RequestParam("id") Integer id){
${table.entityName} ${table.entityName?uncap_first}One = ${table.entityName?uncap_first}Service.get${table.entityName}( id);
return ${table.entityName?uncap_first}One;
}
@GetMapping("/listAll")
<#-- @RequiresPermissions("sys:${table.entityName?uncap_first}:list")-->
@ApiOperation("${table.entityName}查询全部")
public List<${table.entityName}> getAll${table.entityName}(){
List<${table.entityName}> ${table.entityName?uncap_first}List = ${table.entityName?uncap_first}Service.getAll${table.entityName}();
return ${table.entityName?uncap_first}List;
}
@PostMapping("/add")
<#-- @RequiresPermissions("sys:${table.entityName?uncap_first}:add")-->
@ApiOperation("${table.entityName}新增")
public Object add(@Valid @RequestBody ${table.entityName} ${table.entityName?uncap_first}) {
${table.entityName?uncap_first}Service.add( ${table.entityName?uncap_first});
return null;
}
@PutMapping("/update")
<#-- @RequiresPermissions("sys:${table.entityName?uncap_first}:update")-->
@ApiOperation("${table.entityName}修改")
public int update(@Valid @RequestBody ${table.entityName} ${table.entityName?uncap_first}) {
int num = ${table.entityName?uncap_first}Service.modify( ${table.entityName?uncap_first});
return num;
}
@DeleteMapping(value = "/delete/{ids}")
<#-- @RequiresPermissions("sys:${table.entityName?uncap_first}:delete")-->
@ApiOperation("${table.entityName}删除(单个条目)")
public Object remove(@NotBlank(message = "{required}") @PathVariable String ids) {
${table.entityName?uncap_first}Service.remove(ids);
return null;
}
}
</#if>

@ -0,0 +1,53 @@
package ${package.Service};
import ${package.Entity}.${entity};
import ${superServiceClassPackage};
import java.util.List;
/**
* @author ${author}
* @since ${date}
*/
<#if kotlin>
interface ${table.serviceName} : ${superServiceClass}<${entity}>
<#else>
public interface ${table.serviceName} extends ${superServiceClass}<${entity}> {
/**
* ${table.entityName!}详情
* @param
* @return
*/
${table.entityName} get${table.entityName}( Integer id);
/**
* ${table.entityName!}详情
* @param
* @return
*/
List<${table.entityName}> getAll${table.entityName}();
/**
* ${table.entityName!}新增
* @param ${table.entityName?uncap_first} 根据需要进行传值
* @return
*/
void add(${entity} ${table.entityName?uncap_first});
/**
* ${table.entityName!}修改
* @param ${table.entityName?uncap_first} 根据需要进行传值
* @return
*/
int modify(${entity} ${table.entityName?uncap_first});
/**
* ${table.entityName!}删除
* @param ids
* @return
*/
void remove(String ids);
}
</#if>

@ -0,0 +1,69 @@
package ${package.ServiceImpl};
import ${package.Entity}.${entity};
import ${package.Mapper}.${table.mapperName};
import ${package.Service}.${table.serviceName};
import ${superServiceImplClassPackage};
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.Arrays;
/**
* ${table.comment!} 服务实现类
*
* @author ${author}
* @since ${date}
*/
@Service
<#if kotlin>
open class ${table.serviceImplName} : ${superServiceImplClass}<${table.mapperName}, ${entity}>(), ${table.serviceName} {
}
<#else>
public class ${table.serviceImplName} extends ${superServiceImplClass}<${table.mapperName}, ${entity}> implements ${table.serviceName} {
@Autowired
${table.entityName}Mapper ${table.entityName?uncap_first}Mapper;
@Override
public ${table.entityName} get${table.entityName}(Integer id){
return ${table.entityName?uncap_first}Mapper.selectById(id);
}
@Override
public List<${table.entityName}> getAll${table.entityName}(){
return ${table.entityName?uncap_first}Mapper.selectList(null);
}
@Override
public void add( ${table.entityName} ${table.entityName?uncap_first}) {
${table.entityName?uncap_first}Mapper.insert(${table.entityName?uncap_first});
}
@Override
public int modify( ${table.entityName} ${table.entityName?uncap_first}) {
//乐观锁更新
${table.entityName} current${table.entityName}= ${table.entityName?uncap_first}Mapper.selectById(${table.entityName?uncap_first}.getId());
${table.entityName?uncap_first}.setVersion(current${table.entityName}.getVersion());
return ${table.entityName?uncap_first}Mapper.updateById(${table.entityName?uncap_first});
}
@Override
public void remove( String ids) {
if(StringUtils.isNotEmpty(ids)){
String[] array = ids.split(",");
if (!CollectionUtils.isEmpty(Arrays.asList(array))) {
${table.entityName?uncap_first}Mapper.deleteBatchIds(Arrays.asList(array));
}
}
}
}
</#if>

@ -1,14 +1,18 @@
package com.supervision.demo; package com.supervision.demo;
import cn.hutool.core.util.StrUtil;
import com.supervision.police.domain.ModelCase;
import com.supervision.police.service.ModelCaseService;
import com.supervision.police.vo.dify.DifyChatReqVO; import com.supervision.police.vo.dify.DifyChatReqVO;
import com.supervision.utils.DifyApiUtil; import com.supervision.utils.DifyApiUtil;
import com.supervision.utils.Document; import com.supervision.utils.Document;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import java.util.List; import java.util.List;
@Slf4j
@SpringBootTest @SpringBootTest
public class DifyTest { public class DifyTest {
@Autowired @Autowired
@ -24,6 +28,22 @@ public class DifyTest {
difyApiUtil.deleteDataset("65c3a191-2433-4f79-9fd2-5c4dfaf4264d"); difyApiUtil.deleteDataset("65c3a191-2433-4f79-9fd2-5c4dfaf4264d");
} }
@Autowired
private ModelCaseService modelCaseService;
@Test
public void removeCaseDataSet(){
List<ModelCase> list = modelCaseService.list();
for (ModelCase modelCase : list) {
String knowledgeBaseId = modelCase.getKnowledgeBaseId();
if (StrUtil.isEmpty(knowledgeBaseId)){
log.info("案件:{} 未创建知识库,不进行删除...",modelCase.getCaseName());
continue;
}
log.info("案件:{} 开始删除知识库,知识库id:{}...",modelCase.getCaseName(),knowledgeBaseId);
difyApiUtil.deleteDataset(knowledgeBaseId);
}
}
@Test @Test
public void testCreateDocumentByFile() { public void testCreateDocumentByFile() {
System.out.println(difyApiUtil.createDocumentByFile("d6c3e9fa-05a3-4d10-b482-d2797d7eee25", "1823953980884635650")); System.out.println(difyApiUtil.createDocumentByFile("d6c3e9fa-05a3-4d10-b482-d2797d7eee25", "1823953980884635650"));

Loading…
Cancel
Save