소스 검색

知识库列表和文件上传代码

huangguoce 1 주 전
부모
커밋
5054fb3d3c

+ 116 - 16
src/main/java/com/jeeplus/modules/knowledgeSharing/dify/DifyApiClient.java

@@ -1,5 +1,9 @@
 package com.jeeplus.modules.knowledgeSharing.dify;
 
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.common.utils.StringUtils;
+import com.jeeplus.modules.knowledgeSharing.entity.KnowledgeBase;
+import com.jeeplus.modules.knowledgeSharing.entity.KnowledgeBaseDoc;
 import org.apache.http.HttpEntity;
 import org.apache.http.client.methods.CloseableHttpResponse;
 import org.apache.http.client.methods.HttpGet;
@@ -17,32 +21,43 @@ import org.json.JSONArray;
 import org.json.JSONObject;
 
 import java.io.File;
+import java.io.InputStream;
 import java.net.URLEncoder;
 import java.nio.charset.StandardCharsets;
+import java.text.MessageFormat;
 
 /**
  * 知识分享Controller
+ *
  * @author 徐滕
  * @create 2022-04-11 09:20
  */
 public class DifyApiClient {
 
     // Dify API 密钥和端点
-    private static final String API_KEY = "app-rWTbPVHyPDLqWOqqWX1DQ6EQ"; // 替换为你的 Dify API 密钥
-    private static final String API_URL = "http://localhost/v1/chat-messages"; // 替换为实际的 Dify API 端点
+    //private static final String API_KEY = "app-rWTbPVHyPDLqWOqqWX1DQ6EQ"; // 替换为你的 Dify API 密钥
+    //private static final String API_URL = "http://localhost/v1/chat-messages"; // 替换为实际的 Dify API 端点
+
+    //开发
+    private static final String API_KEY = "dataset-TinelGDdnlrXJPyFe38iA0Zh";
+    private static final String API_URL = "http://3081089em4.wicp.vip:20667/v1/datasets";
+
+
+
 
     public static void main(String[] args) {
-        try {
-            // 调用 Dify API
-            JSONObject result = selectKnowledgeBaseList();
-            System.out.println("API Response: " + result.toString(4)); // 格式化输出 JSON 响应
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
+        //try {
+        //    // 调用 Dify API
+        //    JSONObject result = selectKnowledgeBaseList();
+        //    System.out.println("API Response: " + result.toString(4)); // 格式化输出 JSON 响应
+        //} catch (Exception e) {
+        //    e.printStackTrace();
+        //}
     }
 
     /**
      * 聊天窗查询
+     *
      * @return
      * @throws Exception
      */
@@ -86,6 +101,7 @@ public class DifyApiClient {
 
     /**
      * 通过文本创建文档
+     *
      * @return
      * @throws Exception
      */
@@ -128,12 +144,56 @@ 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",
+                    id
+            );
+            HttpPost httpPost = new HttpPost(url);
+
+            // 设置 Authorization 头
+            httpPost.setHeader("Authorization", "Bearer " + API_KEY);
+
+            // 构建 JSON 参数
+            JSONObject dataJson = new JSONObject();
+            dataJson.put("indexing_technique", "high_quality");
+
+            // 构建 Multipart 请求体
+            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
+            builder.setCharset(StandardCharsets.UTF_8); // 设置整个 multipart 编码为 UTF-8
+            builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
+
+            // 添加 JSON 文本部分
+            builder.addTextBody("data", dataJson.toString(), ContentType.APPLICATION_JSON);
+
+            // 添加文件部分
+            builder.addBinaryBody("file",
+                    fileInputStream,
+                    ContentType.APPLICATION_OCTET_STREAM,
+                    fileName);
+            // 设置最终请求体
+            httpPost.setEntity(builder.build());
+            // 执行请求
+            try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
+                HttpEntity responseEntity = response.getEntity();
+                EntityUtils.toString(responseEntity, "UTF-8");
+                if (response.getStatusLine().getStatusCode() == 200) {
+                    return true;
+                } else {
+                    return false;
+                }
+            }
+        }
+    }
+
     /**
-     * 通过文件创建文档
+     * 通过文件创建文档,暂未使用
+     *
      * @return
      * @throws Exception
      */
-    public static JSONObject createByFileDifyApi() throws Exception {
+    public static JSONObject createByFileDifyApi1() throws Exception {
         try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
             HttpPost httpPost = new HttpPost("http://localhost/v1/datasets/e2f96c65-8b83-4305-a404-609304ad355e/document/create-by-file");
 
@@ -203,20 +263,24 @@ public class DifyApiClient {
     }
 
 
-
     /**
      * 知识库文档列表
+     *
      * @return
      * @throws Exception
      */
-    public static JSONObject selectKnowledgeBaseList() throws Exception {
+    public static JSONObject selectKnowledgeBaseList(Page<KnowledgeBase> page, KnowledgeBase knowledgeBase) throws Exception {
         // 创建 HTTP 客户端
         try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
-            // 创建 GET 请求
-            HttpGet httpGet = new HttpGet("http://3081089em4.wicp.vip:20667/v1/datasets?page=1&limit=20");
+            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);
+            HttpGet httpGet = new HttpGet(url);
 
             // 设置请求头
-            httpGet.setHeader("Authorization", "Bearer dataset-TinelGDdnlrXJPyFe38iA0Zh");
+            httpGet.setHeader("Authorization", "Bearer "+API_KEY);
 
             // 执行请求并获取响应
             try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
@@ -234,5 +298,41 @@ public class DifyApiClient {
         }
     }
 
+    /**
+     * 知识库文档列表
+     *
+     * @return
+     * @throws Exception
+     */
+    public static JSONObject findKnowledgeBaseById(int pageNo,int pageSize, String id,String fileName) throws Exception {
+        // 创建 HTTP 客户端
+        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
+            String url = MessageFormat.format(
+                    "http://3081089em4.wicp.vip:20667/v1/datasets/{0}/documents?page={1}&limit={2}",
+                    id, pageNo, pageSize
+            );
+            if(StringUtils.isNotBlank(fileName)){
+                url = url + "&keyword=" + fileName;
+            }
+
+            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);
+                }
+            }
+        }
+    }
+
 
 }

