From ab6c7c8576b3cbc9169c13457a8909b99972e481 Mon Sep 17 00:00:00 2001 From: wangys <3401275564@qq.com> Date: Fri, 7 Nov 2025 15:17:49 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=86=E6=AE=B5=E4=BF=AE=E6=94=B9=E5=AE=8C?= =?UTF-8?q?=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ai/controller/DifyProxyController.java | 152 ++++- schoolNewsWeb/src/apis/ai/document-segment.ts | 74 ++- .../ai/components/DocumentSegmentDialog.vue | 569 ++++++++++++++---- 3 files changed, 674 insertions(+), 121 deletions(-) diff --git a/schoolNewsServ/ai/src/main/java/org/xyzh/ai/controller/DifyProxyController.java b/schoolNewsServ/ai/src/main/java/org/xyzh/ai/controller/DifyProxyController.java index 7b0b1c3..31d4eaa 100644 --- a/schoolNewsServ/ai/src/main/java/org/xyzh/ai/controller/DifyProxyController.java +++ b/schoolNewsServ/ai/src/main/java/org/xyzh/ai/controller/DifyProxyController.java @@ -6,9 +6,10 @@ import org.springframework.web.bind.annotation.*; import org.xyzh.ai.client.DifyApiClient; import org.xyzh.ai.mapper.AiUploadFileMapper; import org.xyzh.common.core.domain.ResultDomain; +import org.xyzh.common.core.page.PageDomain; +import org.xyzh.common.core.page.PageParam; import org.xyzh.common.dto.ai.TbAiUploadFile; -import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; import java.util.Date; @@ -38,27 +39,60 @@ public class DifyProxyController { // ===================== 文档分段管理 API ===================== /** - * @description 获取文档分段列表 + * @description 获取文档分段列表(支持分页) * @param datasetId Dify数据集ID * @param documentId Dify文档ID - * @return ResultDomain 分段列表JSON + * @param page 页码(默认1) + * @param limit 每页条数(默认10) + * @return ResultDomain 分段列表JSON(包含分页信息) * @author AI Assistant * @since 2025-11-04 */ @GetMapping("/datasets/{datasetId}/documents/{documentId}/segments") public ResultDomain getDocumentSegments( @PathVariable(name = "datasetId") String datasetId, - @PathVariable(name = "documentId") String documentId) { + @PathVariable(name = "documentId") String documentId, + @RequestParam(name = "page", defaultValue = "1") int page, + @RequestParam(name = "limit", defaultValue = "20") int limit) { ResultDomain result = new ResultDomain<>(); - log.info("获取文档分段列表: datasetId={}, documentId={}", datasetId, documentId); + log.info("获取文档分段列表: datasetId={}, documentId={}, page={}, limit={}", + datasetId, documentId, page, limit); try { - // 调用Dify API(使用默认配置的API Key) - String path = "/datasets/" + datasetId + "/documents/" + documentId + "/segments"; + // 调用Dify API(使用默认配置的API Key,支持分页) + String path = "/datasets/" + datasetId + "/documents/" + documentId + + "/segments?page=" + page + "&limit=" + limit; String response = difyApiClient.get(path, null); JSONObject jsonObject = JSONObject.parseObject(response); - result.success("获取文档分段列表成功", JSONArray.parseArray(jsonObject.getJSONArray("data").toJSONString(), JSONObject.class)); + // 解析数据列表 + List data = jsonObject.getJSONArray("data").toList(JSONObject.class); + + // 构建分页返回对象 + PageDomain pageDomain = new PageDomain<>(); + pageDomain.setDataList(data); + + // 设置分页参数(添加空值检查) + PageParam pageParam = new PageParam(); + pageParam.setPageSize(limit); + pageParam.setPageNumber(page); + + // 安全地获取 total,如果不存在则使用 data.size() + Long total = jsonObject.getLong("total"); + pageParam.setTotalElements(total != null ? total : (long) data.size()); + + // 安全地获取 total_pages,如果不存在则计算 + Integer totalPages = jsonObject.getInteger("total_pages"); + if (totalPages == null) { + long totalElements = pageParam.getTotalElements(); + totalPages = (int) Math.ceil((double) totalElements / limit); + } + pageParam.setTotalPages(totalPages); + + pageDomain.setPageParam(pageParam); + + // 返回完整的分页数据 + result.success("获取文档分段列表成功", pageDomain); return result; } catch (Exception e) { log.error("获取文档分段列表失败", e); @@ -67,6 +101,108 @@ public class DifyProxyController { } } + /** + * @description 更新文档分段 + * @param datasetId Dify数据集ID + * @param documentId Dify文档ID + * @param segmentId 分段ID + * @param requestBody 请求体(包含segment对象) + * @return ResultDomain 更新结果 + * @author AI Assistant + * @since 2025-11-07 + */ + @PostMapping("/datasets/{datasetId}/documents/{documentId}/segments/{segmentId}") + public ResultDomain updateSegment( + @PathVariable(name = "datasetId") String datasetId, + @PathVariable(name = "documentId") String documentId, + @PathVariable(name = "segmentId") String segmentId, + @RequestBody Map requestBody) { + + log.info("更新文档分段: datasetId={}, documentId={}, segmentId={}", + datasetId, documentId, segmentId); + + ResultDomain result = new ResultDomain<>(); + try { + // 调用Dify API(使用默认配置的API Key) + String path = "/datasets/" + datasetId + "/documents/" + documentId + + "/segments/" + segmentId; + String response = difyApiClient.post(path, requestBody, null); + + result.success("更新分段成功", response); + return result; + } catch (Exception e) { + log.error("更新分段失败", e); + result.fail("更新分段失败: " + e.getMessage()); + return result; + } + } + + /** + * @description 创建文档分段 + * @param datasetId Dify数据集ID + * @param documentId Dify文档ID + * @param requestBody 请求体(包含segments数组) + * @return ResultDomain 创建结果 + * @author AI Assistant + * @since 2025-11-07 + */ + @PostMapping("/datasets/{datasetId}/documents/{documentId}/segments") + public ResultDomain createSegment( + @PathVariable(name = "datasetId") String datasetId, + @PathVariable(name = "documentId") String documentId, + @RequestBody Map requestBody) { + + log.info("创建文档分段: datasetId={}, documentId={}", datasetId, documentId); + + ResultDomain result = new ResultDomain<>(); + try { + // 调用Dify API(使用默认配置的API Key) + String path = "/datasets/" + datasetId + "/documents/" + documentId + "/segments"; + String response = difyApiClient.post(path, requestBody, null); + + result.success("创建分段成功", response); + return result; + } catch (Exception e) { + log.error("创建分段失败", e); + result.fail("创建分段失败: " + e.getMessage()); + return result; + } + } + + /** + * @description 删除文档分段 + * @param datasetId Dify数据集ID + * @param documentId Dify文档ID + * @param segmentId 分段ID + * @return ResultDomain 删除结果 + * @author AI Assistant + * @since 2025-11-07 + */ + @DeleteMapping("/datasets/{datasetId}/documents/{documentId}/segments/{segmentId}") + public ResultDomain deleteSegment( + @PathVariable(name = "datasetId") String datasetId, + @PathVariable(name = "documentId") String documentId, + @PathVariable(name = "segmentId") String segmentId) { + + log.info("删除文档分段: datasetId={}, documentId={}, segmentId={}", + datasetId, documentId, segmentId); + + ResultDomain result = new ResultDomain<>(); + try { + // 调用Dify API(使用默认配置的API Key) + String path = "/datasets/" + datasetId + "/documents/" + documentId + + "/segments/" + segmentId; + String response = difyApiClient.delete(path, null); + + result.success("删除分段成功", response); + return result; + } catch (Exception e) { + log.error("删除分段失败", e); + result.fail("删除分段失败: " + e.getMessage()); + return result; + } + } + /** * @description 获取分段的子块列表 * @param datasetId Dify数据集ID diff --git a/schoolNewsWeb/src/apis/ai/document-segment.ts b/schoolNewsWeb/src/apis/ai/document-segment.ts index 9ded4fc..d160266 100644 --- a/schoolNewsWeb/src/apis/ai/document-segment.ts +++ b/schoolNewsWeb/src/apis/ai/document-segment.ts @@ -18,17 +18,83 @@ import type { */ export const documentSegmentApi = { /** - * 获取文档的所有分段(父级) + * 获取文档的所有分段(父级,支持分页) * @param datasetId Dify数据集ID * @param documentId Dify文档ID - * @returns Promise> 后端直接返回分段数组 + * @param page 页码(默认1) + * @param limit 每页条数(默认10) + * @returns Promise> 返回包含data数组和分页信息的对象 */ async getDocumentSegments( datasetId: string, - documentId: string + documentId: string, + page = 1, + limit = 20 ): Promise> { const response = await api.get( - `/ai/dify/datasets/${datasetId}/documents/${documentId}/segments` + `/ai/dify/datasets/${datasetId}/documents/${documentId}/segments`, + { + page, + limit + },{showLoading: false} + ); + return response.data; + }, + + /** + * 更新文档分段 + * @param datasetId Dify数据集ID + * @param documentId Dify文档ID + * @param segmentId 分段ID + * @param segment 分段更新数据 + * @returns Promise> + */ + async updateSegment( + datasetId: string, + documentId: string, + segmentId: string, + segment: { content?: string; keywords?: string[]; enabled?: boolean } + ): Promise> { + const response = await api.post( + `/ai/dify/datasets/${datasetId}/documents/${documentId}/segments/${segmentId}`, + { segment } + ); + return response.data; + }, + + /** + * 创建文档分段 + * @param datasetId Dify数据集ID + * @param documentId Dify文档ID + * @param segments 分段数据数组 + * @returns Promise> + */ + async createSegment( + datasetId: string, + documentId: string, + segments: Array<{ content: string; answer?: string; keywords?: string[] }> + ): Promise> { + const response = await api.post( + `/ai/dify/datasets/${datasetId}/documents/${documentId}/segments`, + { segments } + ); + return response.data; + }, + + /** + * 删除文档分段 + * @param datasetId Dify数据集ID + * @param documentId Dify文档ID + * @param segmentId 分段ID + * @returns Promise> + */ + async deleteSegment( + datasetId: string, + documentId: string, + segmentId: string + ): Promise> { + const response = await api.delete( + `/ai/dify/datasets/${datasetId}/documents/${documentId}/segments/${segmentId}` ); return response.data; }, diff --git a/schoolNewsWeb/src/views/admin/manage/ai/components/DocumentSegmentDialog.vue b/schoolNewsWeb/src/views/admin/manage/ai/components/DocumentSegmentDialog.vue index 45e5535..576570a 100644 --- a/schoolNewsWeb/src/views/admin/manage/ai/components/DocumentSegmentDialog.vue +++ b/schoolNewsWeb/src/views/admin/manage/ai/components/DocumentSegmentDialog.vue @@ -1,24 +1,30 @@