Compare commits

...

9 Commits

14 changed files with 266 additions and 260 deletions

View File

@@ -1,4 +1,4 @@
FROM keking/kkfileview-base:4.4.0
FROM keking/kkfileview-base:5.0.0
ADD server/target/kkFileView-*.tar.gz /opt/
ENV KKFILEVIEW_BIN_FOLDER=/opt/kkFileView-4.4.0/bin
ENTRYPOINT ["java","-Dfile.encoding=UTF-8","-Dspring.config.location=/opt/kkFileView-4.4.0/config/application.properties","-jar","/opt/kkFileView-4.4.0/bin/kkFileView-4.4.0.jar"]
ENV KKFILEVIEW_BIN_FOLDER=/opt/kkFileView-5.0.0/bin
ENTRYPOINT ["java","-Dfile.encoding=UTF-8","-Dspring.config.location=/opt/kkFileView-5.0.0/config/application.properties","-jar","/opt/kkFileView-5.0.0/bin/kkFileView-5.0.0.jar"]

View File

@@ -149,7 +149,7 @@ pdf预览模式预览效果如下
### 历史更新记录
#### > 2026年01月20v5.0 版本发布
#### > 2026年04月14v5.0.0 版本发布
#### 优化内容
1. xlsx 前端解析优化 - 提升Excel文件前端渲染性能
2. 图片解析优化 - 改进图片处理机制
@@ -159,6 +159,10 @@ pdf预览模式预览效果如下
6. ftp多客户端接入优化 - 提升FTP服务兼容性
7. 首页目录访问优化 - 采用post服务端分页机制
8. marked 解析优化 - 改进Markdown渲染
9. 压缩包预览页重构为单工作区布局支持目录折叠与右侧内嵌预览
10. 优化压缩包内文件类型标识以及单图预览页的展示样式
11. 补充面向工程自动化与编码代理的仓库说明文档
12. 重构演示门户页面包括首页接入说明版本记录与赞助页
#### 新增功能
1. msg邮件解析 - 新增msg格式邮件文件预览支持
@@ -179,6 +183,12 @@ pdf预览模式预览效果如下
2. 安全问题 - 修复安全漏洞
3. 图片水印不全问题 - 修复水印显示不完整
4. SSL自签证书接入问题 - 修复自签名证书兼容性
5. 修复压缩包内 Office 文件在重复解压后被追加写坏导致一直卡在加载中的问题
6. Office 默认预览改为 PDF 模式 PDF 预览默认打开缩略图侧栏
7. 启动脚本改为自动发现当前发布包中的 jar移除过时的硬编码 jar 名称
8. 更新 Docker 与发布辅助文档使其与 5.0.0 发布线保持一致
9. 修复 OFD 表格竖线溢出导致的渲染异常
10. 修复 PDF.js 兼容性补丁避免兼容环境下的预览报错
#### 更新内容
1. JDK版本要求 - 强制要求JDK 21及以上版本
@@ -189,6 +199,8 @@ pdf预览模式预览效果如下
6. tif后端异步转换优化 - 实现多线程异步转换
7. 视频后端异步转换优化 - 实现多线程异步转换
8. CAD后端异步转换优化 - 实现多线程异步转换
9. 默认预览配置策略调整 - Office 预览默认切换为 PDF 模式默认隐藏图片/PDF 模式切换按钮 PDF 预览默认展开缩略图侧栏若升级后仍需保持旧的图片优先体验请显式设置 `office.preview.type=image` `office.preview.switch.disabled=false`
10. 信任域名配置匹配策略扩展 - `trust.host` 及相关规则现已支持通配符和 CIDR 匹配升级后如果你依赖域名/IP 模式匹配需要重新检查白名单和黑名单的实际生效范围
#### > 2025年01月16日v4.4.0 版本发布
@@ -468,4 +480,3 @@ dcm医疗数位影像 引用于 [dcmjs](https://github.com/dcmjs-org/dcmjs )开
- 本项目诞生于[凯京集团]在取得公司高层同意后以 Apache 协议开源出来反哺社区在此特别感谢凯京集团以及集团领导[@唐老大](https://github.com/tangshd)的支持、@端木详笑的贡献。
- 本项目已脱离公司由[KK开源社区]维护发展壮大感谢所有给 kkFileView Issue Pr 开发者
- 本项目引入的第三方组件已在 '关于引用' 列表列出感谢这些项目 kkFileView 更出色

View File

@@ -65,9 +65,9 @@ URL[https://file.kkview.cn](https://file.kkview.cn)
## Change History
### Version 5.0 (January 20, 2026)
### Version 5.0.0 (April 14, 2026)
#### Optimizations
#### Improvements
1. Enhanced xlsx front-end parsing - Improved Excel file front-end rendering performance
2. Optimized image parsing - Enhanced image processing mechanism
3. Improved tif parsing - Enhanced TIF format support
@@ -76,6 +76,10 @@ URL[https://file.kkview.cn](https://file.kkview.cn)
6. Optimized ftp multi-client access - Improved FTP service compatibility
7. Enhanced home page directory access - Implemented post server-side pagination mechanism
8. Improved marked parsing - Enhanced Markdown rendering
9. Redesigned archive preview into a single workspace with a collapsible tree and inline file preview
10. Improved archive preview file-type badges and single-image preview styling
11. Added an agent-focused repository guide for engineering automation and maintenance
12. Refreshed the demo portal pages, including the index, integration guide, release record, and sponsor pages
#### New Features
1. msg email parsing - Added support for msg format email file preview
@@ -96,6 +100,12 @@ URL[https://file.kkview.cn](https://file.kkview.cn)
2. Security issues - Fixed security vulnerabilities
3. Incomplete image watermark issues - Fixed incomplete watermark display
4. SSL self-signed certificate access issues - Fixed compatibility with self-signed certificates
5. Fixed archive-contained Office files that could stay stuck on loading because repeated extraction appended to existing files
6. Default Office preview now prefers PDF mode, and PDF preview opens with the thumbnail sidebar visible by default
7. Updated startup scripts to discover the packaged jar dynamically instead of relying on stale hard-coded jar names
8. Updated Docker and release helper docs to align with the 5.0.0 release line
9. Fixed OFD table border overflow rendering issues
10. Refined the PDF.js compatibility polyfill to avoid preview errors in compatibility environments
#### Updates
1. JDK version requirement - Mandatory requirement for JDK 21 or higher
@@ -106,6 +116,8 @@ URL[https://file.kkview.cn](https://file.kkview.cn)
6. tif backend async conversion optimization - Implemented multi-threaded asynchronous conversion
7. Video backend async conversion optimization - Implemented multi-threaded asynchronous conversion
8. CAD backend async conversion optimization - Implemented multi-threaded asynchronous conversion
9. Default preview configuration strategy adjusted - Office preview now defaults to PDF mode, the mode switch is hidden by default, and PDF preview opens with the thumbnail sidebar visible. If you need the previous image-first behavior after upgrade, explicitly set `office.preview.type=image` and `office.preview.switch.disabled=false`.
10. Trust host configuration matching expanded - `trust.host` and related rules now support wildcard and CIDR matching, which may broaden or narrow effective allow/deny behavior after upgrade depending on your patterns
### Version 4.4.0 (January 16, 2025)

View File

@@ -3,7 +3,7 @@
当前线上 Windows 服务器的实际部署信息如下
- 部署根目录`C:\kkFileView-5.0`
- 运行 jar`C:\kkFileView-5.0\bin\kkFileView-5.0.jar`
- 运行 jar`C:\kkFileView-5.0\bin\kkFileView-<当前项目版本>.jar`
- 启动脚本`C:\kkFileView-5.0\bin\startup.bat`
- 运行配置`C:\kkFileView-5.0\config\test.properties`
- 健康检查地址`http://127.0.0.1:8012/`

View File

@@ -7,10 +7,10 @@
然后使用 kkfileview-base 作为基础镜像进行构建加快 kkfileview docker 镜像构建与发布
执行如下命令即可构建基础镜像
> 这里镜像 tag 4.4.0 为例本项目所维护的 Dockerfile 文件考虑了跨平台兼容性 如果你需要用到 arm64 架构镜像, 则在arm64 架构机器上同样执行下面的构建命令即可
> 这里镜像 tag 5.0.0 为例本项目所维护的 Dockerfile 文件考虑了跨平台兼容性 如果你需要用到 arm64 架构镜像, 则在arm64 架构机器上同样执行下面的构建命令即可
```shell
docker build --tag keking/kkfileview-base:4.4.0 .
docker build --tag keking/kkfileview-base:5.0.0 .
```
@@ -46,5 +46,5 @@ docker build --tag keking/kkfileview-base:4.4.0 .
现在就可以愉快地开始构建了构建命令示例:
```shell
docker buildx build --platform=linux/amd64,linux/arm64 -t keking/kkfileview-base:4.4.0 --push .
docker buildx build --platform=linux/amd64,linux/arm64 -t keking/kkfileview-base:5.0.0 --push .
```

View File

@@ -8,10 +8,10 @@ Then, use kkfileview-base as the base image to build and speed up the kkfileview
To build the base image, run the following command:
> In this example, the image tag is 4.4.0. The Dockerfile maintained in this project considers cross-platform compatibility. If you need an arm64 architecture image, run the same build command on an arm64 architecture machine.
> In this example, the image tag is 5.0.0. The Dockerfile maintained in this project considers cross-platform compatibility. If you need an arm64 architecture image, run the same build command on an arm64 architecture machine.
```shell
docker build --tag keking/kkfileview-base:4.4.0 .
docker build --tag keking/kkfileview-base:5.0.0 .
```
@@ -49,5 +49,5 @@ Assuming the current machine is amd64 (x86_64) architecture, you'll need to enab
Now you can enjoy the building. Heres an example build command:
```shell
docker buildx build --platform=linux/amd64,linux/arm64 -t keking/kkfileview-base:4.4.0 --push .
docker buildx build --platform=linux/amd64,linux/arm64 -t keking/kkfileview-base:5.0.0 --push .
```

View File

@@ -6,7 +6,7 @@
<groupId>cn.keking</groupId>
<artifactId>kkFileView-parent</artifactId>
<version>5.0</version>
<version>5.0.0</version>
<properties>
<!-- ========== Java 和编译配置 ========== -->
@@ -110,4 +110,4 @@
<system>github</system>
<url>https://github.com/kekingcn/kkFileView/issues</url>
</issueManagement>
</project>
</project>

View File

@@ -6,7 +6,7 @@
<parent>
<artifactId>kkFileView-parent</artifactId>
<groupId>cn.keking</groupId>
<version>5.0</version>
<version>5.0.0</version>
</parent>
<artifactId>kkFileView</artifactId>

View File

@@ -1,10 +1,20 @@
@echo off
set "KKFILEVIEW_BIN_FOLDER=%cd%"
cd "%KKFILEVIEW_BIN_FOLDER%"
set "JAR_NAME="
for %%F in (kkFileView-*.jar) do (
set "JAR_NAME=%%~nxF"
goto :jar_found
)
echo Error: kkFileView jar not found in %KKFILEVIEW_BIN_FOLDER%
exit /b 1
:jar_found
echo Using KKFILEVIEW_BIN_FOLDER %KKFILEVIEW_BIN_FOLDER%
echo Using JAR_NAME %JAR_NAME%
echo Starting kkFileView...
echo Please check log file in ../log/kkFileView.log for more information
echo You can get help in our official home site: https://kkview.cn
echo If you need further help, please join our kk opensource community: https://t.zsxq.com/09ZHSXbsQ
echo If this project is helpful to you, please star it on https://gitee.com/kekingcn/file-online-preview/stargazers
java -Dspring.config.location=..\config\application.properties -jar kkFileView-4.4.0.jar -> ..\log\kkFileView.log
java -Dspring.config.location=..\config\application.properties -jar "%JAR_NAME%" > ..\log\kkFileView.log 2>&1

View File

@@ -49,9 +49,16 @@ else
fi
fi
JAR_PATH=$(ls kkFileView-*.jar 2>/dev/null | head -n 1)
if [ -z "${JAR_PATH}" ]; then
echo "kkFileView jar not found in ${KKFILEVIEW_BIN_FOLDER}"
exit 1
fi
## 启动kkFileView
echo "Starting kkFileView..."
nohup java -Dfile.encoding=UTF-8 -Dspring.config.location=../config/application.properties -jar kkFileView-4.4.0.jar > ../log/kkFileView.log 2>&1 &
echo "Using jar ${JAR_PATH}"
nohup java -Dfile.encoding=UTF-8 -Dspring.config.location=../config/application.properties -jar "${JAR_PATH}" > ../log/kkFileView.log 2>&1 &
echo "Please execute ./showlog.sh to check log for more information"
echo "You can get help in our official home site: https://kkview.cn"
echo "If you need further help, please join our kk opensource community: https://t.zsxq.com/09ZHSXbsQ"

View File

@@ -96,11 +96,11 @@ office.documentopenpasswords = ${KK_OFFICE_DOCUMENTOPENPASSWORD:true}
office.type.web = ${KK_OFFICE_TYPE_WEB:web}
# Office文档预览类型
# 支持动态配置可选值image/pdf
# 支持动态配置可选值image/pdf默认使用pdf模式
office.preview.type = ${KK_OFFICE_PREVIEW_TYPE:pdf}
# 是否关闭Office预览模式切换开关默认为false允许切换
# 设置为true时用户无法在图片和PDF模式间切换
# 是否关闭Office预览模式切换开关默认为true关闭切换
# 设置为false时用户可以在图片和PDF模式间切换
office.preview.switch.disabled = ${KK_OFFICE_PREVIEW_SWITCH_DISABLED:true}

View File

@@ -1,6 +1,5 @@
package cn.keking.config;
import io.netty.channel.nio.NioEventLoopGroup;
import org.apache.commons.lang3.StringUtils;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
@@ -13,8 +12,8 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.util.ClassUtils;
/**
* Redisson 客户端配置
* Created by kl on 2017/09/26.
* Redisson 客户端配置(完善版)
* 支持 single / cluster / master-slave / sentinel 四种模式,配置完整,统一参数。
*/
@ConditionalOnExpression("'${cache.type:default}'.equals('redis')")
@ConfigurationProperties(prefix = "spring.redisson")
@@ -22,114 +21,71 @@ import org.springframework.util.ClassUtils;
public class RedissonConfig {
// ========================== 连接配置 ==========================
private static String address;
private static String password;
private static String clientName;
private static int database = 0;
private static String mode = "single";
private static String masterName = "kkfile";
private String address;
private String password;
private String clientName;
private int database = 0;
private String mode = "single";
private String masterName = "kkfile";
// ========================== 超时配置 ==========================
private static int idleConnectionTimeout = 10000;
private static int connectTimeout = 10000;
private static int timeout = 3000;
private int idleConnectionTimeout = 10000;
private int connectTimeout = 10000;
private int timeout = 3000;
// ========================== 重试配置 ==========================
private static int retryAttempts = 3;
private static int retryInterval = 1500;
private int retryAttempts = 3;
private int retryInterval = 1500;
// ========================== 连接池配置 ==========================
private static int connectionMinimumIdleSize = 10;
private static int connectionPoolSize = 64;
private static int subscriptionsPerConnection = 5;
private static int subscriptionConnectionMinimumIdleSize = 1;
private static int subscriptionConnectionPoolSize = 50;
private int connectionMinimumIdleSize = 10;
private int connectionPoolSize = 64;
private int subscriptionsPerConnection = 5;
private int subscriptionConnectionMinimumIdleSize = 1;
private int subscriptionConnectionPoolSize = 50;
// ========================== 集群专用配置 ==========================
private int scanInterval = 2000;
// ========================== 其他配置 ==========================
private static int dnsMonitoringInterval = 5000;
private static int thread; // 当前处理核数 * 2
private static String codec = "org.redisson.codec.JsonJacksonCodec";
private int dnsMonitoringInterval = 5000;
private int threads; // 默认为0表示使用 CPU 核数 * 2
private String codec = "org.redisson.codec.JsonJacksonCodec";
@Bean
public static RedissonClient config() throws Exception {
public RedissonClient redissonClient() {
Config config = new Config();
// 密码处理
if (StringUtils.isBlank(password)) {
password = null;
}
// 密码处理:空字符串转为 null
String pwd = StringUtils.isBlank(password) ? null : password;
// 根据模式创建对应的 Redisson 配置
switch (mode) {
// 根据模式构建配置
switch (mode.toLowerCase()) {
case "cluster":
configureClusterMode(config);
configureClusterMode(config, pwd);
break;
case "master-slave":
configureMasterSlaveMode(config);
configureMasterSlaveMode(config, pwd);
break;
case "sentinel":
configureSentinelMode(config);
configureSentinelMode(config, pwd);
break;
default:
configureSingleMode(config);
configureSingleMode(config, pwd);
break;
}
// 公共配置:编码器、线程数
applyCommonConfig(config);
return Redisson.create(config);
}
// ========================== 配置方法 ==========================
/**
* 配置集群模式
*/
private static void configureClusterMode(Config config) {
String[] clusterAddresses = address.split(",");
config.useClusterServers()
.setScanInterval(2000)
.addNodeAddress(clusterAddresses)
.setPassword(password)
.setRetryAttempts(retryAttempts)
.setTimeout(timeout)
.setMasterConnectionPoolSize(100)
.setSlaveConnectionPoolSize(100);
}
/**
* 配置主从模式
*/
private static void configureMasterSlaveMode(Config config) {
String[] masterSlaveAddresses = address.split(",");
validateMasterSlaveAddresses(masterSlaveAddresses);
String[] slaveAddresses = new String[masterSlaveAddresses.length - 1];
System.arraycopy(masterSlaveAddresses, 1, slaveAddresses, 0, slaveAddresses.length);
config.useMasterSlaveServers()
.setDatabase(database)
.setPassword(password)
.setMasterAddress(masterSlaveAddresses[0])
.addSlaveAddress(slaveAddresses);
}
/**
* 配置哨兵模式
*/
private static void configureSentinelMode(Config config) {
String[] sentinelAddresses = address.split(",");
config.useSentinelServers()
.setDatabase(database)
.setPassword(password)
.setMasterName(masterName)
.addSentinelAddress(sentinelAddresses);
}
/**
* 配置单机模式
*/
private static void configureSingleMode(Config config) throws Exception {
private void configureSingleMode(Config config, String pwd) {
String normalizedAddress = normalizeAddress(address);
config.useSingleServer()
.setAddress(address)
.setAddress(normalizedAddress)
.setConnectionMinimumIdleSize(connectionMinimumIdleSize)
.setConnectionPoolSize(connectionPoolSize)
.setDatabase(database)
@@ -143,183 +99,184 @@ public class RedissonConfig {
.setTimeout(timeout)
.setConnectTimeout(connectTimeout)
.setIdleConnectionTimeout(idleConnectionTimeout)
.setPassword(StringUtils.trimToNull(password));
// 设置编码器
Class<?> codecClass = ClassUtils.forName(getCodec(), ClassUtils.getDefaultClassLoader());
Codec codecInstance = (Codec) codecClass.getDeclaredConstructor().newInstance();
config.setCodec(codecInstance);
// 设置线程和事件循环组
config.setThreads(thread);
config.setEventLoopGroup(new NioEventLoopGroup());
.setPassword(pwd);
}
/**
* 验证主从模式地址
*/
private static void validateMasterSlaveAddresses(String[] addresses) {
if (addresses.length == 1) {
throw new IllegalArgumentException(
"redis.redisson.address MUST have multiple redis addresses for master-slave mode.");
private void configureClusterMode(Config config, String pwd) {
String[] nodeAddresses = normalizeAddresses(address.split(","));
config.useClusterServers()
.setScanInterval(scanInterval)
.addNodeAddress(nodeAddresses)
.setPassword(pwd)
.setRetryAttempts(retryAttempts)
.setRetryInterval(retryInterval)
.setTimeout(timeout)
.setConnectTimeout(connectTimeout)
.setIdleConnectionTimeout(idleConnectionTimeout)
.setMasterConnectionPoolSize(connectionPoolSize)
.setSlaveConnectionPoolSize(connectionPoolSize)
.setSubscriptionConnectionPoolSize(subscriptionConnectionPoolSize)
.setSubscriptionConnectionMinimumIdleSize(subscriptionConnectionMinimumIdleSize)
.setSubscriptionsPerConnection(subscriptionsPerConnection)
.setClientName(clientName);
}
private void configureMasterSlaveMode(Config config, String pwd) {
String[] addresses = address.split(",");
validateMasterSlaveAddresses(addresses);
String[] normalizedAddresses = normalizeAddresses(addresses);
String masterAddress = normalizedAddresses[0];
String[] slaveAddresses = new String[normalizedAddresses.length - 1];
System.arraycopy(normalizedAddresses, 1, slaveAddresses, 0, slaveAddresses.length);
config.useMasterSlaveServers()
.setDatabase(database)
.setPassword(pwd)
.setMasterAddress(masterAddress)
.addSlaveAddress(slaveAddresses)
.setRetryAttempts(retryAttempts)
.setRetryInterval(retryInterval)
.setTimeout(timeout)
.setConnectTimeout(connectTimeout)
.setIdleConnectionTimeout(idleConnectionTimeout)
.setMasterConnectionPoolSize(connectionPoolSize)
.setSlaveConnectionPoolSize(connectionPoolSize)
.setSubscriptionConnectionPoolSize(subscriptionConnectionPoolSize)
.setSubscriptionConnectionMinimumIdleSize(subscriptionConnectionMinimumIdleSize)
.setSubscriptionsPerConnection(subscriptionsPerConnection)
.setClientName(clientName);
}
private void configureSentinelMode(Config config, String pwd) {
String[] sentinelAddresses = normalizeAddresses(address.split(","));
config.useSentinelServers()
.setDatabase(database)
.setPassword(pwd)
.setMasterName(masterName)
.addSentinelAddress(sentinelAddresses)
.setRetryAttempts(retryAttempts)
.setRetryInterval(retryInterval)
.setTimeout(timeout)
.setConnectTimeout(connectTimeout)
.setIdleConnectionTimeout(idleConnectionTimeout)
.setMasterConnectionPoolSize(connectionPoolSize)
.setSlaveConnectionPoolSize(connectionPoolSize)
.setSubscriptionConnectionPoolSize(subscriptionConnectionPoolSize)
.setSubscriptionConnectionMinimumIdleSize(subscriptionConnectionMinimumIdleSize)
.setSubscriptionsPerConnection(subscriptionsPerConnection)
.setClientName(clientName);
}
private void applyCommonConfig(Config config) {
// 设置编码器
if (StringUtils.isNotBlank(codec)) {
try {
Class<?> codecClass = ClassUtils.forName(codec, ClassUtils.getDefaultClassLoader());
Codec codecInstance = (Codec) codecClass.getDeclaredConstructor().newInstance();
config.setCodec(codecInstance);
} catch (Exception e) {
throw new IllegalStateException("Failed to create Redisson codec: " + codec, e);
}
}
// 设置线程数大于0时生效否则Redisson使用默认值CPU核数*2
if (threads > 0) {
config.setThreads(threads);
}
}
// ========================== Getter和Setter方法 ==========================
// ========================== 辅助方法 ==========================
// 连接配置
public String getAddress() {
return address;
/**
* 自动补齐 Redis 地址协议前缀redis:// 或 rediss://
*/
private String normalizeAddress(String addr) {
if (addr == null) {
return null;
}
addr = addr.trim();
if (!addr.startsWith("redis://") && !addr.startsWith("rediss://")) {
addr = "redis://" + addr;
}
return addr;
}
public void setAddress(String address) {
RedissonConfig.address = address;
private String[] normalizeAddresses(String[] addresses) {
String[] normalized = new String[addresses.length];
for (int i = 0; i < addresses.length; i++) {
normalized[i] = normalizeAddress(addresses[i]);
}
return normalized;
}
public String getPassword() {
return password;
private void validateMasterSlaveAddresses(String[] addresses) {
if (addresses.length < 2) {
throw new IllegalArgumentException(
"Master-slave mode requires at least 2 addresses: master and at least one slave. " +
"Current addresses: " + String.join(",", addresses));
}
}
public void setPassword(String password) {
RedissonConfig.password = password;
}
// ========================== Getter / Setter供 Spring 绑定配置) ==========================
// 以下所有字段都需要提供 getter/setter示例中只列出关键字段实际使用时请补全所有字段。
// 建议使用 Lombok @Data 或 IDE 自动生成。这里只展示部分,避免篇幅过长。
public String getClientName() {
return clientName;
}
public String getAddress() { return address; }
public void setAddress(String address) { this.address = address; }
public void setClientName(String clientName) {
RedissonConfig.clientName = clientName;
}
public String getPassword() { return password; }
public void setPassword(String password) { this.password = password; }
public int getDatabase() {
return database;
}
public String getClientName() { return clientName; }
public void setClientName(String clientName) { this.clientName = clientName; }
public void setDatabase(int database) {
RedissonConfig.database = database;
}
public int getDatabase() { return database; }
public void setDatabase(int database) { this.database = database; }
public static String getMode() {
return mode;
}
public String getMode() { return mode; }
public void setMode(String mode) { this.mode = mode; }
public void setMode(String mode) {
RedissonConfig.mode = mode;
}
public String getMasterName() { return masterName; }
public void setMasterName(String masterName) { this.masterName = masterName; }
public static String getMasterNamee() {
return masterName;
}
public int getIdleConnectionTimeout() { return idleConnectionTimeout; }
public void setIdleConnectionTimeout(int idleConnectionTimeout) { this.idleConnectionTimeout = idleConnectionTimeout; }
public void setMasterNamee(String masterName) {
RedissonConfig.masterName = masterName;
}
public int getConnectTimeout() { return connectTimeout; }
public void setConnectTimeout(int connectTimeout) { this.connectTimeout = connectTimeout; }
// 超时配置
public int getIdleConnectionTimeout() {
return idleConnectionTimeout;
}
public int getTimeout() { return timeout; }
public void setTimeout(int timeout) { this.timeout = timeout; }
public void setIdleConnectionTimeout(int idleConnectionTimeout) {
RedissonConfig.idleConnectionTimeout = idleConnectionTimeout;
}
public int getRetryAttempts() { return retryAttempts; }
public void setRetryAttempts(int retryAttempts) { this.retryAttempts = retryAttempts; }
public int getConnectTimeout() {
return connectTimeout;
}
public int getRetryInterval() { return retryInterval; }
public void setRetryInterval(int retryInterval) { this.retryInterval = retryInterval; }
public void setConnectTimeout(int connectTimeout) {
RedissonConfig.connectTimeout = connectTimeout;
}
public int getConnectionMinimumIdleSize() { return connectionMinimumIdleSize; }
public void setConnectionMinimumIdleSize(int connectionMinimumIdleSize) { this.connectionMinimumIdleSize = connectionMinimumIdleSize; }
public int getTimeout() {
return timeout;
}
public int getConnectionPoolSize() { return connectionPoolSize; }
public void setConnectionPoolSize(int connectionPoolSize) { this.connectionPoolSize = connectionPoolSize; }
public void setTimeout(int timeout) {
RedissonConfig.timeout = timeout;
}
public int getSubscriptionsPerConnection() { return subscriptionsPerConnection; }
public void setSubscriptionsPerConnection(int subscriptionsPerConnection) { this.subscriptionsPerConnection = subscriptionsPerConnection; }
// 重试配置
public int getRetryAttempts() {
return retryAttempts;
}
public int getSubscriptionConnectionMinimumIdleSize() { return subscriptionConnectionMinimumIdleSize; }
public void setSubscriptionConnectionMinimumIdleSize(int subscriptionConnectionMinimumIdleSize) { this.subscriptionConnectionMinimumIdleSize = subscriptionConnectionMinimumIdleSize; }
public void setRetryAttempts(int retryAttempts) {
RedissonConfig.retryAttempts = retryAttempts;
}
public int getSubscriptionConnectionPoolSize() { return subscriptionConnectionPoolSize; }
public void setSubscriptionConnectionPoolSize(int subscriptionConnectionPoolSize) { this.subscriptionConnectionPoolSize = subscriptionConnectionPoolSize; }
public int getRetryInterval() {
return retryInterval;
}
public int getScanInterval() { return scanInterval; }
public void setScanInterval(int scanInterval) { this.scanInterval = scanInterval; }
public void setRetryInterval(int retryInterval) {
RedissonConfig.retryInterval = retryInterval;
}
public int getDnsMonitoringInterval() { return dnsMonitoringInterval; }
public void setDnsMonitoringInterval(int dnsMonitoringInterval) { this.dnsMonitoringInterval = dnsMonitoringInterval; }
// 连接池配置
public int getConnectionMinimumIdleSize() {
return connectionMinimumIdleSize;
}
public int getThreads() { return threads; }
public void setThreads(int threads) { this.threads = threads; }
public void setConnectionMinimumIdleSize(int connectionMinimumIdleSize) {
RedissonConfig.connectionMinimumIdleSize = connectionMinimumIdleSize;
}
public int getConnectionPoolSize() {
return connectionPoolSize;
}
public void setConnectionPoolSize(int connectionPoolSize) {
RedissonConfig.connectionPoolSize = connectionPoolSize;
}
public int getSubscriptionsPerConnection() {
return subscriptionsPerConnection;
}
public void setSubscriptionsPerConnection(int subscriptionsPerConnection) {
RedissonConfig.subscriptionsPerConnection = subscriptionsPerConnection;
}
public int getSubscriptionConnectionMinimumIdleSize() {
return subscriptionConnectionMinimumIdleSize;
}
public void setSubscriptionConnectionMinimumIdleSize(int subscriptionConnectionMinimumIdleSize) {
RedissonConfig.subscriptionConnectionMinimumIdleSize = subscriptionConnectionMinimumIdleSize;
}
public int getSubscriptionConnectionPoolSize() {
return subscriptionConnectionPoolSize;
}
public void setSubscriptionConnectionPoolSize(int subscriptionConnectionPoolSize) {
RedissonConfig.subscriptionConnectionPoolSize = subscriptionConnectionPoolSize;
}
// 其他配置
public int getDnsMonitoringInterval() {
return dnsMonitoringInterval;
}
public void setDnsMonitoringInterval(int dnsMonitoringInterval) {
RedissonConfig.dnsMonitoringInterval = dnsMonitoringInterval;
}
public int getThread() {
return thread;
}
public void setThread(int thread) {
RedissonConfig.thread = thread;
}
public static String getCodec() {
return codec;
}
public void setCodec(String codec) {
RedissonConfig.codec = codec;
}
public String getCodec() { return codec; }
public void setCodec(String codec) { this.codec = codec; }
}

View File

@@ -1,11 +1,9 @@
package cn.keking.service.cache.impl;
import cn.keking.service.cache.CacheService;
import org.redisson.Redisson;
import org.redisson.api.RBlockingQueue;
import org.redisson.api.RMapCache;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.stereotype.Service;
@@ -23,8 +21,9 @@ public class CacheServiceRedisImpl implements CacheService {
private final RedissonClient redissonClient;
public CacheServiceRedisImpl(Config config) {
this.redissonClient = Redisson.create(config);
// 直接注入 Spring 容器中的 RedissonClient Bean
public CacheServiceRedisImpl(RedissonClient redissonClient) {
this.redissonClient = redissonClient;
}
@Override

View File

@@ -41,10 +41,10 @@
你可以先看最新版本的升级重点,再顺着时间轴继续了解历史版本细节。
</p>
<div class="release-badge-row">
<span class="tag highlight">最新版本 v5.0</span>
<span class="tag brand">发布日期 2026-01-20</span>
<span class="tag highlight">最新版本 v5.0.0</span>
<span class="tag brand">发布日期 2026-04-14</span>
<span class="tag warn">JDK 21+ 强制要求</span>
<span class="tag">PDF / TIF / CAD 异步化</span>
<span class="tag">压缩包工作区预览 / PDF 默认模式</span>
</div>
</div>
</section>
@@ -53,9 +53,9 @@
<div class="timeline-year">2026</div>
<div class="timeline-list">
<article class="release-card">
<h3>v5.0</h3>
<h3>v5.0.0</h3>
<div class="release-meta">
<span class="tag brand">2026-01-20</span>
<span class="tag brand">2026-04-14</span>
<span class="tag highlight">最新稳定版本</span>
<span class="tag warn">升级需 JDK 21+</span>
</div>
@@ -66,6 +66,9 @@
<li>优化 xlsx、图片、tif、svg、json 解析效果。</li>
<li>优化 FTP 多客户端接入与 marked 解析。</li>
<li>首页支持目录访问,并切换为 POST 服务端分页。</li>
<li>压缩包预览页重构为单工作区布局,支持目录折叠与右侧内嵌预览。</li>
<li>优化压缩包内文件类型标识,以及单图预览页展示样式。</li>
<li>重构演示门户页面,包括首页、接入说明、版本记录与赞助页。</li>
</ul>
</div>
<div class="release-group">
@@ -74,6 +77,7 @@
<li>新增 msg、heic/heif、页码、高亮、AES、Basic Auth、秘钥等能力。</li>
<li>新增防重复转换、异步等待、上传限制与 cadviewer 转换方法。</li>
<li>新增 pptm 支持。</li>
<li>补充面向工程自动化与编码代理的仓库说明文档。</li>
</ul>
</div>
<div class="release-group">
@@ -82,6 +86,9 @@
<li>修复压缩包路径问题与安全问题。</li>
<li>修复图片水印不完整。</li>
<li>修复 SSL 自签证书接入问题。</li>
<li>修复压缩包内 Office 文件重复解压后被追加写坏、导致一直加载中的问题。</li>
<li>Office 默认预览切到 PDF 模式,并默认展开 PDF 缩略图侧栏。</li>
<li>修复 OFD 表格竖线溢出导致的渲染异常,并修正 PDF.js 兼容性补丁。</li>
</ul>
</div>
<div class="release-group">
@@ -90,6 +97,9 @@
<li>JDK 版本要求升级到 21 及以上。</li>
<li>前端解析链路升级PDF、ODF、3D 模型。</li>
<li>后端异步转换升级PDF、TIF、视频、CAD。</li>
<li>启动脚本改为自动发现当前发布包中的 jar并同步更新 Docker 与发布辅助文档。</li>
<li>默认配置策略调整Office 预览默认使用 PDF 模式,默认隐藏图片/PDF 模式切换按钮;如需保留旧的图片优先体验,请显式设置 <code>office.preview.type=image</code> 与 <code>office.preview.switch.disabled=false</code>。</li>
<li>信任域名配置匹配策略扩展:<code>trust.host</code> 及相关规则支持通配符与 CIDR 匹配;升级后请重新核对白名单和黑名单的匹配范围。</li>
</ul>
</div>
</div>