+ 19 - 0
src/main/java/com/jeeplus/modules/knowledgeSharing/entity/DataSourceDetailDict.java

@@ -0,0 +1,19 @@
+package com.jeeplus.modules.knowledgeSharing.entity;
+
+/**
+ * 知识库详情关联类
+ * @author 徐滕
+ * @create 2022-04-11 09:31
+ */
+public class DataSourceDetailDict {
+        private UploadFile uploadFile;
+
+        public UploadFile getUploadFile() {
+            return uploadFile;
+        }
+
+        public void setUploadFile(UploadFile uploadFile) {
+            this.uploadFile = uploadFile;
+        }
+
+    }

+ 18 - 0
src/main/java/com/jeeplus/modules/knowledgeSharing/entity/DataSourceInfo.java

@@ -0,0 +1,18 @@
+package com.jeeplus.modules.knowledgeSharing.entity;
+
+/**
+ * 知识库详情关联类
+ * @author 徐滕
+ * @create 2022-04-11 09:31
+ */
+public  class DataSourceInfo {
+        private String uploadFileId;
+
+        public String getUploadFileId() {
+            return uploadFileId;
+        }
+
+        public void setUploadFileId(String uploadFileId) {
+            this.uploadFileId = uploadFileId;
+        }
+    }

+ 45 - 2
src/main/java/com/jeeplus/modules/knowledgeSharing/entity/KnowledgeBase.java

@@ -1,6 +1,5 @@
 package com.jeeplus.modules.knowledgeSharing.entity;
 
-import com.fasterxml.jackson.annotation.JsonFormat;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
 import com.jeeplus.common.persistence.DataEntity;
