Merge remote-tracking branch 'origin/dev' into dev
commit
e22bc18e9e
@ -0,0 +1,15 @@
|
||||
package com.supervision.common.constant;
|
||||
|
||||
public class DifyConstants {
|
||||
public static final String METHOD_DATASET = "/datasets";
|
||||
public static final String METHOD_DOCUMENT = "/document";
|
||||
public static final String METHOD_DOCUMENTS = "/documents";
|
||||
public static final String METHOD_CREATE_BY_FILE = "/create-by-file";
|
||||
public static final String METHOD_CHAT_MESSAGES = "/chat-messages";
|
||||
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_STREAMING = "streaming";
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package com.supervision.police.vo.dify;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.supervision.common.constant.DifyConstants.CHAT_RESPONSE_MODE_BLOCKING;
|
||||
import static com.supervision.common.constant.DifyConstants.CHAT_RESPONSE_MODE_STREAMING;
|
||||
|
||||
@Data
|
||||
public class ChatReqVO {
|
||||
private String conversationId;
|
||||
private String user;
|
||||
private String query;
|
||||
private String response_mode = CHAT_RESPONSE_MODE_STREAMING;
|
||||
private Map<String, Object> inputs = new HashMap<>();
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package com.supervision.police.vo.dify;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ChatResVO {
|
||||
private String event;
|
||||
private String task_id;
|
||||
private String id;
|
||||
private String message_id;
|
||||
private String conversation_id;
|
||||
private String mode;
|
||||
private String answer;
|
||||
private Metadata metadata;
|
||||
private String created_at;
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package com.supervision.police.vo.dify;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import static com.supervision.common.constant.DifyConstants.DATASET_INDEXING_TECHNIQUE_HIGH_QUALITY;
|
||||
|
||||
@Data
|
||||
public class DatasetReqVO {
|
||||
private String name;
|
||||
private String description;
|
||||
private String indexing_technique = DATASET_INDEXING_TECHNIQUE_HIGH_QUALITY;
|
||||
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package com.supervision.police.vo.dify;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class DatasetResVO {
|
||||
private String id;
|
||||
private String name;
|
||||
private String description;
|
||||
private String provider;
|
||||
private String permission;
|
||||
private String data_source_type;
|
||||
private String indexing_technique;
|
||||
private String app_count;
|
||||
private String document_count;
|
||||
private String word_count;
|
||||
private String created_by;
|
||||
private String created_at;
|
||||
private String updated_by;
|
||||
private String updated_at;
|
||||
private String embedding_model;
|
||||
private String embedding_model_provider;
|
||||
private String embedding_available;
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package com.supervision.police.vo.dify;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class Metadata {
|
||||
private Usage usage;
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package com.supervision.police.vo.dify;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class Usage {
|
||||
private int promptTokens;
|
||||
private String promptUnitPrice;
|
||||
private String promptPriceUnit;
|
||||
private String promptPrice;
|
||||
private int completionTokens;
|
||||
private String completionUnitPrice;
|
||||
private String completionPriceUnit;
|
||||
private String completionPrice;
|
||||
private int totalTokens;
|
||||
private String totalPrice;
|
||||
private String currency;
|
||||
private double latency;
|
||||
}
|
@ -0,0 +1,215 @@
|
||||
package com.supervision.utils;
|
||||
|
||||
import cn.hutool.json.JSONObject;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.supervision.minio.domain.MinioFile;
|
||||
import com.supervision.minio.service.MinioService;
|
||||
import com.supervision.police.vo.dify.ChatReqVO;
|
||||
import com.supervision.police.vo.dify.ChatResVO;
|
||||
import com.supervision.police.vo.dify.DatasetReqVO;
|
||||
import com.supervision.police.vo.dify.DatasetResVO;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.hc.client5.http.ClientProtocolException;
|
||||
import org.apache.hc.client5.http.classic.methods.HttpDelete;
|
||||
import org.apache.hc.client5.http.classic.methods.HttpPost;
|
||||
import org.apache.hc.client5.http.entity.mime.MultipartEntityBuilder;
|
||||
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
||||
import org.apache.hc.client5.http.impl.classic.HttpClients;
|
||||
import org.apache.hc.core5.http.*;
|
||||
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
||||
import org.apache.hc.core5.http.io.entity.StringEntity;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import static com.supervision.common.constant.DifyConstants.*;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class DifyApiUtil {
|
||||
|
||||
@Value("${dify.url}")
|
||||
private String difyUrl;
|
||||
@Value("${dify.dataset-auth}")
|
||||
private String difyDatasetAuth;
|
||||
@Value("${dify.app-auth}")
|
||||
private String difyAppAuth;
|
||||
|
||||
@Autowired
|
||||
private MinioService minioService;
|
||||
|
||||
public void chat(ChatReqVO chatReqVO) {
|
||||
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
|
||||
HttpPost httpPost = new HttpPost(difyUrl + METHOD_CHAT_MESSAGES);
|
||||
httpPost.setHeader(HttpHeaders.AUTHORIZATION, difyAppAuth);
|
||||
httpPost.setHeader(HttpHeaders.CONTENT_TYPE, "application/json");
|
||||
log.info("发起对话:{}", chatReqVO);
|
||||
StringEntity entity = new StringEntity(new JSONObject(chatReqVO).toString(), ContentType.APPLICATION_FORM_URLENCODED);
|
||||
httpPost.setEntity(entity);
|
||||
ChatResVO chatResVO1 = httpClient.execute(httpPost, response -> {
|
||||
final int status = response.getCode();
|
||||
if (status >= HttpStatus.SC_SUCCESS && status < HttpStatus.SC_REDIRECTION) {
|
||||
final HttpEntity responseEntity = response.getEntity();
|
||||
try {
|
||||
String responseStr = EntityUtils.toString(responseEntity);
|
||||
log.info("responseStr:{}", responseStr);
|
||||
return new ChatResVO();
|
||||
} catch (final ParseException ex) {
|
||||
throw new ClientProtocolException(ex);
|
||||
}
|
||||
} else {
|
||||
log.info("responseEntity {}", EntityUtils.toString(response.getEntity()));
|
||||
throw new ClientProtocolException("Unexpected response status: " + status);
|
||||
}
|
||||
});
|
||||
log.info("chatResVO1:{}", chatResVO1);
|
||||
} catch (Exception e) {
|
||||
log.error("create dataset error", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建知识库
|
||||
*
|
||||
* @param name 知识库名称
|
||||
* @param description 知识库描述
|
||||
* @return 知识库ID
|
||||
*/
|
||||
public String createDataset(String name, String description) {
|
||||
String id = "";
|
||||
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
|
||||
HttpPost httpPost = new HttpPost(difyUrl + METHOD_DATASET);
|
||||
httpPost.setHeader(HttpHeaders.AUTHORIZATION, difyDatasetAuth);
|
||||
httpPost.setHeader(HttpHeaders.CONTENT_TYPE, "application/json");
|
||||
DatasetReqVO datasetReqVO = new DatasetReqVO();
|
||||
datasetReqVO.setName(name);
|
||||
datasetReqVO.setDescription(description);
|
||||
log.info("创建知识库【{}】", datasetReqVO.getName());
|
||||
StringEntity entity = new StringEntity(new JSONObject(datasetReqVO).toString(), ContentType.APPLICATION_FORM_URLENCODED);
|
||||
httpPost.setEntity(entity);
|
||||
id = httpClient.execute(httpPost, response -> {
|
||||
final int status = response.getCode();
|
||||
if (status >= HttpStatus.SC_SUCCESS && status < HttpStatus.SC_REDIRECTION) {
|
||||
final HttpEntity responseEntity = response.getEntity();
|
||||
try {
|
||||
String responseStr = EntityUtils.toString(responseEntity);
|
||||
Gson gson = new Gson();
|
||||
DatasetResVO datasetResVO = gson.fromJson(responseStr, DatasetResVO.class);
|
||||
log.info("创建知识库成功!ID:【{}】", datasetResVO.getId());
|
||||
return datasetResVO.getId();
|
||||
} catch (final ParseException ex) {
|
||||
throw new ClientProtocolException(ex);
|
||||
}
|
||||
} else {
|
||||
log.info("创建知识库失败!{}", EntityUtils.toString(response.getEntity()));
|
||||
return null;
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
log.error("创建知识库失败!", e);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除知识库
|
||||
*
|
||||
* @param id 知识库ID
|
||||
*/
|
||||
public void deleteDataset(String id) {
|
||||
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
|
||||
HttpDelete httpDelete = new HttpDelete(difyUrl + METHOD_DATASET + "/" + id);
|
||||
httpDelete.setHeader(HttpHeaders.AUTHORIZATION, difyDatasetAuth);
|
||||
log.info("删除知识库【{}】", id);
|
||||
httpClient.execute(httpDelete, response -> {
|
||||
final int status = response.getCode();
|
||||
if (status == HttpStatus.SC_NO_CONTENT) {
|
||||
log.info("删除知识库成功!");
|
||||
} else {
|
||||
log.info("删除知识库失败!状态码:{}", status);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
} catch (Exception e) {
|
||||
log.error("删除知识库失败!", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过文件创建知识库文档
|
||||
*
|
||||
* @param datasetId 知识库ID
|
||||
* @param fileId 文件ID
|
||||
* @return 文档ID
|
||||
*/
|
||||
public String createDocumentByFile(String datasetId, String fileId) {
|
||||
String id = "";
|
||||
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
|
||||
log.info("创建知识库文档【{}】", difyUrl + METHOD_DATASET + "/" + datasetId + METHOD_DOCUMENT + METHOD_CREATE_BY_FILE);
|
||||
HttpPost httpPost = new HttpPost(difyUrl + METHOD_DATASET + "/" + datasetId + METHOD_DOCUMENT + METHOD_CREATE_BY_FILE);
|
||||
httpPost.setHeader(HttpHeaders.AUTHORIZATION, difyDatasetAuth);
|
||||
MinioFile minioFile = minioService.getMinioFile(fileId);
|
||||
if (minioFile == null) {
|
||||
log.error("文件不存在!ID:{}", fileId);
|
||||
return null;
|
||||
}
|
||||
HttpEntity entity = MultipartEntityBuilder.create()
|
||||
// JSON 部分
|
||||
.addTextBody("data", "{\"indexing_technique\":\"high_quality\",\"process_rule\":{\"mode\":\"automatic\"}}", ContentType.APPLICATION_JSON)
|
||||
// 文件部分
|
||||
.addBinaryBody("file", minioService.getObjectInputStream(minioFile), ContentType.DEFAULT_BINARY, minioFile.getFilename())
|
||||
.build();
|
||||
|
||||
httpPost.setEntity(entity);
|
||||
id = httpClient.execute(httpPost, response -> {
|
||||
final int status = response.getCode();
|
||||
if (status >= HttpStatus.SC_SUCCESS && status < HttpStatus.SC_REDIRECTION) {
|
||||
final HttpEntity responseEntity = response.getEntity();
|
||||
try {
|
||||
String responseStr = EntityUtils.toString(responseEntity);
|
||||
log.info("responseStr:{}", responseStr);
|
||||
JsonObject jsonObject = JsonParser.parseString(responseStr).getAsJsonObject();
|
||||
JsonObject document = jsonObject.getAsJsonObject("document");
|
||||
log.info("创建知识库文档成功!ID:{}", document.get("id").getAsString());
|
||||
return document.get("id").getAsString();
|
||||
} catch (final ParseException ex) {
|
||||
throw new ClientProtocolException(ex);
|
||||
}
|
||||
} else {
|
||||
log.info("创建知识库文档失败!{}", EntityUtils.toString(response.getEntity()));
|
||||
return null;
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
log.error("创建知识库文档失败!", e);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除知识库文档
|
||||
*
|
||||
* @param datasetId 知识库ID
|
||||
* @param documentId 文档ID
|
||||
*/
|
||||
public void deleteDocument(String datasetId, String documentId) {
|
||||
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
|
||||
HttpDelete httpDelete = new HttpDelete(difyUrl + METHOD_DATASET + "/" + datasetId + METHOD_DOCUMENTS + "/" + documentId);
|
||||
httpDelete.setHeader(HttpHeaders.AUTHORIZATION, difyDatasetAuth);
|
||||
log.info("删除知识库文档【{}】", documentId);
|
||||
httpClient.execute(httpDelete, response -> {
|
||||
final int status = response.getCode();
|
||||
if (status == HttpStatus.SC_SUCCESS) {
|
||||
log.info("删除知识库文档成功!");
|
||||
} else {
|
||||
log.info("删除知识库文档失败!状态码:{}", status);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
} catch (Exception e) {
|
||||
log.error("删除知识库文档失败!", e);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
package com.supervision.utils;
|
||||
|
||||
import org.apache.hc.client5.http.classic.methods.HttpGet;
|
||||
import org.apache.hc.client5.http.classic.methods.HttpPost;
|
||||
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
||||
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
|
||||
import org.apache.hc.client5.http.impl.classic.HttpClients;
|
||||
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
||||
import org.apache.hc.core5.http.io.entity.StringEntity;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @Author: JCccc
|
||||
* @Date: 2022-6-22 9:51
|
||||
* @Description:
|
||||
*/
|
||||
@Component
|
||||
public class XxlJobUtil {
|
||||
private static String cookie = "";
|
||||
@Value("${xxl.job.admin.addresses}")
|
||||
private String xxlJobAdminAddress;
|
||||
|
||||
public void executeTask(String taskName) throws Exception {
|
||||
String taskQueryUrl = xxlJobAdminAddress + "/xxl-job-admin/api/jobinfo/load";
|
||||
String taskExecuteUrl = xxlJobAdminAddress + "/xxl-job-admin/api/job/trigger";
|
||||
|
||||
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
|
||||
// 查询任务
|
||||
HttpGet httpGet = new HttpGet(taskQueryUrl + "?jobName=" + taskName);
|
||||
try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
|
||||
String jsonResponse = EntityUtils.toString(response.getEntity());
|
||||
// 处理任务信息,例如提取 jobId
|
||||
// 假设 jsonResponse 中有一个字段 "jobId"
|
||||
String jobId = extractJobId(jsonResponse);
|
||||
|
||||
// 执行任务
|
||||
HttpPost httpPost = new HttpPost(taskExecuteUrl);
|
||||
httpPost.setHeader("Content-Type", "application/json");
|
||||
String jsonBody = "{\"jobId\": \"" + jobId + "\"}";
|
||||
httpPost.setEntity(new StringEntity(jsonBody));
|
||||
try (CloseableHttpResponse executeResponse = httpClient.execute(httpPost)) {
|
||||
System.out.println("Task executed: " + EntityUtils.toString(executeResponse.getEntity()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String extractJobId(String jsonResponse) {
|
||||
// 解析 JSON 响应并提取 jobId
|
||||
// 这里需要使用 JSON 解析库,比如 Jackson 或 Gson
|
||||
// 示例代码略
|
||||
return "yourJobId"; // 请替换为实际提取的 jobId
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
package com.supervision.demo;
|
||||
|
||||
import com.supervision.police.vo.dify.ChatReqVO;
|
||||
import com.supervision.utils.DifyApiUtil;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@SpringBootTest
|
||||
public class DifyTest {
|
||||
@Autowired
|
||||
private DifyApiUtil difyApiUtil;
|
||||
|
||||
@Test
|
||||
public void testCreateDataset() {
|
||||
System.out.println(difyApiUtil.createDataset("张三1", "张三1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteDataset() {
|
||||
difyApiUtil.deleteDataset("65c3a191-2433-4f79-9fd2-5c4dfaf4264d");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateDocumentByFile() {
|
||||
System.out.println(difyApiUtil.createDocumentByFile("92e613e7-7369-46b1-ab12-b3d42dd5b646", "1823953980884635650"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteDocument() {
|
||||
difyApiUtil.deleteDocument("92e613e7-7369-46b1-ab12-b3d42dd5b646", "3f2a3719-1ee8-4cfd-b50c-d469954ee72e");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testChat() {
|
||||
System.out.println("Test");
|
||||
ChatReqVO chatReqVO = new ChatReqVO();
|
||||
chatReqVO.setUser("admin");
|
||||
chatReqVO.setQuery("Who are you?");
|
||||
chatReqVO.setInputs(Map.of("dataset_id", "13c60b8c-341f-43ea-b3cc-5289a518abd9"));
|
||||
difyApiUtil.chat(chatReqVO);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue