소스 검색

知识库文档内容展示

huangguoce 1 주 전
부모
커밋
09a959c0e7

+ 38 - 6
src/main/java/com/jeeplus/modules/knowledgeSharing/dify/DifyApiClient.java

@@ -147,7 +147,7 @@ public class DifyApiClient {
     public static Boolean createByFileDifyApi(InputStream fileInputStream, String fileName, String id) throws Exception {
         try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
             String url = MessageFormat.format(
-                    "http://3081089em4.wicp.vip:20667/v1/datasets/{0}/document/create-by-file",
+                    API_URL+"/{0}/document/create-by-file",
                     id
             );
             HttpPost httpPost = new HttpPost(url);
@@ -269,14 +269,12 @@ public class DifyApiClient {
      * @return
      * @throws Exception
      */
-    public static JSONObject selectKnowledgeBaseList(Page<KnowledgeBase> page, KnowledgeBase knowledgeBase) throws Exception {
+    public static JSONObject selectKnowledgeBaseList(int pageNo,int pageSize, KnowledgeBase knowledgeBase) throws Exception {
         // 创建 HTTP 客户端
         try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
-            int pageNo = page.getPageNo();
-            int pageSize = page.getPageSize();
 
             // 创建 GET 请求,动态替换 URL 中的 page 和 limit 参数
-            String url = String.format("http://3081089em4.wicp.vip:20667/v1/datasets?page=%d&limit=%d", pageNo, pageSize);
+            String url = String.format(API_URL+"?page=%d&limit=%d", pageNo, pageSize);
             HttpGet httpGet = new HttpGet(url);
 
             // 设置请求头
@@ -308,7 +306,7 @@ public class DifyApiClient {
         // 创建 HTTP 客户端
         try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
             String url = MessageFormat.format(
-                    "http://3081089em4.wicp.vip:20667/v1/datasets/{0}/documents?page={1}&limit={2}",
+                    API_URL+"/{0}/documents?page={1}&limit={2}",
                     id, pageNo, pageSize
             );
             if(StringUtils.isNotBlank(fileName)){
@@ -335,4 +333,38 @@ public class DifyApiClient {
     }
 
 
+    /**
+     * 获取文档内容
+     *
+     * @return
+     * @throws Exception
+     */
+    public static JSONObject findDocContent( String datasetId,String docId) throws Exception {
+        // 创建 HTTP 客户端
+        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
+            String url = MessageFormat.format(
+                    API_URL+"/{0}/documents/{1}/segments",
+                    datasetId, docId
+            );
+
+            HttpGet httpGet = new HttpGet(url);
+            // 设置请求头
+            httpGet.setHeader("Authorization", "Bearer " + API_KEY);
+
+            // 执行请求并获取响应
+            try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
+                HttpEntity responseEntity = response.getEntity();
+
+                String responseString = EntityUtils.toString(responseEntity, "UTF-8");
+                if (response.getStatusLine().getStatusCode() == 200) {
+                    return new JSONObject(responseString);
+                } else {
+                    throw new RuntimeException("API request failed with status code: "
+                            + response.getStatusLine().getStatusCode() + "\nResponse: " + responseString);
+                }
+            }
+        }
+    }
+
+
 }

+ 108 - 0
src/main/java/com/jeeplus/modules/knowledgeSharing/entity/ChildChunk.java

@@ -0,0 +1,108 @@
+package com.jeeplus.modules.knowledgeSharing.entity;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import com.alibaba.fastjson.parser.DefaultJSONParser;
+import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer;
+import com.jeeplus.common.persistence.DataEntity;
+
+import java.lang.reflect.Type;
+import java.util.Date;
+
+/**
+ * 知识库详情
+ * @author 徐滕
+ * @create 2022-04-11 09:31
+ */
+public class ChildChunk extends DataEntity<ChildChunk> {
+
+
+    @JSONField(name = "id")
+    private String id;
+
+    @JSONField(name = "word_count")
+    private int wordCount;
+
+    @JSONField(name = "updated_at")
+    private Date updatedAt;
+
+    @JSONField(name = "created_at")
+    private Date createdAt;
+
+    @JSONField(name = "position")
+    private int position;
+
+    @JSONField(name = "segment_id")
+    private String segmentId;
+
+    @JSONField(name = "type")
+    private String type;
+
+    @JSONField(name = "content")
+    private String content;
+
+    // Getter and Setter 方法
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public int getWordCount() {
+        return wordCount;
+    }
+
+    public void setWordCount(int wordCount) {
+        this.wordCount = wordCount;
+    }
+
+    public Date getUpdatedAt() {
+        return updatedAt;
+    }
+
+    public void setUpdatedAt(long updatedAt) {
+        this.updatedAt = new Date(updatedAt * 1000); // 将 Unix 时间戳转为 Date
+    }
+
+    public Date getCreatedAt() {
+        return createdAt;
+    }
+
+    public void setCreatedAt(long createdAt) {
+        this.createdAt = new Date(createdAt * 1000); // 将 Unix 时间戳转为 Date
+    }
+
+    public int getPosition() {
+        return position;
+    }
+
+    public void setPosition(int position) {
+        this.position = position;
+    }
+
+    public String getSegmentId() {
+        return segmentId;
+    }
+
+    public void setSegmentId(String segmentId) {
+        this.segmentId = segmentId;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public String getContent() {
+        return content;
+    }
+
+    public void setContent(String content) {
+        this.content = content;
+    }
+
+}

+ 27 - 24
src/main/java/com/jeeplus/modules/knowledgeSharing/entity/KnowledgeBase.java

@@ -1,5 +1,6 @@
 package com.jeeplus.modules.knowledgeSharing.entity;
 
+import com.alibaba.fastjson.annotation.JSONField;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
 import com.jeeplus.common.persistence.DataEntity;
@@ -9,68 +10,70 @@ import java.util.Date;
 import java.util.List;
 
 public class KnowledgeBase extends DataEntity<KnowledgeBase> {
-    @JsonProperty("document_count")
+    @JSONField(name = "document_count")
     private int documentCount;
-    @JsonProperty("indexing_technique")
+
+    @JSONField(name = "indexing_technique")
     private String indexingTechnique;
-    @JsonProperty("retrieval_model_dict")
+
+    @JSONField(name = "retrieval_model_dict")
     private RetrievalModelDict retrievalModelDict;
-    @JsonProperty("external_retrieval_model")
+
+    @JSONField(name = "external_retrieval_model")
     private ExternalRetrievalModel externalRetrievalModel;
-    @JsonProperty("embedding_model")
+
+    @JSONField(name = "embedding_model")
     private String embeddingModel;
 
-    @JsonProperty("doc_form")
+    @JSONField(name = "doc_form")
     private String docForm;
 
-    @JsonProperty("description")
+    @JSONField(name = "description")
     private String description;
 
-
-    @JsonProperty("created_at")
-    @JsonDeserialize(converter = CustomDateConverter.class)
+    @JSONField(name = "created_at", format = "yyyy-MM-dd HH:mm:ss")
     private Date createdAt;
 
-    @JsonProperty("permission")
+    @JSONField(name = "permission")
     private String permission;
 
-    @JsonProperty("data_source_type")
+    @JSONField(name = "data_source_type")
     private String dataSourceType;
 
-    @JsonProperty("created_by")
+    @JSONField(name = "created_by")
     private String createdBy;
 
-    @JsonProperty("tags")
+    @JSONField(name = "tags")
     private List<String> tags;
 
-    @JsonProperty("embedding_model_provider")
+    @JSONField(name = "embedding_model_provider")
     private String embeddingModelProvider;
 
-    @JsonProperty("word_count")
+    @JSONField(name = "word_count")
     private int wordCount;
 
-    @JsonProperty("updated_at")
+    @JSONField(name = "updated_at", format = "yyyy-MM-dd HH:mm:ss")
     private Date updatedAt;
 
-    @JsonProperty("provider")
+    @JSONField(name = "provider")
     private String provider;
 
-    @JsonProperty("name")
+    @JSONField(name = "name")
     private String name;
 
-    @JsonProperty("updated_by")
+    @JSONField(name = "updated_by")
     private String updatedBy;
 
-    @JsonProperty("external_knowledge_info")
+    @JSONField(name = "external_knowledge_info")
     private ExternalKnowledgeInfo externalKnowledgeInfo;
 
-    @JsonProperty("id")
+    @JSONField(name = "id")
     private String id;
 
-    @JsonProperty("embedding_available")
+    @JSONField(name = "embedding_available")
     private boolean embeddingAvailable;
 
-    @JsonProperty("app_count")
+    @JSONField(name = "app_count")
     private int appCount;
 
     //所属的文档列表

+ 52 - 21
src/main/java/com/jeeplus/modules/knowledgeSharing/entity/KnowledgeBaseDoc.java

@@ -1,9 +1,14 @@
 package com.jeeplus.modules.knowledgeSharing.entity;
 
+import com.alibaba.fastjson.annotation.JSONField;
+import com.alibaba.fastjson.parser.DefaultJSONParser;
+import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.jeeplus.common.persistence.DataEntity;
 
+import java.lang.reflect.Type;
 import java.util.Date;
+import java.util.List;
 
 /**
  * 知识库详情
@@ -16,70 +21,80 @@ public class KnowledgeBaseDoc  extends DataEntity<KnowledgeBaseDoc> {
 
     private String parentName;
 
-    @JsonProperty("indexing_status")
+    @JSONField(name = "indexing_status")
     private String indexingStatus;
 
-    @JsonProperty("data_source_info")
+    @JSONField(name = "data_source_info")
     private DataSourceInfo dataSourceInfo;
 
-    @JsonProperty("disabled_at")
+    @JSONField(name = "disabled_at")
     private Long disabledAt;
 
-    @JsonProperty("doc_form")
+    @JSONField(name = "doc_form")
     private String docForm;
 
-    @JsonProperty("created_at")
+    @JSONField(name = "created_at")
     private Date createdAt;
 
-    @JsonProperty("data_source_type")
+    @JSONField(name = "data_source_type")
     private String dataSourceType;
 
-    @JsonProperty("disabled_by")
+    @JSONField(name = "disabled_by")
     private String disabledBy;
 
-    @JsonProperty("error")
+    @JSONField(name = "error")
     private String error;
 
-    @JsonProperty("created_by")
+    @JSONField(name = "created_by")
     private String createdBy;
 
-    @JsonProperty("enabled")
+    @JSONField(name = "enabled")
     private Boolean enabled;
 
-    @JsonProperty("archived")
+    @JSONField(name = "archived")
     private Boolean archived;
 
-    @JsonProperty("word_count")
+    @JSONField(name = "word_count")
     private Integer wordCount;
 
-    @JsonProperty("data_source_detail_dict")
+    @JSONField(name = "data_source_detail_dict")
     private DataSourceDetailDict dataSourceDetailDict;
 
-    @JsonProperty("name")
+    @JSONField(name = "name")
     private String name;
 
-    @JsonProperty("tokens")
+    @JSONField(name = "tokens")
     private Integer tokens;
 
-    @JsonProperty("id")
+    @JSONField(name = "id")
     private String id;
 
-    @JsonProperty("position")
+    @JSONField(name = "position")
     private Integer position;
 
-    @JsonProperty("hit_count")
+    @JSONField(name = "hit_count")
     private Integer hitCount;
 
-    @JsonProperty("created_from")
+    @JSONField(name = "created_from")
     private String createdFrom;
 
-    @JsonProperty("display_status")
+    @JSONField(name = "display_status")
     private String displayStatus;
 
-    @JsonProperty("dataset_process_rule_id")
+    @JSONField(name = "dataset_process_rule_id")
     private String datasetProcessRuleId;
 
 
+    private Integer isAdmin;      //登陆人是否为管理员
+
+    public Integer getIsAdmin() {
+        return isAdmin;
+    }
+
+    public void setIsAdmin(Integer isAdmin) {
+        this.isAdmin = isAdmin;
+    }
+
     public String getParentId() {
         return parentId;
     }
@@ -263,4 +278,20 @@ public class KnowledgeBaseDoc  extends DataEntity<KnowledgeBaseDoc> {
     public void setDatasetProcessRuleId(String datasetProcessRuleId) {
         this.datasetProcessRuleId = datasetProcessRuleId;
     }
+
+    public static class CustomTimestampDeserializer implements ObjectDeserializer {
+        @Override
+        public <T> T deserialze(DefaultJSONParser parser, Type type, Object fieldName) {
+            Long timestamp = parser.parseObject(Long.class);  // 获取时间戳,假设传递的是秒级时间戳
+            if (timestamp != null) {
+                return (T) new Date(timestamp * 1000);  // 转换为毫秒级时间戳
+            }
+            return null;
+        }
+
+        @Override
+        public int getFastMatchToken() {
+            return 0;
+        }
+    }
 }

+ 293 - 0
src/main/java/com/jeeplus/modules/knowledgeSharing/entity/KnowledgeBaseDocContent.java

@@ -0,0 +1,293 @@
+package com.jeeplus.modules.knowledgeSharing.entity;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.jeeplus.common.persistence.DataEntity;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 知识库文档内容
+ * @author 徐滕
+ * @create 2022-04-11 09:31
+ */
+public class KnowledgeBaseDocContent extends DataEntity<KnowledgeBaseDocContent> {
+
+    @JSONField(name  = "keywords")
+    private String keywords;
+
+    @JSONField(name = "index_node_id")
+    private String indexNodeId;
+
+    @JSONField(name = "indexing_at")
+    private Long indexingAt;
+
+    @JSONField(name = "created_at")
+    private Date createdAt;
+
+    @JSONField(name = "disabled_by")
+    private String disabledBy;
+
+    @JSONField(name = "document_id")
+    private String documentId;
+
+    @JSONField(name = "error")
+    private String error;
+
+    @JSONField(name = "content")
+    private String content;
+
+    @JSONField(name = "enabled")
+    private Boolean enabled;
+
+    @JSONField(name = "word_count")
+    private Integer wordCount;
+
+    @JSONField(name = "updated_at")
+    private Date updatedAt;
+
+    @JSONField(name = "tokens")
+    private Integer tokens;
+
+    @JSONField(name = "id")
+    private String id;
+
+    @JSONField(name = "hit_count")
+    private String hitCount;
+
+    @JSONField(name = "stopped_at")
+    private Long stoppedAt;
+
+    @JSONField(name = "sign_content")
+    private String signContent;
+
+    @JSONField(name = "disabled_at")
+    private Long disabledAt;
+
+    @JSONField(name = "created_by")
+    private String createdBy;
+
+    @JSONField(name = "completed_at")
+    private Long completedAt;
+
+    @JSONField(name = "answer")
+    private String answer;
+
+    @JSONField(name = "updated_by")
+    private String updatedBy;
+
+    @JSONField(name = "position")
+    private Integer position;
+
+    @JSONField(name = "index_node_hash")
+    private String indexNodeHash;
+
+    @JSONField(name = "status")
+    private String status;
+
+    public List<ChildChunk> getChildChunks() {
+        return childChunks;
+    }
+
+    public void setChildChunks(List<ChildChunk> childChunks) {
+        this.childChunks = childChunks;
+    }
+
+    @JSONField(name = "child_chunks")
+    private List<ChildChunk> childChunks;
+
+    public String getKeywords() {
+        return keywords;
+    }
+
+    public void setKeywords(String keywords) {
+        this.keywords = keywords;
+    }
+
+    public String getIndexNodeId() {
+        return indexNodeId;
+    }
+
+    public void setIndexNodeId(String indexNodeId) {
+        this.indexNodeId = indexNodeId;
+    }
+
+    public Long getIndexingAt() {
+        return indexingAt;
+    }
+
+    public void setIndexingAt(Long indexingAt) {
+        this.indexingAt = indexingAt;
+    }
+
+    public Date getCreatedAt() {
+        return createdAt;
+    }
+
+    public void setCreatedAt(Date createdAt) {
+        this.createdAt = createdAt;
+    }
+
+    public String getDisabledBy() {
+        return disabledBy;
+    }
+
+    public void setDisabledBy(String disabledBy) {
+        this.disabledBy = disabledBy;
+    }
+
+    public String getDocumentId() {
+        return documentId;
+    }
+
+    public void setDocumentId(String documentId) {
+        this.documentId = documentId;
+    }
+
+    public String getError() {
+        return error;
+    }
+
+    public void setError(String error) {
+        this.error = error;
+    }
+
+    public String getContent() {
+        return content;
+    }
+
+    public void setContent(String content) {
+        this.content = content;
+    }
+
+    public Boolean getEnabled() {
+        return enabled;
+    }
+
+    public void setEnabled(Boolean enabled) {
+        this.enabled = enabled;
+    }
+
+    public Integer getWordCount() {
+        return wordCount;
+    }
+
+    public void setWordCount(Integer wordCount) {
+        this.wordCount = wordCount;
+    }
+
+    public Date getUpdatedAt() {
+        return updatedAt;
+    }
+
+    public void setUpdatedAt(Date updatedAt) {
+        this.updatedAt = updatedAt;
+    }
+
+    public Integer getTokens() {
+        return tokens;
+    }
+
+    public void setTokens(Integer tokens) {
+        this.tokens = tokens;
+    }
+
+    @Override
+    public String getId() {
+        return id;
+    }
+
+    @Override
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getHitCount() {
+        return hitCount;
+    }
+
+    public void setHitCount(String hitCount) {
+        this.hitCount = hitCount;
+    }
+
+    public Long getStoppedAt() {
+        return stoppedAt;
+    }
+
+    public void setStoppedAt(Long stoppedAt) {
+        this.stoppedAt = stoppedAt;
+    }
+
+    public String getSignContent() {
+        return signContent;
+    }
+
+    public void setSignContent(String signContent) {
+        this.signContent = signContent;
+    }
+
+    public Long getDisabledAt() {
+        return disabledAt;
+    }
+
+    public void setDisabledAt(Long disabledAt) {
+        this.disabledAt = disabledAt;
+    }
+
+    public String getCreatedBy() {
+        return createdBy;
+    }
+
+    public void setCreatedBy(String createdBy) {
+        this.createdBy = createdBy;
+    }
+
+    public Long getCompletedAt() {
+        return completedAt;
+    }
+
+    public void setCompletedAt(Long completedAt) {
+        this.completedAt = completedAt;
+    }
+
+    public String getAnswer() {
+        return answer;
+    }
+
+    public void setAnswer(String answer) {
+        this.answer = answer;
+    }
+
+    public String getUpdatedBy() {
+        return updatedBy;
+    }
+
+    public void setUpdatedBy(String updatedBy) {
+        this.updatedBy = updatedBy;
+    }
+
+    public Integer getPosition() {
+        return position;
+    }
+
+    public void setPosition(Integer position) {
+        this.position = position;
+    }
+
+    public String getIndexNodeHash() {
+        return indexNodeHash;
+    }
+
+    public void setIndexNodeHash(String indexNodeHash) {
+        this.indexNodeHash = indexNodeHash;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    public void setStatus(String status) {
+        this.status = status;
+    }
+}

+ 51 - 75
src/main/java/com/jeeplus/modules/knowledgeSharing/service/KnowledgeBaseService.java

@@ -1,5 +1,7 @@
 package com.jeeplus.modules.knowledgeSharing.service;
 
+import com.alibaba.fastjson.JSON;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.gson.Gson;
 import com.jeeplus.common.persistence.Page;
 import com.jeeplus.modules.knowledgeSharing.dify.DifyApiClient;
@@ -15,76 +17,28 @@ import java.util.List;
 
 /**
  * 知识分享Service
+ *
  * @author 徐滕
  * @create 2022-4-11 9:17
  */
 @Service
 @Transactional(readOnly = true)
-public class KnowledgeBaseService  {
-
-    public  Page<KnowledgeBase> findKnowledgePage(Page<KnowledgeBase> page,KnowledgeBase knowledgeBase) throws Exception {
-        JSONObject jsonObject = DifyApiClient.selectKnowledgeBaseList(page,knowledgeBase);
+public class KnowledgeBaseService {
 
+    public Page<KnowledgeBase> findKnowledgePage(Page<KnowledgeBase> page, KnowledgeBase knowledgeBase) throws Exception {
+        int pageNo = page.getPageNo();
+        int pageSize = page.getPageSize();
+        JSONObject jsonObject = DifyApiClient.selectKnowledgeBaseList(pageNo, pageSize, knowledgeBase);
         JSONArray data = jsonObject.getJSONArray("data");
-
-        //格式转换
-        List<KnowledgeBase> knowledgeBaseList = new ArrayList<>();
-        for (int i = 0; i < data.length(); i++) {
-            JSONObject item = data.getJSONObject(i);
-            KnowledgeBase temp = new KnowledgeBase();
-            temp.setId(item.getString("id"));
-            temp.setDocumentCount(item.getInt("document_count"));
-            temp.setIndexingTechnique(item.getString("indexing_technique"));
-
-            JSONObject retrievalModelDict = item.getJSONObject("retrieval_model_dict");
-            Gson gson = new Gson();
-            RetrievalModelDict retrievalModel = gson.fromJson(retrievalModelDict.toString(), RetrievalModelDict.class);
-            temp.setRetrievalModelDict(retrievalModel);
-
-            JSONObject externalRetrievalModel = item.getJSONObject("external_retrieval_model");
-            ExternalRetrievalModel externalRetrieval = gson.fromJson(externalRetrievalModel.toString(), ExternalRetrievalModel.class);
-            temp.setExternalRetrievalModel(externalRetrieval);
-
-            temp.setEmbeddingModel(item.getString("embedding_model"));
-            temp.setDocForm(item.getString("doc_form"));
-            temp.setDescription(item.getString("description"));
-
-
-            long createdAt = item.getLong("created_at");
-            Date createdAtDate = new Date(createdAt * 1000);  // 转换为Date对象
-            temp.setCreatedAt(createdAtDate);  // 设置
-
-            temp.setPermission(item.getString("permission"));
-            temp.setDataSourceType(item.getString("data_source_type"));
-            temp.setCreatedBy(item.getString("created_by"));
-
-            JSONArray tags = item.getJSONArray("tags");
-            List<String> tagsList = new ArrayList<>();
-            for (int j = 0; j < tags.length(); j++) {
-                tagsList.add(tags.getString(i));
+        List<KnowledgeBase> knowledgeBaseList = JSON.parseArray(data.toString(), KnowledgeBase.class);
+        for (KnowledgeBase doc : knowledgeBaseList) {
+            if (doc.getCreatedAt() != null) {
+                doc.setCreatedAt(new Date(doc.getCreatedAt().getTime() * 1000));
+            }
+            if (doc.getUpdatedAt() != null) {
+                doc.setUpdatedAt(new Date(doc.getUpdatedAt().getTime() * 1000));
             }
-            temp.setTags(tagsList);
-
-            temp.setEmbeddingModelProvider(item.getString("embedding_model_provider"));
-            temp.setWordCount(item.getInt("word_count"));
-
-            long updatedAt = item.getLong("updated_at");
-            Date updateAtDate = new Date(updatedAt * 1000);  // 转换为Date对象
-            temp.setUpdatedAt(updateAtDate);  // 设置
-
-            temp.setProvider(item.getString("provider"));
-            temp.setName(item.getString("name"));
-
-            temp.setUpdatedBy(item.getString("updated_by"));
-
-            JSONObject externalKnowledgeInfo = item.getJSONObject("external_knowledge_info");
-            ExternalKnowledgeInfo externalKnowledge = gson.fromJson(externalKnowledgeInfo.toString(), ExternalKnowledgeInfo.class);
-            temp.setExternalKnowledgeInfo(externalKnowledge);
-            temp.setEmbeddingAvailable(item.getBoolean("embedding_available"));
-            temp.setAppCount(item.getInt("app_count"));
-            knowledgeBaseList.add(temp);
         }
-
         //总数
         int total = jsonObject.getInt("total");
         page.setCount(total);
@@ -97,26 +51,20 @@ public class KnowledgeBaseService  {
 
     /**
      * 获取知识库详情数据
+     *
      * @param knowledgeBaseDoc
      */
-    public   Page<KnowledgeBaseDoc> findKnowledgeBaseById(Page<KnowledgeBaseDoc> page,KnowledgeBaseDoc knowledgeBaseDoc) throws Exception {
+    public Page<KnowledgeBaseDoc> findKnowledgeBaseById(Page<KnowledgeBaseDoc> page, KnowledgeBaseDoc knowledgeBaseDoc) throws Exception {
         int pageSize = page.getPageSize();
         int pageNo = page.getPageNo();
-        JSONObject knowledgeBaseDocList = DifyApiClient.findKnowledgeBaseById(pageNo,pageSize,knowledgeBaseDoc.getParentId(),knowledgeBaseDoc.getName());
-        System.out.println(knowledgeBaseDocList);
-        List<KnowledgeBaseDoc> knowledgeBaseDocArrayList = new ArrayList<>();
-        
+        JSONObject knowledgeBaseDocList = DifyApiClient.findKnowledgeBaseById(pageNo, pageSize, knowledgeBaseDoc.getParentId(), knowledgeBaseDoc.getName());
         JSONArray data = knowledgeBaseDocList.getJSONArray("data");
-        for (int i = 0; i < data.length(); i++) {
-            JSONObject item = data.getJSONObject(i);
-            KnowledgeBaseDoc knowledgeBaseDoc1 = new KnowledgeBaseDoc();
-            knowledgeBaseDoc1.setName(item.getString("name"));
-            knowledgeBaseDoc1.setWordCount(item.getInt("word_count"));
-            long createAt = item.getLong("created_at");
-            Date date = new Date(createAt* 1000);
+        List<KnowledgeBaseDoc> knowledgeBaseDocArrayList = JSON.parseArray(data.toString(), KnowledgeBaseDoc.class);
+        for (KnowledgeBaseDoc doc : knowledgeBaseDocArrayList) {
+            if (doc.getCreatedAt() != null) {
+                doc.setCreatedAt(new Date(doc.getCreatedAt().getTime() * 1000));
+            }
 
-            knowledgeBaseDoc1.setCreatedAt(date );
-            knowledgeBaseDocArrayList.add(knowledgeBaseDoc1);
         }
         //总数
         int total = knowledgeBaseDocList.getInt("total");
@@ -127,4 +75,32 @@ public class KnowledgeBaseService  {
         return page;
     }
 
+
+    /**
+     * 获取文档分段内容
+     *
+     * @param knowledgeBaseDoc
+     */
+    public List<KnowledgeBaseDocContent> findDocContent(KnowledgeBaseDoc knowledgeBaseDoc) throws Exception {
+        JSONObject knowledgeBaseDocList = DifyApiClient.findDocContent(knowledgeBaseDoc.getParentId(), knowledgeBaseDoc.getId());
+        JSONArray data = knowledgeBaseDocList.getJSONArray("data");
+        String jsonString = data.toString();
+        List<KnowledgeBaseDocContent> knowledgeBaseDocContentList = JSON.parseArray(jsonString, KnowledgeBaseDocContent.class);
+        for (KnowledgeBaseDocContent doc : knowledgeBaseDocContentList) {
+            if (doc.getCreatedAt() != null) {
+                doc.setCreatedAt(new Date(doc.getCreatedAt().getTime() * 1000));
+            }
+            if (doc.getUpdatedAt() != null) {
+                doc.setUpdatedAt(new Date(doc.getUpdatedAt().getTime() * 1000));
+            }
+
+        }
+        return knowledgeBaseDocContentList;
+    }
+
+    public static String markdownToHtmlSimple(String markdown) {
+        // 转换图片语法 ![alt](url) => <img src="url" alt="alt" />
+        return markdown.replaceAll("!\\[(.*?)\\]\\((.*?)\\)", "<img src=\"$2\" alt=\"$1\" style=\"max-width: 100%;\"/>");
+    }
+
 }

+ 39 - 2
src/main/java/com/jeeplus/modules/knowledgeSharing/web/KnowledgeBaseController.java

@@ -6,6 +6,7 @@ import com.jeeplus.common.utils.StringUtils;
 import com.jeeplus.modules.knowledgeSharing.dify.DifyApiClient;
 import com.jeeplus.modules.knowledgeSharing.entity.KnowledgeBase;
 import com.jeeplus.modules.knowledgeSharing.entity.KnowledgeBaseDoc;
+import com.jeeplus.modules.knowledgeSharing.entity.KnowledgeBaseDocContent;
 import com.jeeplus.modules.knowledgeSharing.service.KnowledgeBaseService;
 import com.jeeplus.modules.sys.utils.UserUtils;
 import org.apache.commons.fileupload.servlet.ServletFileUpload;
@@ -59,7 +60,6 @@ public class KnowledgeBaseController {
      * @param model
      * @return
      */
-    //@RequiresPermissions(value={"knowledgeSharing:knowledgeSharing:add","knowledgeSharing:knowledgeSharing:edit"},logical= Logical.OR)
     @RequestMapping(value = "form")
     public String form(KnowledgeBaseDoc knowledgeBaseDoc, HttpServletRequest request, HttpServletResponse response, Model model) throws Exception {
         Page<KnowledgeBaseDoc> page = new Page<>(request, response);
@@ -69,13 +69,50 @@ public class KnowledgeBaseController {
             knowledgeBaseDoc.setCreateBy(UserUtils.getUser());
             knowledgeBaseDoc.setCreateDate(new Date());
         }
-
+        if(UserUtils.getUser().isAdmin()){
+            knowledgeBaseDoc.setIsAdmin(1);
+        }else{
+            knowledgeBaseDoc.setIsAdmin(0);
+        }
         model.addAttribute("knowledgeBaseDoc", knowledgeBaseDoc);
         model.addAttribute("pages", page);
         return "modules/knowledgeSharing/knowledgeBaseDetailsForm";
     }
 
+    /**
+     * 查看知识库文档内容
+     *
+     * @param knowledgeBaseDoc
+     * @param model
+     * @return
+     */
+    @RequiresPermissions(value={"KnowledgeBase:KnowledgeBase:viewDoc"})
+    @RequestMapping(value = "docContent")
+    public String docContent(KnowledgeBaseDoc knowledgeBaseDoc, HttpServletRequest request, HttpServletResponse response, Model model) {
+        List<KnowledgeBaseDocContent> docContentList = new ArrayList<>();
+        try {
+            if (knowledgeBaseDoc != null && StringUtils.isNotBlank(knowledgeBaseDoc.getParentId())) {
+                docContentList = service.findDocContent(knowledgeBaseDoc);
+            } else {
+                knowledgeBaseDoc.setCreateBy(UserUtils.getUser());
+                knowledgeBaseDoc.setCreateDate(new Date());
+            }
+        } catch (Exception e) {
+            model.addAttribute("errorMsg", "加载文档内容失败,请刷新后重试");
+        }
+
+        model.addAttribute("knowledgeBaseDoc", knowledgeBaseDoc);
+        model.addAttribute("docContentList", docContentList);
+        return "modules/knowledgeSharing/knowledgeBaseDocForm";
+    }
 
+    /**
+     * 上传文件
+     *
+     * @param files
+     * @param id
+     * @return
+     */
     @RequiresPermissions(value={"knowledgeBase:knowledgeBase:upload"})
     @RequestMapping(value = "uploadFile")
     public Object uploadFile(@RequestParam(value = "files") MultipartFile[] files,@RequestParam(value = "id") String id, HttpServletRequest request, HttpServletResponse response) throws Exception {

+ 47 - 7
src/main/webapp/webpage/modules/knowledgeSharing/knowledgeBaseDetailsForm.jsp

@@ -59,18 +59,29 @@
                     {field: 'name', align: 'center', title: '名称'},
                     {field: 'wordCount', align: 'center', title: '字符数'},
                     {field: 'createdAt', align: 'center', title: '上传时间'},
-
+                    {align:'center',title:"操作",width:150,templet: function(d) {
+                            var parentId = '${knowledgeBaseDoc.parentId}';
+                            var url = '${ctx}/knowledgeBase/knowledgeBase/docContent?name=' + d.name +'&parentId=' + parentId + '&id=' + d.id;
+                            var xml = "<div class=\"layui-btn-group\">";
+                            if((d.canview != undefined && d.canview == "1") || d.isAdmin == "1")
+                                xml += "<a href=\"javascript:void(0)\" onclick=\"openInfoDialog('查看文档内容', '" + url + "', '70%', '95%')\" class=\"layui-btn layui-btn-xs layui-bg-green\"> 查看文档</a>";
+                            xml += "</div>";
+                            return xml;
+                        }
+                    }
                 ]]
                 , data: [
                     <c:if test="${ not empty pages.list}">
-                    <c:forEach items="${pages.list}" var="knowledgeBaseDoc" varStatus="index">
+                    <c:forEach items="${pages.list}" var="docInfo" varStatus="index">
                     <c:if test="${index.index != 0}">, </c:if>
                     {
-                        "id": "${knowledgeBaseDoc.id}",
-                        "name": "${knowledgeBaseDoc.name}",
-                        "wordCount": "${knowledgeBaseDoc.wordCount}",
-                        "createdAt": "<fmt:formatDate value="${knowledgeBaseDoc.createdAt}" pattern="yyyy-MM-dd HH:mm:ss"/>"
-                    }
+                        "id": "${docInfo.id}",
+                        "name": "${docInfo.name}",
+                        "wordCount": "${docInfo.wordCount}",
+                        "createdAt": "<fmt:formatDate value="${docInfo.createdAt}" pattern="yyyy-MM-dd HH:mm:ss"/>",
+                        "isAdmin" : "${knowledgeBaseDoc.isAdmin}"
+                        , <shiro:hasPermission name="knowledgeBase:knowledgeBase:viewDoc">"canview" : "1"</shiro:hasPermission>
+        }
                     </c:forEach>
                     </c:if>
                 ]
@@ -150,6 +161,33 @@
             xhr.send(formData);
         }
 
+
+        function openInfoDialog(title,url,width,height,target) {
+
+            if (navigator.userAgent.match(/(iPhone|iPod|Android|ios)/i)) {//如果是移动端,就使用自适应大小弹窗
+                width = 'auto';
+                height = 'auto';
+            } else {//如果是PC端,根据用户设置的width和height显示。
+
+            }
+
+            top.layer.open({
+                type: 2,
+                area: [width, height],
+                title: title,
+                maxmin: true, //开启最大化最小化按钮
+                content: url,
+                skin: 'two-btns',
+                btn: ['确定', '关闭'],
+                btn1: function(index, layero){
+                    top.layer.close(index);
+                },
+                btn2: function (index) {
+                }
+            });
+        }
+
+
     </script>
 </head>
 <body>
@@ -176,6 +214,8 @@
                     <div class="layui-item layui-col-xs12" >
                         <div class="nav-btns" style="padding-left: 0!important;">
                             <div class="layui-btn-group">
+                                <button class="layui-btn layui-btn-sm" data-toggle="tooltip" data-placement="left" onclick="sortOrRefresh()" title="刷新"> 刷新</button>
+
                                 <shiro:hasPermission name="knowledgeBase:knowledgeBase:upload">
                                     <!-- multiple 支持多选 -->
                                     <input type="file" id="uploadFileInput" style="display: none;" multiple onchange="uploadFile()" />

+ 191 - 0
src/main/webapp/webpage/modules/knowledgeSharing/knowledgeBaseDocForm.jsp

@@ -0,0 +1,191 @@
+<%@ page contentType="text/html;charset=UTF-8" %>
+<%@ include file="/webpage/include/taglib.jsp" %>
+
+<html>
+<head>
+    <title>知识库详情</title>
+    <meta name="decorator" content="default"/>
+    <script type="text/javascript" src="${ctxStatic}/helloweba_editable-select/jquery.editable-select.min.js"></script>
+    <script type="text/javascript" src="${ctxStatic}/iCheck/icheck.min.js"></script>
+    <script type="text/javascript" src="${ctxStatic}/layui/layui.js"></script>
+    <script src="${ctxStatic}/common/html/js/script.js"></script>
+
+    <link rel='stylesheet' type="text/css"
+          href="${ctxStatic}/helloweba_editable-select/jquery.editable-select.min.css"/>
+    <link rel='stylesheet' type="text/css" href="${ctxStatic}/layui/css/layui.css"/>
+    <style>
+        .doc-card{
+            display: flex;
+            flex-direction: column;
+            align-items: center;
+            margin-bottom: 20px;
+        }
+        .custom-blue {
+            width: 90%;
+            border-left: 5px solid #0f92fb !important;
+            background-color: #fff;
+            padding-bottom: 20px;
+            box-sizing: border-box;
+        }
+        .custom-blue:hover{
+            background-image: linear-gradient(180deg, #f2f4f7, #f9fafb);
+
+        }
+        .doc-info{
+            width: 100%;
+            display: flex;
+            margin-bottom: 20px;
+        }
+        .doc-left,.doc-right{
+            width: 50%;
+            display: flex;
+            align-items: center;
+        }
+        .doc-content{
+            text-indent: 2em;
+            font-size: 14px;
+            font-weight: 400;
+            line-height: 24px;
+        }
+        .doc-info-text{
+            font-size: 12px;
+            font-weight: 400;
+            line-height: 20px;
+            margin: 5px 0 !important;
+            margin-right: 12px !important;
+            color: #676f83;
+        }
+        .pad-box{
+            padding: 0 30px;
+            box-sizing: border-box;
+        }
+    </style>
+    <script type="text/javascript">
+        var validateForm;
+        var clientCount = 0;
+
+        function doSubmit(i) {//回调函数,在编辑和保存动作时,供openDialog调用提交表单。
+            if (validateForm.form()) {
+                $("#inputForm").submit();
+                return true;
+            }
+            return false;
+        }
+
+        $(document).ready(function () {
+            layui.use(['form', 'layer'], function () {
+                var form = layui.form;
+            });
+            validateForm = $("#inputForm").validate({
+                submitHandler: function (form) {
+                    loading('正在提交,请稍等...');
+                    form.submit();
+                },
+                errorContainer: "#messageBox",
+                errorPlacement: function (error, element) {
+                    $("#messageBox").text("输入有误,请先更正。");
+                    if (element.is(":checkbox") || element.is(":radio") || element.parent().is(".input-append")) {
+                        error.appendTo(element.parent().parent());
+                    } else {
+                        error.insertAfter(element);
+                    }
+                }
+            });
+
+        });
+
+
+    </script>
+</head>
+<body>
+<div class="single-form">
+    <div class="container">
+        <sys:message content="${message}"/>
+        <form:form id="inputForm" modelAttribute="knowledgeBaseDoc" action="${ctx}/knowledgeBase/knowledgeBase/form"
+                   method="post" class="form-horizontal layui-form">
+            <form:hidden id="parentId" path="parentId"/>
+            <input id="pageNo" name="pageNo" type="hidden" value="${pages.pageNo}"/>
+            <input id="pageSize" name="pageSize" type="hidden" value="${pages.pageSize}"/>
+            <table:sortColumn id="orderBy" name="orderBy" value="${pages.orderBy}" callback="sortOrRefresh();"/><!-- 支持排序 -->
+            <div class="form-group layui-row pad-box">
+                <div class="form-group-label"><h2>文档内容</h2></div>
+                <div class="layui-item layui-col-sm6 lw12">
+                    <label class="layui-form-label"><span class="require-item">*</span>文档名称:</label>
+                    <div class="layui-input-block">
+                        <form:input path="name" readonly="true" placeholder="name" htmlEscape="false"
+                                    class="form-control layui-input required"/>
+                    </div>
+                </div>
+            </div>
+            <div class="form-group layui-row pad-box" >
+                <div class="form-group-label"><h2>文档内容</h2></div>
+
+                <c:choose>
+                    <c:when test="${not empty errorMsg}">
+                        <div id="error-msg" style="display:none;">${errorMsg}</div>
+                        <script>
+                            layui.use('layer', function(){
+                                var layer = layui.layer;
+                                var msg = document.getElementById("error-msg").innerText;
+                                top.layer.alert(msg, { title: "提示", area: '300px' },
+                                     function(index){
+                                        // 关闭当前弹窗
+                                        top.layer.close(index);
+                                         // 关闭上一级弹窗
+                                         var iframeIndex = top.layer.getFrameIndex(window.name);
+                                         top.layer.close(iframeIndex);
+                                    });
+                            });
+                        </script>
+                    </c:when>
+                    <c:otherwise>
+                        <c:forEach var="doc" items="${docContentList}" varStatus="status">
+                            <div class="doc-card">
+                                <blockquote class="layui-elem-quote custom-blue">
+                                    <div class="doc-info">
+                                        <div class="doc-left">
+                                            <p class="doc-info-text">
+                                                父分段-${status.index + 1}
+                                            </p>
+                                            <p class="doc-info-text">
+                                                    ${doc.wordCount} 字符
+                                            </p>
+                                            <p class="doc-info-text">
+                                                    ${doc.hitCount} 召回次数
+                                            </p>
+                                            <p class="doc-info-text">
+                                                更新时间  <fmt:formatDate value="${doc.updatedAt}" pattern="yyyy-MM-dd HH:mm:ss"/>
+
+                                            </p>
+                                        </div>
+                                        <div class="doc-right">
+                                            <c:choose>
+                                                <c:when test="${doc.status == 'completed'}">
+                                                    <span class="layui-badge layui-bg-green">已启用</span>
+                                                </c:when>
+                                                <c:otherwise>
+                                                    <span class="layui-badge">未启用</span>
+                                                </c:otherwise>
+                                            </c:choose>
+                                        </div>
+                                    </div>
+                                    <p class="doc-content"><c:out value="${doc.content}" /></p>
+                                    <p class="doc-info-text" style="margin: 6px 0">
+                                            子分段
+                                    </p>
+                                    <c:forEach var="childChunk" items="${doc.childChunks}" varStatus="childChunksStatus">
+                                        <p class="doc-content" style="text-indent: 4em"><c:out value="${childChunk.content}" /></p>
+                                    </c:forEach>
+                                </blockquote>
+                            </div>
+                        </c:forEach>
+                    </c:otherwise>
+                </c:choose>
+            </div>
+            <div class="form-group layui-row page-end pad-box"></div>
+        </form:form>
+    </div>
+</div>
+</body>
+
+</html>

+ 2 - 1
src/main/webapp/webpage/modules/knowledgeSharing/knowledgeBaseList.jsp

@@ -53,6 +53,7 @@
 				btn: ['确定', '关闭'],
 				btn1: function(index, layero){
 					top.layer.close(index);
+
 				},
 				btn2: function (index) {
 				}
@@ -198,7 +199,7 @@
 				// {field:'createdBy', align:'center', width:80, title: '创建人'},
 				// {field:'tags', align:'center', width:120, title: '标签'},
 				// {field:'embeddingModelProvider', align:'center', width:80, title: '嵌入模型提供方'},
-				{field:'wordCount', align:'center', width:120, title: '单词数'},
+				{field:'wordCount', align:'center', width:120, title: '字符数'},
 				{field:'updatedAt', align:'center', title: '更新时间'},
 				// {field:'provider', align:'center', title: '提供方'},
 				// {field:'updatedBy', align:'center', width:80, title: '更新人'},