@@ -16,32 +15,75 @@ public class KnowledgeBase extends DataEntity<KnowledgeBase> {
     private String indexingTechnique;
     @JsonProperty("retrieval_model_dict")
     private RetrievalModelDict retrievalModelDict;
+    @JsonProperty("external_retrieval_model")
     private ExternalRetrievalModel externalRetrievalModel;
+    @JsonProperty("embedding_model")
     private String embeddingModel;
+
+    @JsonProperty("doc_form")
     private String docForm;
+
+    @JsonProperty("description")
     private String description;
 
+
+    @JsonProperty("created_at")
     @JsonDeserialize(converter = CustomDateConverter.class)
     private Date createdAt;
 
+    @JsonProperty("permission")
     private String permission;
+
+    @JsonProperty("data_source_type")
     private String dataSourceType;
+
+    @JsonProperty("created_by")
     private String createdBy;
+
+    @JsonProperty("tags")
     private List<String> tags;
+
+    @JsonProperty("embedding_model_provider")
     private String embeddingModelProvider;
+
+    @JsonProperty("word_count")
     private int wordCount;
 
-    @JsonDeserialize(converter = CustomDateConverter.class)
+    @JsonProperty("updated_at")
     private Date updatedAt;
 
+    @JsonProperty("provider")
     private String provider;
+
+    @JsonProperty("name")
     private String name;
+
+    @JsonProperty("updated_by")
     private String updatedBy;
+
+    @JsonProperty("external_knowledge_info")
     private ExternalKnowledgeInfo externalKnowledgeInfo;
+
+    @JsonProperty("id")
     private String id;
+
+    @JsonProperty("embedding_available")
     private boolean embeddingAvailable;
+
+    @JsonProperty("app_count")
     private int appCount;
 
+    //所属的文档列表
+    private List<KnowledgeBaseDoc> knowledgeBaseDocList;
+
+    public List<KnowledgeBaseDoc> getKnowledgeBaseDocList() {
+        return knowledgeBaseDocList;
+    }
+
+    public void setKnowledgeBaseDocList(List<KnowledgeBaseDoc> knowledgeBaseDocList) {
+        this.knowledgeBaseDocList = knowledgeBaseDocList;
+    }
+
     public int getDocumentCount() {
         return documentCount;
     }
@@ -102,6 +144,7 @@ public class KnowledgeBase extends DataEntity<KnowledgeBase> {
         return createdAt;
     }
 
+
     public void setCreatedAt(Date createdAt) {
         this.createdAt = createdAt;
     }

+ 266 - 0
src/main/java/com/jeeplus/modules/knowledgeSharing/entity/KnowledgeBaseDoc.java

@@ -0,0 +1,266 @@
+package com.jeeplus.modules.knowledgeSharing.entity;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.jeeplus.common.persistence.DataEntity;
+
+import java.util.Date;
+
+/**
+ * 知识库详情
+ * @author 徐滕
+ * @create 2022-04-11 09:31
+ */
+public class KnowledgeBaseDoc  extends DataEntity<KnowledgeBaseDoc> {
+
+    private String parentId;
+
+    private String parentName;
+
+    @JsonProperty("indexing_status")
+    private String indexingStatus;
+
+    @JsonProperty("data_source_info")
+    private DataSourceInfo dataSourceInfo;
+
+    @JsonProperty("disabled_at")
+    private Long disabledAt;
+
+    @JsonProperty("doc_form")
+    private String docForm;
+
+    @JsonProperty("created_at")
+    private Date createdAt;
+
+    @JsonProperty("data_source_type")
+    private String dataSourceType;
+
+    @JsonProperty("disabled_by")
+    private String disabledBy;
+
+    @JsonProperty("error")
+    private String error;
+
+    @JsonProperty("created_by")
+    private String createdBy;
+
+    @JsonProperty("enabled")
+    private Boolean enabled;
+
+    @JsonProperty("archived")
+    private Boolean archived;
+
+    @JsonProperty("word_count")
+    private Integer wordCount;
+
+    @JsonProperty("data_source_detail_dict")
+    private DataSourceDetailDict dataSourceDetailDict;
+
+    @JsonProperty("name")
+    private String name;
+
+    @JsonProperty("tokens")
+    private Integer tokens;
+
+    @JsonProperty("id")
+    private String id;
+
+    @JsonProperty("position")
+    private Integer position;
+
+    @JsonProperty("hit_count")
+    private Integer hitCount;
+
+    @JsonProperty("created_from")
+    private String createdFrom;
+
+    @JsonProperty("display_status")
+    private String displayStatus;
+
+    @JsonProperty("dataset_process_rule_id")
+    private String datasetProcessRuleId;
+
+
+    public String getParentId() {
+        return parentId;
+    }
+
+    public void setParentId(String parentId) {
+        this.parentId = parentId;
+    }
+
+
+    public String getParentName() {
+        return parentName;
+    }
+
+    public void setParentName(String parentName) {
+        this.parentName = parentName;
+    }
+    public String getIndexingStatus() {
+        return indexingStatus;
+    }
+
+    public void setIndexingStatus(String indexingStatus) {
+        this.indexingStatus = indexingStatus;
+    }
+
+    public DataSourceInfo getDataSourceInfo() {
+        return dataSourceInfo;
+    }
+
+    public void setDataSourceInfo(DataSourceInfo dataSourceInfo) {
+        this.dataSourceInfo = dataSourceInfo;
+    }
+
+    public Long getDisabledAt() {
+        return disabledAt;
+    }
+
+    public void setDisabledAt(Long disabledAt) {
+        this.disabledAt = disabledAt;
+    }
+
+    public String getDocForm() {
+        return docForm;
+    }
+
+    public void setDocForm(String docForm) {
+        this.docForm = docForm;
+    }
+
+    public Date getCreatedAt() {
+        return createdAt;
+    }
+
+    public void setCreatedAt(Date createdAt) {
+        this.createdAt = createdAt;
+    }
+
+    public String getDataSourceType() {
+        return dataSourceType;
+    }
+
+    public void setDataSourceType(String dataSourceType) {
+        this.dataSourceType = dataSourceType;
+    }
+
+    public String getDisabledBy() {
+        return disabledBy;
+    }
+
+    public void setDisabledBy(String disabledBy) {
+        this.disabledBy = disabledBy;
+    }
+
+    public String getError() {
+        return error;
+    }
+
+    public void setError(String error) {
+        this.error = error;
+    }
+
+    public String getCreatedBy() {
+        return createdBy;
+    }
+
+    public void setCreatedBy(String createdBy) {
+        this.createdBy = createdBy;
+    }
+
+    public Boolean getEnabled() {
+        return enabled;
+    }
+
+    public void setEnabled(Boolean enabled) {
+        this.enabled = enabled;
+    }
+
+    public Boolean getArchived() {
+        return archived;
+    }
+
+    public void setArchived(Boolean archived) {
+        this.archived = archived;
+    }
+
+    public Integer getWordCount() {
+        return wordCount;
+    }
+
+    public void setWordCount(Integer wordCount) {
+        this.wordCount = wordCount;
+    }
+
+    public DataSourceDetailDict getDataSourceDetailDict() {
+        return dataSourceDetailDict;
+    }
+
+    public void setDataSourceDetailDict(DataSourceDetailDict dataSourceDetailDict) {
+        this.dataSourceDetailDict = dataSourceDetailDict;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Integer getTokens() {
+        return tokens;
+    }
+
+    public void setTokens(Integer tokens) {
+        this.tokens = tokens;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public Integer getPosition() {
+        return position;
+    }
+
+    public void setPosition(Integer position) {
+        this.position = position;
+    }
+
+    public Integer getHitCount() {
+        return hitCount;
+    }
+
+    public void setHitCount(Integer hitCount) {
+        this.hitCount = hitCount;
+    }
+
+    public String getCreatedFrom() {
+        return createdFrom;
+    }
+
+    public void setCreatedFrom(String createdFrom) {
+        this.createdFrom = createdFrom;
+    }
+
+    public String getDisplayStatus() {
+        return displayStatus;
+    }
+
+    public void setDisplayStatus(String displayStatus) {
+        this.displayStatus = displayStatus;
+    }
+
+    public String getDatasetProcessRuleId() {
+        return datasetProcessRuleId;
+    }
+
+    public void setDatasetProcessRuleId(String datasetProcessRuleId) {
+        this.datasetProcessRuleId = datasetProcessRuleId;
+    }
+}

+ 247 - 0
src/main/java/com/jeeplus/modules/knowledgeSharing/entity/KnowledgeBaseResponse.java

@@ -1,5 +1,10 @@
 package com.jeeplus.modules.knowledgeSharing.entity;
 
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.jeeplus.modules.knowledgeSharing.utils.CustomDateConverter;
+
+import java.util.Date;
 import java.util.List;
 
 public class KnowledgeBaseResponse {
@@ -48,4 +53,246 @@ public class KnowledgeBaseResponse {
     public void setPage(int page) {
         this.page = page;
     }
+
+    @JsonProperty("document_count")
+    private int documentCount;
+    @JsonProperty("indexing_technique")
+    private String indexingTechnique;
+    @JsonProperty("retrieval_model_dict")
+    private RetrievalModelDict retrievalModelDict;
+    @JsonProperty("external_retrieval_model")
+    private ExternalRetrievalModel externalRetrievalModel;
+    @JsonProperty("embedding_model")
+    private String embeddingModel;
+
+    @JsonProperty("doc_form")
+    private String docForm;
+
+    @JsonProperty("description")
+    private String description;
+
+
+    @JsonProperty("created_at")
+    @JsonDeserialize(converter = CustomDateConverter.class)
+    private Date createdAt;
+
+    @JsonProperty("permission")
+    private String permission;
+
+    @JsonProperty("data_source_type")
+    private String dataSourceType;
+
+    @JsonProperty("created_by")
+    private String createdBy;
+
+    @JsonProperty("tags")
+    private List<String> tags;
+
+    @JsonProperty("embedding_model_provider")
+    private String embeddingModelProvider;
+
+    @JsonProperty("word_count")
+    private int wordCount;
+
+    @JsonProperty("updated_at")
+    @JsonDeserialize(converter = CustomDateConverter.class)
+    private Date updatedAt;
+
+    @JsonProperty("provider")
+    private String provider;
+
+    @JsonProperty("name")
+    private String name;
+
+    @JsonProperty("updated_by")
+    private String updatedBy;
+
+    @JsonProperty("external_knowledge_info")
+    private ExternalKnowledgeInfo externalKnowledgeInfo;
+
+    @JsonProperty("id")
+    private String id;
+
+    @JsonProperty("embedding_available")
+    private boolean embeddingAvailable;
+
+    @JsonProperty("app_count")
+    private int appCount;
+
+
+    public int getDocumentCount() {
+        return documentCount;
+    }
+
+    public void setDocumentCount(int documentCount) {
+        this.documentCount = documentCount;
+    }
+
+    public String getIndexingTechnique() {
+        return indexingTechnique;
+    }
+
+    public void setIndexingTechnique(String indexingTechnique) {
+        this.indexingTechnique = indexingTechnique;
+    }
+
+    public RetrievalModelDict getRetrievalModelDict() {
+        return retrievalModelDict;
+    }
+
+    public void setRetrievalModelDict(RetrievalModelDict retrievalModelDict) {
+        this.retrievalModelDict = retrievalModelDict;
+    }
+
+    public ExternalRetrievalModel getExternalRetrievalModel() {
+        return externalRetrievalModel;
+    }
+
+    public void setExternalRetrievalModel(ExternalRetrievalModel externalRetrievalModel) {
+        this.externalRetrievalModel = externalRetrievalModel;
+    }
+
+    public String getEmbeddingModel() {
+        return embeddingModel;
+    }
+
+    public void setEmbeddingModel(String embeddingModel) {
+        this.embeddingModel = embeddingModel;
+    }
+
+    public String getDocForm() {
+        return docForm;
+    }
+
+    public void setDocForm(String docForm) {
+        this.docForm = docForm;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public Date getCreatedAt() {
+        return createdAt;
+    }
+
+    public void setCreatedAt(Date createdAt) {
+        this.createdAt = createdAt;
+    }
+
+    public String getPermission() {
+        return permission;
+    }
+
+    public void setPermission(String permission) {
+        this.permission = permission;
+    }
+
+    public String getDataSourceType() {
+        return dataSourceType;
+    }
+
+    public void setDataSourceType(String dataSourceType) {
+        this.dataSourceType = dataSourceType;
+    }
+
+    public String getCreatedBy() {
+        return createdBy;
+    }
+
+    public void setCreatedBy(String createdBy) {
+        this.createdBy = createdBy;
+    }
+
+    public List<String> getTags() {
+        return tags;
+    }
+
+    public void setTags(List<String> tags) {
+        this.tags = tags;
+    }
+
+    public String getEmbeddingModelProvider() {
+        return embeddingModelProvider;
+    }
+
+    public void setEmbeddingModelProvider(String embeddingModelProvider) {
+        this.embeddingModelProvider = embeddingModelProvider;
+    }
+
+    public int getWordCount() {
+        return wordCount;
+    }
+
+    public void setWordCount(int wordCount) {
+        this.wordCount = wordCount;
+    }
+
+    public Date getUpdatedAt() {
+        return updatedAt;
+    }
+
+    public void setUpdatedAt(Date updatedAt) {
+        this.updatedAt = updatedAt;
+    }
+
+    public String getProvider() {
+        return provider;
+    }
+
+    public void setProvider(String provider) {
+        this.provider = provider;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getUpdatedBy() {
+        return updatedBy;
+    }
+
+    public void setUpdatedBy(String updatedBy) {
+        this.updatedBy = updatedBy;
+    }
+
+    public ExternalKnowledgeInfo getExternalKnowledgeInfo() {
+        return externalKnowledgeInfo;
+    }
+
+    public void setExternalKnowledgeInfo(ExternalKnowledgeInfo externalKnowledgeInfo) {
+        this.externalKnowledgeInfo = externalKnowledgeInfo;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public boolean isEmbeddingAvailable() {
+        return embeddingAvailable;
+    }
+
+    public void setEmbeddingAvailable(boolean embeddingAvailable) {
+        this.embeddingAvailable = embeddingAvailable;
+    }
+
+    public int getAppCount() {
+        return appCount;
+    }
+
+    public void setAppCount(int appCount) {
+        this.appCount = appCount;
+    }
 }

+ 72 - 0
src/main/java/com/jeeplus/modules/knowledgeSharing/entity/UploadFile.java

@@ -0,0 +1,72 @@
+package com.jeeplus.modules.knowledgeSharing.entity;
+
+/**
+ * 知识库详情关联类
+ * @author 徐滕
+ * @create 2022-04-11 09:31
+ */
+public  class UploadFile {
+            private String extension;
+            private Integer size;
+            private String mimeType;
+            private String name;
+            private Long createdAt;
+            private String id;
+            private String createdBy;
+
+            public String getExtension() {
+                return extension;
+            }
+
+            public void setExtension(String extension) {
+                this.extension = extension;
+            }
+
+            public Integer getSize() {
+                return size;
+            }
+
+            public void setSize(Integer size) {
+                this.size = size;
+            }
+
+            public String getMimeType() {
+                return mimeType;
+            }
+
+            public void setMimeType(String mimeType) {
+                this.mimeType = mimeType;
+            }
+
+            public String getName() {
+                return name;
+            }
+
+            public void setName(String name) {
+                this.name = name;
+            }
+
+            public Long getCreatedAt() {
+                return createdAt;
+            }
+
+            public void setCreatedAt(Long createdAt) {
+                this.createdAt = createdAt;
+            }
+
+            public String getId() {
+                return id;
+            }
+
+            public void setId(String id) {
+                this.id = id;
+            }
+
+            public String getCreatedBy() {
+                return createdBy;
+            }
+
+            public void setCreatedBy(String createdBy) {
+                this.createdBy = createdBy;
+            }
+        }

+ 130 - 0
src/main/java/com/jeeplus/modules/knowledgeSharing/service/KnowledgeBaseService.java

@@ -0,0 +1,130 @@
+package com.jeeplus.modules.knowledgeSharing.service;
+
+import com.google.gson.Gson;
+import com.jeeplus.common.persistence.Page;
+import com.jeeplus.modules.knowledgeSharing.dify.DifyApiClient;
+import com.jeeplus.modules.knowledgeSharing.entity.*;
+import org.json.JSONArray;
+import org.json.JSONObject;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.ArrayList;
+import java.util.Date;
+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);
+
+        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));
+            }
+            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);
+        page.setCountFlag(false);
+        knowledgeBase.setPage(page);
+        page.setList(knowledgeBaseList);
+        return page;
+    }
+
+
+    /**
+     * 获取知识库详情数据
+     * @param knowledgeBaseDoc
+     */
+    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<>();
+        
+        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);
+
+            knowledgeBaseDoc1.setCreatedAt(date );
+            knowledgeBaseDocArrayList.add(knowledgeBaseDoc1);
+        }
+        //总数
+        int total = knowledgeBaseDocList.getInt("total");
+        page.setCount(total);
+        page.setCountFlag(false);
+        knowledgeBaseDoc.setPage(page);
+        page.setList(knowledgeBaseDocArrayList);
+        return page;
+    }
+
+}

