diff --git a/jeecg-boot/jeecg-boot-base-core/pom.xml b/jeecg-boot/jeecg-boot-base-core/pom.xml
index e2d763c1ddf35dee17d657a8afd8b2972cd09c50..8a8cb52f1f52b693a4f21ec9d137bcf5842f5d4c 100644
--- a/jeecg-boot/jeecg-boot-base-core/pom.xml
+++ b/jeecg-boot/jeecg-boot-base-core/pom.xml
@@ -10,7 +10,7 @@
jeecg-boot-base-core
- 3.1.5
+ 3.4.1
@@ -90,6 +90,7 @@
io.micrometer
micrometer-registry-prometheus
+ 1.11.5
@@ -369,4 +370,4 @@
jeecg-boot-starter3-chatgpt
-
\ No newline at end of file
+
diff --git a/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/aspect/AutoLogAspect.java b/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/aspect/AutoLogAspect.java
index c9c4c901d219ff86ee59e1e7e8c20016f68adedd..95a6f9cf195988b51905a3ff9c03e7122de2cd50 100644
--- a/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/aspect/AutoLogAspect.java
+++ b/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/common/aspect/AutoLogAspect.java
@@ -20,7 +20,7 @@ import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.IpUtils;
import org.jeecg.common.util.SpringContextUtils;
import org.jeecg.common.util.oConvertUtils;
-import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
+
import org.springframework.core.StandardReflectionParameterNameDiscoverer;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult;
diff --git a/jeecg-boot/jeecg-module-KM/pom.xml b/jeecg-boot/jeecg-module-KM/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..99c6c3de5ce5dea9774db9b6ca7f2bb25ac23014
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/pom.xml
@@ -0,0 +1,175 @@
+
+
+
+ jeecg-boot-parent
+ org.jeecgframework.boot
+ 3.7.1
+
+ 4.0.0
+
+ jeecg-module-KM
+
+
+
+ aliyun
+ aliyun Repository
+ http://maven.aliyun.com/nexus/content/groups/public
+
+ false
+
+
+
+ jeecg
+ jeecg Repository
+ http://maven.jeecg.org/nexus/content/repositories/jeecg
+
+ false
+
+
+
+
+
+
+ org.jeecgframework.boot
+ jeecg-boot-base-core
+
+
+ org.springframework.ai
+ spring-ai-ollama-spring-boot-starter
+
+
+ org.springframework.ai
+ spring-ai-pgvector-store-spring-boot-starter
+
+
+ org.springframework.ai
+ spring-ai-pdf-document-reader
+
+
+ org.springframework.ai
+ spring-ai-tika-document-reader
+
+
+ io.swagger
+ swagger-annotations
+ 1.6.10
+
+
+
+ org.opensearch.client
+ spring-data-opensearch-starter
+ 1.6.0
+
+
+ org.opensearch.client
+ opensearch-rest-high-level-client
+
+
+
+
+ org.opensearch.client
+ opensearch-rest-client
+ 2.18.0
+
+
+ org.opensearch.client
+ opensearch-java
+ 2.11.1
+
+
+ org.apache.tika
+ tika-core
+ 1.17
+
+
+ org.apache.tika
+ tika-parsers
+ 1.17
+
+
+ org.jodd
+ jodd-all
+ 4.3.1
+
+
+
+ org.springframework.boot
+ spring-boot-configuration-processor
+ true
+
+
+ org.jeecgframework.boot
+ jeecg-system-local-api
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ true
+
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+ 2.5.1
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ com.h2database
+ h2
+ runtime
+
+
+ com.googlecode.json-simple
+ json-simple
+ 1.1
+
+
+ com.google.code.gson
+ gson
+ 2.8.9
+
+
+ com.inversoft
+ prime-jwt
+ 1.3.1
+
+
+
+
+
+
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ 2.11.3
+
+
+
+ org.modelmapper
+ modelmapper
+ 2.4.2
+
+
+ org.springframework
+ spring-test
+ 5.3.2
+
+
+
+
+
+
+
+
+
+
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/VO/KmChartVO.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/VO/KmChartVO.java
new file mode 100644
index 0000000000000000000000000000000000000000..47b2b60f5425b26974ae13affd5733a75f8cd115
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/VO/KmChartVO.java
@@ -0,0 +1,29 @@
+package org.jeecg.modules.KM.VO;
+
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+@Accessors(chain = true)
+@EqualsAndHashCode(callSuper = false)
+@ApiModel(value="km_doc首页chart对象", description="km_doc")
+public class KmChartVO implements Serializable {
+
+ //分类:1
+ List categoryChartList;
+ //标签:4
+ List businessChartList;
+ //专题:5
+ List topicChartList;
+ //热词
+ List hotKeywordList;
+ //热门专题
+ List hotTopicList;
+ //全局数据:知识数,存储空间
+ KmDocSummaryVO kmDocSummaryVO;
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/VO/KmDocCommentsVO.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/VO/KmDocCommentsVO.java
new file mode 100644
index 0000000000000000000000000000000000000000..daf4c0ceb985eb0b7e846f3b1de3f2bb05b18af1
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/VO/KmDocCommentsVO.java
@@ -0,0 +1,13 @@
+package org.jeecg.modules.KM.VO;
+
+
+import lombok.Data;
+import org.jeecg.modules.KM.entity.KmDocComments;
+
+import java.io.Serializable;
+
+@Data
+public class KmDocCommentsVO extends KmDocComments implements Serializable {
+ private String avatar;
+
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/VO/KmDocEsFilterParamVO.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/VO/KmDocEsFilterParamVO.java
new file mode 100644
index 0000000000000000000000000000000000000000..109a18b94828a8eac3cf81d643eee32b47c83cc5
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/VO/KmDocEsFilterParamVO.java
@@ -0,0 +1,41 @@
+package org.jeecg.modules.KM.VO;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+@Data
+public class KmDocEsFilterParamVO implements Serializable {
+ //高级检索标识 0-普通 1-高级
+ private Boolean advSearchFlag;
+ @ApiModelProperty(value = "是否精确检索标识:0-否,1-是")
+ private Boolean phraseMatchSearchFlag;
+
+ private String title;
+
+ private List keywords;
+
+ private String content;
+
+ private List category;
+
+ private List businessTypes;
+
+ private List topicCodes;
+
+ @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
+ @DateTimeFormat(pattern="yyyy-MM-dd")
+ @ApiModelProperty(value = "createTimeStart")
+ private Date createTimeStart;
+
+ @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
+ @DateTimeFormat(pattern="yyyy-MM-dd")
+ @ApiModelProperty(value = "createTimeEnd")
+ private Date createTimeEnd;
+
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/VO/KmDocEsParamVO.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/VO/KmDocEsParamVO.java
new file mode 100644
index 0000000000000000000000000000000000000000..7ae8725a90826d011dd209848fe65df9976a66ba
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/VO/KmDocEsParamVO.java
@@ -0,0 +1,46 @@
+package org.jeecg.modules.KM.VO;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Builder;
+import lombok.Data;
+import lombok.ToString;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+@Data
+public class KmDocEsParamVO implements Serializable {
+ //高级检索标识 0-普通 1-高级
+ private Boolean advSearchFlag;
+ @ApiModelProperty(value = "是否精确检索标识:0-否,1-是")
+ private Boolean phraseMatchSearchFlag;
+ private String title;
+ private List keywords;
+ private String content;
+ private List category;
+ private List businessTypes;
+ private List topicCodes;
+ //结果中检索的前置条件
+ private List filterParams;
+
+ //结果排序字段
+ private String column;
+ private String order;
+ private Integer pageNo;
+ private Integer pageSize;
+
+ @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
+ @DateTimeFormat(pattern="yyyy-MM-dd")
+ @ApiModelProperty(value = "createTimeStart")
+ private Date createTimeStart;
+
+ @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
+ @DateTimeFormat(pattern="yyyy-MM-dd")
+ @ApiModelProperty(value = "createTimeEnd")
+ private Date createTimeEnd;
+
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/VO/KmDocEsVO.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/VO/KmDocEsVO.java
new file mode 100644
index 0000000000000000000000000000000000000000..7c33cd8861acebfbcff6dcc0c296cf5bbce29a25
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/VO/KmDocEsVO.java
@@ -0,0 +1,44 @@
+package org.jeecg.modules.KM.VO;
+
+import lombok.Data;
+import lombok.ToString;
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+@ToString
+public class KmDocEsVO implements Serializable {
+
+ //private String indexId; //todo:考虑是否改名,跟es的_id字段一致
+ private String docId;
+ private String fileNo;
+
+ /*
+ 状态:0-下架 1-有效
+ */
+ private Integer releaseFlag;
+ /*
+ 状态:0-内部公开 1-对外公开
+ */
+ private Integer publicRemark;
+
+ private String title;
+
+ private String category;
+
+ private String orgCode;
+
+ private Date createTime;
+
+// private String pubTimeTxt;
+//
+// private String[] versions;
+
+ private String[] businessTypes;
+
+ private String[] keywords;
+
+ private String[] topicCodes;
+
+ private String content;
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/VO/KmDocParamVO.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/VO/KmDocParamVO.java
new file mode 100644
index 0000000000000000000000000000000000000000..2eac7b610e48d5bccf1064b8fca511cdb94b23dd
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/VO/KmDocParamVO.java
@@ -0,0 +1,44 @@
+package org.jeecg.modules.KM.VO;
+
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.jeecg.modules.KM.entity.KmDoc;
+import org.springframework.format.annotation.DateTimeFormat;
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+@Data
+public class KmDocParamVO extends KmDoc implements Serializable {
+
+// private List versionList;
+// private List sourceList;
+// private List addVersionList;
+// private List removeVersionList;
+// private String pubTimeStart;
+// private String pubTimeEnd;
+
+ //多状态查询
+ private List statusList;
+ private List businessTypeList;
+ private List depIdList;
+ private List addBusinessTypeList;
+ private List removeBusinessTypeList;
+ private List addTopicIdList;
+ private List removeTopicIdList;
+
+ private boolean departmentFilterEnabled;
+
+ @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
+ @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
+ @ApiModelProperty(value = "createTimeStart")
+ private Date createTimeStart;
+
+ @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
+ @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
+ @ApiModelProperty(value = "createTimeEnd")
+ private Date createTimeEnd;
+
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/VO/KmDocStatisticsVO.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/VO/KmDocStatisticsVO.java
new file mode 100644
index 0000000000000000000000000000000000000000..751b0e80767a172421b02700c2538376b966221f
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/VO/KmDocStatisticsVO.java
@@ -0,0 +1,20 @@
+package org.jeecg.modules.KM.VO;
+
+import io.swagger.annotations.ApiModel;
+import jodd.madvoc.meta.In;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import java.io.Serializable;
+
+@Data
+@Accessors(chain = true)
+@EqualsAndHashCode(callSuper = false)
+@ApiModel(value="km_doc统计结果", description="km_doc")
+public class KmDocStatisticsVO implements Serializable {
+
+ private String itemText;
+ private Integer amount;
+ private Long fileSizeInt;
+ private String fileSize;
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/VO/KmDocSummaryVO.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/VO/KmDocSummaryVO.java
new file mode 100644
index 0000000000000000000000000000000000000000..2516955df0e0243420ce19da52dd66c06f2ef1a6
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/VO/KmDocSummaryVO.java
@@ -0,0 +1,22 @@
+package org.jeecg.modules.KM.VO;
+
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+@Data
+@Accessors(chain = true)
+@EqualsAndHashCode(callSuper = false)
+@ApiModel(value="km_doc全局计数", description="km_doc")
+public class KmDocSummaryVO implements Serializable {
+ private Integer kmAmount;
+ private Long fileSizeLong;
+ private Long viewsLong;
+ private Long downloadsLong;
+ private Long commentsLong;
+ private Long favouritesLong;
+ private String fileSizeString;
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/VO/KmDocVO.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/VO/KmDocVO.java
new file mode 100644
index 0000000000000000000000000000000000000000..38228814a560b9b99301f15f1b6ccfeffbe1f5e2
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/VO/KmDocVO.java
@@ -0,0 +1,19 @@
+package org.jeecg.modules.KM.VO;
+
+
+import lombok.Data;
+import org.jeecg.common.aspect.annotation.Dict;
+import org.jeecg.modules.KM.entity.KmDoc;
+import java.io.Serializable;
+
+@Data
+public class KmDocVO extends KmDoc implements Serializable {
+ private Integer favourite;
+ @Dict(dicCode = "km_dict_business")
+ private String businessTypes;
+ @Dict(dicCode = "km_dict_versions")
+ private String versions;
+ @Dict(dicCode="id",dictTable = "sys_category",dicText = "name")
+ private String topicIds;
+
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/VO/KmDocVisitRecordEsVO.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/VO/KmDocVisitRecordEsVO.java
new file mode 100644
index 0000000000000000000000000000000000000000..ce21ccbe7f14a08efc8a94ac664f5429d8b52553
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/VO/KmDocVisitRecordEsVO.java
@@ -0,0 +1,23 @@
+package org.jeecg.modules.KM.VO;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+public class KmDocVisitRecordEsVO implements Serializable {
+ private String docId;
+ /**1:上传 2:预览 3:下载 4:删除*/
+ private Integer visitType;
+ private String keywords;
+ private String[] keywordsMax;
+ private String sourceIp;
+ private String createBy;
+ @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
+ @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
+ @ApiModelProperty(value = "createTime")
+ private Date createTime;
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/VO/KmSearchRecordEsVO.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/VO/KmSearchRecordEsVO.java
new file mode 100644
index 0000000000000000000000000000000000000000..49cc0d4695f89c29fbb65694542ea8a857c971e8
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/VO/KmSearchRecordEsVO.java
@@ -0,0 +1,25 @@
+package org.jeecg.modules.KM.VO;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+public class KmSearchRecordEsVO implements Serializable {
+ private String keywords;
+ private String[] keywordsMax;
+ private String title;
+ private String content;
+ private String[] topicCodes;
+ private String sourceIp;
+ private String createBy;
+ /**createTime*/
+ @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
+ @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
+ @ApiModelProperty(value = "createTime")
+ private Date createTime;
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/VO/KmSearchResultVO.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/VO/KmSearchResultVO.java
new file mode 100644
index 0000000000000000000000000000000000000000..42563b8fae96153efe561268173dd6cceaa01624
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/VO/KmSearchResultVO.java
@@ -0,0 +1,43 @@
+package org.jeecg.modules.KM.VO;
+
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.jeecg.common.aspect.annotation.Dict;
+import java.io.Serializable;
+import java.math.BigInteger;
+import java.util.Date;
+
+@Data
+@Accessors(chain = true)
+@EqualsAndHashCode(callSuper = false)
+@ApiModel(value="km_doc检索对象", description="km_doc")
+public class KmSearchResultVO implements Serializable {
+
+ private Integer favourite;
+
+ private String id;
+ private String fileId;
+ private String previewFileId;
+ private Integer downloadFlag;
+ private Integer publicRemark;
+ private Long fileSize;
+ private String content;
+ private String title;
+ @Dict(dictTable ="sys_depart",dicText = "depart_name",dicCode = "org_code")
+ private String orgCode;
+ private String createBy;
+ private String fileType;
+ @Dict(dicCode = "km_dict_category")
+ private String category;
+ private Date createTime;
+ @Dict(dicCode = "km_dict_business")
+ private String businessTypes;
+ private String keywords;
+ @Dict(dicCode="code",dictTable = "sys_category",dicText = "name")
+ private String topicCodes;
+ private BigInteger downloads;
+ private BigInteger views;
+ private String remark;
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/OSinfo.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/OSinfo.java
new file mode 100644
index 0000000000000000000000000000000000000000..130852eb41915851ace9b66dcc5f4e7f0be4dfdd
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/OSinfo.java
@@ -0,0 +1,116 @@
+package org.jeecg.modules.KM.common;
+
+import org.jeecg.modules.KM.common.enums.EPlatform;
+
+/**
+ * 操作系统类:
+ * 获取System.getProperty("os.name")对应的操作系统
+ * @author isea533
+ */
+public class OSinfo {
+ private static String OS = System.getProperty("os.name").toLowerCase();
+ private static OSinfo _instance = new OSinfo();
+ private EPlatform platform;
+ private OSinfo(){}
+ public static boolean isLinux(){
+ return OS.indexOf("linux")>=0;
+ }
+ public static boolean isMacOS(){
+ return OS.indexOf("mac")>=0&&OS.indexOf("os")>0&&OS.indexOf("x")<0;
+ }
+ public static boolean isMacOSX(){
+ return OS.indexOf("mac")>=0&&OS.indexOf("os")>0&&OS.indexOf("x")>0;
+ }
+ public static boolean isWindows(){
+ return OS.indexOf("windows")>=0;
+ }
+ public static boolean isOS2(){
+ return OS.indexOf("os/2")>=0;
+ }
+ public static boolean isSolaris(){
+ return OS.indexOf("solaris")>=0;
+ }
+ public static boolean isSunOS(){
+ return OS.indexOf("sunos")>=0;
+ }
+ public static boolean isMPEiX(){
+ return OS.indexOf("mpe/ix")>=0;
+ }
+ public static boolean isHPUX(){
+ return OS.indexOf("hp-ux")>=0;
+ }
+ public static boolean isAix(){
+ return OS.indexOf("aix")>=0;
+ }
+ public static boolean isOS390(){
+ return OS.indexOf("os/390")>=0;
+ }
+ public static boolean isFreeBSD(){
+ return OS.indexOf("freebsd")>=0;
+ }
+ public static boolean isIrix(){
+ return OS.indexOf("irix")>=0;
+ }
+ public static boolean isDigitalUnix(){
+ return OS.indexOf("digital")>=0&&OS.indexOf("unix")>0;
+ }
+ public static boolean isNetWare(){
+ return OS.indexOf("netware")>=0;
+ }
+ public static boolean isOSF1(){
+ return OS.indexOf("osf1")>=0;
+ }
+ public static boolean isOpenVMS(){
+ return OS.indexOf("openvms")>=0;
+ }
+ /**
+ * 获取操作系统名字
+ * @return 操作系统名
+ */
+ public static EPlatform getOSname(){
+ if(isAix()){
+ _instance.platform = EPlatform.AIX;
+ }else if (isDigitalUnix()) {
+ _instance.platform = EPlatform.Digital_Unix;
+ }else if (isFreeBSD()) {
+ _instance.platform = EPlatform.FreeBSD;
+ }else if (isHPUX()) {
+ _instance.platform = EPlatform.HP_UX;
+ }else if (isIrix()) {
+ _instance.platform = EPlatform.Irix;
+ }else if (isLinux()) {
+ _instance.platform = EPlatform.Linux;
+ }else if (isMacOS()) {
+ _instance.platform = EPlatform.Mac_OS;
+ }else if (isMacOSX()) {
+ _instance.platform = EPlatform.Mac_OS_X;
+ }else if (isMPEiX()) {
+ _instance.platform = EPlatform.MPEiX;
+ }else if (isNetWare()) {
+ _instance.platform = EPlatform.NetWare_411;
+ }else if (isOpenVMS()) {
+ _instance.platform = EPlatform.OpenVMS;
+ }else if (isOS2()) {
+ _instance.platform = EPlatform.OS2;
+ }else if (isOS390()) {
+ _instance.platform = EPlatform.OS390;
+ }else if (isOSF1()) {
+ _instance.platform = EPlatform.OSF1;
+ }else if (isSolaris()) {
+ _instance.platform = EPlatform.Solaris;
+ }else if (isSunOS()) {
+ _instance.platform = EPlatform.SunOS;
+ }else if (isWindows()) {
+ _instance.platform = EPlatform.Windows;
+ }else{
+ _instance.platform = EPlatform.Others;
+ }
+ return _instance.platform;
+ }
+ /**
+ * @param args
+ */
+ public static void main(String[] args) {
+ System.out.println(OSinfo.getOSname());
+ }
+}
\ No newline at end of file
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/config/BaseConfig.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/config/BaseConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..67f8bc837a9d70f5243719953090ae66c612fc85
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/config/BaseConfig.java
@@ -0,0 +1,116 @@
+
+package org.jeecg.modules.KM.common.config;
+
+import org.jeecg.modules.KM.common.rules.KMConstant;
+import org.jeecg.modules.KM.common.utils.KMDateUtils;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+import jakarta.annotation.PostConstruct;
+import java.io.File;
+import java.util.Date;
+
+@Configuration
+@ConfigurationProperties(prefix = "base")
+@EnableConfigurationProperties(BaseConfig.class)
+public class BaseConfig {
+
+ @PostConstruct
+ public void init(){
+ File file=new File(uploadDir);
+ if(!file.exists()){
+ file.mkdirs();
+ }
+ }
+
+
+ private String uploadDir;
+ private String sofficePath;
+// private String oneSystemUrl;
+// private String oneMapUrl;
+
+// public String getOneSystemUrl() {
+// return oneSystemUrl;
+// }
+//
+// public void setOneSystemUrl(String oneSystemUrl) {
+// this.oneSystemUrl = oneSystemUrl;
+// }
+//
+// public String getOneMapUrl() {
+// return oneMapUrl;
+// }
+//
+// public void setOneMapUrl(String oneMapUrl) {
+// this.oneMapUrl = oneMapUrl;
+// }
+
+ public String getSofficePath() {
+ return sofficePath;
+ }
+
+ public void setSofficePath(String sofficePath) {
+ this.sofficePath = sofficePath;
+ }
+
+ public String getUploadDir() {
+ return uploadDir;
+ }
+
+ public void setUploadDir(String uploadDir) {
+ this.uploadDir = uploadDir;
+ }
+
+
+ public File getTodayUploadDir(){
+ String today= KMDateUtils.formatDate1(new Date());
+ File t=new File(uploadDir,today);
+ if(!t.exists()){
+ t.mkdirs();
+ }
+ return t;
+ }
+
+ public String getRelativePath(File file){
+ String absPath = file.getAbsolutePath();
+// String a =absPath.substring(0,uploadDir.length());
+ if(absPath.isEmpty() || absPath.length() {
+ httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
+ return httpClientBuilder;
+ });
+
+ // 创建RestClientTransport实例
+ RestClientTransport transport = new RestClientTransport(builder.build(), new JacksonJsonpMapper());
+
+ // 创建OpenSearchClient实例
+ OpenSearchClient client = new OpenSearchClient(transport);
+
+ return client;
+}
+ public OpenSearchClient openSearchClientNoAuth() {
+ // 设置主机信息
+ final String hostname = masterHost;
+ final int port = masterPort;
+ final String scheme = HttpHost.DEFAULT_SCHEME_NAME; // 使用HTTP协议
+
+ // 创建RestClient实例
+ RestClientBuilder builder = RestClient.builder(new HttpHost(hostname, port, scheme));
+
+ // 创建RestClientTransport实例
+ RestClientTransport transport = new RestClientTransport(builder.build(), new JacksonJsonpMapper());
+
+ // 创建OpenSearchClient实例
+ OpenSearchClient client = new OpenSearchClient(transport);
+
+ return client;
+ }
+
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/enums/DocConvertFlagEnum.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/enums/DocConvertFlagEnum.java
new file mode 100644
index 0000000000000000000000000000000000000000..4de2e7143af78ac47cc5ad3c4eecfc5a46671365
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/enums/DocConvertFlagEnum.java
@@ -0,0 +1,23 @@
+package org.jeecg.modules.KM.common.enums;
+
+public enum DocConvertFlagEnum {
+
+ Fail(-1),
+ WaitConvert(0),
+ Converted(1),
+ NonConvert(2);
+
+ DocConvertFlagEnum(Integer code ) {
+ this.code = code;
+ }
+
+ private Integer code;
+
+ public Integer getCode() {
+ return code;
+ }
+
+ public void setCode(Integer code) {
+ this.code = code;
+ }
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/enums/DocFTIFlagEnum.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/enums/DocFTIFlagEnum.java
new file mode 100644
index 0000000000000000000000000000000000000000..992887f1d922b74289411d987d00d0a2bd9d9a10
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/enums/DocFTIFlagEnum.java
@@ -0,0 +1,21 @@
+package org.jeecg.modules.KM.common.enums;
+
+public enum DocFTIFlagEnum {
+ Fail(-1),
+ WaitProcess(0),
+ Processed(1),
+ NonFTI(2);
+
+ DocFTIFlagEnum(Integer code ) {
+ this.code = code;
+ }
+
+ private Integer code;
+ public Integer getCode() {
+ return code;
+ }
+
+ public void setCode(Integer code) {
+ this.code = code;
+ }
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/enums/DocPublicRemark.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/enums/DocPublicRemark.java
new file mode 100644
index 0000000000000000000000000000000000000000..6148253b6e5cb93f8ec4cf8ba0b6c349d50f565a
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/enums/DocPublicRemark.java
@@ -0,0 +1,30 @@
+package org.jeecg.modules.KM.common.enums;
+
+public enum DocPublicRemark {
+ OwnOrg(1,"本部门及下属"),
+ Public(0,"所有部门");
+
+ DocPublicRemark(Integer code, String name) {
+ this.code = code;
+ this.name = name;
+ }
+
+ private Integer code;
+ private String name;
+
+ public Integer getCode() {
+ return code;
+ }
+
+ public void setCode(Integer code) {
+ this.code = code;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/enums/DocReleaseFlagEnum.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/enums/DocReleaseFlagEnum.java
new file mode 100644
index 0000000000000000000000000000000000000000..88c38bb064ff75dae875b56869dff68fad16f4b8
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/enums/DocReleaseFlagEnum.java
@@ -0,0 +1,19 @@
+package org.jeecg.modules.KM.common.enums;
+
+public enum DocReleaseFlagEnum {
+ Off(0),
+ Released(1);
+
+ DocReleaseFlagEnum(Integer code ) {
+ this.code = code;
+ }
+
+ private Integer code;
+ public Integer getCode() {
+ return code;
+ }
+
+ public void setCode(Integer code) {
+ this.code = code;
+ }
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/enums/DocStatusEnum.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/enums/DocStatusEnum.java
new file mode 100644
index 0000000000000000000000000000000000000000..a3e3ca069cde50f8a460b16e94e36bbcdda460a3
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/enums/DocStatusEnum.java
@@ -0,0 +1,33 @@
+package org.jeecg.modules.KM.common.enums;
+
+public enum DocStatusEnum {
+ Draft(0,"草稿"),
+ WaitAudit(1,"待审核"),
+ Passed(2,"审核通过"),
+ Reject(3,"审核驳回"),
+ Delete(9,"删除");
+
+ DocStatusEnum(Integer code, String name) {
+ this.code = code;
+ this.name = name;
+ }
+
+ private Integer code;
+ private String name;
+
+ public Integer getCode() {
+ return code;
+ }
+
+ public void setCode(Integer code) {
+ this.code = code;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/enums/DocVisitTypeEnum.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/enums/DocVisitTypeEnum.java
new file mode 100644
index 0000000000000000000000000000000000000000..9935c0ff63c17cdd4822ca799cceafcaf783ca6f
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/enums/DocVisitTypeEnum.java
@@ -0,0 +1,30 @@
+package org.jeecg.modules.KM.common.enums;
+
+public enum DocVisitTypeEnum {
+
+
+ Upload(0),
+ AuditPass(1),
+ AuditReject(2),
+ ChangePreview(3),
+ Download(4),
+ View(5),
+ Edit(6),
+ Delete(7),
+ UpdateFile(8);
+
+ DocVisitTypeEnum(Integer code) {
+ this.code = code;
+ }
+
+ private Integer code;
+
+ public Integer getCode() {
+ return code;
+ }
+
+ public void setCode(Integer code) {
+ this.code = code;
+ }
+
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/enums/EPlatform.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/enums/EPlatform.java
new file mode 100644
index 0000000000000000000000000000000000000000..9496a6e6be42958345816a379e0e47025aa00e3f
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/enums/EPlatform.java
@@ -0,0 +1,34 @@
+package org.jeecg.modules.KM.common.enums;
+
+/**
+ * 平台
+ * @author isea533
+ */
+public enum EPlatform {
+ Any("any"),
+ Linux("Linux"),
+ Mac_OS("Mac OS"),
+ Mac_OS_X("Mac OS X"),
+ Windows("Windows"),
+ OS2("OS/2"),
+ Solaris("Solaris"),
+ SunOS("SunOS"),
+ MPEiX("MPE/iX"),
+ HP_UX("HP-UX"),
+ AIX("AIX"),
+ OS390("OS/390"),
+ FreeBSD("FreeBSD"),
+ Irix("Irix"),
+ Digital_Unix("Digital Unix"),
+ NetWare_411("NetWare"),
+ OSF1("OSF1"),
+ OpenVMS("OpenVMS"),
+ Others("Others");
+ private EPlatform(String desc){
+ this.description = desc;
+ }
+ public String toString(){
+ return description;
+ }
+ private String description;
+}
\ No newline at end of file
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/init/EsTemplateInit.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/init/EsTemplateInit.java
new file mode 100644
index 0000000000000000000000000000000000000000..4e37d7a19e731201040b52fad5cdab60ad6c1675
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/init/EsTemplateInit.java
@@ -0,0 +1,22 @@
+package org.jeecg.modules.KM.common.init;
+
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.modules.KM.service.IKmEsMgntService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+
+@Component
+@Slf4j
+@Order(1) //指定顺序
+public class EsTemplateInit implements CommandLineRunner {
+ @Autowired
+ IKmEsMgntService iKmEsMgntService;
+
+ @Override
+ public void run(String... args) throws Exception {
+ log.info("start check ES template and init...");
+ iKmEsMgntService.initTemplateAndSyncDocs();
+ }
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/rules/KMConstant.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/rules/KMConstant.java
new file mode 100644
index 0000000000000000000000000000000000000000..eabc601974120b26222d50e329b3ebf73b376ac5
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/rules/KMConstant.java
@@ -0,0 +1,139 @@
+package org.jeecg.modules.KM.common.rules;
+import org.jeecg.modules.KM.common.OSinfo;
+import org.jeecg.modules.KM.service.IKmSysConfigService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class KMConstant {
+ @Autowired
+ private IKmSysConfigService kmSysConfigService;
+
+ public static String SearchTermSeprator = " + ";
+ public static char fileSeparator = '/';
+
+ //redis prefix
+ public static String UserDocVisitHistoryPrefix = "UserDocVisitHistoryPrefix_";
+ public static String UserDownloadLimitPrefix = "UserDownloadLimitPerDay_";
+ public static String UserSearchLimitPrefix = "UserSearchLimitPerTenSeconds_";
+ public static String UserViewLimitPrefix = "UserViewLimitPerTenSeconds_";
+
+ //ES prefix
+// public static String DocIndexPrefix = "test_";
+ public static String DocIndexPrefix = "";
+ public static String DocIndexName = DocIndexPrefix + "km_doc";
+ public static String DocIndexAliasName = DocIndexPrefix + "km_doc_alias";
+ public static String KMSearchRecordIndexName = DocIndexPrefix + "log_km_search_record";
+ public static String KMSearchRecordIndexAliasName = DocIndexPrefix + "log_km_search_record_alias";
+ public static String DocVisitIndexName = DocIndexPrefix + "log_km_doc_visit_record";
+ public static String DocVisitIndexAliasName = DocIndexPrefix + "log_km_doc_visit_record_alias";
+
+ //定时任务相关
+ public static String JobAutoScanFileBasePath = "JobAutoScanFileBasePath";
+
+ public static Integer SearchTimeOutSeconds = 10; //秒
+ public static Integer SaveTimeOutHours = 1; //1小时
+ public static Integer SaveTimeOutMinutes = 1; //1分钟
+ public static String InnerUser = "1";
+ public static String PublicUser = "0";
+ public static Integer DocPublic = 1;
+ public static Integer DocNotPublic = 0;
+ public static Integer AllowDownload = 1;
+ public static Integer ForbideDownload = 0;
+
+
+ private Float TitleSearchBoost = Float.valueOf("1");
+ private Float ContentSearchBoost = Float.valueOf("1");
+ private Float KeywordSearchBoost = Float.valueOf("1");
+ private Integer DownloadLimit = 1000;
+ private Integer SearchLimit = 10;
+ private Integer ViewLimit = 10;
+
+ public Float getTitleSearchBoost() {
+ String titleSearchBoostConfig = kmSysConfigService.getSysConfigValue("TitleSearchBoostConfig");
+ if( titleSearchBoostConfig!= null && !titleSearchBoostConfig.isEmpty())
+ TitleSearchBoost = Float.valueOf(titleSearchBoostConfig);
+ return TitleSearchBoost;
+ }
+
+ public Float getContentSearchBoost() {
+ String contentSearchBoostConfig = kmSysConfigService.getSysConfigValue("ContentSearchBoostConfig");
+ if( contentSearchBoostConfig!= null && !contentSearchBoostConfig.isEmpty())
+ ContentSearchBoost = Float.valueOf(contentSearchBoostConfig);
+ return ContentSearchBoost;
+ }
+
+ public Float getKeywordSearchBoost() {
+ String keywordSearchBoostConfig = kmSysConfigService.getSysConfigValue("KeywordSearchBoostConfig");
+ if( keywordSearchBoostConfig!= null && !keywordSearchBoostConfig.isEmpty())
+ KeywordSearchBoost = Float.valueOf(keywordSearchBoostConfig);
+ return KeywordSearchBoost;
+ }
+
+ public Integer getDownloadLimit() {
+ String downloadLimitConfig = kmSysConfigService.getSysConfigValue("downloadLimitConfig");
+ if( downloadLimitConfig!= null && !downloadLimitConfig.isEmpty())
+ DownloadLimit = Integer.valueOf(downloadLimitConfig);
+ return DownloadLimit;
+ }
+
+
+ public Integer getSearchLimit() {
+ String searchLimitConfig = kmSysConfigService.getSysConfigValue("searchLimitConfig");
+ if( searchLimitConfig!= null && !searchLimitConfig.isEmpty())
+ SearchLimit = Integer.valueOf(searchLimitConfig);
+ return SearchLimit;
+ }
+
+ public Integer getViewLimit() {
+ String viewLimitConfig = kmSysConfigService.getSysConfigValue("viewLimitConfig");
+ if( viewLimitConfig!= null && !viewLimitConfig.isEmpty())
+ ViewLimit = Integer.valueOf(viewLimitConfig);
+ return ViewLimit;
+ }
+
+ static {
+ if(OSinfo.isWindows()) fileSeparator = '\\';
+ if(OSinfo.isLinux()) fileSeparator = '/';
+ }
+
+ public boolean isFileTypeSupport(String suffix){
+ String fileTypes = kmSysConfigService.getSysConfigValue("supportFileTypes");
+ if(fileTypes!=null && !fileTypes.isEmpty() ){
+ if(fileTypes.equals("*"))
+ return true;
+ for (String s : fileTypes.split(",")) {
+ if(suffix.toLowerCase().equals(s))
+ return true;
+ }
+ }
+ else{
+ return true;
+ }
+ return false;
+ }
+
+ public boolean isIndexFileType(String suffix){
+ String fileTypes = kmSysConfigService.getSysConfigValue("IndexFileTypes");
+ if(fileTypes!=null && !fileTypes.isEmpty() ){
+ for (String s : fileTypes.split(",")) {
+ if(suffix.toLowerCase().equals(s))
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public boolean isConvertFileType(String suffix){
+ String fileTypes = kmSysConfigService.getSysConfigValue("ConvertFileTypes");
+ if(fileTypes!=null && !fileTypes.isEmpty() ){
+ for (String s : fileTypes.split(",")) {
+ if(suffix.toLowerCase().equals(s))
+ return true;
+ }
+ }
+ return false;
+ }
+
+
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/rules/SerialNumberRule.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/rules/SerialNumberRule.java
new file mode 100644
index 0000000000000000000000000000000000000000..9d5e005d9b63405ea3955793f2e4450fd15c29fd
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/rules/SerialNumberRule.java
@@ -0,0 +1,18 @@
+package org.jeecg.modules.KM.common.rules;
+
+import org.apache.commons.lang.math.RandomUtils;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class SerialNumberRule {
+ static public String generate() {
+ String prefix = "Z";
+
+ SimpleDateFormat format = new SimpleDateFormat("yyMMddHHmmss");
+ int random = RandomUtils.nextInt(90) + 10;
+ String value = prefix + format.format(new Date()) + random;
+ return value;
+ }
+
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/system/vo/KmSearchResultObjVO.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/system/vo/KmSearchResultObjVO.java
new file mode 100644
index 0000000000000000000000000000000000000000..605b98d553d69cc09d6f6e5ba8a2a243e0fc830c
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/system/vo/KmSearchResultObjVO.java
@@ -0,0 +1,20 @@
+package org.jeecg.common.system.vo;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+@ApiModel(value="检索返回对象", description="检索返回对象")
+public class KmSearchResultObjVO implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ private boolean success;
+ private List paramPath;
+ private IPage kmSearchResultVOPage;
+ private String message;
+
+ public KmSearchResultObjVO(){}
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/utils/DictUtils.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/utils/DictUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..dd7e904edca4f466a157e39a2b2ef54dc1d70944
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/utils/DictUtils.java
@@ -0,0 +1,177 @@
+package org.jeecg.modules.KM.common.utils;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.aspect.annotation.Dict;
+import org.jeecg.common.constant.CommonConstant;
+import org.jeecg.common.system.api.ISysBaseAPI;
+import org.jeecg.common.system.vo.DictModel;
+import org.jeecg.common.util.oConvertUtils;
+import org.jeecg.common.system.vo.KmSearchResultObjVO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
+
+import java.lang.reflect.Field;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+@Component
+@Slf4j
+public class DictUtils {
+
+ @Autowired
+ private ISysBaseAPI sysBaseAPI;
+ @Autowired
+ private RedisTemplate redisTemplate;
+
+
+ public String getDicText(String dicCode,String dicItemCode){
+ String dicText = "";
+ List dictModelList = sysBaseAPI.queryDictItemsByCode(dicCode);
+ if(dictModelList !=null && !dictModelList.isEmpty()){
+ for(int i=0;i items = new ArrayList<>();
+ for (Object record : ((KmSearchResultObjVO) ( (Result) result).getResult()).getKmSearchResultVOPage().getRecords()) {
+ ObjectMapper mapper = new ObjectMapper();
+ String json="{}";
+ try {
+ //解决@JsonFormat注解解析不了的问题详见SysAnnouncement类的@JsonFormat
+ json = mapper.writeValueAsString(record);
+ } catch (JsonProcessingException e) {
+ log.error("json解析失败"+e.getMessage(),e);
+ }
+ JSONObject item = JSONObject.parseObject(json);
+ //update-begin--Author:scott -- Date:20190603 ----for:解决继承实体字段无法翻译问题------
+ //for (Field field : record.getClass().getDeclaredFields()) {
+ for (Field field : oConvertUtils.getAllFields(record)) {
+ //update-end--Author:scott -- Date:20190603 ----for:解决继承实体字段无法翻译问题------
+ if (field.getAnnotation(Dict.class) != null) {
+ String code = field.getAnnotation(Dict.class).dicCode();
+ String text = field.getAnnotation(Dict.class).dicText();
+ String table = field.getAnnotation(Dict.class).dictTable();
+ String key = String.valueOf(item.get(field.getName()));
+
+ //翻译字典值对应的txt
+ String textValue = translateDictValue(code, text, table, key);
+
+ log.debug(" 字典Val : "+ textValue);
+ log.debug(" __翻译字典字段__ "+field.getName() + CommonConstant.DICT_TEXT_SUFFIX+": "+ textValue);
+ item.put(field.getName() + CommonConstant.DICT_TEXT_SUFFIX, textValue);
+ }
+ //date类型默认转换string格式化日期
+ if (field.getType().getName().equals("java.util.Date")&&field.getAnnotation(JsonFormat.class)==null&&item.get(field.getName())!=null){
+ SimpleDateFormat aDate=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ item.put(field.getName(), aDate.format(new Date((Long) item.get(field.getName()))));
+ }
+ }
+ items.add(item);
+ }
+ //((KmSearchResultObjVO) ((Result) result).getResult()).getKmSearchResultVOPage().setRecords(items);
+ }
+
+ }
+ }
+
+ /**
+ * 翻译字典文本
+ * @param code
+ * @param text
+ * @param table
+ * @param key
+ * @return
+ */
+ private String translateDictValue(String code, String text, String table, String key) {
+ if(oConvertUtils.isEmpty(key)) {
+ return null;
+ }
+ StringBuffer textValue=new StringBuffer();
+ String[] keys = key.split(",");
+ for (String k : keys) {
+ String tmpValue = null;
+ log.debug(" 字典 key : "+ k);
+ if (k.trim().length() == 0) {
+ continue; //跳过循环
+ }
+ //update-begin--Author:scott -- Date:20210531 ----for: !56 优化微服务应用下存在表字段需要字典翻译时加载缓慢问题-----
+ if (!StringUtils.isEmpty(table)){
+ log.info("--DictAspect------dicTable="+ table+" ,dicText= "+text+" ,dicCode="+code);
+ String keyString = String.format("sys:cache:dictTable::SimpleKey [%s,%s,%s,%s]",table,text,code,k.trim());
+ if (redisTemplate.hasKey(keyString)){
+ try {
+ tmpValue = oConvertUtils.getString(redisTemplate.opsForValue().get(keyString));
+ } catch (Exception e) {
+ log.warn(e.getMessage());
+ }
+ }else {
+ tmpValue= sysBaseAPI.translateDictFromTable(table,text,code,k.trim());
+ }
+ }else {
+ String keyString = String.format("sys:cache:dict::%s:%s",code,k.trim());
+ if (redisTemplate.hasKey(keyString)){
+ try {
+ tmpValue = oConvertUtils.getString(redisTemplate.opsForValue().get(keyString));
+ } catch (Exception e) {
+ log.warn(e.getMessage());
+ }
+ }else {
+ tmpValue = sysBaseAPI.translateDict(code, k.trim());
+ }
+ }
+ //update-end--Author:scott -- Date:20210531 ----for: !56 优化微服务应用下存在表字段需要字典翻译时加载缓慢问题-----
+
+ if (tmpValue != null) {
+ if (!"".equals(textValue.toString())) {
+ textValue.append(",");
+ }
+ textValue.append(tmpValue);
+ }
+
+ }
+ return textValue.toString();
+ }
+
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/utils/EsUtils.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/utils/EsUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..cc8e0aba6f198d548e238bdc655abd83566e9466
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/utils/EsUtils.java
@@ -0,0 +1,235 @@
+package org.jeecg.modules.KM.common.utils;
+
+import org.apache.http.HttpHost;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.CredentialsProvider;
+import org.apache.http.impl.client.BasicCredentialsProvider;
+import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
+import org.opensearch.client.opensearch.OpenSearchClient;
+import org.opensearch.client.opensearch.indices.AnalyzeRequest;
+import org.opensearch.client.opensearch.indices.AnalyzeResponse;
+import org.opensearch.client.opensearch.indices.analyze.AnalyzeToken;
+import org.opensearch.client.opensearch._types.query_dsl.BoolQuery;
+import org.opensearch.client.opensearch._types.query_dsl.Query;
+import org.opensearch.client.opensearch._types.query_dsl.QueryBuilders;
+import org.opensearch.client.opensearch._types.query_dsl.TermsQuery;
+import org.opensearch.client.opensearch._types.query_dsl.MatchPhraseQuery;
+import org.opensearch.client.opensearch._types.query_dsl.MatchQuery;
+import org.opensearch.client.opensearch._types.query_dsl.RangeQuery;
+import org.opensearch.client.opensearch._types.query_dsl.PrefixQuery;
+import org.opensearch.client.opensearch._types.query_dsl.TermQuery;
+import org.opensearch.client.opensearch._types.FieldValue;
+import org.opensearch.client.json.JsonData;
+
+import org.jeecg.common.util.oConvertUtils;
+import org.jeecg.modules.KM.VO.KmDocEsFilterParamVO;
+import org.jeecg.modules.KM.VO.KmDocEsParamVO;
+import org.jeecg.modules.KM.common.rules.KMConstant;
+import org.jeecg.modules.KM.entity.KmSearchRecord;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Date;
+import java.util.Arrays;
+import java.util.stream.Collectors;
+
+@Component
+public class EsUtils {
+ @Autowired
+ private OpenSearchClient openSearchClient;
+ @Autowired
+ private KMConstant kmConstant;
+
+/**
+ * 获取使用 ik_smart 分析器分析后的搜索词列表。
+ *
+ * @param searchContent 需要分析的搜索内容
+ * @return 分析后的搜索词列表
+ */
+ public List getIkAnalyzeSearchTerms(String searchContent) {
+ // 创建 AnalyzeRequest 实例
+ AnalyzeRequest request = new AnalyzeRequest.Builder()
+ .index(KMConstant.DocIndexAliasName)
+ .analyzer("ik_smart")
+ .text(searchContent)
+ .build();
+
+ List result = new ArrayList<>();
+ try {
+ if (!searchContent.isEmpty()) {
+ // 使用 OpenSearchClient 发送请求并获取响应
+ AnalyzeResponse response = openSearchClient.indices().analyze(request);
+
+ // 处理响应中的 tokens
+ for (AnalyzeToken token : response.tokens()) {
+ result.add(token.token());
+ }
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return result;
+ }
+ public BoolQuery.Builder buildESQueryParams(List filterParams){
+ //最终条件
+ BoolQuery.Builder boolQueryBuilder = QueryBuilders.bool();
+ for (KmDocEsFilterParamVO filterParam : filterParams) {
+ BoolQuery.Builder oneFilter = buildESQueryParam(filterParam);
+ // 将子查询的条件分别添加到主查询中
+ boolQueryBuilder.must(Query.of(q -> q.bool(oneFilter.build())));
+ }
+ return boolQueryBuilder;
+ }
+public BoolQuery.Builder buildESQueryParam(KmDocEsFilterParamVO kmDocEsFilterParamVO) {
+
+ // 创建 BoolQuery.Builder 实例
+ BoolQuery.Builder boolQueryBuilder = new BoolQuery.Builder();
+ BoolQuery.Builder boolQueryBuilderDefault = new BoolQuery.Builder();
+
+ // 1. 分类检索,用 filter
+ if (kmDocEsFilterParamVO.getCategory() != null && !kmDocEsFilterParamVO.getCategory().isEmpty()) {
+ List categorys = kmDocEsFilterParamVO.getCategory();
+ // 将 List 转换为 List
+ List fieldValues = categorys.stream()
+ .map(FieldValue::of)
+ .collect(Collectors.toList());
+ Query termsQuery = new TermsQuery.Builder()
+ .field("category")
+ .terms(t -> t.value(fieldValues))
+ .build()._toQuery();
+ boolQueryBuilder.filter(termsQuery);
+ }
+
+ // 准备好标题、全文检索的条件
+ Query titleMatchQuery = null;
+ Query contentMatchQuery = null;
+ if (oConvertUtils.isNotEmpty(kmDocEsFilterParamVO.getTitle())) {
+ if (kmDocEsFilterParamVO.getPhraseMatchSearchFlag() != null && kmDocEsFilterParamVO.getPhraseMatchSearchFlag()) {
+ titleMatchQuery = new MatchPhraseQuery.Builder()
+ .field("title")
+ .query(kmDocEsFilterParamVO.getTitle())
+ .slop(2)
+ .build()._toQuery();
+ } else {
+ FieldValue titleFieldValue = FieldValue.of(kmDocEsFilterParamVO.getTitle());
+ titleMatchQuery = new MatchQuery.Builder()
+ .field("title")
+ .query(titleFieldValue)
+ .analyzer("ik_smart")
+ .boost(kmConstant.getTitleSearchBoost())
+ .build()._toQuery();
+ }
+ }
+ if (oConvertUtils.isNotEmpty(kmDocEsFilterParamVO.getContent())) {
+ if (kmDocEsFilterParamVO.getPhraseMatchSearchFlag() != null && kmDocEsFilterParamVO.getPhraseMatchSearchFlag()) {
+ contentMatchQuery = new MatchPhraseQuery.Builder()
+ .field("content")
+ .query(kmDocEsFilterParamVO.getContent())
+ .slop(2)
+ .build()._toQuery();
+ } else {
+ FieldValue cFieldValue = FieldValue.of(kmDocEsFilterParamVO.getContent());
+ contentMatchQuery = new MatchQuery.Builder()
+ .field("content")
+ .query(cFieldValue)
+ .analyzer("ik_smart")
+ .boost(kmConstant.getContentSearchBoost())
+ .build()._toQuery();
+ }
+ }
+
+ // 2. 标题检索 高级用 must,快速用 should
+ if (kmDocEsFilterParamVO.getTitle() != null && !kmDocEsFilterParamVO.getTitle().isEmpty()) {
+ if (kmDocEsFilterParamVO.getAdvSearchFlag()) {
+ boolQueryBuilder.must(titleMatchQuery);
+ } else {
+ boolQueryBuilderDefault.should(titleMatchQuery);
+ }
+ }
+
+ // 3. 全文检索 高级用 must,快速用 should
+ if (kmDocEsFilterParamVO.getContent() != null && !kmDocEsFilterParamVO.getContent().isEmpty()) {
+ if (kmDocEsFilterParamVO.getAdvSearchFlag() != null && kmDocEsFilterParamVO.getAdvSearchFlag()) {
+ boolQueryBuilder.must(contentMatchQuery);
+ } else {
+ boolQueryBuilderDefault.should(contentMatchQuery);
+ }
+ }
+
+ // 4. 关键字检索 用 term 精确匹配; 高级用 must,快速用 should
+ if (kmDocEsFilterParamVO.getKeywords() != null && !kmDocEsFilterParamVO.getKeywords().isEmpty()) {
+ BoolQuery.Builder boolQueryBuilderKeywords = new BoolQuery.Builder();
+ kmDocEsFilterParamVO.getKeywords().forEach(keyword -> {
+ FieldValue kFieldValue = FieldValue.of(keyword);
+ boolQueryBuilderKeywords.should(new TermQuery.Builder()
+ .field("keywords")
+ .value(kFieldValue)
+ .boost(kmConstant.getKeywordSearchBoost())
+ .build()._toQuery());
+ });
+ if (kmDocEsFilterParamVO.getAdvSearchFlag() != null && kmDocEsFilterParamVO.getAdvSearchFlag()) {
+ boolQueryBuilder.must(boolQueryBuilderKeywords.build()._toQuery());
+ } else {
+ boolQueryBuilderDefault.should(boolQueryBuilderKeywords.build()._toQuery());
+ }
+ }
+
+ // 处理快速检索的合并条件:标题、关键字、全文
+ if (kmDocEsFilterParamVO.getAdvSearchFlag() == null || !kmDocEsFilterParamVO.getAdvSearchFlag()) {
+ boolQueryBuilder.must(boolQueryBuilderDefault.build()._toQuery());
+ }
+
+ // 5. 发布时间检索 用 filter
+ SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
+ if (kmDocEsFilterParamVO.getCreateTimeEnd() != null) {
+ Query rangeQueryEnd = new RangeQuery.Builder()
+ .field("createTime")
+ .lte(JsonData.of(format.format(kmDocEsFilterParamVO.getCreateTimeEnd())))
+ .build()._toQuery();
+ boolQueryBuilder.filter(rangeQueryEnd);
+ }
+ if (kmDocEsFilterParamVO.getCreateTimeStart() != null) {
+ Query rangeQueryStart = new RangeQuery.Builder()
+ .field("createTime")
+ .gte(JsonData.of(format.format(kmDocEsFilterParamVO.getCreateTimeStart())))
+ .build()._toQuery();
+ boolQueryBuilder.filter(rangeQueryStart);
+ }
+
+ // 7. 标签检索(多选) 用 filter
+ if (kmDocEsFilterParamVO.getBusinessTypes() != null && !kmDocEsFilterParamVO.getBusinessTypes().isEmpty()) {
+ List businessTypes = kmDocEsFilterParamVO.getBusinessTypes();
+ // 将 List 转换为 List
+ List fieldValues = businessTypes.stream()
+ .map(FieldValue::of)
+ .collect(Collectors.toList());
+ Query termsQuery = new TermsQuery.Builder()
+ .field("businessTypes")
+ .terms(t -> t.value(fieldValues))
+ .build()._toQuery();
+ boolQueryBuilder.filter(termsQuery);
+ }
+
+ // 9. 专题检索(多选,前缀模糊匹配) 用 filter
+ if (kmDocEsFilterParamVO.getTopicCodes() != null && !kmDocEsFilterParamVO.getTopicCodes().isEmpty()) {
+ BoolQuery.Builder boolQueryBuilderTopicCodes = new BoolQuery.Builder();
+ for (String topicCode : kmDocEsFilterParamVO.getTopicCodes()) {
+ boolQueryBuilderTopicCodes.should(new PrefixQuery.Builder()
+ .field("topicCodes")
+ .value(topicCode)
+ .build()._toQuery());
+ }
+ Query boolQueryTopicCodes = boolQueryBuilderTopicCodes.build()._toQuery();
+ boolQueryBuilder.filter(boolQueryTopicCodes);
+ }
+
+ // 返回 BoolQuery.Builder 而不是构建好的 BoolQuery
+ return boolQueryBuilder;
+}
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/utils/HashUtil.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/utils/HashUtil.java
new file mode 100644
index 0000000000000000000000000000000000000000..3074f0cc131c1e8b173ce2b6e338008023d8abce
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/utils/HashUtil.java
@@ -0,0 +1,64 @@
+package org.jeecg.modules.KM.common.utils;
+
+import org.apache.commons.io.IOUtils;
+
+import java.io.*;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+public class HashUtil {
+ public static String sha256(File file){
+ InputStream fis = null;
+ try {
+ fis = new FileInputStream(file);
+ return sha256(fis);
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ public static String sha256(String s) {
+ InputStream fis = new ByteArrayInputStream(s.getBytes());
+ try {
+ return sha256(fis);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ public static String sha256(InputStream inputStream) throws IOException
+
+ {
+ byte buffer[] = new byte[1024 * 10];
+ MessageDigest md5 = null;
+ try {
+ md5 = MessageDigest.getInstance("SHA-256");
+ for (int numRead = 0; (numRead = inputStream.read(buffer)) > 0; ) {
+ md5.update(buffer, 0, numRead);
+ }
+ byte[] digest = md5.digest();
+ return toHexString(digest);
+ } catch (NoSuchAlgorithmException e) {
+ e.printStackTrace();
+ } finally {
+ IOUtils.closeQuietly(inputStream);
+ }
+ return null;
+ }
+
+ private static String toHexString(byte[] digest) {
+ StringBuffer strHexString = new StringBuffer();
+ for (int i = 0; i < digest.length; i++) {
+ String hex = Integer.toHexString(0xff & digest[i]);
+ if (hex.length() == 1) {
+ strHexString.append('0');
+ }
+ strHexString.append(hex);
+ }
+ return strHexString.toString();
+ }
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/utils/IpUtils.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/utils/IpUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..5f3f35c8eee17a8cafdfa8e205fd515eb8ad2c12
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/utils/IpUtils.java
@@ -0,0 +1,48 @@
+package org.jeecg.modules.KM.common.utils;
+
+import lombok.extern.slf4j.Slf4j;
+//import me.zhyd.oauth.log.Log;
+
+import jakarta.servlet.http.HttpServletRequest;
+
+
+@Slf4j
+public class IpUtils {
+
+ public static String getIpAddr(HttpServletRequest request) {
+ String ip = request.getHeader("x-forwarded-for");
+ log.debug("x-forwarded-for ip: " + ip);
+ if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) {
+ // 多次反向代理后会有多个ip值,第一个ip才是真实ip
+ if( ip.indexOf(",")!=-1 ){
+ ip = ip.split(",")[0];
+ }
+ }
+ if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+ ip = request.getHeader("Proxy-Client-IP");
+ log.debug("Proxy-Client-IP ip: " + ip);
+ }
+ if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+ ip = request.getHeader("WL-Proxy-Client-IP");
+ log.debug("WL-Proxy-Client-IP ip: " + ip);
+ }
+ if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+ ip = request.getHeader("HTTP_CLIENT_IP");
+ log.debug("HTTP_CLIENT_IP ip: " + ip);
+ }
+ if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+ ip = request.getHeader("HTTP_X_FORWARDED_FOR");
+ log.debug("HTTP_X_FORWARDED_FOR ip: " + ip);
+ }
+ if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+ ip = request.getHeader("X-Real-IP");
+ log.debug("X-Real-IP ip: " + ip);
+ }
+ if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+ ip = request.getRemoteAddr();
+ log.debug("getRemoteAddr ip: " + ip);
+ }
+ log.debug("获取客户端ip: " + ip);
+ return ip;
+ }
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/utils/KMDateUtils.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/utils/KMDateUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..058ba65f5b224b91c9b648d2385e2a5540519ea3
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/utils/KMDateUtils.java
@@ -0,0 +1,79 @@
+package org.jeecg.modules.KM.common.utils;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.TimeZone;
+
+public class KMDateUtils {
+
+ public static String formatDateyyyyMM(Date date){
+ SimpleDateFormat sd = new SimpleDateFormat("yyyyMM");
+ return sd.format(date);
+ }
+
+ public static String formatDateyyyyMMdd(Date date){
+ SimpleDateFormat sd = new SimpleDateFormat("yyyyMMdd");
+ return sd.format(date);
+ }
+
+ public static String formatDate1(Date date){
+ SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd");
+ return sd.format(date);
+ }
+
+ public static String formatDate2(Date date){
+ SimpleDateFormat sd = new SimpleDateFormat("yyyyMMddHHmmssSSS");
+ return sd.format(date);
+ }
+
+
+
+ public static String formatDate3(Date date){
+ SimpleDateFormat sd = new SimpleDateFormat("yyyyMMddHHmms");
+ return sd.format(date);
+ }
+
+ public static String formatDate4(Date date){
+ SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ return sd.format(date);
+ }
+
+ public static Date parseTZDateString(String dateString){
+ SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd'T'HHmmss'Z'");
+ df.setTimeZone(TimeZone.getTimeZone("UTC"));
+ try {
+ return df.parse(dateString);
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+
+ public static String getTimeStamp(){
+ Long timeStamp = System.currentTimeMillis();
+ String timeStampString = Long.toString(timeStamp);
+ return timeStampString.substring(0,timeStampString.length()-3);
+ }
+
+ public static Date parse(String src){
+ SimpleDateFormat sd = new SimpleDateFormat("yyyyMMddHHmms");
+ try {
+ return sd.parse(src);
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ public static Date parse2(String src){
+ SimpleDateFormat sd = new SimpleDateFormat("yyyyMMddHHmmssSSS");
+ try {
+ return sd.parse(src);
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/utils/KMRedisUtils.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/utils/KMRedisUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..a2936c02b0b26a8255f8efa432b74487b37e72db
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/utils/KMRedisUtils.java
@@ -0,0 +1,114 @@
+package org.jeecg.modules.KM.common.utils;
+
+import org.apache.shiro.SecurityUtils;
+import org.jeecg.common.system.vo.LoginUser;
+import org.jeecg.common.util.DateUtils;
+import org.jeecg.modules.KM.common.rules.KMConstant;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.stereotype.Component;
+
+import java.text.ParseException;
+import java.util.Calendar;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+
+@Component
+public class KMRedisUtils {
+
+ @Autowired
+ private StringRedisTemplate stringRedisTemplate;
+ @Autowired
+ private RedisTemplate redisTemplate;
+
+ //检查时间内下载次数是否超限制
+ public boolean validUserLimit(String limitType, Integer limitAmount,Integer calendarUnit,Integer amount) throws ParseException {
+ resetUserLimit(limitType,calendarUnit,amount);
+ LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
+ if(sysUser == null)
+ return false;
+
+ String userId = sysUser.getUsername();
+ String userKey = limitType + userId;
+ return !redisTemplate.hasKey(userKey)
+ || redisTemplate.opsForList().size(userKey) < limitAmount;
+ }
+
+ //重设下载次数缓存,从左到右的时间升序列表
+ private void resetUserLimit(String limitType, Integer timeUnit, Integer amount) throws ParseException {
+ LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
+ if(sysUser == null)
+ return;
+
+ String userId = sysUser.getUsername();
+ String userKey = limitType + userId;
+ if(redisTemplate.hasKey(userKey)
+ && redisTemplate.opsForList().size(userKey) >0){
+ //清除掉xx时间以前的记录
+ Calendar startDate = DateUtils.getCalendar();
+ startDate.add(timeUnit,-1 * amount);
+
+ Calendar downloadDate = DateUtils.parseCalendar(
+ redisTemplate
+ .opsForList()
+ .range(userKey,0,1)
+ .get(0)
+ .toString() ,"yyyyMMddHHmmss");
+ while(DateUtils.dateDiff('s',downloadDate,startDate) < 0
+ && redisTemplate.opsForList().size(userKey) > 0){
+ redisTemplate.opsForList().leftPop(userKey);
+ downloadDate = DateUtils.parseCalendar(
+ redisTemplate
+ .opsForList()
+ .range(userKey,0,1)
+ .get(0)
+ .toString() ,"yyyyMMddHHmmss");
+ }
+ }
+ }
+
+ //在右边push当前时间,并设置失效时间
+ public void refreshUserLimit(String limitType, TimeUnit unit, Integer amount){
+ LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
+ if(sysUser == null)
+ return;
+
+ String userId = sysUser.getUsername();
+ String userKey =limitType + userId;
+ redisTemplate.opsForList()
+ .rightPush(userKey, DateUtils.formatDate("yyyyMMddHHmmss"));
+ //设置一天后过期
+ redisTemplate.opsForList()
+ .getOperations()
+ .expire(userKey,amount, unit);
+ }
+
+ //设置用户访问历史文档,保留最近十个
+ public void logPersonalDocHistory(String userId,String docId){
+ String userKey = KMConstant.UserDocVisitHistoryPrefix + userId;
+ if(stringRedisTemplate.hasKey(userKey)){
+// 计数参数以下列方式影响操作:
+// count> 0:删除等于从头到尾移动的值的元素。
+// count <0:删除等于从尾到头移动的值的元素。
+// count = 0:删除等于value的所有元素。
+ stringRedisTemplate.opsForList().remove(userKey,0,docId);
+ if(stringRedisTemplate.opsForList().size(userKey) >= 10){
+ stringRedisTemplate.opsForList().rightPop(userKey);
+ }
+ }
+ stringRedisTemplate.opsForList().leftPush(userKey,docId);
+ }
+
+ //获取用户最近访问的档案
+ public List getPersonalDocHistory(String userId){
+ String userKey = KMConstant.UserDocVisitHistoryPrefix + userId;
+ List result = stringRedisTemplate
+ .opsForList()
+ .range(userKey,0,-1);
+ return result;
+ }
+
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/utils/OfficeUtils.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/utils/OfficeUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..2de706e86435ea2d1ebf6882707fc0123be2e12c
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/utils/OfficeUtils.java
@@ -0,0 +1,213 @@
+package org.jeecg.modules.KM.common.utils;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.io.IOUtils;
+import org.apache.poi.hssf.usermodel.HSSFPrintSetup;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+import org.apache.poi.ss.usermodel.PrintSetup;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.xssf.usermodel.XSSFPrintSetup;
+import org.apache.poi.xssf.usermodel.XSSFSheet;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+
+import java.io.*;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+/**
+ *
+ * Title: OfficeUtils.java
+ *
+ * @author lwx
+ * @time 2018/6/29 下午5:20
+ */
+@Slf4j
+public class OfficeUtils {
+
+ private static void formatExcel(String srcFile){
+ String fileExt = StringUtils.getFileSuffix(srcFile);
+ if ( fileExt != null ) {
+ try {
+ if(fileExt.equals("xlsx")){
+ XSSFWorkbook wb = new XSSFWorkbook(Files.newInputStream(Paths.get(srcFile)));
+
+ for (int i = 0; i < wb.getNumberOfSheets(); i++) {
+ XSSFSheet sheet = wb.getSheetAt(i);
+ //打印设置
+ XSSFPrintSetup print = sheet.getPrintSetup();
+ print.setLandscape(true); // 打印方向,true:横向,false:纵向(默认)
+ print.setFitHeight((short)0);//设置高度为自动分页
+ print.setFitWidth((short)1);//设置宽度为一页
+ print.setPaperSize(HSSFPrintSetup.A4_PAPERSIZE); //纸张类型
+// print.setScale((short)55);//自定义缩放①,此处100为无缩放
+ //启用“适合页面”打印选项的标志
+ sheet.setFitToPage(true);
+ }
+ File file = new File(srcFile);
+ OutputStream fos = new FileOutputStream(file);
+ wb.write(fos);
+ }else if(fileExt.equals("xls")){
+ POIFSFileSystem fs = new POIFSFileSystem(Files.newInputStream(Paths.get(srcFile)));
+ HSSFWorkbook wb = new HSSFWorkbook(fs);
+
+ for (int i = 0; i < wb.getNumberOfSheets(); i++) {
+ Sheet sheet = wb.getSheetAt(i);
+ //打印设置
+ PrintSetup print = sheet.getPrintSetup();
+ print.setLandscape(true); // 打印方向,true:横向,false:纵向(默认)
+ print.setFitHeight((short)0);//设置高度为自动分页
+ print.setFitWidth((short)1);//设置宽度为一页
+ print.setPaperSize(HSSFPrintSetup.A4_PAPERSIZE); //纸张类型
+ //启用“适合页面”打印选项的标志
+ sheet.setFitToPage(true);
+ }
+ File file = new File(srcFile);
+ OutputStream fos = new FileOutputStream(file);
+ wb.write(fos);
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ public static boolean convertPdf(String sofficePath,File srcFile, File targetDir){
+ //设置excel文件格式为不换行折断
+ formatExcel(srcFile.getAbsolutePath());
+ Listcommands=new ArrayList<>();
+ String outputDir = targetDir.getAbsolutePath();
+ commands.add(sofficePath);
+ commands.add("--headless");
+ commands.add("--invisible");
+ commands.add("--convert-to");
+ commands.add("pdf");
+ commands.add("--outdir");
+ commands.add(outputDir);
+ commands.add(srcFile.getAbsolutePath());
+ log.info("开始转换pdf,命令行是:{}", Arrays.toString(commands.toArray()));
+ try {
+
+ ProcessBuilder pb = new ProcessBuilder(commands);
+ pb.redirectErrorStream(true);
+ Process process = pb.start();
+ String result = IOUtils.toString(process.getInputStream(),"utf-8");
+ boolean exitFlag = process.waitFor(10, TimeUnit.SECONDS);
+ if(exitFlag) {
+ int code = process.exitValue();
+
+ log.info("convertPdf from {} output: {}\n result:{}\n exitValue:{}\n", srcFile.getAbsolutePath(), outputDir, result, code);
+
+ process.destroy();
+
+ File targetFile = new File(targetDir, StringUtils.getFileNameWithoutSuffix(srcFile.getName()) + ".pdf");
+ if (targetFile.exists()) {
+ log.info("文档转化成功,{},目标文件是:{}", srcFile.getAbsolutePath(), targetFile.getAbsolutePath());
+ return true;
+ } else {
+ log.info("文档转化失败,{},目标文件是:{}", srcFile.getAbsolutePath(), targetFile.getAbsolutePath());
+ return false;
+ }
+ }
+ else {
+ log.info("等待命令退出失败");
+ return false;
+ }
+ } catch (IOException e) {
+ log.error("convertPdf IOException:",e);
+ }catch (InterruptedException e) {
+ log.error("convertPdf InterruptedException:",e);
+ }
+ return false;
+ }
+
+ public static void printStream(InputStream inputStream){
+ new Thread(){
+ @Override
+ public void run() {
+ log.info("开始读取流,thread:{}",currentThread().getId());
+ try {
+ String s = IOUtils.toString(inputStream,"utf-8");
+ log.info("流内容:{}",s);
+ } catch (IOException e) {
+ log.error("读取流异常",e);
+ }
+ log.info("结束读取流,thread:{}",currentThread().getId());
+ }
+ }.start();
+ }
+//
+// public static boolean convertPdf(String sofficePath,File srcFile, File targetDir) {
+// OutputStream outputStream = null;
+// File targetFile = new File(targetDir,
+// StringUtils.getFileNameWithoutSuffix(srcFile.getName())+".pdf");
+// if (!targetFile.exists()) {
+// 19 try {
+// 20 // 如果文件找不到,就new一个
+// 21 targetFile.createNewFile();
+// 22 } catch (IOException e) {
+// 23 e.printStackTrace();
+// 24 }
+// 25 }
+//
+// String content = fileToTxt(srcFile);
+//
+// try {
+// outputStream = new FileOutputStream(targetFile);
+// } catch (FileNotFoundException e) {
+// e.printStackTrace();
+// log.error("文件不存在:" + srcFile.getAbsolutePath()+srcFile.getName());
+// return false;
+// }
+// try {
+// outputStream.write(content.getBytes());
+// outputStream.close();
+// } catch (IOException e) {
+// e.printStackTrace();
+// log.error("文件操作异常:" + srcFile.getAbsolutePath()+srcFile.getName());
+// return false;
+// }
+// return true;
+// }
+//
+// private static String fileToTxt(File f) {
+// //1、创建一个parser
+// Parser parser = new AutoDetectParser();
+// InputStream is = null;
+// try {
+// Metadata metadata = new Metadata();
+// metadata.set(Metadata.RESOURCE_NAME_KEY, f.getName());
+// is = new FileInputStream(f);
+// ContentHandler handler = new BodyContentHandler();
+// ParseContext context = new ParseContext();
+// context.set(Parser.class,parser);
+// //2、执行parser的parse()方法。
+// parser.parse(is,handler, metadata,context);
+// for(String name:metadata.names()) {
+// System.out.println(name+":"+metadata.get(name));
+// }
+// return handler.toString();
+// } catch (FileNotFoundException e) {
+// e.printStackTrace();
+// } catch (IOException e) {
+// e.printStackTrace();
+// } catch (SAXException e) {
+// e.printStackTrace();
+// } catch (TikaException e) {
+// e.printStackTrace();
+// } finally {
+// try {
+// if(is!=null) is.close();
+// } catch (IOException e) {
+// e.printStackTrace();
+// }
+// }
+// return "";
+// }
+
+
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/utils/RandomUtils.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/utils/RandomUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..7398e49331f305dde14cfbc86e8d2ff5467e2aa4
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/utils/RandomUtils.java
@@ -0,0 +1,53 @@
+//package org.jeecg.modules.KM.common.utils;
+//
+//import cn.hutool.core.util.RandomUtil;
+//import io.swagger.models.auth.In;
+//
+//import java.util.ArrayList;
+//import java.util.List;
+//
+//public class RandomUtils {
+//
+// private final static String[] keywords = {"中国","技术","系统","基础","运维","功夫","科亿信息技术","程序员","进口红酒","红酒","进口","中国人民","中国人民银行","全国","银行","人民银行","中国人","国人","员工","程序"};
+// private final static String[] topicCodes = {"A01","A01B01","A01B02","A01B01C01","A01B01C02","A01B01C03","A01C01","A01C02","A01C03","A01C03D01","A01C03D02","B01","B01C03D01","B01C01D01","B01C03D02","B01A03D01","B01A03A01","B01C03D04","A03","B09"};
+//
+// public static String[] generateRamdonTopicCodes(){
+// String topicCodeString[] = new String[5];
+// for(int i=0;i<5;i++){
+// topicCodeString[i]=topicCodes[RandomUtil.randomInt(0,20)];
+// }
+//
+// return topicCodeString;
+// }
+//
+// public static String generateRamdonKeywords(){
+// String keyWordString = "关键字";
+// int count = RandomUtil.randomInt(5,10);
+// for(int i=0;i intList = new ArrayList();
+// for(int i=0;i<10;i++){
+// Integer t = RandomUtil.randomInt(1,10);
+// intList.add(t);
+// }
+//
+// String a= intList.toString();
+// return a.substring(1,a.length()-1);
+// }
+//
+//}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/utils/SetUtils.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/utils/SetUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..e34d6db3183b334b3f478f73abc7a8b85dcf8d19
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/utils/SetUtils.java
@@ -0,0 +1,43 @@
+package org.jeecg.modules.KM.common.utils;
+
+import java.util.HashSet;
+import java.util.Set;
+public class SetUtils {
+
+ public static Set union(Set setA, Set setB) {
+ Set tmp = new HashSet(setA);
+ tmp.addAll(setB);
+ return tmp;
+ }
+
+ public static Set intersection(Set setA, Set setB) {
+ Set tmp = new HashSet();
+ for (T x : setA)
+ if (setB.contains(x))
+ tmp.add(x);
+ return tmp;
+ }
+
+ public static Set difference(Set setA, Set setB) {
+ Set tmp = new HashSet(setA);
+ tmp.removeAll(setB);
+ return tmp;
+ }
+
+ public static Set symDifference(Set setA, Set setB) {
+ Set tmpA;
+ Set tmpB;
+
+ tmpA = union(setA, setB);
+ tmpB = intersection(setA, setB);
+ return difference(tmpA, tmpB);
+ }
+
+ public static boolean isSubset(Set setA, Set setB) {
+ return setB.containsAll(setA);
+ }
+
+ public static boolean isSuperset(Set setA, Set setB) {
+ return setA.containsAll(setB);
+ }
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/utils/StringUtils.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/utils/StringUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..b926caa02999b8bb015de42bc44fa17015d9ef70
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/utils/StringUtils.java
@@ -0,0 +1,88 @@
+package org.jeecg.modules.KM.common.utils;
+
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+
+public class StringUtils {
+ public static String byteToStringUTF8(byte[]bytes){
+ try {
+ return new String (bytes,"utf-8");
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static byte[] stringToByteUTF8(String s){
+ try {
+ return s.getBytes("utf-8");
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static String getFileSuffix(String fileName){
+ int pos=fileName.lastIndexOf(".");
+ if(pos>=0){
+ if(pos+1!=fileName.length()){
+ return fileName.substring(pos+1,fileName.length()).toLowerCase();
+ }
+ }
+ return "";
+ }
+
+ public static String getFileNameWithoutSuffix(String fileName){
+ int pos=fileName.lastIndexOf(".");
+ if(pos>=0){
+ if(pos+1!=fileName.length()){
+ return fileName.substring(0,pos);
+ }
+ }
+ return "";
+ }
+
+
+ public static List splitStrListToList(List sourceList){
+ List resultList = new ArrayList<>();
+ for (int i = 0; i < sourceList.size(); i++) {
+ resultList.addAll(splitStringToList(sourceList.get(i)));
+ }
+
+ return resultList;
+ }
+
+ //更换其他字符或空格为",",最后得到string数组
+ public static List splitStringToList(String source){
+ List resultList = new ArrayList<>();
+ List tmptList = new ArrayList<>();
+ //String regExpress = "-~!@#%&_`=}:\"<>]\\\\;\'/\\$\\(\\)\\*\\+\\.\\[\\?\\\\\\^\\{\\|";
+ String regExpress = "[<~!@#%&_`=}:\">\\;'/\\$\\(\\)\\*\\+\\.\\[\\?\\\\\\^\\{\\|\\-\\]]";
+ if(source !=null && source.length()>0){
+ source = source.replaceAll(regExpress,",")
+ .replace(" ",",");
+ tmptList = Arrays.asList(source.split(","));
+ tmptList.forEach((e)->{
+ if(!e.isEmpty()){
+ resultList.add(e);
+ }
+ });
+ }
+ return resultList;
+ }
+
+ //合并字符list成为字符串,用分隔符","
+ public static String concatListToString(List stringList){
+ String result = "";
+ if(stringList != null & stringList.size()>0) {
+ for (int i = 0; i < stringList.size(); i++) {
+ if(stringList.get(i) != null && stringList.get(i).length()>0)
+ result = result + stringList.get(i) + ",";
+ }
+ if(result.length()>0)
+ result = result.substring(0,result.length()-1);
+ }
+ return result;
+ }
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/utils/TikaUtils.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/utils/TikaUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..0596cbcba3df2e78767f1c8c253e13abe7532b68
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/common/utils/TikaUtils.java
@@ -0,0 +1,64 @@
+package org.jeecg.modules.KM.common.utils;
+
+import jodd.util.StringUtil;
+import org.apache.commons.io.FileUtils;
+import org.apache.tika.detect.EncodingDetector;
+import org.apache.tika.metadata.Metadata;
+import org.apache.tika.parser.AutoDetectParser;
+import org.apache.tika.parser.txt.UniversalEncodingDetector;
+import org.apache.tika.sax.BodyContentHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.Charset;
+
+public class TikaUtils {
+ private static Logger logger= LoggerFactory.getLogger(TikaUtils.class);
+ public static String parseContent(File f){
+ String content =null;
+ try{
+ InputStream stream = FileUtils.openInputStream(f);
+ content =parseContent(stream);
+ if(StringUtil.isEmpty(content)){
+ content=parseTxt(f);
+ }
+ if (content != null) {
+ return content;
+ }
+ }catch (Exception e){
+ logger.error("tika parse error",e);
+ }
+ return content;
+ }
+
+ private static String parseTxt(File file) throws IOException {
+ InputStream stream1 = FileUtils.openInputStream(file);
+ EncodingDetector detector=new UniversalEncodingDetector();
+ Charset charset = detector.detect(new BufferedInputStream(stream1), new Metadata());
+ stream1.close();
+ if(charset!=null){
+ return FileUtils.readFileToString(file,charset);
+ }else {
+ return null;
+ }
+ }
+
+ public static String parseContent(InputStream stream){
+ String content =null;
+ try{
+ AutoDetectParser parser = new AutoDetectParser();
+ BodyContentHandler handler = new BodyContentHandler(Integer.MAX_VALUE);
+ Metadata metadata = new Metadata();
+ parser.parse(stream, handler, metadata);
+ content = handler.toString();
+ }catch (Exception e){
+ logger.error("tika parse error",e);
+ }
+ return content;
+ }
+
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/controller/EsMgntController.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/controller/EsMgntController.java
new file mode 100644
index 0000000000000000000000000000000000000000..136bd2ebd2187a366bcda0aa0ce69daa34ad2c71
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/controller/EsMgntController.java
@@ -0,0 +1,46 @@
+package org.jeecg.modules.KM.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.modules.KM.service.IKmEsMgntService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.io.IOException;
+
+@Api(tags="ES-management")
+@RestController
+@RequestMapping("/KM/EsMgnt")
+@Slf4j
+public class EsMgntController {
+ @Autowired
+ private IKmEsMgntService kmEsMgntService;
+
+ @ApiOperation(value="ES-management-km_doc模板初始化", notes="ES-management-km_doc模板初始化")
+ @PutMapping(value = "/initKmDocTemplate")
+ public Result> initKmDocTemplate() throws IOException {
+ return kmEsMgntService.initKmDocTemplate();
+
+ }
+
+
+ @ApiOperation(value="ES-management-km_doc_visit_record模板初始化", notes="ES-management-km_doc_visit_record模板初始化")
+ @PutMapping(value = "/initKmDocVisitTemplate")
+ public Result> initKmDocVisitTemplate() throws IOException {
+ return kmEsMgntService.initKmDocVisitTemplate();
+
+ }
+
+
+ @ApiOperation(value="ES-management-km_search_record模板初始化", notes="ES-management-km_search_record模板初始化")
+ @PutMapping(value = "/initKmSearchRecordTemplate")
+ public Result> initKmSearchRecordTemplate() throws IOException {
+ return kmEsMgntService.initKmSearchRecordTemplate();
+ }
+
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/controller/IndexController.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/controller/IndexController.java
new file mode 100644
index 0000000000000000000000000000000000000000..1f25056654ccf7fb4dc0ccae1462783e005a32a5
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/controller/IndexController.java
@@ -0,0 +1,48 @@
+package org.jeecg.modules.KM.controller;
+
+import org.jeecg.modules.KM.service.DocumentService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import java.util.List;
+import org.springframework.ai.document.Document;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+@RestController
+@RequestMapping("/api/vi/rag")
+@Tag(name = "RAG demo")
+public class IndexController {
+
+ @Autowired
+ private DocumentService documentService;
+
+
+ @Operation(summary = "上传文档")
+ @PostMapping("/upload")
+ public ResponseEntity upload(@RequestBody MultipartFile file) {
+ documentService.uploadDocument(file);
+ return ResponseEntity.ok("success");
+ }
+
+ @Operation(summary = "搜索文档")
+ @GetMapping("/search")
+ public ResponseEntity> searchDoc(@RequestParam String keyword) {
+ return ResponseEntity.ok(documentService.search(keyword));
+ }
+
+
+ @Operation(summary = "问答文档")
+ @GetMapping("/chat")
+ public ResponseEntity chat(@RequestParam String message) {
+ return ResponseEntity.ok(documentService.chat(message));
+ }
+
+
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/controller/KmDocBusinessTypeController.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/controller/KmDocBusinessTypeController.java
new file mode 100644
index 0000000000000000000000000000000000000000..77fe8713c0ce69d988633ccd5eb3d72560b627b9
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/controller/KmDocBusinessTypeController.java
@@ -0,0 +1,148 @@
+package org.jeecg.modules.KM.controller;
+
+import java.util.Arrays;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.modules.KM.entity.KmDocBusinessType;
+import org.jeecg.modules.KM.service.IKmDocBusinessTypeService;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.system.base.controller.JeecgController;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.servlet.ModelAndView;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.jeecg.common.aspect.annotation.AutoLog;
+
+@Api(tags="km_doc_business_type")
+@RestController
+@RequestMapping("/KM/kmDocBusinessType")
+@Slf4j
+public class KmDocBusinessTypeController extends JeecgController {
+ @Autowired
+ private IKmDocBusinessTypeService kmDocBusinessTypeService;
+
+ /**
+ * 分页列表查询
+ *
+ * @param kmDocBusinessType
+ * @param pageNo
+ * @param pageSize
+ * @param req
+ * @return
+ */
+ @AutoLog(value = "km_doc_business_type-分页列表查询")
+ @ApiOperation(value="km_doc_business_type-分页列表查询", notes="km_doc_business_type-分页列表查询")
+ @GetMapping(value = "/list")
+ public Result> queryPageList(KmDocBusinessType kmDocBusinessType,
+ @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
+ @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
+ HttpServletRequest req) {
+ QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(kmDocBusinessType, req.getParameterMap());
+ Page page = new Page(pageNo, pageSize);
+ IPage pageList = kmDocBusinessTypeService.page(page, queryWrapper);
+ return Result.OK(pageList);
+ }
+
+ /**
+ * 添加
+ *
+ * @param kmDocBusinessType
+ * @return
+ */
+ @AutoLog(value = "km_doc_business_type-添加")
+ @ApiOperation(value="km_doc_business_type-添加", notes="km_doc_business_type-添加")
+ @PostMapping(value = "/add")
+ public Result> add(@RequestBody KmDocBusinessType kmDocBusinessType) {
+ kmDocBusinessTypeService.save(kmDocBusinessType);
+ return Result.OK("添加成功!");
+ }
+
+ /**
+ * 编辑
+ *
+ * @param kmDocBusinessType
+ * @return
+ */
+ @AutoLog(value = "km_doc_business_type-编辑")
+ @ApiOperation(value="km_doc_business_type-编辑", notes="km_doc_business_type-编辑")
+ @PutMapping(value = "/edit")
+ public Result> edit(@RequestBody KmDocBusinessType kmDocBusinessType) {
+ kmDocBusinessTypeService.updateById(kmDocBusinessType);
+ return Result.OK("编辑成功!");
+ }
+
+ /**
+ * 通过id删除
+ *
+ * @param id
+ * @return
+ */
+ @AutoLog(value = "km_doc_business_type-通过id删除")
+ @ApiOperation(value="km_doc_business_type-通过id删除", notes="km_doc_business_type-通过id删除")
+ @DeleteMapping(value = "/delete")
+ public Result> delete(@RequestParam(name="id",required=true) String id) {
+ kmDocBusinessTypeService.removeById(id);
+ return Result.OK("删除成功!");
+ }
+
+ /**
+ * 批量删除
+ *
+ * @param ids
+ * @return
+ */
+ @AutoLog(value = "km_doc_business_type-批量删除")
+ @ApiOperation(value="km_doc_business_type-批量删除", notes="km_doc_business_type-批量删除")
+ @DeleteMapping(value = "/deleteBatch")
+ public Result> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
+ this.kmDocBusinessTypeService.removeByIds(Arrays.asList(ids.split(",")));
+ return Result.OK("批量删除成功!");
+ }
+
+ /**
+ * 通过id查询
+ *
+ * @param id
+ * @return
+ */
+ @AutoLog(value = "km_doc_business_type-通过id查询")
+ @ApiOperation(value="km_doc_business_type-通过id查询", notes="km_doc_business_type-通过id查询")
+ @GetMapping(value = "/queryById")
+ public Result> queryById(@RequestParam(name="id",required=true) String id) {
+ KmDocBusinessType kmDocBusinessType = kmDocBusinessTypeService.getById(id);
+ if(kmDocBusinessType==null) {
+ return Result.error("未找到对应数据");
+ }
+ return Result.OK(kmDocBusinessType);
+ }
+
+ /**
+ * 导出excel
+ *
+ * @param request
+ * @param kmDocBusinessType
+ */
+ @RequestMapping(value = "/exportXls")
+ public ModelAndView exportXls(HttpServletRequest request, KmDocBusinessType kmDocBusinessType) {
+ return super.exportXls(request, kmDocBusinessType, KmDocBusinessType.class, "km_doc_business_type");
+ }
+
+ /**
+ * 通过excel导入数据
+ *
+ * @param request
+ * @param response
+ * @return
+ */
+ @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
+ public Result> importExcel(HttpServletRequest request, HttpServletResponse response) {
+ return super.importExcel(request, response, KmDocBusinessType.class);
+ }
+
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/controller/KmDocCommentsController.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/controller/KmDocCommentsController.java
new file mode 100644
index 0000000000000000000000000000000000000000..5a6fae6044932bfc487026116ac434ccfb6153b6
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/controller/KmDocCommentsController.java
@@ -0,0 +1,150 @@
+package org.jeecg.modules.KM.controller;
+
+import java.util.Arrays;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.modules.KM.VO.KmDocCommentsVO;
+import org.jeecg.modules.KM.entity.KmDocComments;
+import org.jeecg.modules.KM.service.IKmDocCommentsService;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.system.base.controller.JeecgController;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.servlet.ModelAndView;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.jeecg.common.aspect.annotation.AutoLog;
+
+@Api(tags="km_doc_comments")
+@RestController
+@RequestMapping("/KM/KmDocComments")
+@Slf4j
+public class KmDocCommentsController extends JeecgController {
+ @Autowired
+ private IKmDocCommentsService KmDocCommentsService;
+
+ /**
+ * 分页列表查询
+ *
+ * @param KmDocComments
+ * @param pageNo
+ * @param pageSize
+ * @param req
+ * @return
+ */
+ @AutoLog(value = "km_doc_comments-分页列表查询")
+ @ApiOperation(value="km_doc_comments-分页列表查询", notes="km_doc_comments-分页列表查询")
+ @GetMapping(value = "/list")
+ public Result> queryPageList(KmDocComments KmDocComments,
+ @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
+ @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
+ HttpServletRequest req) {
+// QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(KmDocComments, req.getParameterMap());
+ Page page = new Page<>(pageNo, pageSize);
+ IPage pageList = KmDocCommentsService.queryPageList(page, KmDocComments);
+ return Result.OK(pageList);
+ }
+
+ /**
+ * 添加
+ *
+ * @param KmDocComments
+ * @return
+ */
+ @AutoLog(value = "km_doc_comments-添加")
+ @ApiOperation(value="km_doc_comments-添加", notes="km_doc_comments-添加")
+ @PostMapping(value = "/add")
+ public Result> add(@RequestBody KmDocComments KmDocComments) {
+ KmDocCommentsService.save(KmDocComments);
+ return Result.OK("添加成功!");
+ }
+
+ /**
+ * 编辑
+ *
+ * @param KmDocComments
+ * @return
+ */
+ @AutoLog(value = "km_doc_comments-编辑")
+ @ApiOperation(value="km_doc_comments-编辑", notes="km_doc_comments-编辑")
+ @PutMapping(value = "/edit")
+ public Result> edit(@RequestBody KmDocComments KmDocComments) {
+ KmDocCommentsService.updateById(KmDocComments);
+ return Result.OK("编辑成功!");
+ }
+
+ /**
+ * 通过id删除
+ *
+ * @param id
+ * @return
+ */
+ @AutoLog(value = "km_doc_comments-通过id删除")
+ @ApiOperation(value="km_doc_comments-通过id删除", notes="km_doc_comments-通过id删除")
+ @DeleteMapping(value = "/delete")
+ public Result> delete(@RequestParam(name="id",required=true) String id) {
+ KmDocCommentsService.removeById(id);
+ return Result.OK("删除成功!");
+ }
+
+ /**
+ * 批量删除
+ *
+ * @param ids
+ * @return
+ */
+ @AutoLog(value = "km_doc_comments-批量删除")
+ @ApiOperation(value="km_doc_comments-批量删除", notes="km_doc_comments-批量删除")
+ @DeleteMapping(value = "/deleteBatch")
+ public Result> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
+ this.KmDocCommentsService.removeByIds(Arrays.asList(ids.split(",")));
+ return Result.OK("批量删除成功!");
+ }
+
+ /**
+ * 通过id查询
+ *
+ * @param id
+ * @return
+ */
+ @AutoLog(value = "km_doc_comments-通过id查询")
+ @ApiOperation(value="km_doc_comments-通过id查询", notes="km_doc_comments-通过id查询")
+ @GetMapping(value = "/queryById")
+ public Result> queryById(@RequestParam(name="id",required=true) String id) {
+ KmDocComments KmDocComments = KmDocCommentsService.getById(id);
+ if(KmDocComments==null) {
+ return Result.error("未找到对应数据");
+ }
+ return Result.OK(KmDocComments);
+ }
+
+ /**
+ * 导出excel
+ *
+ * @param request
+ * @param KmDocComments
+ */
+ @RequestMapping(value = "/exportXls")
+ public ModelAndView exportXls(HttpServletRequest request, KmDocComments KmDocComments) {
+ return super.exportXls(request, KmDocComments, KmDocComments.class, "km_doc_comments");
+ }
+
+ /**
+ * 通过excel导入数据
+ *
+ * @param request
+ * @param response
+ * @return
+ */
+ @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
+ public Result> importExcel(HttpServletRequest request, HttpServletResponse response) {
+ return super.importExcel(request, response, KmDocComments.class);
+ }
+
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/controller/KmDocController.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/controller/KmDocController.java
new file mode 100644
index 0000000000000000000000000000000000000000..e925798d1fca92fa81caa3220583f258f267e74b
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/controller/KmDocController.java
@@ -0,0 +1,814 @@
+package org.jeecg.modules.KM.controller;
+
+import java.io.*;
+import java.text.ParseException;
+import java.util.*;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import org.apache.shiro.SecurityUtils;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.aspect.annotation.PermissionData;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.common.system.vo.KmSearchResultObjVO;
+import org.jeecg.common.system.vo.LoginUser;
+import org.jeecg.common.util.DateUtils;
+import org.jeecg.modules.KM.VO.*;
+import org.jeecg.modules.KM.common.config.BaseConfig;
+import org.jeecg.modules.KM.common.enums.DocConvertFlagEnum;
+import org.jeecg.modules.KM.common.enums.DocStatusEnum;
+import org.jeecg.modules.KM.common.enums.DocVisitTypeEnum;
+import org.jeecg.modules.KM.common.rules.KMConstant;
+import org.jeecg.modules.KM.common.utils.*;
+import org.jeecg.modules.KM.entity.KmDoc;
+import org.jeecg.modules.KM.entity.KmFile;
+import org.jeecg.modules.KM.service.*;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.system.base.controller.JeecgController;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.servlet.ModelAndView;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.jeecg.common.aspect.annotation.AutoLog;
+
+@Api(tags="km_doc")
+@RestController
+@RequestMapping("/KM/kmDoc")
+@Slf4j
+public class KmDocController extends JeecgController {
+ @Autowired
+ private IKmDocService kmDocService;
+ @Autowired
+ private IKmFileService kmFileService;
+ //@Autowired
+ //private openSearchClient client;
+ @Autowired
+ private KMConstant commonConstant;
+ @Autowired
+ private IKmDocVisitRecordService kmDocVisitRecordService;
+ @Autowired
+ private IThreadPoolExecutorService executorService;
+ @Autowired
+ private DictUtils dictUtils;
+ @Autowired
+ private BaseConfig baseConfig;
+ @Autowired
+ private IKmSysConfigService kmSysConfigService;
+
+ @Autowired
+ private IKmDocTopicTypeService kmDocTopicTypeService;
+
+ @AutoLog(value = "km_doc-文件上传")
+ @ApiOperation(value = "km_doc-文件上传", notes = "km_doc-文件上传")
+ @PostMapping("/uploadDoc")
+ @ResponseBody
+ public Result> uploadDoc(@RequestParam(value = "file") MultipartFile file,HttpServletRequest req){
+ try{
+ if(!commonConstant.isFileTypeSupport(StringUtils.getFileSuffix(file.getOriginalFilename()))){
+ return Result.error("不支持的文件格式");
+ }
+
+ KmFile dupFile =kmFileService.getKmFileBySha256(HashUtil.sha256(file.getInputStream()));
+ if(dupFile != null){
+ return Result.error("该文件已经存在无需重复上传,源文件:"+ dupFile.getOriginalName());
+ }
+
+ Map parameterMap = req.getParameterMap();
+// Gson gson = new Gson();
+// String json = gson.toJson(req.getParameterMap());
+
+ KmDocParamVO kmDocParamVO = new KmDocParamVO();
+ if (parameterMap.containsKey("category")){
+ kmDocParamVO.setCategory(parameterMap.get("category")[0]);
+ }
+ if (parameterMap.containsKey("businessTypes")){
+ kmDocParamVO.setBusinessTypeList(Arrays.asList(parameterMap.get("businessTypes")[0].split(",")));
+ }
+ if (parameterMap.containsKey("topicIds")){
+ kmDocParamVO.setAddTopicIdList(Arrays.asList(parameterMap.get("topicIds")[0].split(",")));
+ }
+ if (parameterMap.containsKey("depId")){
+ kmDocParamVO.setDepId(parameterMap.get("depId")[0]);
+ }
+ if (parameterMap.containsKey("keywords")){
+ kmDocParamVO.setKeywords(parameterMap.get("keywords")[0]);
+ }
+ if (parameterMap.containsKey("publicRemark")){
+ kmDocParamVO.setPublicRemark(Integer.parseInt(parameterMap.get("publicRemark")[0]));
+ }
+
+ KmFile kmFile = kmFileService.saveFile(file);
+
+ KmDoc kmDoc = kmDocService.saveDoc(kmFile,kmDocParamVO);
+
+ if(kmDoc != null && kmDoc.getId() != null) {
+ kmDocVisitRecordService.logVisit(kmDoc.getId(),
+ IpUtils.getIpAddr(req),
+ DocVisitTypeEnum.Upload.getCode());
+ }
+ else{
+ kmFileService.deleteKmFile(kmFile.getId());
+ return Result.error("保存文档数据发生错误");
+ }
+ }catch (Exception e){
+ log.error("uploadDoc",e);
+ return Result.error(e.getMessage());
+ }
+ return Result.OK();
+ }
+
+ /**
+ * 提审
+ *
+ * @param id
+ * @return
+ */
+ @AutoLog(value = "km_doc-提审")
+ @ApiOperation(value="km_doc-提审", notes="km_doc-提审")
+ @PutMapping(value = "/submitAudit")
+ public Result> submitAudit(@RequestParam(name="id") String id) {
+ KmDoc kmDoc = kmDocService.getById(id);
+ if(kmDoc!= null && (kmDoc.getStatus().equals(DocStatusEnum.Draft.getCode())
+ || kmDoc.getStatus().equals(DocStatusEnum.Reject.getCode()) )){
+ kmDoc.setStatus(DocStatusEnum.WaitAudit.getCode());
+ if(kmDocService.updateById(kmDoc)){
+ return Result.OK("提审成功");
+ }
+ else
+ return Result.error("全部失败");
+ }
+ else{
+ return Result.error("不允许提审");
+ }
+ }
+
+ /**
+ * 批量提审
+ *
+ * @param ids
+ * @return
+ */
+ @AutoLog(value = "km_doc-批量提审")
+ @ApiOperation(value="km_doc-批量提审", notes="km_doc-批量提审")
+ @PutMapping(value = "/submitAuditBatch")
+ public Result> submitAuditBatch(@RequestParam(name="ids",required=true) String ids) {
+ Integer success = 0;
+ List failIds = new ArrayList<>();
+ if(ids.length()>0) {
+ List idList = Arrays.asList(ids.split(","));
+ for (String id : idList) {
+ KmDoc kmDoc = kmDocService.getById(id);
+ if(kmDoc!= null && (kmDoc.getStatus().equals(DocStatusEnum.Draft.getCode())
+ || kmDoc.getStatus().equals(DocStatusEnum.Reject.getCode()) )){
+ kmDoc.setStatus(DocStatusEnum.WaitAudit.getCode());
+ if(kmDocService.updateById(kmDoc)){
+ success +=1;
+ }
+ else
+ failIds.add(id);
+ }
+ else{
+ failIds.add(id);
+ }
+ }
+ }
+ if(success >0)
+ return Result.OK(failIds);
+ else
+ return Result.error("全部失败");
+ }
+
+ //取消文件收录
+ @ApiOperation(value="km_doc-取消文件收录", notes="km_doc-取消文件收录")
+ @PutMapping(value = "/removeDocFromTopic")
+ public Result> removeDocFromTopic(@RequestParam(name="topicId",required = true) String topicId,
+ @RequestParam(name="docId", required = true) String docId) {
+ return kmDocService.removeDocFromTopic(topicId,docId);
+ }
+
+
+ //收录文件到专题
+ @ApiOperation(value="km_doc-收录文件到专题", notes="km_doc-收录文件到专题")
+ @PutMapping(value = "/addDocToTopic")
+ public Result> addDocToTopic(@RequestParam(name="topicId",required = true) String topicId,
+ @RequestParam(name="docIds", required = true) String docIds) {
+ if(docIds != null && docIds.length()>0) {
+ return kmDocService.addDocToTopic(topicId, Arrays.asList(docIds.split(",")));
+ }
+ else
+ return Result.error("文档参数不能为空");
+ }
+
+ /**
+ * 分页查询专题文档
+ *
+ * @param topicId
+ * @param pageNo
+ * @param pageSize
+ * @param topicId
+ * @return
+ */
+ @ApiOperation(value="km_doc-分页查询专题文档", notes="km_doc-分页查询专题文档")
+ @GetMapping(value = "/listTopicPageList")
+ public Result> queryTopicPageList(@RequestParam(name="topicId",required = true) String topicId,
+ @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
+ @RequestParam(name="pageSize", defaultValue="10") Integer pageSize) {
+ Page page = new Page(pageNo, pageSize);
+ IPage pageList = kmDocService.queryTopicPageList(page,topicId);
+ return Result.OK(pageList);
+ }
+
+ /**
+ * 分页草稿列表
+ *
+ * @param kmDocParamVO
+ * @param pageNo
+ * @param pageSize
+ * @param req
+ * @return
+ */
+ @ApiOperation(value="km_doc-分页草稿列表", notes="km_doc-分页草稿列表")
+ @GetMapping(value = "/listDraft")
+ public Result> queryDraftPageList(KmDocParamVO kmDocParamVO,
+ @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
+ @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
+ HttpServletRequest req) {
+ QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(kmDocParamVO, req.getParameterMap());
+ String orderBy = queryWrapper.getExpression().getOrderBy().getSqlSegment();
+ kmDocParamVO.setStatusList(Arrays.asList(0,3));
+ LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
+ //草稿箱只看自己创建的
+ if(sysUser != null) {
+ kmDocParamVO.setCreateBy(sysUser.getUsername());
+ }
+ else
+ return Result.error("当前登录用户信息异常");
+
+ Page page = new Page<>(pageNo, pageSize);
+ IPage pageList = kmDocService.queryPageList(page,kmDocParamVO,orderBy);
+ return Result.OK(pageList);
+ }
+
+ /**
+ * 分页待审核列表
+ *
+ * @param kmDocParamVO
+ * @param pageNo
+ * @param pageSize
+ * @param req
+ * @return
+ */
+ @ApiOperation(value="km_doc-分页待审核列表", notes="km_doc-分页待审核列表")
+ @GetMapping(value = "/listWaitAudit")
+ @PermissionData(pageComponent = "km/filemanagement/PendingReviewList")
+ public Result> queryWaitAuditPageList(KmDocParamVO kmDocParamVO,
+ @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
+ @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
+ HttpServletRequest req) {
+ QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(kmDocParamVO, req.getParameterMap());
+ String orderBy = queryWrapper.getExpression().getOrderBy().getSqlSegment();
+ kmDocParamVO.setStatusList(Arrays.asList(1));
+ Page page = new Page(pageNo, pageSize);
+ IPage pageList = kmDocService.queryPageList(page,kmDocParamVO,orderBy);
+ return Result.OK(pageList);
+ }
+
+
+ /**
+ * 分页已审核列表
+ *
+ * @param kmDocParamVO
+ * @param pageNo
+ * @param pageSize
+ * @param req
+ * @return
+ */
+ @ApiOperation(value="km_doc-分页已审核列表", notes="km_doc-分页已审核列表")
+ @GetMapping(value = "/listPassed")
+ @PermissionData(pageComponent = "km/filemanagement/AuditedList")
+ public Result> queryPassedPageList(KmDocParamVO kmDocParamVO,
+ @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
+ @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
+ HttpServletRequest req) {
+ QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(kmDocParamVO, req.getParameterMap());
+ String orderBy = queryWrapper.getExpression().getOrderBy().getSqlSegment();
+ kmDocParamVO.setStatusList(Arrays.asList(2));
+ Page page = new Page(pageNo, pageSize);
+ IPage pageList = kmDocService.queryPageList(page,kmDocParamVO,orderBy);
+ return Result.OK(pageList);
+ }
+
+ @ApiOperation(value="km_doc-最新发布档案", notes="km_doc-最新发布档案")
+ @GetMapping(value = "/listRecently")
+ public Result> queryRecentPageList(KmDocParamVO kmDocParamVO,
+ @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
+ @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
+ HttpServletRequest req) {
+ QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(kmDocParamVO, req.getParameterMap());
+ String orderBy = queryWrapper.getExpression().getOrderBy().getSqlSegment();
+ kmDocParamVO.setStatusList(Arrays.asList(2));
+ Page page = new Page(pageNo, pageSize);
+ IPage pageList = kmDocService.queryPublicPageList(page,kmDocParamVO,orderBy);
+ return Result.OK(pageList);
+ }
+
+ @AutoLog(value = "km_doc-编辑草稿")
+ @ApiOperation(value="km_doc-编辑草稿", notes="km_doc-编辑草稿")
+ @PutMapping(value = "/editDraft")
+ @Transactional
+ public Result> editDraft(@RequestBody KmDocParamVO kmdDocTarget,HttpServletRequest req) {
+ Result> result = kmDocService.editDraft(kmdDocTarget);
+ if(result.isSuccess()){
+ kmDocVisitRecordService.logVisit(kmdDocTarget.getId(),IpUtils.getIpAddr(req),DocVisitTypeEnum.Edit.getCode());
+ }
+ return result;
+ }
+
+ @AutoLog(value = "km_doc-编辑并发布")
+ @ApiOperation(value="km_doc-编辑并发布", notes="km_doc-编辑并发布")
+ @PutMapping(value = "/editAndRelease")
+ @Transactional
+ public Result> editAndRelease(@RequestBody KmDocParamVO kmdDocTarget,HttpServletRequest req) {
+ Result> result = kmDocService.editAndRelease(kmdDocTarget,req);
+ if(result.isSuccess()){
+ kmDocVisitRecordService.logVisit(kmdDocTarget.getId(),IpUtils.getIpAddr(req),DocVisitTypeEnum.Edit.getCode());
+ }
+ return result;
+ }
+
+ @AutoLog(value = "km_doc-编辑发布状态")
+ @ApiOperation(value="km_doc-编辑发布状态", notes="km_doc-编辑发布状态")
+ @PutMapping(value = "/editReleaseFlag")
+ public Result> editReleaseFlag(@RequestBody KmDoc kmDoc,HttpServletRequest req) {
+ Result> result = kmDocService.editReleaseFlag(kmDoc);
+ if(result.isSuccess()){
+ kmDocVisitRecordService.logVisit(kmDoc.getId(),IpUtils.getIpAddr(req),DocVisitTypeEnum.Edit.getCode());
+ }
+ return result;
+ }
+
+ @AutoLog(value = "km_doc-编辑已审核")
+ @ApiOperation(value="km_doc-编辑已审核", notes="km_doc-编辑已审核")
+ @PutMapping(value = "/editRelease")
+ @Transactional
+ public Result> editAuditPassed(@RequestBody KmDocParamVO kmDocTarget,HttpServletRequest req) {
+ Result> result = kmDocService.editAuditPassed(kmDocTarget);
+ if(result.isSuccess()){
+ kmDocVisitRecordService.logVisit(kmDocTarget.getId(),IpUtils.getIpAddr(req),DocVisitTypeEnum.Edit.getCode());
+ }
+ return result;
+ }
+
+ /**
+ * 审核驳回
+ *
+ * @param id
+ * @return
+ */
+ @AutoLog(value = "km_doc-审核驳回")
+ @ApiOperation(value="km_doc-审核驳回", notes="km_doc-审核驳回")
+ @PutMapping(value = "/auditReject")
+ public Result> auditReject(@RequestParam(name="id",required=true) String id,HttpServletRequest req) {
+ KmDoc kmDoc = kmDocService.getById(id);
+ if(kmDoc !=null && kmDoc.getStatus().equals(DocStatusEnum.WaitAudit.getCode())){
+ kmDoc.setStatus(DocStatusEnum.Reject.getCode());
+ if(kmDocService.updateById(kmDoc)) {
+ kmDocVisitRecordService.logVisit(kmDoc.getId(),IpUtils.getIpAddr(req),DocVisitTypeEnum.AuditReject.getCode());
+ log.info("驳回文档成功:{}",kmDoc.getName());
+ return Result.OK("审核成功!");
+ }
+ }
+ return Result.error("审核失败!");
+ }
+
+ /**
+ * 批量审核驳回
+ *
+ * @param ids
+ * @return
+ */
+ @AutoLog(value = "km_doc-批量审核驳回")
+ @ApiOperation(value="km_doc-批量审核驳回", notes="km_doc-批量审核驳回")
+ @PutMapping(value = "/auditRejectBatch")
+ public Result> auditRejectBatch(@RequestParam(name="ids",required=true) String ids,HttpServletRequest req) {
+ Integer success = 0;
+ List successIds = new ArrayList<>();
+ List failIds = new ArrayList<>();
+ if(ids.length()>0) {
+ List idList = Arrays.asList(ids.split(","));
+ for (String id : idList) {
+ KmDoc kmDoc = kmDocService.getById(id);
+ if(kmDoc!= null && kmDoc.getStatus().equals(DocStatusEnum.WaitAudit.getCode()) ){
+ kmDoc.setStatus(DocStatusEnum.Reject.getCode());
+ if(kmDocService.updateById(kmDoc)){
+ kmDocVisitRecordService.logVisit(kmDoc.getId(),IpUtils.getIpAddr(req),DocVisitTypeEnum.AuditReject.getCode());
+ log.info("驳回文档成功:{}",kmDoc.getName());
+ successIds.add(id);
+ success +=1;
+ }
+ else
+ failIds.add(id);
+ }
+ else{
+ failIds.add(id);
+ }
+ }
+ }
+ if(success >0) {
+ return Result.OK(failIds);
+ }
+ else
+ return Result.error("全部失败");
+ }
+
+ /**
+ * 审核通过
+ *
+ * @param id
+ * @return
+ */
+ @AutoLog(value = "km_doc-审核通过")
+ @ApiOperation(value="km_doc-审核通过", notes="km_doc-审核通过")
+ @PutMapping(value = "/auditPass")
+ public Result> auditPass(@RequestParam(name="id",required=true) String id,HttpServletRequest req) {
+ return kmDocService.auditDoc(id,req);
+ }
+
+ /**
+ * 批量审核通过
+ *
+ * @param ids
+ * @return
+ */
+ @AutoLog(value = "km_doc-批量审核通过")
+ @ApiOperation(value="km_doc-批量审核通过", notes="km_doc-批量审核通过")
+ @PutMapping(value = "/auditPassBatch")
+ public Result> auditPassBatch(@RequestParam(name="ids",required=true) String ids,HttpServletRequest req) {
+ Integer success = 0;
+ List successIds = new ArrayList<>();
+ List failIds = new ArrayList<>();
+ if(ids.length()>0) {
+ String ip = IpUtils.getIpAddr(req);
+ LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
+ //String userId = "1";
+ if(sysUser == null)
+ return Result.error("用户信息异常");
+
+ String userId = sysUser.getUsername();
+
+ List idList = Arrays.asList(ids.split(","));
+ for (String id : idList) {
+ KmDoc kmDoc = kmDocService.getById(id);
+ if(kmDoc!= null && kmDoc.getStatus().equals(DocStatusEnum.WaitAudit.getCode()) ){
+ kmDoc.setStatus(DocStatusEnum.Passed.getCode());
+ kmDoc.setLastUpdateTime(DateUtils.getDate());
+ kmDoc.setLastUpdateBy(userId);
+ if(kmDocService.updateById(kmDoc)){
+ kmDocService.indexDocSync(kmDoc);
+ successIds.add(id);
+ success +=1;
+
+ log.info("审核文档成功:{}",kmDoc.getName());
+ kmDocVisitRecordService.logVisit(id,
+ IpUtils.getIpAddr(req),
+ DocVisitTypeEnum.AuditPass.getCode());
+ }
+ else
+ failIds.add(id);
+ }
+ else{
+ failIds.add(id);
+ }
+ }
+ }
+ if(success >0) {
+ //审核后才入库ES kmDocService.indexDocSyncBatch(successIds);
+ return Result.OK(failIds);
+ }
+ else
+ return Result.error("全部失败");
+ }
+
+ /**
+ * 通过id删除
+ *
+ * @param id
+ * @return
+ */
+ @AutoLog(value = "km_doc-通过id删除")
+ @ApiOperation(value="km_doc-通过id删除", notes="km_doc-通过id删除")
+ @DeleteMapping(value = "/delete")
+ public Result> delete(@RequestParam(name="id",required=true) String id,HttpServletRequest req) {
+// if (!kmDocTopicTypeService.removeDocFromAllTopics(id)) {
+// return Result.error("removeDocFromAllTopics fail:" + id);
+// }
+ kmDocTopicTypeService.removeDocFromAllTopics(id);
+ return kmDocService.deleteDoc(id,req);
+ }
+
+ /**
+ * 批量删除
+ *
+ * @param ids
+ * @return
+ */
+ @AutoLog(value = "km_doc-批量删除")
+ @ApiOperation(value="km_doc-批量删除", notes="km_doc-批量删除")
+ @DeleteMapping(value = "/deleteBatch")
+ public Result> deleteBatch(@RequestParam(name="ids",required=true) String ids,HttpServletRequest req) {
+ Integer success = 0;
+ List failIds = new ArrayList<>();
+
+ if(ids.length()>0) {
+ List idList = Arrays.asList(ids.split(","));
+ for (String id : idList) {
+ KmDoc kmDoc = kmDocService.getById(id);
+ if(kmDoc!= null ){
+ Result> result = kmDocService.deleteDoc(id,req);
+ if(result.isSuccess()){
+ kmDocTopicTypeService.removeDocFromAllTopics(id);
+ success +=1;
+ }
+ else
+ failIds.add(id);
+ }
+ else{
+ failIds.add(id);
+ }
+ }
+ }
+ if(success >0)
+ return Result.OK(failIds);
+ else
+ return Result.error("全部失败");
+ }
+
+ /**
+ * 通过id查询
+ *
+ * @param id
+ * @return
+ */
+ @ApiOperation(value="km_doc-通过id查询", notes="km_doc-通过id查询")
+ @GetMapping(value = "/queryById")
+ public Result> queryById(@RequestParam(name="id",required=true) String id) {
+// KmDoc kmDoc = kmDocService.getById(id);
+ Page page = new Page<>(1, 1);
+ KmDocParamVO kmDocParamVO = new KmDocParamVO();
+ kmDocParamVO.setId(id);
+ IPage pageList = kmDocService.queryPageList(page,kmDocParamVO,"");
+ if(pageList.getSize()<=0) {
+ return Result.error("未找到对应数据");
+ }
+ return Result.OK(pageList);
+ }
+
+ /**
+ * 导出excel
+ *
+ * @param request
+ * @param kmDoc
+ */
+ @RequestMapping(value = "/exportXls")
+ public ModelAndView exportXls(HttpServletRequest request, KmDoc kmDoc) {
+ return super.exportXls(request, kmDoc, KmDoc.class, "km_doc");
+ }
+
+ /**
+ * 通过excel导入数据
+ *
+ * @param request
+ * @param response
+ * @return
+ */
+ @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
+ public Result> importExcel(HttpServletRequest request, HttpServletResponse response) {
+ return super.importExcel(request, response, KmDoc.class);
+ }
+
+
+ //以下是ES库综合检索api
+ /**
+ * @param docId 指想排重的docid
+ * @param checkType 1-标题排重,2-文本内容排重
+ * @功能描述 传入指定的indexid,列出相似的文档
+ */
+ @ApiOperation(value="km_doc-排重检索", notes="km_doc-排重检索")
+ @GetMapping(value = "/docDPCheck")
+ public Result> docDPCheck(String docId,String checkType,
+ @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
+ @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
+ HttpServletRequest req){
+ try {
+ //KmDocEsVO kmDocEsVO = kmDocService.getEsDocByDocId(indexId);
+ KmDocEsParamVO kmDocEsParamVO = new KmDocEsParamVO();
+ kmDocEsParamVO.setColumn("_score");
+ kmDocEsParamVO.setOrder("desc");
+ KmDoc kmDoc = kmDocService.getById(docId);
+ if(kmDoc != null ) {
+ String docTitle = kmDoc.getTitle();
+
+
+ if(checkType.equals("2") ){
+ KmFile kmFile = kmFileService.getKmFile(kmDoc.getFileId());
+ File file = baseConfig.getFile(kmFile.getPhysicalPath());
+ if (file != null && file.exists()) {
+ String content = TikaUtils.parseContent(file);
+ if (content != null && !content.isEmpty()) {
+ String maxContentSearchLength = kmSysConfigService.getSysConfigValue("MaxContentSearchLength");
+ if(maxContentSearchLength!= null && !maxContentSearchLength.isEmpty()) {
+ Integer intMaxContentSearchLength = 0;
+ try{
+ intMaxContentSearchLength = Integer.parseInt(maxContentSearchLength);
+ }
+ catch (NumberFormatException e){
+
+ }
+ if (intMaxContentSearchLength > 0 && content.length() > intMaxContentSearchLength)
+ content = content.substring(0, intMaxContentSearchLength-1);
+ }
+ kmDocEsParamVO.setContent(content);
+ } else {
+ return Result.error("file not found");
+ }
+ }
+ }
+
+ if(checkType.equals("1") && docTitle != null && !docTitle.isEmpty())
+ kmDocEsParamVO.setTitle(docTitle);
+
+ Page page = new Page(pageNo, pageSize);
+ KmSearchResultObjVO kmSearchResultObjVO = kmDocService.checkDuplicateESKmDoc(page, kmDocEsParamVO, req);
+ if (kmSearchResultObjVO.isSuccess()) {
+ dictUtils.parseDictText(kmSearchResultObjVO);
+ return Result.OK(kmSearchResultObjVO);
+ } else
+ return Result.error(kmSearchResultObjVO.getMessage());
+ }
+ else{
+ return Result.error("doc not found");
+ }
+ }
+ catch (IOException e){
+ return Result.error(e.getMessage());
+ }
+ }
+
+ @ApiOperation(value="km_doc-普通检索", notes="km_doc-普通检索")
+ @PostMapping(value = "/searchDoc")
+ public Result> searchDoc(@RequestBody(required = true) KmDocEsParamVO kmDocEsParamVO,
+// @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
+// @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
+ HttpServletRequest req){
+ try {
+// if(kmDocEsParamVO.getKeywords() !=null && kmDocEsParamVO.getKeywords().size() >0) {
+// kmDocEsParamVO.setKeywords(
+// StringUtils.splitStrListToList(
+// kmDocEsParamVO.getKeywords()));
+// }
+ kmDocEsParamVO.setPageNo(kmDocEsParamVO.getPageNo() == null ? 1:kmDocEsParamVO.getPageNo());
+ kmDocEsParamVO.setPageSize(kmDocEsParamVO.getPageSize() == null ? 10:kmDocEsParamVO.getPageSize());
+ Page page = new Page(kmDocEsParamVO.getPageNo(), kmDocEsParamVO.getPageSize());
+ KmSearchResultObjVO kmSearchResultObjVO = kmDocService.searchESKmDoc(page, kmDocEsParamVO, req);
+ if(kmSearchResultObjVO.isSuccess()) {
+// dictUtils.parseDictText(kmSearchResultObjVO);
+ return Result.OK(kmSearchResultObjVO);
+ }
+ else
+ return Result.error(kmSearchResultObjVO.getMessage());
+ }
+ catch (IOException e){
+ return Result.error(e.getMessage());
+ }
+ }
+
+ @ApiOperation(value="km_doc-高级检索", notes="km_doc-高级检索")
+ @GetMapping(value = "/advanceSearchDoc")
+ public Result> advanceSearchDoc(KmDocEsParamVO kmDocEsParamVO,
+ @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
+ @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
+ HttpServletRequest req){
+ return searchDoc(kmDocEsParamVO,req);
+ }
+
+ /**
+ * @param docId 指想要下载的文档id
+ * @param response
+ * @功能描述 下载文件:将输入流中的数据循环写入到响应输出流中,而不是一次性读取到内存
+ */
+ @ApiOperation(value="km_doc-下载文件", notes="km_doc-下载文件")
+ @GetMapping("/downloadKmDoc")
+ @SuppressWarnings("ALL")
+ public void downloadKmDoc(@RequestParam(value = "docId") String docId, HttpServletResponse response,HttpServletRequest req) throws IOException, ParseException {
+ kmDocService.downloadKmDoc(docId,response,req);
+
+ }
+
+ /**
+ * @param docId 指想要预览的文档id
+ * @param response
+ * @功能描述 下载文件:将输入流中的数据循环写入到响应输出流中,而不是一次性读取到内存
+ */
+ @ApiOperation(value="km_doc-预览文件", notes="km_doc-预览文件")
+ @GetMapping("/previewKmDoc")
+ @SuppressWarnings("ALL")
+ public void previewKmDoc(@RequestParam(value = "docId") String docId, HttpServletResponse response,HttpServletRequest req) throws IOException {
+ kmDocService.viewKmDoc(docId,response,req);
+ }
+
+
+ @AutoLog(value = "km_doc-预览文件替换")
+ @ApiOperation(value = "km_doc-预览文件替换", notes = "km_doc-预览文件替换")
+ @PostMapping("/changePreviewFile")
+ @ResponseBody
+ public Result> changePreviewFile(@RequestParam(value = "file") MultipartFile file,@RequestParam(value = "docId") String docId,HttpServletRequest req){
+ try{
+ if(!StringUtils.getFileSuffix(file.getOriginalFilename()).toLowerCase().equals("pdf") ){
+ return Result.error("仅支持pdf文件");
+ }
+ KmDoc kmDoc = kmDocService.getById(docId);
+ if(kmDoc == null){
+ return Result.error("文档没找到");
+ }
+ KmFile kmFile = kmFileService.saveFile(file);
+ if(kmFile != null){
+ kmDoc.setConvertFlag(DocConvertFlagEnum.Converted.getCode());
+ kmDoc.setProcessMsg("");
+ kmDoc.setPreviewFileId(kmFile.getId());
+ if(!kmDocService.updateById(kmDoc))
+ return Result.error("更新文档信息失败");
+ else{
+ //日志
+ kmDocVisitRecordService.logVisit(docId,
+ IpUtils.getIpAddr(req),
+ DocVisitTypeEnum.ChangePreview.getCode());
+ }
+ }
+ }catch (Exception e){
+ log.error("changePreviewFile",e);
+ return Result.error(e.getMessage());
+ }
+ return Result.OK();
+ }
+
+ @AutoLog(value = "km_doc-预览文件复位")
+ @ApiOperation(value = "km_doc-预览文件复位", notes = "km_doc-预览文件复位")
+ @PostMapping("/resetPreviewFile")
+ @ResponseBody
+ public Result> resetPreviewFile( @RequestParam(value = "docId") String docId){
+ try{
+ KmDoc kmDoc = kmDocService.getById(docId);
+ if(kmDoc == null){
+ return Result.error("文档没找到");
+ }
+
+ if(kmDoc.getOriginalPreviewFileId() != null){
+ kmDoc.setPreviewFileId(kmDoc.getOriginalPreviewFileId());
+ if(!kmDocService.updateById(kmDoc))
+ return Result.error("更新文档信息失败");
+ }
+ }catch (Exception e){
+ log.error("resetPreviewFile",e);
+ return Result.error(e.getMessage());
+ }
+ return Result.OK();
+ }
+
+ @ApiOperation(value="km_doc-文档统计", notes="km_doc-文档统计")
+ @GetMapping(value = "/queryKmDocStatistics")
+ public Result> queryKmDocStatistics( @RequestParam(value = "statisticsType") Integer statisticsType,
+ @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
+ @RequestParam(name="pageSize", defaultValue="10") Integer pageSize ) {
+ Page page = new Page(pageNo, pageSize);
+ IPage pageList = kmDocService.queryKmDocStatistics(page,statisticsType);
+ return Result.OK(pageList);
+ }
+
+
+ @AutoLog(value = "km_doc-批量转换")
+ @ApiOperation(value="km_doc-批量转换", notes="km_doc-批量转换")
+ @PostMapping(value = "/convertAll")
+ public Result> convertAll(HttpServletRequest req) {
+
+ LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
+ wrapper.ne(KmDoc::getFileType,"pdf");
+ List kmDocList = kmDocService.list(wrapper);
+
+ if(kmDocList.size()>0) {
+ for (KmDoc kmDoc : kmDocList) {
+ if(kmDoc!= null ){
+ kmDocService.convertDocSync(kmDoc);
+ }
+ }
+ }
+ return Result.OK();
+ }
+
+ }
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/controller/KmDocFavouriteController.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/controller/KmDocFavouriteController.java
new file mode 100644
index 0000000000000000000000000000000000000000..ff981bd3fa9bb3a6ce762a1fe22459a8bc4d8132
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/controller/KmDocFavouriteController.java
@@ -0,0 +1,163 @@
+package org.jeecg.modules.KM.controller;
+
+import java.util.Arrays;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import org.apache.shiro.SecurityUtils;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.common.system.vo.LoginUser;
+import org.jeecg.modules.KM.VO.KmDocParamVO;
+import org.jeecg.modules.KM.VO.KmDocVO;
+import org.jeecg.modules.KM.entity.KmDocFavourite;
+import org.jeecg.modules.KM.service.IKmDocFavouriteService;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.system.base.controller.JeecgController;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.servlet.ModelAndView;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.jeecg.common.aspect.annotation.AutoLog;
+
+@Api(tags="km_doc_favourite")
+@RestController
+@RequestMapping("/KM/kmDocFavourite")
+@Slf4j
+public class KmDocFavouriteController extends JeecgController {
+ @Autowired
+ private IKmDocFavouriteService kmDocFavouriteService;
+
+ /**
+ * 分页列表查询
+ *
+ * @param
+ * @param pageNo
+ * @param pageSize
+ * @param req
+ * @return
+ */
+ @AutoLog(value = "km_doc_favourite-分页列表查询")
+ @ApiOperation(value="km_doc_favourite-分页列表查询", notes="km_doc_favourite-分页列表查询")
+ @GetMapping(value = "/list")
+ public Result> queryPageList(KmDocParamVO kmDocParamVO,
+ @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
+ @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
+ HttpServletRequest req) {
+ LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
+ if(sysUser != null) {
+// //处理过滤source -> sourceList
+// if(kmDocParamVO.getSource() != null && !kmDocParamVO.getSource().isEmpty())
+// kmDocParamVO.setSourceList(Arrays.asList(kmDocParamVO.getSource().split(",")));
+
+ KmDocVO kmDocVO = new KmDocVO();
+ QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(kmDocVO, req.getParameterMap());
+ String orderBy = queryWrapper.getExpression().getOrderBy().getSqlSegment();
+ Page page = new Page<>(pageNo, pageSize);
+ IPage pageList = kmDocFavouriteService.queryPageList(page, sysUser.getId(),kmDocParamVO,orderBy);
+ return Result.OK(pageList);
+ }
+ else
+ return Result.error("登录信息异常");
+ }
+
+ /**
+ * 添加
+ *
+ * @param docId
+ * @return
+ */
+ @AutoLog(value = "km_doc_favourite-添加")
+ @ApiOperation(value="km_doc_favourite-添加", notes="km_doc_favourite-添加")
+ @PostMapping(value = "/add")
+ public Result> add(@RequestParam(name = "docId") String docId) {
+
+ return kmDocFavouriteService.addFavouriteDoc(docId);
+ }
+
+ /**
+ * 编辑
+ *
+ * @param kmDocFavourite
+ * @return
+ */
+ @AutoLog(value = "km_doc_favourite-编辑")
+ @ApiOperation(value="km_doc_favourite-编辑", notes="km_doc_favourite-编辑")
+ @PutMapping(value = "/edit")
+ public Result> edit(@RequestBody KmDocFavourite kmDocFavourite) {
+ kmDocFavouriteService.updateById(kmDocFavourite);
+ return Result.OK("编辑成功!");
+ }
+
+ /**
+ * 通过id删除
+ *
+ * @param docId
+ * @return
+ */
+ @AutoLog(value = "km_doc_favourite-通过id删除")
+ @ApiOperation(value="km_doc_favourite-通过id删除", notes="km_doc_favourite-通过id删除")
+ @DeleteMapping(value = "/delete")
+ public Result> delete(@RequestParam(name="docId",required=true) String docId) {
+
+ return kmDocFavouriteService.delFavouriteDoc(docId);
+ }
+
+ /**
+ * 批量删除
+ *
+ * @param ids
+ * @return
+ */
+ @AutoLog(value = "km_doc_favourite-批量删除")
+ @ApiOperation(value="km_doc_favourite-批量删除", notes="km_doc_favourite-批量删除")
+ @DeleteMapping(value = "/deleteBatch")
+ public Result> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
+ this.kmDocFavouriteService.removeByIds(Arrays.asList(ids.split(",")));
+ return Result.OK("批量删除成功!");
+ }
+
+ /**
+ * 通过id查询
+ *
+ * @param id
+ * @return
+ */
+ @AutoLog(value = "km_doc_favourite-通过id查询")
+ @ApiOperation(value="km_doc_favourite-通过id查询", notes="km_doc_favourite-通过id查询")
+ @GetMapping(value = "/queryById")
+ public Result> queryById(@RequestParam(name="id",required=true) String id) {
+ KmDocFavourite kmDocFavourite = kmDocFavouriteService.getById(id);
+ if(kmDocFavourite==null) {
+ return Result.error("未找到对应数据");
+ }
+ return Result.OK(kmDocFavourite);
+ }
+
+ /**
+ * 导出excel
+ *
+ * @param request
+ * @param kmDocFavourite
+ */
+ @RequestMapping(value = "/exportXls")
+ public ModelAndView exportXls(HttpServletRequest request, KmDocFavourite kmDocFavourite) {
+ return super.exportXls(request, kmDocFavourite, KmDocFavourite.class, "km_doc_favourite");
+ }
+
+ /**
+ * 通过excel导入数据
+ *
+ * @param request
+ * @param response
+ * @return
+ */
+ @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
+ public Result> importExcel(HttpServletRequest request, HttpServletResponse response) {
+ return super.importExcel(request, response, KmDocFavourite.class);
+ }
+
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/controller/KmDocTopicTypeController.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/controller/KmDocTopicTypeController.java
new file mode 100644
index 0000000000000000000000000000000000000000..d847a1491fce7e9d1dd4af0c2deb464725c33333
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/controller/KmDocTopicTypeController.java
@@ -0,0 +1,148 @@
+package org.jeecg.modules.KM.controller;
+
+import java.util.Arrays;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.modules.KM.entity.KmDocTopicType;
+import org.jeecg.modules.KM.service.IKmDocTopicTypeService;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.system.base.controller.JeecgController;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.servlet.ModelAndView;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.jeecg.common.aspect.annotation.AutoLog;
+
+@Api(tags="km_doc_topic_type")
+@RestController
+@RequestMapping("/KM/kmDocTopicType")
+@Slf4j
+public class KmDocTopicTypeController extends JeecgController {
+ @Autowired
+ private IKmDocTopicTypeService kmDocTopicTypeService;
+
+ /**
+ * 分页列表查询
+ *
+ * @param kmDocTopicType
+ * @param pageNo
+ * @param pageSize
+ * @param req
+ * @return
+ */
+ @AutoLog(value = "km_doc_topic_type-分页列表查询")
+ @ApiOperation(value="km_doc_topic_type-分页列表查询", notes="km_doc_topic_type-分页列表查询")
+ @GetMapping(value = "/list")
+ public Result> queryPageList(KmDocTopicType kmDocTopicType,
+ @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
+ @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
+ HttpServletRequest req) {
+ QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(kmDocTopicType, req.getParameterMap());
+ Page page = new Page(pageNo, pageSize);
+ IPage pageList = kmDocTopicTypeService.page(page, queryWrapper);
+ return Result.OK(pageList);
+ }
+
+ /**
+ * 添加
+ *
+ * @param kmDocTopicType
+ * @return
+ */
+ @AutoLog(value = "km_doc_topic_type-添加")
+ @ApiOperation(value="km_doc_topic_type-添加", notes="km_doc_topic_type-添加")
+ @PostMapping(value = "/add")
+ public Result> add(@RequestBody KmDocTopicType kmDocTopicType) {
+ kmDocTopicTypeService.save(kmDocTopicType);
+ return Result.OK("添加成功!");
+ }
+
+ /**
+ * 编辑
+ *
+ * @param kmDocTopicType
+ * @return
+ */
+ @AutoLog(value = "km_doc_topic_type-编辑")
+ @ApiOperation(value="km_doc_topic_type-编辑", notes="km_doc_topic_type-编辑")
+ @PutMapping(value = "/edit")
+ public Result> edit(@RequestBody KmDocTopicType kmDocTopicType) {
+ kmDocTopicTypeService.updateById(kmDocTopicType);
+ return Result.OK("编辑成功!");
+ }
+
+ /**
+ * 通过id删除
+ *
+ * @param id
+ * @return
+ */
+ @AutoLog(value = "km_doc_topic_type-通过id删除")
+ @ApiOperation(value="km_doc_topic_type-通过id删除", notes="km_doc_topic_type-通过id删除")
+ @DeleteMapping(value = "/delete")
+ public Result> delete(@RequestParam(name="id",required=true) String id) {
+ kmDocTopicTypeService.removeById(id);
+ return Result.OK("删除成功!");
+ }
+
+ /**
+ * 批量删除
+ *
+ * @param ids
+ * @return
+ */
+ @AutoLog(value = "km_doc_topic_type-批量删除")
+ @ApiOperation(value="km_doc_topic_type-批量删除", notes="km_doc_topic_type-批量删除")
+ @DeleteMapping(value = "/deleteBatch")
+ public Result> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
+ this.kmDocTopicTypeService.removeByIds(Arrays.asList(ids.split(",")));
+ return Result.OK("批量删除成功!");
+ }
+
+ /**
+ * 通过id查询
+ *
+ * @param id
+ * @return
+ */
+ @AutoLog(value = "km_doc_topic_type-通过id查询")
+ @ApiOperation(value="km_doc_topic_type-通过id查询", notes="km_doc_topic_type-通过id查询")
+ @GetMapping(value = "/queryById")
+ public Result> queryById(@RequestParam(name="id",required=true) String id) {
+ KmDocTopicType kmDocTopicType = kmDocTopicTypeService.getById(id);
+ if(kmDocTopicType==null) {
+ return Result.error("未找到对应数据");
+ }
+ return Result.OK(kmDocTopicType);
+ }
+
+ /**
+ * 导出excel
+ *
+ * @param request
+ * @param kmDocTopicType
+ */
+ @RequestMapping(value = "/exportXls")
+ public ModelAndView exportXls(HttpServletRequest request, KmDocTopicType kmDocTopicType) {
+ return super.exportXls(request, kmDocTopicType, KmDocTopicType.class, "km_doc_topic_type");
+ }
+
+ /**
+ * 通过excel导入数据
+ *
+ * @param request
+ * @param response
+ * @return
+ */
+ @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
+ public Result> importExcel(HttpServletRequest request, HttpServletResponse response) {
+ return super.importExcel(request, response, KmDocTopicType.class);
+ }
+
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/controller/KmDocVersionController.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/controller/KmDocVersionController.java
new file mode 100644
index 0000000000000000000000000000000000000000..d19d75b3d292ef361e740f312a2bfc2a46202f22
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/controller/KmDocVersionController.java
@@ -0,0 +1,149 @@
+//package org.jeecg.modules.KM.controller;
+//
+//import java.util.Arrays;
+//import jakarta.servlet.http.HttpServletRequest;
+//import jakarta.servlet.http.HttpServletResponse;
+//import org.jeecg.common.api.vo.Result;
+//import org.jeecg.common.system.query.QueryGenerator;
+//import org.jeecg.modules.KM.entity.KmDocVersion;
+//import org.jeecg.modules.KM.service.IKmDocVersionService;
+//
+//import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+//import com.baomidou.mybatisplus.core.metadata.IPage;
+//import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+//import lombok.extern.slf4j.Slf4j;
+//import org.jeecg.common.system.base.controller.JeecgController;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.web.bind.annotation.*;
+//import org.springframework.web.servlet.ModelAndView;
+//import io.swagger.annotations.Api;
+//import io.swagger.annotations.ApiOperation;
+//import org.jeecg.common.aspect.annotation.AutoLog;
+//
+//@Api(tags="km_doc_version")
+//@RestController
+//@RequestMapping("/KM/kmDocVersion")
+//@Slf4j
+//public class KmDocVersionController extends JeecgController {
+// @Autowired
+// private IKmDocVersionService kmDocVersionService;
+//
+// /**
+// * 分页列表查询
+// *
+// * @param kmDocVersion
+// * @param pageNo
+// * @param pageSize
+// * @param req
+// * @return
+// */
+// @AutoLog(value = "km_doc_version-分页列表查询")
+// @ApiOperation(value="km_doc_version-分页列表查询", notes="km_doc_version-分页列表查询")
+// @GetMapping(value = "/list")
+// public Result> queryPageList(KmDocVersion kmDocVersion,
+// @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
+// @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
+// HttpServletRequest req) {
+// QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(kmDocVersion, req.getParameterMap());
+// Page page = new Page(pageNo, pageSize);
+// IPage pageList = kmDocVersionService.page(page, queryWrapper);
+// return Result.OK(pageList);
+// }
+//
+// /**
+// * 添加
+// *
+// * @param kmDocVersion
+// * @return
+// */
+// @AutoLog(value = "km_doc_version-添加")
+// @ApiOperation(value="km_doc_version-添加", notes="km_doc_version-添加")
+// @PostMapping(value = "/add")
+// public Result> add(@RequestBody KmDocVersion kmDocVersion) {
+// kmDocVersionService.save(kmDocVersion);
+// return Result.OK("添加成功!");
+// }
+//
+// /**
+// * 编辑
+// *
+// * @param kmDocVersion
+// * @return
+// */
+// @AutoLog(value = "km_doc_version-编辑")
+// @ApiOperation(value="km_doc_version-编辑", notes="km_doc_version-编辑")
+// @PutMapping(value = "/edit")
+// public Result> edit(@RequestBody KmDocVersion kmDocVersion) {
+// kmDocVersionService.updateById(kmDocVersion);
+// return Result.OK("编辑成功!");
+// }
+//
+// /**
+// * 通过id删除
+// *
+// * @param id
+// * @return
+// */
+// @AutoLog(value = "km_doc_version-通过id删除")
+// @ApiOperation(value="km_doc_version-通过id删除", notes="km_doc_version-通过id删除")
+// @DeleteMapping(value = "/delete")
+// public Result> delete(@RequestParam(name="id",required=true) String id) {
+// kmDocVersionService.removeById(id);
+// return Result.OK("删除成功!");
+// }
+//
+// /**
+// * 批量删除
+// *
+// * @param ids
+// * @return
+// */
+// @AutoLog(value = "km_doc_version-批量删除")
+// @ApiOperation(value="km_doc_version-批量删除", notes="km_doc_version-批量删除")
+// @DeleteMapping(value = "/deleteBatch")
+// public Result> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
+// this.kmDocVersionService.removeByIds(Arrays.asList(ids.split(",")));
+// return Result.OK("批量删除成功!");
+// }
+//
+// /**
+// * 通过id查询
+// *
+// * @param id
+// * @return
+// */
+// @AutoLog(value = "km_doc_version-通过id查询")
+// @ApiOperation(value="km_doc_version-通过id查询", notes="km_doc_version-通过id查询")
+// @GetMapping(value = "/queryById")
+// public Result> queryById(@RequestParam(name="id",required=true) String id) {
+// KmDocVersion kmDocVersion = kmDocVersionService.getById(id);
+// if(kmDocVersion==null) {
+// return Result.error("未找到对应数据");
+// }
+// return Result.OK(kmDocVersion);
+// }
+//
+// /**
+// * 导出excel
+// *
+// * @param request
+// * @param kmDocVersion
+// */
+// @RequestMapping(value = "/exportXls")
+// public ModelAndView exportXls(HttpServletRequest request, KmDocVersion kmDocVersion) {
+// return super.exportXls(request, kmDocVersion, KmDocVersion.class, "km_doc_version");
+// }
+//
+// /**
+// * 通过excel导入数据
+// *
+// * @param request
+// * @param response
+// * @return
+// */
+// @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
+// public Result> importExcel(HttpServletRequest request, HttpServletResponse response) {
+// return super.importExcel(request, response, KmDocVersion.class);
+// }
+//
+//}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/controller/KmDocVisitRecordController.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/controller/KmDocVisitRecordController.java
new file mode 100644
index 0000000000000000000000000000000000000000..f28a32d3bb9470385d9ecd128b9756474c660990
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/controller/KmDocVisitRecordController.java
@@ -0,0 +1,194 @@
+package org.jeecg.modules.KM.controller;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import org.apache.shiro.SecurityUtils;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.common.system.vo.LoginUser;
+import org.jeecg.modules.KM.common.utils.KMRedisUtils;
+import org.jeecg.modules.KM.entity.KmDoc;
+import org.jeecg.modules.KM.entity.KmDocVisitRecord;
+import org.jeecg.modules.KM.service.IKmDocService;
+import org.jeecg.modules.KM.service.IKmDocVisitRecordService;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.system.base.controller.JeecgController;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.servlet.ModelAndView;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.jeecg.common.aspect.annotation.AutoLog;
+
+@Api(tags="km_doc_visit_record")
+@RestController
+@RequestMapping("/KM/kmDocVisitRecord")
+@Slf4j
+public class KmDocVisitRecordController extends JeecgController {
+ @Autowired
+ private IKmDocVisitRecordService kmDocVisitRecordService;
+ @Autowired
+ private IKmDocService kmDocService;
+ @Autowired
+ private KMRedisUtils kmRedisUtils;
+
+
+ @ApiOperation(value="km_doc_visit_record-最近访问档案", notes="km_doc_visit_record-最近访问档案")
+ @GetMapping(value = "/recentlyVisitDocs")
+ public Result> recentlyVisitDocs(){
+ try {
+ LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
+ if(sysUser != null) {
+ String userId = sysUser.getUsername();
+
+ List recentlyDocIds = kmRedisUtils.getPersonalDocHistory(userId);
+ if(recentlyDocIds.size() > 0) {
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
+ queryWrapper.in(KmDoc::getId, recentlyDocIds);
+ List recentlyDocs = kmDocService.list(queryWrapper);
+ List result = new ArrayList<>();
+ for (int i = 0; i < recentlyDocIds.size(); i++) {
+ String docId = recentlyDocIds.get(i);
+
+ for (int j = 0; j < recentlyDocs.size(); j++) {
+ if(recentlyDocs.get(j).getId().equals(docId))
+ result.add(recentlyDocs.get(j));
+ }
+ }
+
+ return Result.OK(result);
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ return Result.error("发生异常");
+ }
+ return Result.OK("空数据");
+ }
+
+ /**
+ * 分页列表查询
+ *
+ * @param kmDocVisitRecord
+ * @param pageNo
+ * @param pageSize
+ * @param req
+ * @return
+ */
+ @AutoLog(value = "km_doc_visit_record-分页列表查询")
+ @ApiOperation(value="km_doc_visit_record-分页列表查询", notes="km_doc_visit_record-分页列表查询")
+ @GetMapping(value = "/list")
+ public Result> queryPageList(KmDocVisitRecord kmDocVisitRecord,
+ @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
+ @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
+ HttpServletRequest req) {
+ QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(kmDocVisitRecord, req.getParameterMap());
+ Page page = new Page(pageNo, pageSize);
+ IPage pageList = kmDocVisitRecordService.page(page, queryWrapper);
+ return Result.OK(pageList);
+ }
+
+ /**
+ * 添加
+ *
+ * @param kmDocVisitRecord
+ * @return
+ */
+ @AutoLog(value = "km_doc_visit_record-添加")
+ @ApiOperation(value="km_doc_visit_record-添加", notes="km_doc_visit_record-添加")
+ @PostMapping(value = "/add")
+ public Result> add(@RequestBody KmDocVisitRecord kmDocVisitRecord) {
+ kmDocVisitRecordService.save(kmDocVisitRecord);
+ return Result.OK("添加成功!");
+ }
+
+ /**
+ * 编辑
+ *
+ * @param kmDocVisitRecord
+ * @return
+ */
+ @AutoLog(value = "km_doc_visit_record-编辑")
+ @ApiOperation(value="km_doc_visit_record-编辑", notes="km_doc_visit_record-编辑")
+ @PutMapping(value = "/edit")
+ public Result> edit(@RequestBody KmDocVisitRecord kmDocVisitRecord) {
+ kmDocVisitRecordService.updateById(kmDocVisitRecord);
+ return Result.OK("编辑成功!");
+ }
+
+ /**
+ * 通过id删除
+ *
+ * @param id
+ * @return
+ */
+ @AutoLog(value = "km_doc_visit_record-通过id删除")
+ @ApiOperation(value="km_doc_visit_record-通过id删除", notes="km_doc_visit_record-通过id删除")
+ @DeleteMapping(value = "/delete")
+ public Result> delete(@RequestParam(name="id",required=true) String id) {
+ kmDocVisitRecordService.removeById(id);
+ return Result.OK("删除成功!");
+ }
+
+ /**
+ * 批量删除
+ *
+ * @param ids
+ * @return
+ */
+ @AutoLog(value = "km_doc_visit_record-批量删除")
+ @ApiOperation(value="km_doc_visit_record-批量删除", notes="km_doc_visit_record-批量删除")
+ @DeleteMapping(value = "/deleteBatch")
+ public Result> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
+ this.kmDocVisitRecordService.removeByIds(Arrays.asList(ids.split(",")));
+ return Result.OK("批量删除成功!");
+ }
+
+ /**
+ * 通过id查询
+ *
+ * @param id
+ * @return
+ */
+ @AutoLog(value = "km_doc_visit_record-通过id查询")
+ @ApiOperation(value="km_doc_visit_record-通过id查询", notes="km_doc_visit_record-通过id查询")
+ @GetMapping(value = "/queryById")
+ public Result> queryById(@RequestParam(name="id",required=true) String id) {
+ KmDocVisitRecord kmDocVisitRecord = kmDocVisitRecordService.getById(id);
+ if(kmDocVisitRecord==null) {
+ return Result.error("未找到对应数据");
+ }
+ return Result.OK(kmDocVisitRecord);
+ }
+
+ /**
+ * 导出excel
+ *
+ * @param request
+ * @param kmDocVisitRecord
+ */
+ @RequestMapping(value = "/exportXls")
+ public ModelAndView exportXls(HttpServletRequest request, KmDocVisitRecord kmDocVisitRecord) {
+ return super.exportXls(request, kmDocVisitRecord, KmDocVisitRecord.class, "km_doc_visit_record");
+ }
+
+ /**
+ * 通过excel导入数据
+ *
+ * @param request
+ * @param response
+ * @return
+ */
+ @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
+ public Result> importExcel(HttpServletRequest request, HttpServletResponse response) {
+ return super.importExcel(request, response, KmDocVisitRecord.class);
+ }
+
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/controller/KmFileController.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/controller/KmFileController.java
new file mode 100644
index 0000000000000000000000000000000000000000..2a4d90d826542a79c793398c5e873bae3ccb80f0
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/controller/KmFileController.java
@@ -0,0 +1,148 @@
+package org.jeecg.modules.KM.controller;
+
+import java.util.Arrays;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.modules.KM.entity.KmFile;
+import org.jeecg.modules.KM.service.IKmFileService;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.system.base.controller.JeecgController;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.servlet.ModelAndView;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.jeecg.common.aspect.annotation.AutoLog;
+
+@Api(tags="km_file")
+@RestController
+@RequestMapping("/KM/kmFile")
+@Slf4j
+public class KmFileController extends JeecgController {
+ @Autowired
+ private IKmFileService kmFileService;
+
+ /**
+ * 分页列表查询
+ *
+ * @param kmFile
+ * @param pageNo
+ * @param pageSize
+ * @param req
+ * @return
+ */
+ @AutoLog(value = "km_file-分页列表查询")
+ @ApiOperation(value="km_file-分页列表查询", notes="km_file-分页列表查询")
+ @GetMapping(value = "/list")
+ public Result> queryPageList(KmFile kmFile,
+ @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
+ @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
+ HttpServletRequest req) {
+ QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(kmFile, req.getParameterMap());
+ Page page = new Page(pageNo, pageSize);
+ IPage pageList = kmFileService.page(page, queryWrapper);
+ return Result.OK(pageList);
+ }
+
+ /**
+ * 添加
+ *
+ * @param kmFile
+ * @return
+ */
+ @AutoLog(value = "km_file-添加")
+ @ApiOperation(value="km_file-添加", notes="km_file-添加")
+ @PostMapping(value = "/add")
+ public Result> add(@RequestBody KmFile kmFile) {
+ kmFileService.save(kmFile);
+ return Result.OK("添加成功!");
+ }
+
+ /**
+ * 编辑
+ *
+ * @param kmFile
+ * @return
+ */
+ @AutoLog(value = "km_file-编辑")
+ @ApiOperation(value="km_file-编辑", notes="km_file-编辑")
+ @PutMapping(value = "/edit")
+ public Result> edit(@RequestBody KmFile kmFile) {
+ kmFileService.updateById(kmFile);
+ return Result.OK("编辑成功!");
+ }
+
+ /**
+ * 通过id删除
+ *
+ * @param id
+ * @return
+ */
+ @AutoLog(value = "km_file-通过id删除")
+ @ApiOperation(value="km_file-通过id删除", notes="km_file-通过id删除")
+ @DeleteMapping(value = "/delete")
+ public Result> delete(@RequestParam(name="id",required=true) String id) {
+ kmFileService.removeById(id);
+ return Result.OK("删除成功!");
+ }
+
+ /**
+ * 批量删除
+ *
+ * @param ids
+ * @return
+ */
+ @AutoLog(value = "km_file-批量删除")
+ @ApiOperation(value="km_file-批量删除", notes="km_file-批量删除")
+ @DeleteMapping(value = "/deleteBatch")
+ public Result> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
+ this.kmFileService.removeByIds(Arrays.asList(ids.split(",")));
+ return Result.OK("批量删除成功!");
+ }
+
+ /**
+ * 通过id查询
+ *
+ * @param id
+ * @return
+ */
+ @AutoLog(value = "km_file-通过id查询")
+ @ApiOperation(value="km_file-通过id查询", notes="km_file-通过id查询")
+ @GetMapping(value = "/queryById")
+ public Result> queryById(@RequestParam(name="id",required=true) String id) {
+ KmFile kmFile = kmFileService.getById(id);
+ if(kmFile==null) {
+ return Result.error("未找到对应数据");
+ }
+ return Result.OK(kmFile);
+ }
+
+ /**
+ * 导出excel
+ *
+ * @param request
+ * @param kmFile
+ */
+ @RequestMapping(value = "/exportXls")
+ public ModelAndView exportXls(HttpServletRequest request, KmFile kmFile) {
+ return super.exportXls(request, kmFile, KmFile.class, "km_file");
+ }
+
+ /**
+ * 通过excel导入数据
+ *
+ * @param request
+ * @param response
+ * @return
+ */
+ @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
+ public Result> importExcel(HttpServletRequest request, HttpServletResponse response) {
+ return super.importExcel(request, response, KmFile.class);
+ }
+
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/controller/KmHonePageController.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/controller/KmHonePageController.java
new file mode 100644
index 0000000000000000000000000000000000000000..18717a086ea274844de6db210428e7ea72192b72
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/controller/KmHonePageController.java
@@ -0,0 +1,105 @@
+package org.jeecg.modules.KM.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.system.api.ISysBaseAPI;
+import org.jeecg.common.system.base.controller.JeecgController;
+import org.jeecg.common.system.vo.DictModel;
+import org.jeecg.common.system.vo.SysCategoryModel;
+import org.jeecg.modules.KM.VO.KmChartVO;
+import org.jeecg.modules.KM.VO.KmDocStatisticsVO;
+import org.jeecg.modules.KM.VO.KmDocSummaryVO;
+import org.jeecg.modules.KM.entity.KmDoc;
+import org.jeecg.modules.KM.service.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import java.io.IOException;
+import java.util.*;
+
+@Api(tags="km_doc")
+@RestController
+@RequestMapping("/KM/HomePage")
+@Slf4j
+public class KmHonePageController extends JeecgController {
+ @Autowired
+ private IKmSearchRecordService kmSearchRecordService;
+ @Autowired
+ private IKmSysConfigService kmSysConfigService;
+ @Autowired
+ private ISysBaseAPI sysBaseAPI;
+ @Autowired
+ private IKmDocService kmDocService;
+
+
+ @ApiOperation(value="km_doc-首页专题", notes="km_doc-首页专题")
+ @GetMapping(value = "/listRecommendTopic")
+ public Result> listRecommendTopic( ) {
+ Map sysCategoryModelsTarget = new HashMap<>();
+ List sysCategoryModels =sysBaseAPI.queryCategoryRecommend();
+ for (SysCategoryModel model : sysCategoryModels){
+ sysCategoryModelsTarget.put(model.getCode(),model);
+ }
+
+ String recommendHotTopic = kmSysConfigService.getSysConfigValue("RecommendHotTopic");
+ if(recommendHotTopic != null && recommendHotTopic.equals("1")) {
+ try {
+ List sysCategoryModelsHot = kmSearchRecordService.retriveHotTopic();
+ if(sysCategoryModelsHot != null && !sysCategoryModelsHot.isEmpty()){
+
+ for (SysCategoryModel modelHot:sysCategoryModelsHot){
+ if(!sysCategoryModelsTarget.containsKey(modelHot.getCode()))
+ sysCategoryModelsTarget.put(modelHot.getCode(),modelHot);
+ }
+ }
+ }
+ catch (IOException e){
+ e.printStackTrace();
+ //return Result.error("io异常");
+ }
+ }
+ if(!sysCategoryModelsTarget.isEmpty()) {
+ List sysCategoryModelsResult = new ArrayList<>(sysCategoryModelsTarget.values());
+ if(sysCategoryModelsResult.size()>20)
+ sysCategoryModelsResult = sysCategoryModelsResult.subList(0,19);
+ return Result.OK(sysCategoryModelsResult);
+ }
+ else
+ return Result.OK();
+ }
+
+ @ApiOperation(value="km_doc-首页业务列表", notes="km_doc-首页业务列表")
+ @GetMapping(value = "/listBusinessType")
+ public Result> listBusinessType( ) {
+ List dictModelList = sysBaseAPI.queryDictItemList("km_dict_business");
+ if(dictModelList.size()>20)
+ dictModelList = dictModelList.subList(0,19);
+ return Result.OK(dictModelList);
+ }
+
+ @ApiOperation(value="km_doc-后台数据统计页面接口", notes="km_doc-后台数据统计页面接口")
+ @GetMapping(value = "/getCharData")
+ public Result> getCharData( ) throws IOException {
+ KmChartVO kmChartVO = new KmChartVO();
+ List categoryList = kmDocService.queryKmDocStatistics(1);
+ kmChartVO.setCategoryChartList(categoryList);
+ List businessList = kmDocService.queryKmDocStatistics(4);
+ kmChartVO.setBusinessChartList(businessList);
+ List topicList = kmDocService.queryKmDocStatistics(5);
+ kmChartVO.setTopicChartList(topicList);
+ List hotKeyword = kmSearchRecordService.hotKeywordReport();
+ kmChartVO.setHotKeywordList(hotKeyword);
+ List hotTopic = kmSearchRecordService.hotTopicReport();
+ kmChartVO.setHotTopicList(hotTopic);
+ KmDocSummaryVO kmDocSummaryVO = kmDocService.queryKmDocSummary();
+ kmChartVO.setKmDocSummaryVO(kmDocSummaryVO);
+ return Result.OK(kmChartVO);
+ }
+
+
+
+
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/controller/KmSearchRecordController.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/controller/KmSearchRecordController.java
new file mode 100644
index 0000000000000000000000000000000000000000..33fdada7058b91bc0d11748b112a86ad9bc7e53f
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/controller/KmSearchRecordController.java
@@ -0,0 +1,170 @@
+package org.jeecg.modules.KM.controller;
+
+import java.util.Arrays;
+import java.util.List;
+import java.io.IOException;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.modules.KM.entity.KmSearchRecord;
+import org.jeecg.modules.KM.service.IKmSearchRecordService;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.system.base.controller.JeecgController;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.servlet.ModelAndView;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.jeecg.common.aspect.annotation.AutoLog;
+
+@Api(tags="km_search_record")
+@RestController
+@RequestMapping("/KM/kmSearchRecord")
+@Slf4j
+public class KmSearchRecordController extends JeecgController {
+ @Autowired
+ private IKmSearchRecordService kmSearchRecordService;
+
+ @ApiOperation(value="km_search_record-热词报告", notes="km_search_record-热词报告")
+ @GetMapping(value = "/hotKeywordReport")
+ public Result> hotKeywordReport(){
+ try {
+ List result = kmSearchRecordService.hotKeywordReport();
+ return Result.OK(result);
+ } catch (IOException e) {
+ e.printStackTrace();
+ return Result.error("错误,io异常");
+ }
+ }
+
+ @ApiOperation(value="km_search_record-热门专题报告", notes="km_search_record-热门专题报告")
+ @GetMapping(value = "/hotTopicReport")
+ public Result> hotTopicReport(){
+ List result = kmSearchRecordService.hotTopicReport();
+ return Result.OK(result);
+
+ }
+
+ /**
+ * 分页列表查询
+ *
+ * @param kmSearchRecord
+ * @param pageNo
+ * @param pageSize
+ * @param req
+ * @return
+ */
+ @AutoLog(value = "km_search_record-分页列表查询")
+ @ApiOperation(value="km_search_record-分页列表查询", notes="km_search_record-分页列表查询")
+ @GetMapping(value = "/list")
+ public Result> queryPageList(KmSearchRecord kmSearchRecord,
+ @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
+ @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
+ HttpServletRequest req) {
+ QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(kmSearchRecord, req.getParameterMap());
+ Page page = new Page(pageNo, pageSize);
+ IPage pageList = kmSearchRecordService.page(page, queryWrapper);
+ return Result.OK(pageList);
+ }
+
+ /**
+ * 添加
+ *
+ * @param kmSearchRecord
+ * @return
+ */
+ @AutoLog(value = "km_search_record-添加")
+ @ApiOperation(value="km_search_record-添加", notes="km_search_record-添加")
+ @PostMapping(value = "/add")
+ public Result> add(@RequestBody KmSearchRecord kmSearchRecord) {
+ kmSearchRecordService.save(kmSearchRecord);
+ return Result.OK("添加成功!");
+ }
+
+ /**
+ * 编辑
+ *
+ * @param kmSearchRecord
+ * @return
+ */
+ @AutoLog(value = "km_search_record-编辑")
+ @ApiOperation(value="km_search_record-编辑", notes="km_search_record-编辑")
+ @PutMapping(value = "/edit")
+ public Result> edit(@RequestBody KmSearchRecord kmSearchRecord) {
+ kmSearchRecordService.updateById(kmSearchRecord);
+ return Result.OK("编辑成功!");
+ }
+
+ /**
+ * 通过id删除
+ *
+ * @param id
+ * @return
+ */
+ @AutoLog(value = "km_search_record-通过id删除")
+ @ApiOperation(value="km_search_record-通过id删除", notes="km_search_record-通过id删除")
+ @DeleteMapping(value = "/delete")
+ public Result> delete(@RequestParam(name="id",required=true) String id) {
+ kmSearchRecordService.removeById(id);
+ return Result.OK("删除成功!");
+ }
+
+ /**
+ * 批量删除
+ *
+ * @param ids
+ * @return
+ */
+ @AutoLog(value = "km_search_record-批量删除")
+ @ApiOperation(value="km_search_record-批量删除", notes="km_search_record-批量删除")
+ @DeleteMapping(value = "/deleteBatch")
+ public Result> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
+ this.kmSearchRecordService.removeByIds(Arrays.asList(ids.split(",")));
+ return Result.OK("批量删除成功!");
+ }
+
+ /**
+ * 通过id查询
+ *
+ * @param id
+ * @return
+ */
+ @AutoLog(value = "km_search_record-通过id查询")
+ @ApiOperation(value="km_search_record-通过id查询", notes="km_search_record-通过id查询")
+ @GetMapping(value = "/queryById")
+ public Result> queryById(@RequestParam(name="id",required=true) String id) {
+ KmSearchRecord kmSearchRecord = kmSearchRecordService.getById(id);
+ if(kmSearchRecord==null) {
+ return Result.error("未找到对应数据");
+ }
+ return Result.OK(kmSearchRecord);
+ }
+
+ /**
+ * 导出excel
+ *
+ * @param request
+ * @param kmSearchRecord
+ */
+ @RequestMapping(value = "/exportXls")
+ public ModelAndView exportXls(HttpServletRequest request, KmSearchRecord kmSearchRecord) {
+ return super.exportXls(request, kmSearchRecord, KmSearchRecord.class, "km_search_record");
+ }
+
+ /**
+ * 通过excel导入数据
+ *
+ * @param request
+ * @param response
+ * @return
+ */
+ @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
+ public Result> importExcel(HttpServletRequest request, HttpServletResponse response) {
+ return super.importExcel(request, response, KmSearchRecord.class);
+ }
+
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/controller/KmSysConfigController.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/controller/KmSysConfigController.java
new file mode 100644
index 0000000000000000000000000000000000000000..adb6c3702cd61a18ab8672bb9b9661eafaf0b923
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/controller/KmSysConfigController.java
@@ -0,0 +1,174 @@
+package org.jeecg.modules.KM.controller;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import org.apache.ibatis.annotations.Param;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.modules.KM.common.rules.KMConstant;
+import org.jeecg.modules.KM.entity.KmSysConfig;
+import org.jeecg.modules.KM.service.IKmSysConfigService;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.system.base.controller.JeecgController;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.servlet.ModelAndView;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.jeecg.common.aspect.annotation.AutoLog;
+//import springfox.documentation.spring.web.json.Json;
+
+@Api(tags="km_sys_config")
+@RestController
+@RequestMapping("/KM/kmSysConfig")
+@Slf4j
+public class KmSysConfigController extends JeecgController {
+ @Autowired
+ private IKmSysConfigService kmSysConfigService;
+
+ /**
+ * 分页列表查询
+ *
+ * @param kmSysConfig
+ * @param pageNo
+ * @param pageSize
+ * @param req
+ * @return
+ */
+ @AutoLog(value = "km_sys_config-分页列表查询")
+ @ApiOperation(value="km_sys_config-分页列表查询", notes="km_sys_config-分页列表查询")
+ @GetMapping(value = "/list")
+ public Result> queryPageList(KmSysConfig kmSysConfig,
+ @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
+ @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
+ HttpServletRequest req) {
+ QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(kmSysConfig, req.getParameterMap());
+ Page page = new Page(pageNo, pageSize);
+ IPage pageList = kmSysConfigService.page(page, queryWrapper);
+ return Result.OK(pageList);
+ }
+
+ @AutoLog(value = "km_sys_config-获取所有配置")
+ @ApiOperation(value="km_sys_config-获取所有配置", notes="km_sys_config-获取所有配置")
+ @GetMapping(value = "/listAllConfig")
+ public Result> queryAllConfigist() {
+ Map allConfig = kmSysConfigService.queryAllConfig();
+ return Result.OK(allConfig);
+ }
+
+ /**
+ * 添加
+ *
+ * @param kmSysConfig
+ * @return
+ */
+ @AutoLog(value = "km_sys_config-添加")
+ @ApiOperation(value="km_sys_config-添加", notes="km_sys_config-添加")
+ @PostMapping(value = "/add")
+ public Result> add(@RequestBody KmSysConfig kmSysConfig) {
+ kmSysConfigService.save(kmSysConfig);
+ return Result.OK("添加成功!");
+ }
+
+ /**
+ * 编辑
+ *
+ * @param kmSysConfig
+ * @return
+ */
+ @AutoLog(value = "km_sys_config-编辑")
+ @ApiOperation(value="km_sys_config-编辑", notes="km_sys_config-编辑")
+ @PutMapping(value = "/edit")
+ @CacheEvict(value = "kmSysConfig",allEntries = true)
+ public Result> edit(@RequestBody KmSysConfig kmSysConfig) {
+ kmSysConfigService.updateById(kmSysConfig);
+ return Result.OK("编辑成功!");
+ }
+
+ /**
+ * 通过id删除
+ *
+ * @param id
+ * @return
+ */
+ @AutoLog(value = "km_sys_config-通过id删除")
+ @ApiOperation(value="km_sys_config-通过id删除", notes="km_sys_config-通过id删除")
+ @DeleteMapping(value = "/delete")
+ public Result> delete(@RequestParam(name="id",required=true) String id) {
+ kmSysConfigService.removeById(id);
+ return Result.OK("删除成功!");
+ }
+
+ /**
+ * 批量删除
+ *
+ * @param ids
+ * @return
+ */
+ @AutoLog(value = "km_sys_config-批量删除")
+ @ApiOperation(value="km_sys_config-批量删除", notes="km_sys_config-批量删除")
+ @DeleteMapping(value = "/deleteBatch")
+ public Result> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
+ this.kmSysConfigService.removeByIds(Arrays.asList(ids.split(",")));
+ return Result.OK("批量删除成功!");
+ }
+
+ /**
+ * 通过id查询
+ *
+ * @param id
+ * @return
+ */
+ @AutoLog(value = "km_sys_config-通过id查询")
+ @ApiOperation(value="km_sys_config-通过id查询", notes="km_sys_config-通过id查询")
+ @GetMapping(value = "/queryById")
+ public Result> queryById(@RequestParam(name="id",required=true) String id) {
+ KmSysConfig kmSysConfig = kmSysConfigService.getById(id);
+ if(kmSysConfig==null) {
+ return Result.error("未找到对应数据");
+ }
+ return Result.OK(kmSysConfig);
+ }
+ @AutoLog(value = "km_sys_config-查询site信息")
+ @ApiOperation(value="km_sys_config-查询site信息", notes="km_sys_config-查询site信息")
+ @GetMapping(value = "/querySiteInfo")
+ public Result> querySiteInfo() {
+ List kmSysConfigList = kmSysConfigService.querySiteInfo();
+// KmSysConfig kmSysConfig = (KmSysConfig) kmSysConfigList
+ if(kmSysConfigList==null || kmSysConfigList.size() == 0) {
+ return Result.error("未找到对应数据");
+ }
+ return Result.OK(kmSysConfigList);
+ }
+
+ /**
+ * 导出excel
+ *
+ * @param request
+ * @param kmSysConfig
+ */
+ @RequestMapping(value = "/exportXls")
+ public ModelAndView exportXls(HttpServletRequest request, KmSysConfig kmSysConfig) {
+ return super.exportXls(request, kmSysConfig, KmSysConfig.class, "km_sys_config");
+ }
+
+ /**
+ * 通过excel导入数据
+ *
+ * @param request
+ * @param response
+ * @return
+ */
+ @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
+ public Result> importExcel(HttpServletRequest request, HttpServletResponse response) {
+ return super.importExcel(request, response, KmSysConfig.class);
+ }
+
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/controller/KmSysDbBackupController.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/controller/KmSysDbBackupController.java
new file mode 100644
index 0000000000000000000000000000000000000000..363045f198e4c5917451b1cfa88415c047cd8e04
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/controller/KmSysDbBackupController.java
@@ -0,0 +1,300 @@
+package org.jeecg.modules.KM.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.aspect.annotation.AutoLog;
+import org.jeecg.common.system.base.controller.JeecgController;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.common.util.CommonUtils;
+import org.jeecg.common.util.oConvertUtils;
+import org.jeecg.modules.KM.common.rules.KMConstant;
+import org.jeecg.modules.KM.entity.KmSysDbBackup;
+import org.jeecg.modules.KM.entity.KmSysDbBackup;
+import org.jeecg.modules.KM.service.IKmSysDbBackupService;
+import org.jeecg.modules.KM.service.IKmSysDbBackupService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.servlet.ModelAndView;
+
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import java.io.*;
+import java.net.URLEncoder;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.concurrent.TimeUnit;
+
+@Api(tags="km_sys_db_backup")
+@RestController
+@RequestMapping("/KM/kmSysDbBackup")
+@Slf4j
+public class KmSysDbBackupController extends JeecgController {
+ @Autowired
+ private IKmSysDbBackupService kmSysDbBackupService;
+
+ @Value("${spring.datasource.dynamic.datasource.master.url}")
+ private String dbServerUrl;
+ @Value("${spring.datasource.dynamic.datasource.master.username}")
+ private String dbServerUserName;
+ @Value("${spring.datasource.dynamic.datasource.master.password}")
+ private String dbServerPassword;
+ @Value("${base.db-backup-dir}")
+ private String dbBackupDir;
+
+ /**
+ * 分页列表查询
+ *
+ * @param KmSysDbBackup
+ * @param pageNo
+ * @param pageSize
+ * @param req
+ * @return
+ */
+ @AutoLog(value = "km_sys_db_backup-分页列表查询")
+ @ApiOperation(value="km_sys_db_backup-分页列表查询", notes="km_sys_db_backup-分页列表查询")
+ @GetMapping(value = "/list")
+ public Result> queryPageList(KmSysDbBackup KmSysDbBackup,
+ @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
+ @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
+ HttpServletRequest req) {
+ QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(KmSysDbBackup, req.getParameterMap());
+ Page page = new Page(pageNo, pageSize);
+ IPage pageList = kmSysDbBackupService.page(page, queryWrapper);
+ return Result.OK(pageList);
+ }
+
+ /**
+ * 添加
+ *
+ * @param
+ * @return
+ */
+ @AutoLog(value = "km_sys_db_backup-添加")
+ @ApiOperation(value="km_sys_db_backup-添加", notes="km_sys_db_backup-添加")
+ @PostMapping(value = "/add")
+ public Result> add() {
+ String dbType = CommonUtils.getDatabaseType();
+ if (!dbType.equalsIgnoreCase("mysql")) {
+ return Result.error("只支持mysql数据库备份");
+ }
+ if (oConvertUtils.isEmpty(dbBackupDir) || oConvertUtils.isEmpty(dbServerUrl) || oConvertUtils.isEmpty(dbServerUserName) || oConvertUtils.isEmpty(dbServerPassword)) {
+ return Result.error("备份配置缺失");
+ }
+ String fileName = "backup_" + new Date().getTime() + ".sql";
+ String filePath = dbBackupDir + File.separator + fileName;
+
+ String temp = dbServerUrl.substring(dbServerUrl.indexOf("//"));
+ String dbServerIp = temp.substring(2,temp.indexOf(":"));
+ temp = temp.substring(temp.indexOf(":"));
+ String dbServerPort = temp.substring(1,temp.indexOf("/"));
+ temp = temp.substring(temp.indexOf("/"));
+ String dbName = temp.substring(1,temp.indexOf("?"));
+
+ String cmd = "cmd /c mysqldump -u" + dbServerUserName + " -p" + dbServerPassword + " -h " + dbServerIp + " -P " + dbServerPort + " " + dbName +" > " + filePath;
+ //-u后的root为mysql数据库用户名,-p后接的123456为该用户密码,注意不要有空格;dbName填写需要备份数据的数据库名称,大于号后接生成文件路径
+ try {
+ Process process = Runtime.getRuntime().exec(cmd);
+ boolean exitFlag = process.waitFor(10*60, TimeUnit.SECONDS);
+ if(exitFlag) {
+ int code = process.exitValue();
+ log.info("code:"+code);
+ if(code == 0){
+ KmSysDbBackup kmSysDbBackup = new KmSysDbBackup();
+ File backupFile = new File(filePath);
+ kmSysDbBackup.setSize(backupFile.length());
+ kmSysDbBackup.setFileName(fileName);
+ kmSysDbBackup.setFilePath(filePath);
+ kmSysDbBackup.setCreateTime(new Date());
+ kmSysDbBackupService.save(kmSysDbBackup);
+ log.info("【备份数据库】成功,SQL文件:{}", fileName);
+ return Result.OK("备份成功!");
+ }else {
+ return Result.error("备份命令执行失败,返回码:",code);
+ }
+ }else {
+ return Result.error("备份超时");
+ }
+ }catch (Exception e){
+ log.error("【备份数据库】失败:{}", e.getMessage());
+ return Result.error(e.getMessage());
+ }
+ }
+
+ /**
+ * 通过id下载
+ *
+ * @param id
+ * @return
+ */
+ @AutoLog(value = "km_sys_db_backup-通过id下载")
+ @ApiOperation(value="km_sys_db_backup-通过id下载", notes="km_sys_db_backup-通过id下载")
+ @GetMapping(value = "/downloadById")
+ public void downloadById(@RequestParam(name="id",required=true) String id, HttpServletResponse response) throws IOException {
+ KmSysDbBackup kmSysDbBackup = kmSysDbBackupService.getById(id);
+ if(kmSysDbBackup==null) {
+ response.sendError(HttpServletResponse.SC_NOT_FOUND);
+ }
+ assert kmSysDbBackup != null;
+ String filePath = kmSysDbBackup.getFilePath();
+ if(oConvertUtils.isEmpty(filePath)){
+ return;
+ }
+ // 其余处理略
+ InputStream inputStream = null;
+ OutputStream outputStream = null;
+ try {
+ File file = new File(filePath);
+ if(!file.exists()){
+ response.setStatus(404);
+ throw new RuntimeException("文件["+filePath+"]不存在..");
+ }
+ response.setContentType("application/force-download");// 设置强制下载不打开
+// response.setContentType("application/octet-stream");
+ response.addHeader("Access-Control-Expose-Headers","Content-disposition");
+ response.addHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(kmSysDbBackup.getFileName(), "UTF-8"));
+ inputStream = new BufferedInputStream(new FileInputStream(filePath));
+ outputStream = response.getOutputStream();
+ byte[] buf = new byte[1024];
+ int len;
+ while ((len = inputStream.read(buf)) > 0) {
+ outputStream.write(buf, 0, len);
+ }
+ response.flushBuffer();
+ } catch (IOException e) {
+ log.error("下载备份文件失败" + e.getMessage());
+ response.setStatus(404);
+ e.printStackTrace();
+ } finally {
+ if (inputStream != null) {
+ try {
+ inputStream.close();
+ } catch (IOException e) {
+ log.error(e.getMessage(), e);
+ }
+ }
+ if (outputStream != null) {
+ try {
+ outputStream.close();
+ } catch (IOException e) {
+ log.error(e.getMessage(), e);
+ }
+ }
+ }
+ }
+
+ /**
+ * 通过id删除
+ *
+ * @param id
+ * @return
+ */
+ @AutoLog(value = "km_sys_db_backup-通过id删除")
+ @ApiOperation(value="km_sys_db_backup-通过id删除", notes="km_sys_db_backup-通过id删除")
+ @DeleteMapping(value = "/delete")
+ public Result> delete(@RequestParam(name="id",required=true) String id) {
+ KmSysDbBackup kmSysDbBackup = kmSysDbBackupService.getById(id);
+ if(kmSysDbBackup==null) {
+ return Result.error("未找到对应数据");
+ }
+ String filePath = kmSysDbBackup.getFilePath();
+ File file = new File(filePath);
+ if (file.exists()) {
+ file.delete();
+ }
+ kmSysDbBackupService.removeById(id);
+ return Result.OK("删除成功!");
+ }
+
+ /**
+ * 批量删除
+ *
+ * @param ids
+ * @return
+ */
+ @AutoLog(value = "km_sys_db_backup-批量删除")
+ @ApiOperation(value="km_sys_db_backup-批量删除", notes="km_sys_db_backup-批量删除")
+ @DeleteMapping(value = "/deleteBatch")
+ public Result> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
+ this.kmSysDbBackupService.removeByIds(Arrays.asList(ids.split(",")));
+ return Result.OK("批量删除成功!");
+ }
+
+ /**
+ * 通过id查询
+ *
+ * @param id
+ * @return
+ */
+ @AutoLog(value = "km_sys_db_backup-通过id查询")
+ @ApiOperation(value="km_sys_db_backup-通过id查询", notes="km_sys_db_backup-通过id查询")
+ @GetMapping(value = "/queryById")
+ public Result> queryById(@RequestParam(name="id",required=true) String id) {
+ KmSysDbBackup kmSysDbBackup = kmSysDbBackupService.getById(id);
+ if(kmSysDbBackup==null) {
+ return Result.error("未找到对应数据");
+ }
+ return Result.OK(kmSysDbBackup);
+ }
+
+
+ /**
+ * 添加
+ *
+ * @param
+ * @return
+ */
+ @AutoLog(value = "km_sys_db_backup-恢复")
+ @ApiOperation(value="km_sys_db_backup-恢复", notes="km_sys_db_backup-恢复")
+ @PostMapping(value = "/recover")
+ public Result> recover(@RequestParam(name="id",required=true) String id) {
+ String dbType = CommonUtils.getDatabaseType();
+ if (!dbType.equalsIgnoreCase("mysql")) {
+ return Result.error("只支持mysql数据库备份");
+ }
+ if (oConvertUtils.isEmpty(dbBackupDir) || oConvertUtils.isEmpty(dbServerUrl) || oConvertUtils.isEmpty(dbServerUserName) || oConvertUtils.isEmpty(dbServerPassword)) {
+ return Result.error("备份配置缺失");
+ }
+ KmSysDbBackup kmSysDbBackup = kmSysDbBackupService.getById(id);
+ if(kmSysDbBackup==null) {
+ return Result.error("未找到对应数据");
+ }
+
+ String filePath = kmSysDbBackup.getFilePath();
+
+ String temp = dbServerUrl.substring(dbServerUrl.indexOf("//"));
+ String dbServerIp = temp.substring(2,temp.indexOf(":"));
+ temp = temp.substring(temp.indexOf(":"));
+ String dbServerPort = temp.substring(1,temp.indexOf("/"));
+ temp = temp.substring(temp.indexOf("/"));
+ String dbName = temp.substring(1,temp.indexOf("?"));
+
+ String cmd = "cmd /c mysqldump -u" + dbServerUserName + " -p" + dbServerPassword + " -h " + dbServerIp + " -P " + dbServerPort + " " + dbName +" < " + filePath;
+ //-u后的root为mysql数据库用户名,-p后接的123456为该用户密码,注意不要有空格;dbName填写需要备份数据的数据库名称,大于号后接生成文件路径
+ try {
+ Process process = Runtime.getRuntime().exec(cmd);
+ boolean exitFlag = process.waitFor(10*60, TimeUnit.SECONDS);
+ if(exitFlag) {
+ int code = process.exitValue();
+ log.info("code:"+code);
+ if(code == 0){
+ log.info("【恢复数据库】成功,SQL文件:{}", kmSysDbBackup.getFileName());
+ return Result.OK("恢复数据库成功!");
+ }else {
+ return Result.error("命令执行失败,返回码:",code);
+ }
+ }else {
+ return Result.error("备份超时");
+ }
+ }catch (Exception e){
+ log.error("【恢复数据库】失败:{}", e.getMessage());
+ return Result.error(e.getMessage());
+ }
+ }
+
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/entity/KmDoc.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/entity/KmDoc.java
new file mode 100644
index 0000000000000000000000000000000000000000..c84b09f41f2f067319ec787671aff5c9666acf5c
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/entity/KmDoc.java
@@ -0,0 +1,158 @@
+package org.jeecg.modules.KM.entity;
+
+import java.io.Serializable;
+import java.math.BigInteger;
+import java.util.Date;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.jeecgframework.poi.excel.annotation.Excel;
+import org.jeecg.common.aspect.annotation.Dict;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+@JsonIgnoreProperties(ignoreUnknown = true)
+@Data
+@TableName("km_doc")
+@Accessors(chain = true)
+@EqualsAndHashCode(callSuper = false)
+@ApiModel(value="km_doc对象", description="km_doc")
+public class KmDoc implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ /**id*/
+ @TableId(type = IdType.ASSIGN_ID)
+ @ApiModelProperty(value = "id")
+ private String id;
+ /**fileId*/
+ @Excel(name = "fileId", width = 15)
+ @ApiModelProperty(value = "fileId")
+ private String fileId;
+ /**previewFileId*/
+ @Excel(name = "previewFileId", width = 15)
+ @ApiModelProperty(value = "previewFileId")
+ private String previewFileId;
+ /**originalPreviewFileId*/
+ @Excel(name = "originalPreviewFileId", width = 15)
+ @ApiModelProperty(value = "originalPreviewFileId")
+ private String originalPreviewFileId;
+ private String indexId;
+ /**orgCode*/
+ @Excel(name = "orgCode", width = 15)
+ @Dict(dictTable ="sys_depart",dicText = "depart_name",dicCode = "org_code")
+ @ApiModelProperty(value = "orgCode")
+ private String orgCode;
+ /**depId*/
+ @Excel(name = "depId", width = 15)
+ @Dict(dictTable ="sys_depart",dicText = "depart_name",dicCode = "id")
+ @ApiModelProperty(value = "depId")
+ private String depId;
+ /**fileSize*/
+ @Excel(name = "fileSize", width = 15)
+ @ApiModelProperty(value = "fileSize")
+ private Long fileSize;
+ /**name*/
+ @Excel(name = "name", width = 15)
+ @ApiModelProperty(value = "name")
+ private String name;
+ /**title*/
+ @Excel(name = "title", width = 15)
+ @ApiModelProperty(value = "title")
+ private String title;
+ /**favourites*/
+ @Excel(name = "favourites", width = 15)
+ @ApiModelProperty(value = "favourites")
+ private BigInteger favourites;
+ /**serialNumber*/
+ @Excel(name = "serialNumber", width = 15)
+ @ApiModelProperty(value = "serialNumber")
+ private String serialNumber;
+ /**fileType*/
+ @Excel(name = "fileType", width = 15)
+ @ApiModelProperty(value = "fileType")
+ private String fileType;
+ /**status*/
+ @Excel(name = "status", width = 15)
+ @ApiModelProperty(value = "status")
+ private Integer status;
+ /**category*/
+ @Excel(name = "category", width = 15)
+ @ApiModelProperty(value = "category")
+ @Dict(dicCode = "km_dict_category")
+ private String category;
+ /**keywords*/
+ @Excel(name = "keywords", width = 15)
+ @ApiModelProperty(value = "keywords")
+ private String keywords;
+ /**ftiFlag*/
+ @Excel(name = "ftiFlag", width = 15)
+ @ApiModelProperty(value = "ftiFlag")
+ @Dict(dicCode = "dict_fti_flag")
+ private Integer ftiFlag;
+ /**convertFlag*/
+ @Excel(name = "convertFlag", width = 15)
+ @ApiModelProperty(value = "convertFlag")
+ private Integer convertFlag;
+ /**releaseFlag*/
+ @Excel(name = "releaseFlag", width = 15)
+ @ApiModelProperty(value = "releaseFlag")
+ private Integer releaseFlag;
+ /**downloadFlag*/
+ @Excel(name = "downloadFlag", width = 15)
+ @ApiModelProperty(value = "downloadFlag")
+ @Dict(dicCode = "dict_downloadFlag")
+ private Integer downloadFlag;
+ /**downloads*/
+ @Excel(name = "downloads", width = 15)
+ @ApiModelProperty(value = "downloads")
+ private BigInteger downloads;
+ /**comments*/
+ @Excel(name = "comments", width = 15)
+ @ApiModelProperty(value = "comments")
+ private BigInteger comments;
+ /**views*/
+ @Excel(name = "views", width = 15)
+ @ApiModelProperty(value = "views")
+ private BigInteger views;
+ /**lastUpdateBy*/
+ @Excel(name = "lastUpdateBy", width = 15)
+ @ApiModelProperty(value = "lastUpdateBy")
+ private String lastUpdateBy;
+ /**lastUpdateTime*/
+ @Excel(name = "lastUpdateTime", width = 15, format = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
+ @DateTimeFormat(pattern="yyyyy-MM-dd HH:mm:ss")
+ @ApiModelProperty(value = "lastUpdateTime")
+ private Date lastUpdateTime;
+ /**createBy*/
+ @ApiModelProperty(value = "createBy")
+ private String createBy;
+ /**createTime*/
+ @Excel(name = "createTime", width = 15, format = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
+ @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
+ @ApiModelProperty(value = "createTime")
+ private Date createTime;
+ /**processMsg*/
+ @Excel(name = "processMsg", width = 15)
+ @ApiModelProperty(value = "processMsg")
+ private String processMsg;
+ /**publicRemark*/
+ @Dict(dicCode = "dict_public_remark")
+ @Excel(name = "publicRemark", width = 15)
+ @ApiModelProperty(value = "publicRemark")
+ private Integer publicRemark;
+ /**remark*/
+ @Excel(name = "remark", width = 15)
+ @ApiModelProperty(value = "remark")
+ private String remark;
+ /**currentVersion*/
+ @Excel(name = "currentVersion", width = 15)
+ @ApiModelProperty(value = "currentVersion")
+ private Integer currentVersion;
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/entity/KmDocBusinessType.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/entity/KmDocBusinessType.java
new file mode 100644
index 0000000000000000000000000000000000000000..d7f7338c3ed088338dbdbbd442bc3446bec74d66
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/entity/KmDocBusinessType.java
@@ -0,0 +1,34 @@
+package org.jeecg.modules.KM.entity;
+
+import java.io.Serializable;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import org.jeecgframework.poi.excel.annotation.Excel;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+@Data
+@TableName("km_doc_business_type")
+@Accessors(chain = true)
+@EqualsAndHashCode(callSuper = false)
+@ApiModel(value="km_doc_business_type对象", description="km_doc_business_type")
+public class KmDocBusinessType implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ /**id*/
+ @TableId(type = IdType.ASSIGN_ID)
+ @ApiModelProperty(value = "id")
+ private java.lang.String id;
+ /**id*/
+ @Excel(name = "id", width = 15)
+ @ApiModelProperty(value = "id")
+ private java.lang.String docId;
+ /**businessType*/
+ @Excel(name = "businessType", width = 15)
+ @ApiModelProperty(value = "businessType")
+ private java.lang.String businessType;
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/entity/KmDocComments.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/entity/KmDocComments.java
new file mode 100644
index 0000000000000000000000000000000000000000..a25faf5d2e6cd7eb1fd5c2b9b80dea93e6745207
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/entity/KmDocComments.java
@@ -0,0 +1,50 @@
+package org.jeecg.modules.KM.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.jeecgframework.poi.excel.annotation.Excel;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+@TableName("km_doc_comments")
+@Accessors(chain = true)
+@EqualsAndHashCode(callSuper = false)
+@ApiModel(value="km_doc_comments对象", description="km_doc_comments对象")
+public class KmDocComments implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ /**id*/
+ @TableId(type = IdType.ASSIGN_ID)
+ @ApiModelProperty(value = "id")
+ private String id;
+ /**docid*/
+ @Excel(name = "id", width = 15)
+ @ApiModelProperty(value = "id")
+ private String docId;
+ /**create_time*/
+ @Excel(name = "create_time", width = 15)
+ @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
+ @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
+ @ApiModelProperty(value = "id")
+ private Date createTime;
+ /**create_by*/
+ @Excel(name = "create_by", width = 15)
+ @ApiModelProperty(value = "id")
+ private String createBy;
+ /**comment*/
+ @Excel(name = "comment", width = 15)
+ @ApiModelProperty(value = "comment")
+ private String comment;
+
+
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/entity/KmDocFavourite.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/entity/KmDocFavourite.java
new file mode 100644
index 0000000000000000000000000000000000000000..74965fd61b77f4c57988b03c0b8e1d910b494b9e
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/entity/KmDocFavourite.java
@@ -0,0 +1,42 @@
+package org.jeecg.modules.KM.entity;
+
+import java.io.Serializable;
+import java.util.Date;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.jeecgframework.poi.excel.annotation.Excel;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+@Data
+@TableName("km_doc_favourite")
+@Accessors(chain = true)
+@EqualsAndHashCode(callSuper = false)
+@ApiModel(value="km_doc_favourite对象", description="km_doc_favourite")
+public class KmDocFavourite implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ /**id*/
+ @TableId(type = IdType.ASSIGN_ID)
+ @ApiModelProperty(value = "id")
+ private String id;
+ /**userId*/
+ @Excel(name = "userId", width = 15)
+ @ApiModelProperty(value = "userId")
+ private String userId;
+ /**docId*/
+ @Excel(name = "docId", width = 15)
+ @ApiModelProperty(value = "docId")
+ private String docId;
+ /**addTime*/
+ @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
+ @DateTimeFormat(pattern="yyyy-MM-dd")
+ @ApiModelProperty(value = "addTime")
+ private Date addTime;
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/entity/KmDocTopicType.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/entity/KmDocTopicType.java
new file mode 100644
index 0000000000000000000000000000000000000000..8dcba78c27690924c27cbfc3b886b51822a1010a
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/entity/KmDocTopicType.java
@@ -0,0 +1,34 @@
+package org.jeecg.modules.KM.entity;
+
+import java.io.Serializable;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import org.jeecgframework.poi.excel.annotation.Excel;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+@Data
+@TableName("km_doc_topic_type")
+@Accessors(chain = true)
+@EqualsAndHashCode(callSuper = false)
+@ApiModel(value="km_doc_topic_type对象", description="km_doc_topic_type")
+public class KmDocTopicType implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ /**id*/
+ @TableId(type = IdType.ASSIGN_ID)
+ @ApiModelProperty(value = "id")
+ private String id;
+ /**id*/
+ @Excel(name = "id", width = 15)
+ @ApiModelProperty(value = "id")
+ private String docId;
+ /**topicId*/
+ @Excel(name = "topicId", width = 15)
+ @ApiModelProperty(value = "topicId")
+ private String topicId;
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/entity/KmDocVersion.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/entity/KmDocVersion.java
new file mode 100644
index 0000000000000000000000000000000000000000..6659063b75b3d53714cff0179c3410c7464e8489
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/entity/KmDocVersion.java
@@ -0,0 +1,58 @@
+package org.jeecg.modules.KM.entity;
+
+import java.io.Serializable;
+import java.util.Date;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import org.jeecgframework.poi.excel.annotation.Excel;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.springframework.format.annotation.DateTimeFormat;
+
+@Data
+@TableName("km_doc_version")
+@Accessors(chain = true)
+@EqualsAndHashCode(callSuper = false)
+@ApiModel(value="km_doc_version对象", description="km_doc_version")
+public class KmDocVersion implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ /**id*/
+ @TableId(type = IdType.ASSIGN_ID)
+ @ApiModelProperty(value = "id")
+ private java.lang.String id;
+ /**docid*/
+ @Excel(name = "id", width = 15)
+ @ApiModelProperty(value = "id")
+ private java.lang.String docId;
+ /**file_id*/
+ @Excel(name = "file_id", width = 15)
+ @ApiModelProperty(value = "file_id")
+ private java.lang.String fileId;
+ /**version*/
+ @Excel(name = "version", width = 15)
+ @ApiModelProperty(value = "version")
+ private java.lang.Integer version;
+ /**create_time*/
+ @Excel(name = "create_time", width = 15)
+ @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
+ @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
+ @ApiModelProperty(value = "id")
+ private Date createTime;
+ /**create_by*/
+ @Excel(name = "create_by", width = 15)
+ @ApiModelProperty(value = "id")
+ private java.lang.String createBy;
+ /**comment*/
+ @Excel(name = "comment", width = 15)
+ @ApiModelProperty(value = "comment")
+ private java.lang.String comment;
+
+
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/entity/KmDocVisitRecord.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/entity/KmDocVisitRecord.java
new file mode 100644
index 0000000000000000000000000000000000000000..91e69d63e777d99c7999a3061cb7ade21cc1aca2
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/entity/KmDocVisitRecord.java
@@ -0,0 +1,51 @@
+package org.jeecg.modules.KM.entity;
+
+import java.io.Serializable;
+import java.util.Date;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.jeecgframework.poi.excel.annotation.Excel;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+@Data
+@TableName("km_doc_visit_record")
+@Accessors(chain = true)
+@EqualsAndHashCode(callSuper = false)
+@ApiModel(value="km_doc_visit_record对象", description="km_doc_visit_record")
+public class KmDocVisitRecord implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ /**id*/
+ @TableId(type = IdType.ASSIGN_ID)
+ @ApiModelProperty(value = "id")
+ private String id;
+ /**id*/
+ @Excel(name = "id", width = 15)
+ @ApiModelProperty(value = "id")
+ private String docId;
+ /**1:上传 2:预览 3:下载 4:删除*/
+ @Excel(name = "1:上传 2:预览 3:下载 4:删除", width = 15)
+ @ApiModelProperty(value = "1:上传 2:预览 3:下载 4:删除")
+ private Integer visitType;
+ private String keywords;
+ private String keywordsMax;
+ /**sourceIp*/
+ @Excel(name = "sourceIp", width = 15)
+ @ApiModelProperty(value = "sourceIp")
+ private String sourceIp;
+ /**createBy*/
+ @ApiModelProperty(value = "createBy")
+ private String createBy;
+ /**createTime*/
+ @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
+ @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
+ @ApiModelProperty(value = "createTime")
+ private Date createTime;
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/entity/KmFile.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/entity/KmFile.java
new file mode 100644
index 0000000000000000000000000000000000000000..a063c496919a39d00502688c29719bc62b7062c3
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/entity/KmFile.java
@@ -0,0 +1,38 @@
+package org.jeecg.modules.KM.entity;
+
+import java.io.Serializable;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import org.jeecgframework.poi.excel.annotation.Excel;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+@Data
+@TableName("km_file")
+@Accessors(chain = true)
+@EqualsAndHashCode(callSuper = false)
+@ApiModel(value="km_file对象", description="km_file")
+public class KmFile implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ /**id*/
+ @TableId(type = IdType.ASSIGN_ID)
+ @ApiModelProperty(value = "id")
+ private String id;
+ /**sha256*/
+ @Excel(name = "sha256", width = 15)
+ @ApiModelProperty(value = "sha256")
+ private String sha256;
+ /**physicalPath*/
+ @Excel(name = "physicalPath", width = 15)
+ @ApiModelProperty(value = "physicalPath")
+ private String physicalPath;
+ /**originalName*/
+ @Excel(name = "originalName", width = 15)
+ @ApiModelProperty(value = "originalName")
+ private String originalName;
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/entity/KmSearchRecord.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/entity/KmSearchRecord.java
new file mode 100644
index 0000000000000000000000000000000000000000..5e516d572144d97bbaf15b392ce0d739c31fddae
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/entity/KmSearchRecord.java
@@ -0,0 +1,49 @@
+package org.jeecg.modules.KM.entity;
+
+import java.io.Serializable;
+import java.util.Date;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.jeecgframework.poi.excel.annotation.Excel;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+@Data
+@TableName("km_search_record")
+@Accessors(chain = true)
+@EqualsAndHashCode(callSuper = false)
+@ApiModel(value="km_search_record对象", description="km_search_record")
+public class KmSearchRecord implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ /**id*/
+ @TableId(type = IdType.ASSIGN_ID)
+ @ApiModelProperty(value = "id")
+ private String id;
+ /**keywords*/
+ @Excel(name = "keywords", width = 15)
+ @ApiModelProperty(value = "keywords")
+ private String keywords;
+ private String keywordsMax;
+ private String title;
+ private String content;
+ private String topicCodes;
+ /**sourceIp*/
+ @Excel(name = "sourceIp", width = 15)
+ @ApiModelProperty(value = "sourceIp")
+ private String sourceIp;
+ /**createBy*/
+ @ApiModelProperty(value = "createBy")
+ private String createBy;
+ /**createTime*/
+ @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
+ @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
+ @ApiModelProperty(value = "createTime")
+ private Date createTime;
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/entity/KmSysConfig.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/entity/KmSysConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..f50d4ad453ce622399bde8905878f0d9e82790e3
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/entity/KmSysConfig.java
@@ -0,0 +1,46 @@
+package org.jeecg.modules.KM.entity;
+
+import java.io.Serializable;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import org.jeecgframework.poi.excel.annotation.Excel;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+@Data
+@TableName("km_sys_config")
+@Accessors(chain = true)
+@EqualsAndHashCode(callSuper = false)
+@ApiModel(value="km_sys_config对象", description="km_sys_config")
+public class KmSysConfig implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ /**id*/
+ @TableId(type = IdType.ASSIGN_ID)
+ @ApiModelProperty(value = "id")
+ private java.lang.String id;
+ /**itemCode*/
+ @Excel(name = "itemCode", width = 15)
+ @ApiModelProperty(value = "itemCode")
+ private java.lang.String itemCode;
+ /**itemValue*/
+ @Excel(name = "itemValue", width = 15)
+ @ApiModelProperty(value = "itemValue")
+ private java.lang.String itemValue;
+ /**itemName*/
+ @Excel(name = "itemName", width = 15)
+ @ApiModelProperty(value = "itemName")
+ private java.lang.String itemName;
+ /**valueType*/
+ @Excel(name = "valueType", width = 15)
+ @ApiModelProperty(value = "valueType")
+ private java.lang.String valueType;
+ /**valueOptions*/
+ @Excel(name = "valueOptions", width = 15)
+ @ApiModelProperty(value = "valueOptions")
+ private java.lang.String valueOptions;
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/entity/KmSysDbBackup.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/entity/KmSysDbBackup.java
new file mode 100644
index 0000000000000000000000000000000000000000..3a17f2b7e652c3158c362b34c3f6b29e1e838d33
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/entity/KmSysDbBackup.java
@@ -0,0 +1,48 @@
+package org.jeecg.modules.KM.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.jeecgframework.poi.excel.annotation.Excel;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+@TableName("km_sys_db_backup")
+@Accessors(chain = true)
+@EqualsAndHashCode(callSuper = false)
+@ApiModel(value="km_sys_db_backup对象", description="数据库备份记录")
+public class KmSysDbBackup implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ /**id*/
+ @TableId(type = IdType.ASSIGN_ID)
+ @ApiModelProperty(value = "id")
+ private String id;
+ /**fileName*/
+ @Excel(name = "fileName", width = 15)
+ @ApiModelProperty(value = "fileName")
+ private String fileName;
+ /**filePath*/
+ @Excel(name = "filePath", width = 15)
+ @ApiModelProperty(value = "filePath")
+ private String filePath;
+ /**size*/
+ @Excel(name = "size", width = 15)
+ @ApiModelProperty(value = "size")
+ private Long size;
+ /**createTime*/
+ @Excel(name = "createTime", width = 15, format = "yyyy-MM-dd HH:mm:ss")
+ @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
+ @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
+ @ApiModelProperty(value = "createTime")
+ private Date createTime;
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/jobs/fileScanImportJob.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/jobs/fileScanImportJob.java
new file mode 100644
index 0000000000000000000000000000000000000000..7da6e8225a3320fadc02b28ed8b9c05a3813dd3e
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/jobs/fileScanImportJob.java
@@ -0,0 +1,92 @@
+package org.jeecg.modules.KM.jobs;
+
+import cn.hutool.core.date.DateTime;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.system.api.ISysBaseAPI;
+import org.jeecg.common.system.vo.DictModel;
+import org.jeecg.common.util.oConvertUtils;
+import org.jeecg.modules.KM.VO.KmDocParamVO;
+import org.jeecg.modules.KM.common.rules.KMConstant;
+import org.jeecg.modules.KM.service.IKmDocService;
+import org.jeecg.modules.KM.service.IKmSysConfigService;
+import org.quartz.Job;
+import org.quartz.JobExecutionContext;
+import org.springframework.beans.factory.annotation.Autowired;
+import java.io.File;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Slf4j
+public class fileScanImportJob implements Job {
+
+ @Autowired
+ private IKmSysConfigService sysConfigService;
+ @Autowired
+ private ISysBaseAPI sysBaseAPI;
+ @Autowired
+ private IKmDocService docService;
+
+ private Map categoryMap = new HashMap<>();
+
+ @Override
+ public void execute(JobExecutionContext jobExecutionContext){
+ log.info("{} - 扫描外部文件启动...", DateTime.now());
+ String externalFileFolder = sysConfigService.getSysConfigValue(KMConstant.JobAutoScanFileBasePath);
+ if (oConvertUtils.isEmpty(externalFileFolder) ) {
+ log.error("扫描导入文件路径启动,但未配置扫描路径...");
+ return;
+ }
+ File baseFolder = new File(externalFileFolder);
+ if (!baseFolder.exists() || !baseFolder.isDirectory()) {
+ log.error("配置的基础扫描路径错误...");
+ return;
+ }
+ File[] listFiles = baseFolder.listFiles();
+ if (listFiles == null || listFiles.length == 0) {
+ log.info("扫描外部文件,根目录为空");
+ return;
+ }
+ initCategoryMap();
+ for (File listFile : listFiles) {
+ if (listFile.isFile()) {
+ KmDocParamVO kmDocParamVO = new KmDocParamVO();
+ Result> result = docService.importExternalFile(listFile, kmDocParamVO);
+ }else {
+ scanAndImportFolder(listFile,listFile.getPath());
+ }
+ }
+
+ }
+
+ private void scanAndImportFolder(File dir,String categoryPath){
+ File[] listFiles = dir.listFiles();
+ if (listFiles == null || listFiles.length == 0) {
+ return;
+ }else {
+ for (File file : listFiles) {
+ if (file.isFile()) {
+ KmDocParamVO kmDocParamVO = new KmDocParamVO();
+ kmDocParamVO.setCategory(categoryMap.get(categoryPath));
+ docService.importExternalFile(file,kmDocParamVO);
+ }else {
+ scanAndImportFolder(file,categoryPath);
+ }
+ }
+ }
+ }
+
+ private void initCategoryMap(){
+ List dictModelList = sysBaseAPI.queryDictItemList("km_dict_category");
+ if (oConvertUtils.isNotEmpty(dictModelList) && dictModelList.size()>0) {
+ for (DictModel dictModel : dictModelList) {
+ if (!categoryMap.containsKey(dictModel.getText())) {
+ categoryMap.put(dictModel.getText(),dictModel.getValue());
+ }
+ }
+ }
+
+ }
+
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/KmDocBusinessTypeMapper.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/KmDocBusinessTypeMapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..dbb7139d95d631d35cd46eeae16d3e7f353ff7f5
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/KmDocBusinessTypeMapper.java
@@ -0,0 +1,15 @@
+package org.jeecg.modules.KM.mapper;
+
+import java.util.List;
+
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+import org.jeecg.modules.KM.entity.KmDocBusinessType;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+public interface KmDocBusinessTypeMapper extends BaseMapper {
+
+ @Select("select business_type from km_doc_business_type where doc_id=#{id}")
+ List getBusinessTypes(@Param("id") String docId);
+
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/KmDocCommentsMapper.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/KmDocCommentsMapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..6a9ae523222122803d1d48c69cae6e8da874d44c
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/KmDocCommentsMapper.java
@@ -0,0 +1,18 @@
+package org.jeecg.modules.KM.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+import org.jeecg.modules.KM.VO.KmDocCommentsVO;
+import org.jeecg.modules.KM.entity.KmDocComments;
+
+import java.util.List;
+
+public interface KmDocCommentsMapper extends BaseMapper {
+ @Select("select * from km_doc_comments where doc_id=#{docId} order by create_time desc")
+ List getComments(@Param("docId") String docId);
+ @Select("select kdc.*,su.avatar from km_doc_comments kdc left join sys_user su on kdc.create_by=su.username where doc_id=#{kmDocComments.docId} order by create_time desc")
+ Page getPageList(Page page, KmDocComments kmDocComments);
+
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/KmDocFavouriteMapper.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/KmDocFavouriteMapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..f78a8b43424edd66b47157b2b277669b0803a603
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/KmDocFavouriteMapper.java
@@ -0,0 +1,19 @@
+package org.jeecg.modules.KM.mapper;
+
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.apache.ibatis.annotations.Param;
+import org.jeecg.modules.KM.VO.KmDocParamVO;
+import org.jeecg.modules.KM.VO.KmDocVO;
+import org.jeecg.modules.KM.entity.KmDocFavourite;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+public interface KmDocFavouriteMapper extends BaseMapper {
+
+ Page getPageList(Page page,
+ @Param("userId") String userId,
+ @Param("kmDocParamVO") KmDocParamVO kmDocParamVO,
+ @Param("dbType")String dbType,
+ @Param("orderBy") String orderBy);
+
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/KmDocMapper.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/KmDocMapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..19cc921698d9b618c4777a94e4354d01749d3bf3
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/KmDocMapper.java
@@ -0,0 +1,37 @@
+package org.jeecg.modules.KM.mapper;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+import org.jeecg.modules.KM.VO.KmDocParamVO;
+import org.jeecg.modules.KM.VO.KmDocStatisticsVO;
+import org.jeecg.modules.KM.VO.KmDocSummaryVO;
+import org.jeecg.modules.KM.VO.KmDocVO;
+import org.jeecg.modules.KM.entity.KmDoc;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+import java.util.List;
+
+public interface KmDocMapper extends BaseMapper {
+
+ Page getPageList(Page page,
+ @Param("userId") String userId,
+ @Param("kmDocParamVO") KmDocParamVO kmDocParamVO,
+ @Param("permissionSql")String permissionSql,
+ @Param("dbType")String dbType,
+ @Param("orderBy") String orderBy);
+
+ KmDoc getKmDocByFileId(@Param("fileId") String fileId);
+
+ Page queryTopicPageList(Page page,@Param("topicId") String topicId);
+
+ Page queryKmDocStatistics(Page page,@Param("statisticsType") Integer statisticsType,@Param("dbType")String dbType);
+ List queryKmDocStatistics( @Param("statisticsType") Integer statisticsType, @Param("dbType")String dbType);
+ KmDocSummaryVO queryKmDocSummary(@Param("dbType")String dbType);
+
+ @Select("SELECT count(0) FROM km_doc_topic_type kdtp join km_doc kd on kd.id = kdtp.doc_id where kd.status!=9 and topic_id=#{topidId} ")
+ Integer checkTopicOfDoc(@Param("topidId") String topidId);
+ @Select("SELECT count(0) FROM km_doc_business_type kdbt join km_doc kd on kd.id = kdbt.doc_id where kd.status!=9 and kdbt.business_type=#{businessType} ")
+ Integer checkBusinessTypeOfDoc(@Param("businessType") String businessType);
+
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/KmDocTopicTypeMapper.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/KmDocTopicTypeMapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..303be510ad5de3d6b2898fd3133e9a42cc826756
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/KmDocTopicTypeMapper.java
@@ -0,0 +1,12 @@
+package org.jeecg.modules.KM.mapper;
+
+import java.util.List;
+
+import org.apache.ibatis.annotations.Param;
+import org.jeecg.modules.KM.entity.KmDocTopicType;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+public interface KmDocTopicTypeMapper extends BaseMapper {
+ List getDocTopicCodes(@Param("docId") String docId);
+
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/KmDocVersionMapper.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/KmDocVersionMapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..2c923779a1049b40b839b2f67c7402bf99b06e1f
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/KmDocVersionMapper.java
@@ -0,0 +1,15 @@
+package org.jeecg.modules.KM.mapper;
+
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+import org.jeecg.modules.KM.entity.KmDocVersion;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+import java.util.List;
+
+public interface KmDocVersionMapper extends BaseMapper {
+ @Select("select version from km_doc_version where doc_id=#{id}")
+ List getversions(@Param("id") String docId);
+
+
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/KmDocVisitRecordMapper.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/KmDocVisitRecordMapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..8f7fc6917c243c775ffd99a9eee11f97cf3d1f69
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/KmDocVisitRecordMapper.java
@@ -0,0 +1,8 @@
+package org.jeecg.modules.KM.mapper;
+
+import org.jeecg.modules.KM.entity.KmDocVisitRecord;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+public interface KmDocVisitRecordMapper extends BaseMapper {
+
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/KmFileMapper.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/KmFileMapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..9d3fd9858c825e5476cb39da3e1f34e5ad85ef20
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/KmFileMapper.java
@@ -0,0 +1,8 @@
+package org.jeecg.modules.KM.mapper;
+
+import org.jeecg.modules.KM.entity.KmFile;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+public interface KmFileMapper extends BaseMapper {
+
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/KmSearchRecordMapper.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/KmSearchRecordMapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..5bc498a2acedbb61bbe7f029edeeffd53e2857d0
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/KmSearchRecordMapper.java
@@ -0,0 +1,8 @@
+package org.jeecg.modules.KM.mapper;
+
+import org.jeecg.modules.KM.entity.KmSearchRecord;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+public interface KmSearchRecordMapper extends BaseMapper {
+
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/KmSysConfigMapper.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/KmSysConfigMapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..81efa8d6b7359c408655daa8ba0833617b187064
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/KmSysConfigMapper.java
@@ -0,0 +1,9 @@
+package org.jeecg.modules.KM.mapper;
+
+import org.jeecg.modules.KM.entity.KmSysConfig;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+public interface KmSysConfigMapper extends BaseMapper {
+
+
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/KmSysDbBackupMapper.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/KmSysDbBackupMapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..8d17a7e8d0ad80d8a81b5e2a2efe2510a13a916b
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/KmSysDbBackupMapper.java
@@ -0,0 +1,9 @@
+package org.jeecg.modules.KM.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.jeecg.modules.KM.entity.KmFile;
+import org.jeecg.modules.KM.entity.KmSysDbBackup;
+
+public interface KmSysDbBackupMapper extends BaseMapper {
+
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/xml/KmDocBusinessTypeMapper.xml b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/xml/KmDocBusinessTypeMapper.xml
new file mode 100644
index 0000000000000000000000000000000000000000..684a353deea9b20e259d57bbb545e0d1b2c4a13a
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/xml/KmDocBusinessTypeMapper.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/xml/KmDocCommentsMapper.xml b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/xml/KmDocCommentsMapper.xml
new file mode 100644
index 0000000000000000000000000000000000000000..95d7b63c98c2b1daa2b23d217aa3bd940ff2c2a7
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/xml/KmDocCommentsMapper.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/xml/KmDocFavouriteMapper.xml b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/xml/KmDocFavouriteMapper.xml
new file mode 100644
index 0000000000000000000000000000000000000000..8a0d8fc2f8d423b8c1374f72266c23df46802dca
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/xml/KmDocFavouriteMapper.xml
@@ -0,0 +1,101 @@
+
+
+
+
+
+
+
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/xml/KmDocMapper.xml b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/xml/KmDocMapper.xml
new file mode 100644
index 0000000000000000000000000000000000000000..fd2775052e6094ac2cd8cd93fc1c07eedd72f4b9
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/xml/KmDocMapper.xml
@@ -0,0 +1,241 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/xml/KmDocTopicTypeMapper.xml b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/xml/KmDocTopicTypeMapper.xml
new file mode 100644
index 0000000000000000000000000000000000000000..7e55fbffe1ed0f48f8bb758085821d94fe91f35d
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/xml/KmDocTopicTypeMapper.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/xml/KmDocVersionMapper.xml b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/xml/KmDocVersionMapper.xml
new file mode 100644
index 0000000000000000000000000000000000000000..7242c8533528e7cca197fd44394a386750e675e1
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/xml/KmDocVersionMapper.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/xml/KmDocVisitRecordMapper.xml b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/xml/KmDocVisitRecordMapper.xml
new file mode 100644
index 0000000000000000000000000000000000000000..9505c15fb749d59382e0a2560362abb316520997
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/xml/KmDocVisitRecordMapper.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/xml/KmFileMapper.xml b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/xml/KmFileMapper.xml
new file mode 100644
index 0000000000000000000000000000000000000000..01f9caa830da02f156bac117dd290561b878e7af
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/xml/KmFileMapper.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/xml/KmSearchRecordMapper.xml b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/xml/KmSearchRecordMapper.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e04d573e5d2aa288d0fcbdb2edd7a8ce5344dc84
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/xml/KmSearchRecordMapper.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/xml/KmSysConfigMapper.xml b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/xml/KmSysConfigMapper.xml
new file mode 100644
index 0000000000000000000000000000000000000000..54edb6dc00cf39b4d1337d2b01ca0748066d0a53
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/xml/KmSysConfigMapper.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/xml/KmSysDbBackup.xml b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/xml/KmSysDbBackup.xml
new file mode 100644
index 0000000000000000000000000000000000000000..2f452849533be69bb2063839d033e37587254840
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/xml/KmSysDbBackup.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/xml/KmTopicTypeMapper.xml b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/xml/KmTopicTypeMapper.xml
new file mode 100644
index 0000000000000000000000000000000000000000..bf2ea485bc0bbd74c4769644553649d71570e76a
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/mapper/xml/KmTopicTypeMapper.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/reader/ParagraphTextReader.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/reader/ParagraphTextReader.java
new file mode 100644
index 0000000000000000000000000000000000000000..a36e00aeb509440de2caad2414c0567e20c20868
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/reader/ParagraphTextReader.java
@@ -0,0 +1,143 @@
+package org.jeecg.modules.KM.reader;
+
+import cn.hutool.core.collection.ListUtil;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import org.springframework.ai.document.Document;
+import org.springframework.ai.document.DocumentReader;
+import org.springframework.core.io.DefaultResourceLoader;
+import org.springframework.core.io.Resource;
+import org.springframework.util.StreamUtils;
+
+/**
+ * @Description: text文本段落读取
+ * @Author: jay
+ * @Date: 2024/3/19 9:05
+ * @Version: 1.0
+ */
+public class ParagraphTextReader implements DocumentReader {
+
+ public static final String CHARSET_METADATA = "charset";
+
+ public static final String SOURCE_METADATA = "source";
+
+ /**
+ * Input resource to load the text from.
+ */
+ private final Resource resource;
+
+ /**
+ * @return Character set to be used when loading data from the
+ */
+ private Charset charset = StandardCharsets.UTF_8;
+
+ /**
+ * 默认窗口大小,为1
+ */
+ private static final int DEFAULT_WINDOW_SIZE = 1;
+
+ /**
+ * 窗口大小,为段落的数量,用于滚动读取
+ */
+ private int windowSize = DEFAULT_WINDOW_SIZE;
+
+ public static final String START_PARAGRAPH_NUMBER = "startParagraphNumber";
+ public static final String END_PARAGRAPH_NUMBER = "endParagraphNumber";
+
+ private final Map customMetadata = new HashMap<>();
+
+ public ParagraphTextReader(String resourceUrl) {
+ this(new DefaultResourceLoader().getResource(resourceUrl));
+ }
+
+ public ParagraphTextReader(Resource resource) {
+ Objects.requireNonNull(resource, "The Spring Resource must not be null");
+ this.resource = resource;
+ }
+
+ public ParagraphTextReader(String resourceUrl, int windowSize) {
+ this(new DefaultResourceLoader().getResource(resourceUrl), windowSize);
+ }
+
+ public ParagraphTextReader(Resource resource, int windowSize) {
+ Objects.requireNonNull(resource, "The Spring Resource must not be null");
+ this.resource = resource;
+ this.windowSize = windowSize;
+ }
+
+ public void setCharset(Charset charset) {
+ Objects.requireNonNull(charset, "The charset must not be null");
+ this.charset = charset;
+ }
+
+ public Charset getCharset() {
+ return this.charset;
+ }
+
+ /**
+ * Metadata associated with all documents created by the loader.
+ *
+ * @return Metadata to be assigned to the output Documents.
+ */
+ public Map getCustomMetadata() {
+ return this.customMetadata;
+ }
+
+ /**
+ * 读取文本内容,并根据换行进行分段,采用窗口模式,窗口为段落的数量
+ *
+ * @return 文档信息列表
+ */
+ @Override
+ public List get() {
+ try {
+
+ List readDocuments = new ArrayList();
+ String document = StreamUtils.copyToString(this.resource.getInputStream(), this.charset);
+
+ // Inject source information as a metadata.
+ this.customMetadata.put(CHARSET_METADATA, this.charset.name());
+ this.customMetadata.put(SOURCE_METADATA, this.resource.getFilename());
+
+ List paragraphs = Arrays.asList(document.split("\n"));
+
+ //采用窗口滑动读取
+ int startIndex = 0;
+ int endIndex = startIndex + this.windowSize;
+ if (endIndex > paragraphs.size()) {
+ readDocuments.add(this.toDocument(paragraphs, startIndex + 1, paragraphs.size()));
+ } else {
+ for (; endIndex <= paragraphs.size(); startIndex++, endIndex++) {
+ readDocuments.add(this.toDocument(ListUtil.sub(paragraphs, startIndex, endIndex), startIndex + 1, endIndex));
+ }
+ }
+ return readDocuments;
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * 封装段落成文档
+ *
+ * @param paragraphList 段落内容列表
+ * @param startParagraphNum 开始段落编码
+ * @param endParagraphNum 结束段落编码
+ * @return 文档信息
+ */
+ private Document toDocument(List paragraphList, int startParagraphNum, int endParagraphNum) {
+ Document doc = new Document(String.join("\n", paragraphList));
+ doc.getMetadata().putAll(this.customMetadata);
+ doc.getMetadata().put(START_PARAGRAPH_NUMBER, startParagraphNum);
+ doc.getMetadata().put(END_PARAGRAPH_NUMBER, endParagraphNum);
+ return doc;
+ }
+
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/service/DocumentService.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/service/DocumentService.java
new file mode 100644
index 0000000000000000000000000000000000000000..00397a7ad70256813974f51b0e5ab0fdf27cb621
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/service/DocumentService.java
@@ -0,0 +1,167 @@
+package org.jeecg.modules.KM.service;
+
+import static org.jeecg.modules.KM.reader.ParagraphTextReader.END_PARAGRAPH_NUMBER;
+import static org.jeecg.modules.KM.reader.ParagraphTextReader.START_PARAGRAPH_NUMBER;
+
+import cn.hutool.core.util.ArrayUtil;
+import org.jeecg.modules.KM.reader.ParagraphTextReader;
+import java.io.File;
+import java.net.MalformedURLException;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.stream.Collectors;
+import org.springframework.ai.document.Document;
+import org.springframework.ai.ollama.OllamaChatModel;
+import org.springframework.ai.vectorstore.VectorStore;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.io.FileUrlResource;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * @Description: 文档服务
+ * @Author: jay
+ * @Date: 2024/3/18 10:02
+ * @Version: 1.0
+ */
+@Service
+public class DocumentService {
+
+ @Autowired
+ private VectorStore vectorStore;
+
+ @Autowired
+ private OllamaChatModel ollamaChatModel;
+
+ private static final String PATH = "/app/ragdemo/path";
+
+ /**
+ * 使用spring ai解析txt文档
+ *
+ * @param file
+ * @throws MalformedURLException
+ */
+ public void uploadDocument(MultipartFile file) {
+ //保存file到本地
+ String textResource = file.getOriginalFilename();
+ //判断文件是否是TXT
+ if (!textResource.endsWith(".txt")) {
+ throw new RuntimeException("只支持txt格式文件");
+ }
+ String filepath = PATH + textResource;
+ File file1 = new File(filepath);
+ if (file1.exists()) {
+ throw new RuntimeException("文件已存在");
+ }
+ try {
+ file.transferTo(file1);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ List documentList = paragraphTextReader(file1);
+ vectorStore.add(documentList);
+ }
+
+ private List paragraphTextReader(File file) {
+ List docs = null;
+ try {
+ ParagraphTextReader reader = new ParagraphTextReader(new FileUrlResource(file.toURI().toURL()), 5);
+ reader.getCustomMetadata().put("filename", file.getName());
+ reader.getCustomMetadata().put("filepath", file.getAbsolutePath());
+ docs = reader.get();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return docs;
+ }
+
+ /**
+ * 合并文档列表
+ *
+ * @param documentList 文档列表
+ * @return 合并后的文档列表
+ */
+ private List mergeDocuments(List documentList) {
+ List mergeDocuments = new ArrayList();
+ //根据文档来源进行分组
+ Map> documentMap = documentList.stream().collect(Collectors.groupingBy(item -> ((String) item.getMetadata().get("source"))));
+ for (Entry> docListEntry : documentMap.entrySet()) {
+ //获取最大的段落结束编码
+ int maxParagraphNum = (int) docListEntry.getValue()
+ .stream().max(Comparator.comparing(item -> ((int) item.getMetadata().get(END_PARAGRAPH_NUMBER)))).get().getMetadata().get(END_PARAGRAPH_NUMBER);
+ //根据最大段落结束编码构建一个用于合并段落的空数组
+ String[] paragraphs = new String[maxParagraphNum];
+ //用于获取最小段落开始编码
+ int minParagraphNum = maxParagraphNum;
+ for (Document document : docListEntry.getValue()) {
+ //文档内容根据回车进行分段
+ String[] tempPs = document.getContent().split("\n");
+ //获取文档开始段落编码
+ int startParagraphNumber = (int) document.getMetadata().get(START_PARAGRAPH_NUMBER);
+ if (minParagraphNum > startParagraphNumber) {
+ minParagraphNum = startParagraphNumber;
+ }
+ //将文档段落列表拷贝到合并段落数组中
+ System.arraycopy(tempPs, 0, paragraphs, startParagraphNumber - 1, tempPs.length);
+ }
+ //合并段落去除空值,并组成文档内容
+ Document mergeDoc = new Document(ArrayUtil.join(ArrayUtil.removeNull(paragraphs), "\n"));
+ //合并元数据
+ mergeDoc.getMetadata().putAll(docListEntry.getValue().get(0).getMetadata());
+ //设置元数据:开始段落编码
+ mergeDoc.getMetadata().put(START_PARAGRAPH_NUMBER, minParagraphNum);
+ //设置元数据:结束段落编码
+ mergeDoc.getMetadata().put(END_PARAGRAPH_NUMBER, maxParagraphNum);
+ mergeDocuments.add(mergeDoc);
+ }
+ return mergeDocuments;
+ }
+
+ /**
+ * 根据关键词搜索向量库
+ *
+ * @param keyword 关键词
+ * @return 文档列表
+ */
+ public List search(String keyword) {
+ return mergeDocuments(vectorStore.similaritySearch(keyword));
+ }
+
+ /**
+ * 问答,根据输入内容回答
+ *
+ * @param message 输入内容
+ * @return 回答内容
+ */
+ public String chat(String message) {
+ //查询获取文档信息
+ List documents = search(message);
+
+ //提取文本内容
+ String content = documents.stream()
+ .map(Document::getContent)
+ .collect(Collectors.joining("\n"));
+
+ //封装prompt并调用大模型
+ String chatResponse = ollamaChatModel.call(getChatPrompt2String(message, content));
+ return chatResponse;
+ }
+
+ /**
+ * 获取prompt
+ *
+ * @param message 提问内容
+ * @param context 上下文
+ * @return prompt
+ */
+ private String getChatPrompt2String(String message, String context) {
+ String promptText = """
+ 请用仅用以下内容回答"%s":
+ %s
+ """;
+ return String.format(promptText, message, context);
+ }
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/service/IKmDocBusinessTypeService.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/service/IKmDocBusinessTypeService.java
new file mode 100644
index 0000000000000000000000000000000000000000..2f77b84a2f4ecd7b765857aafe4c77161aa0b0dd
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/service/IKmDocBusinessTypeService.java
@@ -0,0 +1,11 @@
+package org.jeecg.modules.KM.service;
+
+import org.jeecg.modules.KM.entity.KmDocBusinessType;
+import com.baomidou.mybatisplus.extension.service.IService;
+import java.util.List;
+
+public interface IKmDocBusinessTypeService extends IService {
+// KmDocBusinessType getByDocIdAndBusinessType( String docId, String businessType);
+
+ List getBusinessTypes(String docId);
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/service/IKmDocCommentsService.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/service/IKmDocCommentsService.java
new file mode 100644
index 0000000000000000000000000000000000000000..058b813dcfef7ebf4fae42f217343ee8da16df64
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/service/IKmDocCommentsService.java
@@ -0,0 +1,18 @@
+package org.jeecg.modules.KM.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.jeecg.modules.KM.VO.KmDocCommentsVO;
+import org.jeecg.modules.KM.entity.KmDocComments;
+
+import java.util.List;
+
+
+public interface IKmDocCommentsService extends IService {
+
+ List getComments(String docId);
+
+ Page queryPageList(Page page, KmDocComments kmDocComments);
+
+ boolean save(KmDocComments kmDocComments);
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/service/IKmDocFavouriteService.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/service/IKmDocFavouriteService.java
new file mode 100644
index 0000000000000000000000000000000000000000..a5ff3759f3c350b1688414a07641c4aa3abbad22
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/service/IKmDocFavouriteService.java
@@ -0,0 +1,19 @@
+package org.jeecg.modules.KM.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.modules.KM.VO.KmDocParamVO;
+import org.jeecg.modules.KM.VO.KmDocVO;
+import org.jeecg.modules.KM.entity.KmDocFavourite;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+public interface IKmDocFavouriteService extends IService {
+
+ Page queryPageList(Page page, String userId, KmDocParamVO kmDocParamVO,String orderBy);
+
+ Result> addFavouriteDoc(String docId);
+
+ Result> delFavouriteDoc(String docId);
+
+
+}
diff --git a/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/service/IKmDocService.java b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/service/IKmDocService.java
new file mode 100644
index 0000000000000000000000000000000000000000..40c607fbdee86d32f3da3d20a813d925171119bc
--- /dev/null
+++ b/jeecg-boot/jeecg-module-KM/src/main/java/org/jeecg/modules/KM/service/IKmDocService.java
@@ -0,0 +1,89 @@
+package org.jeecg.modules.KM.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.system.vo.KmSearchResultObjVO;
+import org.jeecg.modules.KM.VO.*;
+import org.jeecg.modules.KM.entity.KmDoc;
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.jeecg.modules.KM.entity.KmFile;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.multipart.MultipartFile;
+
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import java.io.File;
+import java.io.IOException;
+import java.text.ParseException;
+import java.util.List;
+
+
+public interface IKmDocService extends IService {
+
+ Result> updateOfficeFile(String docId, File file,String userName);
+
+ Result> saveDocToEs(KmDocEsVO kmDocEsVO, String indexId);
+
+ Result> deleteDocFromEs(String indexId);
+
+ KmSearchResultObjVO searchESKmDoc(Page page, KmDocEsParamVO kmDocEsParamVO, HttpServletRequest req) throws IOException;
+ KmSearchResultObjVO checkDuplicateESKmDoc(Page page, KmDocEsParamVO kmDocEsParamVO, HttpServletRequest req) throws IOException;
+
+ Page queryPageList(Page page, KmDocParamVO kmDocParamVO,String orderBy);
+
+ //首页最新发布文档列表
+ Page queryPublicPageList(Page