数字民警对话改造初版
parent
d53bca3ada
commit
b54400454f
@ -1,15 +1,28 @@
|
|||||||
package com.supervision.common.constant;
|
package com.supervision.common.constant;
|
||||||
|
|
||||||
public class DifyConstants {
|
public class DifyConstants {
|
||||||
|
public static final String QA_TYPE_DIFY = "0";
|
||||||
|
public static final String QA_TYPE_NX_LLM = "1";
|
||||||
|
|
||||||
|
public static final String INTENT_TYPE_INDEX_RESULT = "0";
|
||||||
|
public static final String INTENT_TYPE_CASE_RESULT = "1";
|
||||||
|
public static final String INTENT_TYPE_CASE_OVERVIEW = "2";
|
||||||
|
public static final String INTENT_TYPE_CASE_EVIDENCE_GUIDE = "3";
|
||||||
|
|
||||||
public static final String METHOD_DATASET = "/datasets";
|
public static final String METHOD_DATASET = "/datasets";
|
||||||
public static final String METHOD_DOCUMENT = "/document";
|
public static final String METHOD_DOCUMENT = "/document";
|
||||||
public static final String METHOD_DOCUMENTS = "/documents";
|
public static final String METHOD_DOCUMENTS = "/documents";
|
||||||
public static final String METHOD_CREATE_BY_FILE = "/create-by-file";
|
public static final String METHOD_CREATE_BY_FILE = "/create-by-file";
|
||||||
public static final String METHOD_CHAT_MESSAGES = "/chat-messages";
|
public static final String METHOD_CHAT_MESSAGES = "/chat-messages";
|
||||||
|
|
||||||
public static final String DATASET_INDEXING_TECHNIQUE_HIGH_QUALITY = "high_quality";
|
public static final String DATASET_INDEXING_TECHNIQUE_HIGH_QUALITY = "high_quality";
|
||||||
public static final String CHAT_RESPONSE_MODE_BLOCKING = "blocking";
|
public static final String CHAT_RESPONSE_MODE_BLOCKING = "blocking";
|
||||||
public static final String CHAT_RESPONSE_MODE_STREAMING = "streaming";
|
public static final String CHAT_RESPONSE_MODE_STREAMING = "streaming";
|
||||||
|
|
||||||
|
public static final String INTENT_TYPE_TEXT_CASE_RESULT = "案件分析结果";
|
||||||
|
public static final String INTENT_TYPE_TEXT_CASE_OVERVIEW = "案件概况";
|
||||||
|
public static final String INTENT_TYPE_TEXT_CASE_EVIDENCE_GUIDE = "案件证据指引";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,56 @@
|
|||||||
|
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 java.util.Date;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 会话记录表
|
||||||
|
* @TableName conversation
|
||||||
|
*/
|
||||||
|
@TableName(value ="conversation")
|
||||||
|
@Data
|
||||||
|
public class Conversation implements Serializable {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@TableId
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 标题
|
||||||
|
*/
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 类型
|
||||||
|
*/
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 案件ID
|
||||||
|
*/
|
||||||
|
private String caseId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户ID
|
||||||
|
*/
|
||||||
|
private String userId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private Date createTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private Date updateTime;
|
||||||
|
|
||||||
|
@TableField(exist = false)
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package com.supervision.police.mapper;
|
||||||
|
|
||||||
|
import com.supervision.police.domain.Conversation;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author yaxin
|
||||||
|
* @description 针对表【conversation(会话记录表)】的数据库操作Mapper
|
||||||
|
* @createDate 2024-11-25 13:43:52
|
||||||
|
* @Entity com.supervision.police.domain.Conversation
|
||||||
|
*/
|
||||||
|
public interface ConversationMapper extends BaseMapper<Conversation> {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
|||||||
|
package com.supervision.police.mapper;
|
||||||
|
|
||||||
|
import com.supervision.police.domain.ConversationQa;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author yaxin
|
||||||
|
* @description 针对表【conversation_qa】的数据库操作Mapper
|
||||||
|
* @createDate 2024-11-22 11:37:02
|
||||||
|
* @Entity com.supervision.police.domain.ConversationQa
|
||||||
|
*/
|
||||||
|
public interface ConversationQaMapper extends BaseMapper<ConversationQa> {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.supervision.police.service;
|
||||||
|
|
||||||
|
import com.supervision.police.domain.ConversationQa;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author yaxin
|
||||||
|
* @description 针对表【conversation_qa】的数据库操作Service
|
||||||
|
* @createDate 2024-11-22 11:37:02
|
||||||
|
*/
|
||||||
|
public interface ConversationQaService extends IService<ConversationQa> {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.supervision.police.service;
|
||||||
|
|
||||||
|
import com.supervision.police.domain.Conversation;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author yaxin
|
||||||
|
* @description 针对表【conversation(会话记录表)】的数据库操作Service
|
||||||
|
* @createDate 2024-11-25 13:43:52
|
||||||
|
*/
|
||||||
|
public interface ConversationService extends IService<Conversation> {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package com.supervision.police.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import com.supervision.police.domain.ConversationQa;
|
||||||
|
import com.supervision.police.service.ConversationQaService;
|
||||||
|
import com.supervision.police.mapper.ConversationQaMapper;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author yaxin
|
||||||
|
* @description 针对表【conversation_qa】的数据库操作Service实现
|
||||||
|
* @createDate 2024-11-22 11:37:02
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class ConversationQaServiceImpl extends ServiceImpl<ConversationQaMapper, ConversationQa>
|
||||||
|
implements ConversationQaService{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,22 @@
|
|||||||
|
package com.supervision.police.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import com.supervision.police.domain.Conversation;
|
||||||
|
import com.supervision.police.service.ConversationService;
|
||||||
|
import com.supervision.police.mapper.ConversationMapper;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author yaxin
|
||||||
|
* @description 针对表【conversation(会话记录表)】的数据库操作Service实现
|
||||||
|
* @createDate 2024-11-25 13:43:52
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class ConversationServiceImpl extends ServiceImpl<ConversationMapper, Conversation>
|
||||||
|
implements ConversationService{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,221 @@
|
|||||||
|
//
|
||||||
|
// Source code recreated from a .class file by IntelliJ IDEA
|
||||||
|
// (powered by FernFlower decompiler)
|
||||||
|
//
|
||||||
|
|
||||||
|
package org.apache.hc.client5.http.entity.mime;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.nio.CharBuffer;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
import org.apache.hc.core5.http.ContentType;
|
||||||
|
import org.apache.hc.core5.http.HttpEntity;
|
||||||
|
import org.apache.hc.core5.http.NameValuePair;
|
||||||
|
import org.apache.hc.core5.http.message.BasicNameValuePair;
|
||||||
|
import org.apache.hc.core5.util.Args;
|
||||||
|
|
||||||
|
public class MultipartEntityBuilder {
|
||||||
|
private static final char[] MULTIPART_CHARS = "-_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
|
||||||
|
private ContentType contentType;
|
||||||
|
private HttpMultipartMode mode;
|
||||||
|
private String boundary;
|
||||||
|
private Charset charset;
|
||||||
|
private List<MultipartPart> multipartParts;
|
||||||
|
private static final NameValuePair[] EMPTY_NAME_VALUE_ARRAY = new NameValuePair[0];
|
||||||
|
|
||||||
|
public static MultipartEntityBuilder create() {
|
||||||
|
return new MultipartEntityBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
MultipartEntityBuilder() {
|
||||||
|
this.mode = HttpMultipartMode.STRICT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MultipartEntityBuilder setMode(HttpMultipartMode mode) {
|
||||||
|
this.mode = mode;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MultipartEntityBuilder setLaxMode() {
|
||||||
|
this.mode = HttpMultipartMode.LEGACY;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MultipartEntityBuilder setStrictMode() {
|
||||||
|
this.mode = HttpMultipartMode.STRICT;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MultipartEntityBuilder setBoundary(String boundary) {
|
||||||
|
this.boundary = boundary;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MultipartEntityBuilder setMimeSubtype(String subType) {
|
||||||
|
Args.notBlank(subType, "MIME subtype");
|
||||||
|
this.contentType = ContentType.create("multipart/" + subType);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MultipartEntityBuilder setContentType(ContentType contentType) {
|
||||||
|
Args.notNull(contentType, "Content type");
|
||||||
|
this.contentType = contentType;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MultipartEntityBuilder addParameter(BasicNameValuePair parameter) {
|
||||||
|
this.contentType = this.contentType.withParameters(new NameValuePair[]{parameter});
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MultipartEntityBuilder setCharset(Charset charset) {
|
||||||
|
this.charset = charset;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MultipartEntityBuilder addPart(MultipartPart multipartPart) {
|
||||||
|
if (multipartPart == null) {
|
||||||
|
return this;
|
||||||
|
} else {
|
||||||
|
if (this.multipartParts == null) {
|
||||||
|
this.multipartParts = new ArrayList();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.multipartParts.add(multipartPart);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public MultipartEntityBuilder addPart(String name, ContentBody contentBody) {
|
||||||
|
Args.notNull(name, "Name");
|
||||||
|
Args.notNull(contentBody, "Content body");
|
||||||
|
return this.addPart(FormBodyPartBuilder.create(name, contentBody).build());
|
||||||
|
}
|
||||||
|
|
||||||
|
public MultipartEntityBuilder addTextBody(String name, String text, ContentType contentType) {
|
||||||
|
return this.addPart(name, new StringBody(text, contentType));
|
||||||
|
}
|
||||||
|
|
||||||
|
public MultipartEntityBuilder addTextBody(String name, String text) {
|
||||||
|
return this.addTextBody(name, text, ContentType.DEFAULT_TEXT);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MultipartEntityBuilder addBinaryBody(String name, byte[] b, ContentType contentType, String filename) {
|
||||||
|
return this.addPart(name, new ByteArrayBody(b, contentType, filename));
|
||||||
|
}
|
||||||
|
|
||||||
|
public MultipartEntityBuilder addBinaryBody(String name, byte[] b) {
|
||||||
|
return this.addPart(name, new ByteArrayBody(b, ContentType.DEFAULT_BINARY));
|
||||||
|
}
|
||||||
|
|
||||||
|
public MultipartEntityBuilder addBinaryBody(String name, File file, ContentType contentType, String filename) {
|
||||||
|
return this.addPart(name, new FileBody(file, contentType, filename));
|
||||||
|
}
|
||||||
|
|
||||||
|
public MultipartEntityBuilder addBinaryBody(String name, File file) {
|
||||||
|
return this.addBinaryBody(name, file, ContentType.DEFAULT_BINARY, file != null ? file.getName() : null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MultipartEntityBuilder addBinaryBody(String name, InputStream stream, ContentType contentType, String filename) {
|
||||||
|
return this.addPart(name, new InputStreamBody(stream, contentType, filename));
|
||||||
|
}
|
||||||
|
|
||||||
|
public MultipartEntityBuilder addBinaryBody(String name, InputStream stream) {
|
||||||
|
return this.addBinaryBody(name, (InputStream)stream, ContentType.DEFAULT_BINARY, (String)null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String generateBoundary() {
|
||||||
|
ThreadLocalRandom rand = ThreadLocalRandom.current();
|
||||||
|
int count = rand.nextInt(30, 41);
|
||||||
|
CharBuffer buffer = CharBuffer.allocate(count);
|
||||||
|
|
||||||
|
while(buffer.hasRemaining()) {
|
||||||
|
buffer.put(MULTIPART_CHARS[rand.nextInt(MULTIPART_CHARS.length)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer.flip();
|
||||||
|
return buffer.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
MultipartFormEntity buildEntity() {
|
||||||
|
String boundaryCopy = this.boundary;
|
||||||
|
if (boundaryCopy == null && this.contentType != null) {
|
||||||
|
boundaryCopy = this.contentType.getParameter("boundary");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (boundaryCopy == null) {
|
||||||
|
boundaryCopy = this.generateBoundary();
|
||||||
|
}
|
||||||
|
|
||||||
|
Charset charsetCopy = this.charset;
|
||||||
|
if (charsetCopy == null && this.contentType != null) {
|
||||||
|
charsetCopy = this.contentType.getCharset();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<NameValuePair> paramsList = new ArrayList(2);
|
||||||
|
paramsList.add(new BasicNameValuePair("boundary", boundaryCopy));
|
||||||
|
if (charsetCopy != null) {
|
||||||
|
paramsList.add(new BasicNameValuePair("charset", charsetCopy.name()));
|
||||||
|
}
|
||||||
|
|
||||||
|
NameValuePair[] params = (NameValuePair[])paramsList.toArray(EMPTY_NAME_VALUE_ARRAY);
|
||||||
|
ContentType contentTypeCopy;
|
||||||
|
if (this.contentType != null) {
|
||||||
|
contentTypeCopy = this.contentType.withParameters(params);
|
||||||
|
} else {
|
||||||
|
boolean formData = false;
|
||||||
|
if (this.multipartParts != null) {
|
||||||
|
Iterator var7 = this.multipartParts.iterator();
|
||||||
|
|
||||||
|
while(var7.hasNext()) {
|
||||||
|
MultipartPart multipartPart = (MultipartPart)var7.next();
|
||||||
|
if (multipartPart instanceof FormBodyPart) {
|
||||||
|
formData = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (formData) {
|
||||||
|
contentTypeCopy = ContentType.MULTIPART_FORM_DATA.withParameters(params);
|
||||||
|
} else {
|
||||||
|
contentTypeCopy = ContentType.create("multipart/mixed", params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<MultipartPart> multipartPartsCopy = this.multipartParts != null ? new ArrayList(this.multipartParts) : Collections.emptyList();
|
||||||
|
HttpMultipartMode modeCopy = this.mode != null ? this.mode : HttpMultipartMode.STRICT;
|
||||||
|
Object form;
|
||||||
|
switch (modeCopy) {
|
||||||
|
case LEGACY:
|
||||||
|
form = new LegacyMultipart(charsetCopy, boundaryCopy, (List)multipartPartsCopy);
|
||||||
|
break;
|
||||||
|
case EXTENDED:
|
||||||
|
if (contentTypeCopy.isSameMimeType(ContentType.MULTIPART_FORM_DATA)) {
|
||||||
|
if (charsetCopy == null) {
|
||||||
|
charsetCopy = StandardCharsets.UTF_8;
|
||||||
|
}
|
||||||
|
|
||||||
|
form = new HttpRFC7578Multipart(charsetCopy, boundaryCopy, (List)multipartPartsCopy);
|
||||||
|
} else {
|
||||||
|
form = new HttpRFC6532Multipart(charsetCopy, boundaryCopy, (List)multipartPartsCopy);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
form = new HttpStrictMultipart(StandardCharsets.UTF_8, boundaryCopy, (List)multipartPartsCopy);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new MultipartFormEntity((AbstractMultipartFormat)form, contentTypeCopy, ((AbstractMultipartFormat)form).getTotalLength());
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpEntity build() {
|
||||||
|
return this.buildEntity();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
<?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.ConversationMapper">
|
||||||
|
|
||||||
|
<resultMap id="BaseResultMap" type="com.supervision.police.domain.Conversation">
|
||||||
|
<id property="id" column="id" jdbcType="VARCHAR"/>
|
||||||
|
<result property="title" column="title" jdbcType="VARCHAR"/>
|
||||||
|
<result property="type" column="type" jdbcType="VARCHAR"/>
|
||||||
|
<result property="caseId" column="case_id" jdbcType="VARCHAR"/>
|
||||||
|
<result property="userId" column="user_id" jdbcType="VARCHAR"/>
|
||||||
|
<result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
|
||||||
|
<result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
|
<sql id="Base_Column_List">
|
||||||
|
id,title,type,
|
||||||
|
case_id,user_id,create_time,
|
||||||
|
update_time
|
||||||
|
</sql>
|
||||||
|
</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.ConversationQaMapper">
|
||||||
|
|
||||||
|
<resultMap id="BaseResultMap" type="com.supervision.police.domain.ConversationQa">
|
||||||
|
<id property="id" column="id" jdbcType="VARCHAR"/>
|
||||||
|
<result property="type" column="type" jdbcType="INTEGER"/>
|
||||||
|
<result property="question" column="question" jdbcType="VARCHAR"/>
|
||||||
|
<result property="completeQuestion" column="complete_question" jdbcType="VARCHAR"/>
|
||||||
|
<result property="questionTime" column="question_time" jdbcType="TIMESTAMP"/>
|
||||||
|
<result property="answer" column="answer" jdbcType="VARCHAR"/>
|
||||||
|
<result property="completeAnswer" column="complete_answer" jdbcType="VARCHAR"/>
|
||||||
|
<result property="anwerTime" column="anwer_time" jdbcType="TIMESTAMP"/>
|
||||||
|
<result property="timeInterval" column="time_interval" jdbcType="INTEGER"/>
|
||||||
|
<result property="userId" column="user_id" jdbcType="VARCHAR"/>
|
||||||
|
<result property="caseId" column="case_id" jdbcType="VARCHAR"/>
|
||||||
|
<result property="conversationId" column="conversation_id" jdbcType="VARCHAR"/>
|
||||||
|
<result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
|
||||||
|
<result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
|
<sql id="Base_Column_List">
|
||||||
|
id,type,question,
|
||||||
|
complete_question,question_time,answer,
|
||||||
|
complete_answer,anwer_time,time_interval,
|
||||||
|
user_id,case_id,conversation_id,
|
||||||
|
create_time,update_time
|
||||||
|
</sql>
|
||||||
|
</mapper>
|
Loading…
Reference in New Issue