+ 156 - 0
src/main/java/com/jeeplus/modules/knowledgeSharing/web/KnowledgeBaseController.java

@@ -0,0 +1,156 @@
+package com.jeeplus.modules.knowledgeSharing.web;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.jeeplus.common.persistence.Page;
+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.service.KnowledgeBaseService;
+import com.jeeplus.modules.sys.utils.UserUtils;
+import org.apache.commons.fileupload.servlet.ServletFileUpload;
+import org.apache.shiro.authz.annotation.Logical;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.json.JSONArray;
+import org.json.JSONObject;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.*;
+
+/**
+ * 知识列表Controller
+ *
+ * @author 徐滕
+ * @create 2022-04-11 09:20
+ */
+@Controller
+@RequestMapping(value = "${adminPath}/knowledgeBase/knowledgeBase")
+public class KnowledgeBaseController {
+
+    @Autowired
+    private KnowledgeBaseService service;
+
+    /**
+     * 知识库列表
+     */
+    @RequiresPermissions("KnowledgeBase:KnowledgeBase:list")
+    @RequestMapping(value = {"list", ""})
+    public String list(KnowledgeBase knowledgeBase, HttpServletRequest request, HttpServletResponse response, Model model) throws Exception {
+        Page<KnowledgeBase> page = service.findKnowledgePage(new Page<KnowledgeBase>(request, response), knowledgeBase);
+        model.addAttribute("page", page);
+        return "modules/knowledgeSharing/knowledgeBaseList";
+    }
+
+
+    /**
+     * 查看知识库数据
+     *
+     * @param knowledgeBaseDoc
+     * @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);
+        if (knowledgeBaseDoc != null && StringUtils.isNotBlank(knowledgeBaseDoc.getParentId())) {
+            page = service.findKnowledgeBaseById(new Page<KnowledgeBaseDoc>(request, response), knowledgeBaseDoc);
+        } else {
+            knowledgeBaseDoc.setCreateBy(UserUtils.getUser());
+            knowledgeBaseDoc.setCreateDate(new Date());
+        }
+
+        model.addAttribute("knowledgeBaseDoc", knowledgeBaseDoc);
+        model.addAttribute("pages", page);
+        return "modules/knowledgeSharing/knowledgeBaseDetailsForm";
+    }
+
+
+    @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 {
+        Map<String, Object> resultAll = new HashMap<>();
+        // 检查文件数量
+        if (files.length > 5) {
+            resultAll.put("message","上传失败");
+            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);  // 400 错误
+            response.getWriter().write(new ObjectMapper().writeValueAsString(resultAll));
+            return null;
+        }
+
+        // 检查文件大小
+        for (MultipartFile file : files) {
+            if (file.getSize() > 50 * 1024 * 1024) { // 50MB
+                resultAll.put("message","文件大小不能超过50MB");
+                response.setStatus(HttpServletResponse.SC_BAD_REQUEST);  // 400 错误
+                response.getWriter().write(new ObjectMapper().writeValueAsString(resultAll));
+                return null;
+            }
+            //检查文件是否重名
+            JSONObject knowledgeBaseDocList = DifyApiClient.findKnowledgeBaseById(1,100,id,file.getOriginalFilename());
+            System.out.println(knowledgeBaseDocList);
+            List<KnowledgeBaseDoc> knowledgeBaseDocArrayList = new ArrayList<>();
+            //如果查询到相同名称,拦截
+            int total = knowledgeBaseDocList.getInt("total");
+            if(total > 0){
+                resultAll.put("message","文件上传失败<br />"+file.getOriginalFilename()+"-存在同名文件");
+                response.setStatus(HttpServletResponse.SC_BAD_REQUEST);  // 400 错误
+                response.getWriter().write(new ObjectMapper().writeValueAsString(resultAll));
+                return null;
+            }
+        }
+
+        if (ServletFileUpload.isMultipartContent(request)) {
+            try {
+                StringBuilder messageStr = new StringBuilder();
+                int fileCount = files.length;
+                // 遍历文件
+                for (int i = 0; i < fileCount; i++) {
+                    // 获取文件名
+                    String fileName = files[i].getOriginalFilename();
+                    if (fileName != null && !fileName.isEmpty()) {
+                        // 获取文件内容的输入流
+                        try {
+                            InputStream fileInputStream = files[i].getInputStream();
+                            // 直接传递给其他接口,无需存储文件
+                            Boolean flag = DifyApiClient.createByFileDifyApi(fileInputStream, fileName, id);
+                            messageStr.append(fileName).append(":上传成功");
+                        } catch (Exception e) {
+                            messageStr.append(fileName).append(":上传失败");
+                        }
+                    }
+                    if (i < fileCount - 1) {
+                        messageStr.append(", ");
+                    }
+                }
+                resultAll.put("message",messageStr);
+                // 设置响应内容类型
+                response.setContentType("application/json; charset=UTF-8");
+                response.setStatus(HttpServletResponse.SC_OK);  // 设置返回状态码为 200
+                // 写回返回结果
+                response.getWriter().write(new ObjectMapper().writeValueAsString(resultAll));
+                return null;
+            } catch (Exception e) {
+                resultAll.put("message","文件上传失败");
+                response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);  // 500 错误
+                response.getWriter().write(new ObjectMapper().writeValueAsString(resultAll));
+                return null;
+            }
+        } else {
+            resultAll.put("message","上传失败");
+            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);  // 400 错误
+            response.getWriter().write(new ObjectMapper().writeValueAsString(resultAll));
+            return null;
+        }
+    }
+}

+ 200 - 0
src/main/webapp/webpage/modules/knowledgeSharing/knowledgeBaseDetailsForm.jsp

@@ -0,0 +1,200 @@
+<%@ 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"/>
+
+    <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);
+                    }
+                }
+            });
+
+        });
+
+
+        layui.use('table', function () {
+            layui.table.render({
+                limit:${ pages.pageSize }
+                , id: "checkboxTable"
+                , elem: '#contentTable'
+                , page: false
+                , cols: [[
+                    {field: 'name', align: 'center', title: '名称'},
+                    {field: 'wordCount', align: 'center', title: '字符数'},
+                    {field: 'createdAt', align: 'center', title: '上传时间'},
+
+                ]]
+                , data: [
+                    <c:if test="${ not empty pages.list}">
+                    <c:forEach items="${pages.list}" var="knowledgeBaseDoc" 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"/>"
+                    }
+                    </c:forEach>
+                    </c:if>
+                ]
+
+            });
+
+        })
+        // 分页方法
+        function page(n,s){
+            if(n) $("#pageNo").val(n);
+            if(s) $("#pageSize").val(s);
+            $("#inputForm").submit();
+            return false;
+        }
+
+        // 选择文件
+        function chooseFile() {
+            document.getElementById('uploadFileInput').click();
+        }
+        //上传文件
+        function uploadFile() {
+            var fileInput = document.getElementById('uploadFileInput');
+            var files = fileInput.files;
+
+            if (files.length === 0) {
+                return;
+            }
+
+            if (files.length > 5) {
+                top.layer.msg("最多只能上传5个文件!", {icon: 0});
+                fileInput.value = ''; // 清空选择
+                return;
+            }
+
+            var formData = new FormData();
+            formData.append('id',  $("#parentId").val());
+            for (var i = 0; i < files.length; i++) {
+                var file = files[i];
+                var maxSize = 50 * 1024 * 1024; // 50MB
+                if (file.size > maxSize) {
+                    top.layer.msg("文件 '" + file.name + "' 超过50MB限制!", {icon: 0});
+                    fileInput.value = ''; // 清空选择
+                    return;
+                }
+                formData.append('files', file); // 注意是多个 files
+            }
+
+            var xhr = new XMLHttpRequest();
+            xhr.open('POST', '${ctx}/knowledgeBase/knowledgeBase/uploadFile', true);
+            xhr.onload = function () {
+                if (xhr.status === 200) {
+                    var result = JSON.parse(xhr.responseText);  // 解析返回的 JSON 数据
+                        // 构建换行字符串
+                        let resArr = result.message.split(',');
+                        var resultMessage = ""
+                        for (var i = 0; i < resArr.length; i++) {
+                            var color = ""
+                            if(resArr[i].includes("失败")){
+                                color = "red"
+                            }else{
+                                color = "green"
+                            }
+                            resultMessage += "<span style='color: " + color + ";'>" + resArr[i] + "</span><br>";  // 拼接并设置颜色
+                        }
+                        top.layer.alert(resultMessage, { title: "提示", area: '300px'});
+                    $("#pageNo").val(1);
+                    $("#pageSize").val(10);
+                    $("#inputForm").submit();
+                } else {
+                    var result = JSON.parse(xhr.responseText);  // 解析返回的 JSON 数据
+                    top.layer.alert(result.message, { title: "提示", area: '300px'});
+                }
+            };
+            xhr.onerror = function () {
+                top.layer.alert("上传失败,网络错误", { title: "提示", area: '300px'});
+            };
+            xhr.send(formData);
+        }
+
+    </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">
+                <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="parentName" readonly="true" placeholder="parentName" htmlEscape="false"
+                                    class="form-control layui-input required"/>
+                    </div>
+                </div>
+
+                <div class="form-group layui-row">
+                    <div class="layui-item layui-col-xs12" >
+                        <div class="nav-btns" style="padding-left: 0!important;">
+                            <div class="layui-btn-group">
+                                <shiro:hasPermission name="knowledgeBase:knowledgeBase:upload">
+                                    <!-- multiple 支持多选 -->
+                                    <input type="file" id="uploadFileInput" style="display: none;" multiple onchange="uploadFile()" />
+                                    <button type="button" class="layui-btn layui-bg-blue  layui-btn-sm" data-toggle="tooltip" data-placement="left" onclick="chooseFile()" title="上传文件">上传文件</button>
+                                </shiro:hasPermission>
+                            </div>
+                        </div>
+
+                        <table class="oa-table layui-table" id="contentTable"></table>
+                        <table:page page="${pages}"></table:page>
+                        <div style="clear: both;"></div>
+                    </div>
+                </div>
+
+            </div>
+
+            <div class="form-group layui-row page-end"></div>
+        </form:form>
+    </div>
+</div>
+</body>
+</html>

+ 261 - 0
src/main/webapp/webpage/modules/knowledgeSharing/knowledgeBaseList.jsp

@@ -0,0 +1,261 @@
+<%@ 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}/ckeditor/ckeditor.js"></script>
+	<script type="text/javascript">
+
+		$(document).ready(function() {
+			//搜索框收放
+            $('#moresee').click(function(){
+                if($('#moresees').is(':visible'))
+                {
+                    $('#moresees').slideUp(0,resizeListWindow1);
+                    $('#moresee i').removeClass("glyphicon glyphicon-menu-up").addClass("glyphicon glyphicon-menu-down");
+                }else{
+                    $('#moresees').slideDown(0,resizeListWindow1);
+                    $('#moresee i').removeClass("glyphicon glyphicon-menu-down").addClass("glyphicon glyphicon-menu-up");
+                }
+            });
+
+			$(".list-tabs li").click(function(){
+				$(".list-tabs li").each(function(){
+					$(this).removeAttr("class","active");
+					var id='#'+$(this).find("span").html();
+					$(id).attr("class","hide");
+				})
+				$(this).attr("class","active");
+				var id='#'+$(this).find("span").html();
+				$(id).removeAttr("class","hide");
+
+				$("#searchForm").submit();
+			})
+		});
+
+		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) {
+				}
+			});
+		}
+
+		function deleteInfo(title,id) {
+
+			layer.open({
+				title: title,
+				maxmin: true, //开启最大化最小化按钮
+				content: '确认要删除帖子吗?',
+				skin: 'two-btns',
+				btn: ['确定', '取消'],
+				btn1: function(index, layero){
+					$.ajax({
+						type:"post",
+						url:"${ctx}/knowledgeBase/knowledgeBase/delete?id="+ id,
+						success:function(data){
+							if(data.success) {
+								parent.layer.msg('删除成功', {icon: 1});
+								window.location.reload();
+							}else {
+								parent.layer.msg('删除失败', {icon: 0});
+							}
+						}
+					})
+
+				},
+				btn2: function (index) {
+				}
+			});
+		}
+
+
+		//打开对话框(查看)
+		function openDialogListView(title,url,width,height){
+
+
+			if(navigator.userAgent.match(/(iPhone|iPod|Android|ios)/i)){//如果是移动端,就使用自适应大小弹窗
+				width='auto';
+				height='auto';
+			}else{//如果是PC端,根据用户设置的width和height显示。
+
+			}
+			$.ajax({
+				async: false,
+				url: url,
+				dataType: "json",
+				success: function (data) {
+					if(data.success){
+						top.layer.open({
+							type: 2,
+							skin: 'one-btn',
+							area: [width, height],
+							title: title,
+							maxmin: true, //开启最大化最小化按钮
+							content: url ,
+							btn: ['关闭'],
+							cancel: function(index){
+							}
+						});
+					}
+				}
+			});
+
+		}
+	</script>
+</head>
+<body>
+<div class="wrapper wrapper-content">
+	<sys:message content="${message}"/>
+	<div class="layui-row">
+		<div class="full-width fl">
+			<div class="contentShadow layui-row" id="queryDiv">
+				<form:form id="searchForm" modelAttribute="knowledgeBase" action="${ctx}/knowledgeBase/knowledgeBase/list" method="post" class="form-inline">
+					<input id="pageNo" name="pageNo" type="hidden" value="${page.pageNo}"/>
+					<input id="pageSize" name="pageSize" type="hidden" value="${page.pageSize}"/>
+					<table:sortColumn id="orderBy" name="orderBy" value="${page.orderBy}" callback="sortOrRefresh();"/><!-- 支持排序 -->
+					<div class="commonQuery">
+						<div class="layui-item query athird">
+							<label class="layui-form-label">知识库列表</label>
+							<div class="layui-input-block">
+<%--								<form:input path="name" htmlEscape="false" maxlength="64"  class=" form-control  layui-input"/>--%>
+							</div>
+						</div>
+<%--						<div class="layui-item athird">--%>
+<%--							<div class="input-group">--%>
+<%--									<a href="#" id="moresee"><i class="glyphicon glyphicon-menu-down"></i></a>--%>
+<%--								<div class="layui-btn-group search-spacing">--%>
+<%--									<button id="searchQuery" class="layui-btn layui-btn-sm  layui-bg-blue" onclick="search()">查询</button>--%>
+<%--									<button id="searchReset" class="layui-btn layui-btn-sm  " onclick="resetSearch()">重置</button>--%>
+<%--								</div>--%>
+<%--							</div>--%>
+<%--						</div>--%>
+<%--						<div style="    clear:both;"></div>--%>
+					</div>
+					<div id="moresees" style="clear:both;display:none;">
+						<div style="clear:both;"></div>
+					</div>
+				</form:form>
+			</div>
+		</div>
+		<div class="full-width fl">
+			<div class="contentShadow layui-form contentDetails">
+				<div class="nav-btns">
+					<div class="layui-btn-group">
+						<button class="layui-btn layui-btn-sm" data-toggle="tooltip" data-placement="left" onclick="sortOrRefresh()" title="刷新"> 刷新</button>
+					</div>
+				</div>
+				<table class="oa-table layui-table" id="contentTable"></table>
+
+				<!-- 分页代码 -->
+				<table:page page="${page}"></table:page>
+				<div style="clear: both;"></div>
+			</div>
+		</div>
+	</div>
+	<div id="changewidth"></div>
+</div>
+<script src="${ctxStatic}/layer-v2.3/layui/layui.all.js" charset="utf-8"></script>
+<script>
+	layui.use('table', function(){
+		layui.table.render({
+			limit:${ page.pageSize }
+			,id:"checkboxTable"
+			,elem: '#contentTable'
+			,page: false
+			,cols: [[
+				//{checkbox: true, fixed: true},
+				// {field:'id', align:'center', width:40, title: 'ID'},
+				{field:'name', align:'center', title: '名称'},
+				{field:'documentCount', align:'center', width:80, title: '文档数量'},
+				// {field:'indexingTechnique', align:'center', width:80, title: '索引技术'},
+				// {field:'retrievalModelDict', align:'center', width:80, title: '检索模型字典'},
+				// {field:'externalRetrievalModel', align:'center', width:80, title: '外部检索模型'},
+				// {field:'embeddingModel', align:'center', width:80, title: '嵌入模型'},
+				// {field:'docForm', align:'center', width:80, title: '文档形式'},
+				{field:'description', align:'center', width:160, title: '描述'},
+				// {field:'createdAt', align:'center', width:80, title: '创建时间'},
+				// {field:'permission', align:'center', width:80, title: '权限'},
+				// {field:'dataSourceType', align:'center', width:80, title: '数据源类型'},
+				// {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:'updatedAt', align:'center', title: '更新时间'},
+				// {field:'provider', align:'center', title: '提供方'},
+				// {field:'updatedBy', align:'center', width:80, title: '更新人'},
+				// {field:'externalKnowledgeInfo', align:'center', width:80, title: '外部知识信息'},
+				// {field:'embeddingAvailable', align:'center', width:80, title: '嵌入是否可用'},
+				{field:'appCount', align:'center', width:80, title: '关联应用'},
+				{align:'center',title:"操作",width:150,templet:function(d){
+						////对操作进行初始化
+						var xml = "<div class=\"layui-btn-group\">";
+							xml += "<a href=\"javascript:void(0)\" onclick=\"openInfoDialog('查看知识库数据', '${ctx}/knowledgeBase/knowledgeBase/form?parentId="+ d.id +"&parentName="+d.name+"','95%', '95%')\"   class=\"layui-btn layui-btn-xs  layui-bg-green\"> 查看</a>";
+						return xml;
+					}}
+			]]
+			,data: [
+				<c:if test="${ not empty page.list}">
+				<c:forEach items="${page.list}" var="knowledgeBase" varStatus="index">
+				<c:if test="${index.index != 0}">,</c:if>
+				{
+					"id":"${knowledgeBase.id}",
+					"name": "${knowledgeBase.name}",
+					"documentCount": "${knowledgeBase.documentCount}",
+					<%--"indexingTechnique": "${knowledgeBase.indexingTechnique}",--%>
+					<%--"retrievalModelDict": "${knowledgeBase.retrievalModelDict}",--%>
+					<%--"externalRetrievalModel": "${knowledgeBase.externalRetrievalModel}",--%>
+					<%--"embeddingModel": "${knowledgeBase.embeddingModel}",--%>
+					<%--"docForm": "${knowledgeBase.docForm}",--%>
+					"description": "${knowledgeBase.description}",
+					<%--"createdAt": "<fmt:formatDate value="${knowledgeBase.createdAt}" pattern="yyyy-MM-dd HH:mm:ss"/>",--%>
+					<%--"permission": "${knowledgeBase.permission}",--%>
+					<%--"dataSourceType": "${knowledgeBase.dataSourceType}",--%>
+					<%--"createdBy": "${knowledgeBase.createdBy}",--%>
+					<%--"tags": "${knowledgeBase.tags}",--%>
+					<%--"embeddingModelProvider": "${knowledgeBase.embeddingModelProvider}",--%>
+					"wordCount": "${knowledgeBase.wordCount}",
+					"updatedAt":  "<fmt:formatDate value="${knowledgeBase.updatedAt}" pattern="yyyy-MM-dd HH:mm:ss"/>",
+					<%--"provider": "${knowledgeBase.provider}",--%>
+					<%--"updatedBy": "${knowledgeBase.updatedBy}",--%>
+					<%--"externalKnowledgeInfo": "${knowledgeBase.externalKnowledgeInfo}",--%>
+					<%--"embeddingAvailable": "${knowledgeBase.embeddingAvailable}",--%>
+					"appCount": "${knowledgeBase.appCount}"
+				}
+				</c:forEach>
+				</c:if>
+			]
+			// ,even: true
+			// ,height: 315
+		});
+
+	})
+
+	resizeListTable();
+</script>
+<script>
+	resizeListWindow1();
+	$(window).resize(function(){
+		resizeListWindow1();
+	});
+</script>
+</body>
+</html>