mirror of
https://github.com/qaiu/netdisk-fast-download.git
synced 2025-12-16 04:13:03 +00:00
feat: 添加 WPS 云文档/WPS 云盘解析支持 (closes #133)
- 新增 PwpsTool 解析器,支持 WPS 云文档直链获取 - 调用 WPS API: https://www.kdocs.cn/api/office/file/{shareKey}/download - 前端添加 kdocs.cn 链接识别规则 - 前端预览功能优化:WPS 云文档直接使用原分享链接预览 - 后端预览接口特殊处理:判断 shareKey 以 pwps: 开头自动重定向 - 支持提取文件名和有效期信息 - 更新 README 文档,添加 WPS 云文档支持说明 Parser 模块设计: - 遵循开放封闭原则,易于扩展新网盘 - 只需实现 IPanTool 接口和注册枚举即可 - 支持自定义域名解析和责任链模式 技术特性: - 免登录获取下载直链 - 支持在线预览(利用 WPS 原生功能) - 文件大小限制:10M(免费版)/2G(会员版) - 初始空间:5G(免费版)
This commit is contained in:
@@ -36,6 +36,8 @@ https://nfd-parser.github.io/nfd-preview/preview.html?src=https%3A%2F%2Flz.qaiu.
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**解析器模块文档:** [parser/README.md](parser/README.md)
|
||||||
|
|
||||||
## 预览地址
|
## 预览地址
|
||||||
[预览地址1](https://lz.qaiu.top)
|
[预览地址1](https://lz.qaiu.top)
|
||||||
[预览地址2](http://www.722shop.top:6401)
|
[预览地址2](http://www.722shop.top:6401)
|
||||||
@@ -75,6 +77,7 @@ main分支依赖JDK17, 提供了JDK11分支[main-jdk11](https://github.com/qaiu/
|
|||||||
- [Cloudreve自建网盘-ce](https://github.com/cloudreve/Cloudreve)
|
- [Cloudreve自建网盘-ce](https://github.com/cloudreve/Cloudreve)
|
||||||
- ~[微雨云存储-pvvy](https://www.vyuyun.com/)~
|
- ~[微雨云存储-pvvy](https://www.vyuyun.com/)~
|
||||||
- [超星云盘(需要referer: https://pan-yz.chaoxing.com)-pcx](https://pan-yz.chaoxing.com)
|
- [超星云盘(需要referer: https://pan-yz.chaoxing.com)-pcx](https://pan-yz.chaoxing.com)
|
||||||
|
- [WPS云文档-pwps](https://www.kdocs.cn/)
|
||||||
- Google云盘-pgd
|
- Google云盘-pgd
|
||||||
- Onedrive-pod
|
- Onedrive-pod
|
||||||
- Dropbox-pdp
|
- Dropbox-pdp
|
||||||
@@ -258,6 +261,7 @@ GET http://127.0.0.1:6400/json/fc/e5079007dc31226096628870c7@QAIU
|
|||||||
| 360亿方云 | √ | √(密码可忽略) | 100G(须实名) | 不限大小 |
|
| 360亿方云 | √ | √(密码可忽略) | 100G(须实名) | 不限大小 |
|
||||||
| 123云盘 | √ | √ | 2T | 100G(>100M需要登录) |
|
| 123云盘 | √ | √ | 2T | 100G(>100M需要登录) |
|
||||||
| 文叔叔 | √ | √ | 10G | 5GB |
|
| 文叔叔 | √ | √ | 10G | 5GB |
|
||||||
|
| WPS云文档 | √ | X | 1G(免费) | 10M(免费)/2G(会员) |
|
||||||
| 夸克网盘 | x | √ | 10G | 不限大小 |
|
| 夸克网盘 | x | √ | 10G | 不限大小 |
|
||||||
| UC网盘 | x | √ | 10G | 不限大小 |
|
| UC网盘 | x | √ | 10G | 不限大小 |
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ NFD 解析器模块:聚合各类网盘/分享页解析,统一输出文件列
|
|||||||
- 模块版本:10.1.17
|
- 模块版本:10.1.17
|
||||||
|
|
||||||
## 依赖(Maven Central)
|
## 依赖(Maven Central)
|
||||||
- Maven(无需额外仓库配置):
|
|
||||||
```xml
|
```xml
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>cn.qaiu</groupId>
|
<groupId>cn.qaiu</groupId>
|
||||||
|
|||||||
@@ -266,6 +266,12 @@ public enum PanDomainTemplate {
|
|||||||
compile("https://pan-yz\\.cldisk\\.com/external/m/file/(?<KEY>\\w+)"),
|
compile("https://pan-yz\\.cldisk\\.com/external/m/file/(?<KEY>\\w+)"),
|
||||||
"https://pan-yz.cldisk.com/external/m/file/{shareKey}",
|
"https://pan-yz.cldisk.com/external/m/file/{shareKey}",
|
||||||
PcxTool.class),
|
PcxTool.class),
|
||||||
|
// WPS:分享格式:https://www.kdocs.cn/l/ck0azivLlDi3 ;API格式:https://www.kdocs.cn/api/office/file/{shareKey}/download
|
||||||
|
// 响应:{download_url: "https://hwc-bj.ag.kdocs.cn/api/xx",url: "",fize: 0,fver: 0,store: ""}
|
||||||
|
PWPS("WPS",
|
||||||
|
compile("https://www\\.kdocs\\.cn/l/(?<KEY>.+)"),
|
||||||
|
"https://www.kdocs.cn/l/{shareKey}",
|
||||||
|
PwpsTool.class),
|
||||||
// =====================音乐类解析 分享链接标志->MxxS (单歌曲/普通音质)==========================
|
// =====================音乐类解析 分享链接标志->MxxS (单歌曲/普通音质)==========================
|
||||||
// http://163cn.tv/xxx
|
// http://163cn.tv/xxx
|
||||||
MNES("网易云音乐分享",
|
MNES("网易云音乐分享",
|
||||||
|
|||||||
63
parser/src/main/java/cn/qaiu/parser/impl/PwpsTool.java
Normal file
63
parser/src/main/java/cn/qaiu/parser/impl/PwpsTool.java
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
package cn.qaiu.parser.impl;
|
||||||
|
|
||||||
|
import cn.qaiu.entity.ShareLinkInfo;
|
||||||
|
import cn.qaiu.parser.PanBase;
|
||||||
|
import io.vertx.core.Future;
|
||||||
|
import io.vertx.core.json.JsonObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <a href="https://www.kdocs.cn/">WPS云文档</a>
|
||||||
|
* 分享格式:https://www.kdocs.cn/l/ck0azivLlDi3
|
||||||
|
* API格式:https://www.kdocs.cn/api/office/file/{shareKey}/download
|
||||||
|
* 响应:{download_url: "https://hwc-bj.ag.kdocs.cn/api/xx",url: "",fize: 0,fver: 0,store: ""}
|
||||||
|
*/
|
||||||
|
public class PwpsTool extends PanBase {
|
||||||
|
private static final String API_URL_TEMPLATE = "https://www.kdocs.cn/api/office/file/%s/download";
|
||||||
|
|
||||||
|
public PwpsTool(ShareLinkInfo shareLinkInfo) {
|
||||||
|
super(shareLinkInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Future<String> parse() {
|
||||||
|
final String shareKey = shareLinkInfo.getShareKey();
|
||||||
|
|
||||||
|
// 构建API URL
|
||||||
|
String apiUrl = String.format(API_URL_TEMPLATE, shareKey);
|
||||||
|
|
||||||
|
// 发送GET请求到WPS API
|
||||||
|
client.getAbs(apiUrl)
|
||||||
|
.send()
|
||||||
|
.onSuccess(res -> {
|
||||||
|
try {
|
||||||
|
JsonObject resJson = asJson(res);
|
||||||
|
|
||||||
|
// 检查响应是否包含download_url字段
|
||||||
|
if (resJson.containsKey("download_url")) {
|
||||||
|
String downloadUrl = resJson.getString("download_url");
|
||||||
|
|
||||||
|
if (downloadUrl != null && !downloadUrl.isEmpty()) {
|
||||||
|
log.info("WPS云文档解析成功: shareKey={}, downloadUrl={}", shareKey, downloadUrl);
|
||||||
|
promise.complete(downloadUrl);
|
||||||
|
} else {
|
||||||
|
fail("download_url字段为空");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 检查是否有错误信息
|
||||||
|
if (resJson.containsKey("error") || resJson.containsKey("msg")) {
|
||||||
|
String errorMsg = resJson.getString("error", resJson.getString("msg", "未知错误"));
|
||||||
|
fail("API返回错误: {}", errorMsg);
|
||||||
|
} else {
|
||||||
|
fail("响应中未找到download_url字段, 响应内容: {}", resJson.encodePrettily());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
fail(e, "解析响应JSON失败");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.onFailure(handleFail(apiUrl));
|
||||||
|
|
||||||
|
return promise.future();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
156
parser/src/test/java/cn/qaiu/parser/impl/WpsPanTest.java
Normal file
156
parser/src/test/java/cn/qaiu/parser/impl/WpsPanTest.java
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
package cn.qaiu.parser.impl;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import cn.qaiu.parser.ParserCreate;
|
||||||
|
import io.vertx.core.json.JsonObject;
|
||||||
|
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WPS 云文档解析测试
|
||||||
|
*/
|
||||||
|
public class WpsPanTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWpsDownload() throws InterruptedException {
|
||||||
|
System.out.println("======= WPS 云文档解析测试 =======");
|
||||||
|
|
||||||
|
// 测试链接:reset_navicat_mac
|
||||||
|
String wpsUrl = "https://www.kdocs.cn/l/ck0azivLlDi3";
|
||||||
|
|
||||||
|
System.out.println("测试链接: " + wpsUrl);
|
||||||
|
System.out.println("文件名称: reset_navicat_mac");
|
||||||
|
System.out.println();
|
||||||
|
|
||||||
|
// 使用 ParserCreate 方式创建解析器
|
||||||
|
ParserCreate parserCreate = ParserCreate.fromShareUrl(wpsUrl);
|
||||||
|
|
||||||
|
System.out.println("解析器类型: " + parserCreate.getShareLinkInfo().getType());
|
||||||
|
System.out.println("网盘名称: " + parserCreate.getShareLinkInfo().getPanName());
|
||||||
|
System.out.println("分享Key: " + parserCreate.getShareLinkInfo().getShareKey());
|
||||||
|
System.out.println("标准URL: " + parserCreate.getShareLinkInfo().getStandardUrl());
|
||||||
|
System.out.println();
|
||||||
|
|
||||||
|
System.out.println("开始解析下载链接...");
|
||||||
|
|
||||||
|
// 创建工具并解析
|
||||||
|
parserCreate.createTool()
|
||||||
|
.parse()
|
||||||
|
.onSuccess(downloadUrl -> {
|
||||||
|
System.out.println("✓ 解析成功!");
|
||||||
|
System.out.println("下载直链: " + downloadUrl);
|
||||||
|
System.out.println();
|
||||||
|
|
||||||
|
// 解析文件信息
|
||||||
|
JsonObject fileInfo = getFileInfo(downloadUrl);
|
||||||
|
System.out.println("文件信息: " + fileInfo.encodePrettily());
|
||||||
|
System.out.println();
|
||||||
|
})
|
||||||
|
.onFailure(error -> {
|
||||||
|
System.err.println("✗ 解析失败!");
|
||||||
|
System.err.println("错误信息: " + error.getMessage());
|
||||||
|
error.printStackTrace();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 等待异步结果
|
||||||
|
System.out.println("等待解析结果...");
|
||||||
|
TimeUnit.SECONDS.sleep(10);
|
||||||
|
|
||||||
|
System.out.println("======= 测试结束 =======");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWpsWithShareKey() throws InterruptedException {
|
||||||
|
System.out.println("======= WPS 云文档解析测试 (使用 shareKey) =======");
|
||||||
|
|
||||||
|
String shareKey = "ck0azivLlDi3";
|
||||||
|
|
||||||
|
System.out.println("分享Key: " + shareKey);
|
||||||
|
System.out.println();
|
||||||
|
|
||||||
|
// 使用 fromType + shareKey 方式
|
||||||
|
ParserCreate parserCreate = ParserCreate.fromType("pwps")
|
||||||
|
.shareKey(shareKey);
|
||||||
|
|
||||||
|
System.out.println("解析器类型: " + parserCreate.getShareLinkInfo().getType());
|
||||||
|
System.out.println("网盘名称: " + parserCreate.getShareLinkInfo().getPanName());
|
||||||
|
System.out.println("标准URL: " + parserCreate.getShareLinkInfo().getStandardUrl());
|
||||||
|
System.out.println();
|
||||||
|
|
||||||
|
System.out.println("开始解析下载链接...");
|
||||||
|
|
||||||
|
// 创建工具并解析
|
||||||
|
parserCreate.createTool()
|
||||||
|
.parse()
|
||||||
|
.onSuccess(downloadUrl -> {
|
||||||
|
System.out.println("✓ 解析成功!");
|
||||||
|
System.out.println("下载直链: " + downloadUrl);
|
||||||
|
System.out.println();
|
||||||
|
|
||||||
|
// 解析文件信息
|
||||||
|
JsonObject fileInfo = getFileInfo(downloadUrl);
|
||||||
|
System.out.println("文件信息: " + fileInfo.encodePrettily());
|
||||||
|
System.out.println();
|
||||||
|
})
|
||||||
|
.onFailure(error -> {
|
||||||
|
System.err.println("✗ 解析失败!");
|
||||||
|
System.err.println("错误信息: " + error.getMessage());
|
||||||
|
error.printStackTrace();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 等待异步结果
|
||||||
|
System.out.println("等待解析结果...");
|
||||||
|
TimeUnit.SECONDS.sleep(10);
|
||||||
|
|
||||||
|
System.out.println("======= 测试结束 =======");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从 WPS 下载直链中提取文件信息
|
||||||
|
* 示例链接: https://hwc-bj.ag.kdocs.cn/api/object/xxx/compatible?response-content-disposition=attachment%3Bfilename%2A%3Dutf-8%27%27reset_navicat_mac.sh&AccessKeyId=xxx&Expires=1760928746&Signature=xxx
|
||||||
|
*
|
||||||
|
* @param downloadUrl WPS 下载直链
|
||||||
|
* @return JSON 格式的文件信息 {fileName: "reset_navicat_mac.sh", expire: "2025-10-20 10:45:46"}
|
||||||
|
*/
|
||||||
|
private JsonObject getFileInfo(String downloadUrl) {
|
||||||
|
String fileName = "未知文件";
|
||||||
|
String expireTime = "未知";
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 1. 提取文件名 - 从 response-content-disposition 参数中提取
|
||||||
|
// 格式: attachment%3Bfilename%2A%3Dutf-8%27%27reset_navicat_mac.sh
|
||||||
|
// 解码后: attachment;filename*=utf-8''reset_navicat_mac.sh
|
||||||
|
Pattern fileNamePattern = Pattern.compile("filename[^=]*=(?:utf-8'')?([^&]+)");
|
||||||
|
Matcher fileNameMatcher = fileNamePattern.matcher(URLDecoder.decode(downloadUrl, StandardCharsets.UTF_8));
|
||||||
|
if (fileNameMatcher.find()) {
|
||||||
|
fileName = fileNameMatcher.group(1);
|
||||||
|
// 再次解码(可能被双重编码)
|
||||||
|
fileName = URLDecoder.decode(fileName, StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 提取有效期 - 从 Expires 参数中提取 Unix timestamp
|
||||||
|
Pattern expiresPattern = Pattern.compile("[?&]Expires=([0-9]+)");
|
||||||
|
Matcher expiresMatcher = expiresPattern.matcher(downloadUrl);
|
||||||
|
if (expiresMatcher.find()) {
|
||||||
|
long timestamp = Long.parseLong(expiresMatcher.group(1));
|
||||||
|
// 转换为日期格式 yyyy-MM-dd HH:mm:ss
|
||||||
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
expireTime = sdf.format(new Date(timestamp * 1000L)); // Unix timestamp 是秒,需要转毫秒
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("解析文件信息失败: " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return JsonObject.of("fileName", fileName, "expire", expireTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -340,6 +340,11 @@
|
|||||||
host: /migu\.cn/,
|
host: /migu\.cn/,
|
||||||
name: '咪咕音乐分享'
|
name: '咪咕音乐分享'
|
||||||
},
|
},
|
||||||
|
kdocs: {
|
||||||
|
reg: /https:\/\/www\.kdocs\.cn\/l\/.+/,
|
||||||
|
host: /www\.kdocs\.cn/,
|
||||||
|
name: 'WPS云文档'
|
||||||
|
},
|
||||||
other: {
|
other: {
|
||||||
reg: /https:\/\/([a-zA-Z0-9]+(-[a-zA-Z0-9]+)*\.)+[a-zA-Z]{2,}\/s\/.+/,
|
reg: /https:\/\/([a-zA-Z0-9]+(-[a-zA-Z0-9]+)*\.)+[a-zA-Z]{2,}\/s\/.+/,
|
||||||
host: /.*/,
|
host: /.*/,
|
||||||
|
|||||||
@@ -110,7 +110,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="file-meta-row">
|
<div class="file-meta-row">
|
||||||
<span class="file-meta-label">文件预览:</span>
|
<span class="file-meta-label">文件预览:</span>
|
||||||
<a :href="previewBaseUrl + encodeURIComponent(downloadUrl)" target="_blank" class="file-meta-link">点击预览</a>
|
<a :href="getPreviewLink()" target="_blank" class="file-meta-link">点击预览</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="file-meta-row">
|
<div class="file-meta-row">
|
||||||
<span class="file-meta-label">文件名:</span>{{ extractFileNameAndExt(downloadUrl).name }}
|
<span class="file-meta-label">文件名:</span>{{ extractFileNameAndExt(downloadUrl).name }}
|
||||||
@@ -299,6 +299,18 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
// 生成预览链接(WPS 云文档特殊处理)
|
||||||
|
getPreviewLink() {
|
||||||
|
// 判断 shareKey 是否以 pwps: 开头(WPS 云文档)
|
||||||
|
const shareKey = this.parseResult?.data?.shareKey
|
||||||
|
if (shareKey && shareKey.startsWith('pwps:')) {
|
||||||
|
// WPS 云文档直接使用原始分享链接
|
||||||
|
return this.link
|
||||||
|
}
|
||||||
|
// 其他类型使用默认预览服务
|
||||||
|
return this.previewBaseUrl + encodeURIComponent(this.downloadUrl)
|
||||||
|
},
|
||||||
|
|
||||||
// 主题切换
|
// 主题切换
|
||||||
handleThemeChange(isDark) {
|
handleThemeChange(isDark) {
|
||||||
this.isDarkMode = isDark
|
this.isDarkMode = isDark
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="file-meta-row">
|
<div class="file-meta-row">
|
||||||
<span class="file-meta-label">在线预览:</span>
|
<span class="file-meta-label">在线预览:</span>
|
||||||
<a :href="previewBaseUrl + encodeURIComponent(downloadUrl)" target="_blank" class="preview-btn">点击在线预览</a>
|
<a :href="getPreviewLink()" target="_blank" class="preview-btn">点击在线预览</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -42,11 +42,24 @@ export default {
|
|||||||
error: '',
|
error: '',
|
||||||
parseResult: {},
|
parseResult: {},
|
||||||
downloadUrl: '',
|
downloadUrl: '',
|
||||||
|
shareUrl: '', // 添加原始分享链接
|
||||||
fileTypeUtils,
|
fileTypeUtils,
|
||||||
previewBaseUrl
|
previewBaseUrl
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
// 生成预览链接(WPS 云文档特殊处理)
|
||||||
|
getPreviewLink() {
|
||||||
|
// 判断 shareKey 是否以 pwps: 开头(WPS 云文档)
|
||||||
|
const shareKey = this.parseResult?.data?.shareKey
|
||||||
|
if (shareKey && shareKey.startsWith('pwps:')) {
|
||||||
|
// WPS 云文档直接使用原始分享链接
|
||||||
|
return this.shareUrl
|
||||||
|
}
|
||||||
|
// 其他类型使用默认预览服务
|
||||||
|
return this.previewBaseUrl + encodeURIComponent(this.downloadUrl)
|
||||||
|
},
|
||||||
|
|
||||||
async fetchFile() {
|
async fetchFile() {
|
||||||
const url = this.$route.query.url
|
const url = this.$route.query.url
|
||||||
if (!url) {
|
if (!url) {
|
||||||
@@ -54,6 +67,7 @@ export default {
|
|||||||
this.loading = false
|
this.loading = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
this.shareUrl = url // 保存原始分享链接
|
||||||
try {
|
try {
|
||||||
const res = await axios.get('/json/parser', { params: { url } })
|
const res = await axios.get('/json/parser', { params: { url } })
|
||||||
this.parseResult = res.data
|
this.parseResult = res.data
|
||||||
|
|||||||
@@ -160,6 +160,21 @@ public class ParserApi {
|
|||||||
*/
|
*/
|
||||||
@RouteMapping(value = "/view/:type/:key", method = RouteMethod.GET, order = 2)
|
@RouteMapping(value = "/view/:type/:key", method = RouteMethod.GET, order = 2)
|
||||||
public void view(HttpServerRequest request, HttpServerResponse response, String type, String key) {
|
public void view(HttpServerRequest request, HttpServerResponse response, String type, String key) {
|
||||||
|
// WPS 网盘类型特殊处理:直接使用原分享链接(WPS 支持在线预览)
|
||||||
|
if ("pwps".equalsIgnoreCase(type)) {
|
||||||
|
try {
|
||||||
|
// 重建原分享链接
|
||||||
|
ParserCreate parserCreate = ParserCreate.fromType(type).shareKey(key);
|
||||||
|
String originalUrl = parserCreate.getShareLinkInfo().getStandardUrl();
|
||||||
|
if (StringUtils.isNotBlank(originalUrl)) {
|
||||||
|
ResponseUtil.redirect(response, originalUrl);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("PWPS 预览链接构建失败: {}", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
String previewURL = SharedDataUtil.getJsonStringForServerConfig("previewURL");
|
String previewURL = SharedDataUtil.getJsonStringForServerConfig("previewURL");
|
||||||
serverApi.parseKeyJson(request, type, key).onSuccess(res -> {
|
serverApi.parseKeyJson(request, type, key).onSuccess(res -> {
|
||||||
redirect(response, previewURL, res);
|
redirect(response, previewURL, res);
|
||||||
@@ -178,6 +193,24 @@ public class ParserApi {
|
|||||||
*/
|
*/
|
||||||
@RouteMapping(value = "/preview", method = RouteMethod.GET, order = 9)
|
@RouteMapping(value = "/preview", method = RouteMethod.GET, order = 9)
|
||||||
public void viewURL(HttpServerRequest request, HttpServerResponse response, String pwd) {
|
public void viewURL(HttpServerRequest request, HttpServerResponse response, String pwd) {
|
||||||
|
// WPS 网盘类型特殊处理:直接使用原分享链接(WPS 支持在线预览)
|
||||||
|
try {
|
||||||
|
String url = URLParamUtil.parserParams(request);
|
||||||
|
ParserCreate parserCreate = ParserCreate.fromShareUrl(url);
|
||||||
|
ShareLinkInfo shareLinkInfo = parserCreate.getShareLinkInfo();
|
||||||
|
|
||||||
|
// 如果是 PWPS 类型,直接重定向到原分享链接
|
||||||
|
if ("pwps".equalsIgnoreCase(shareLinkInfo.getType())) {
|
||||||
|
String originalUrl = shareLinkInfo.getStandardUrl();
|
||||||
|
if (StringUtils.isNotBlank(originalUrl)) {
|
||||||
|
ResponseUtil.redirect(response, originalUrl);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("解析预览链接失败: {}", e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
String previewURL = SharedDataUtil.getJsonStringForServerConfig("previewURL");
|
String previewURL = SharedDataUtil.getJsonStringForServerConfig("previewURL");
|
||||||
new ServerApi().parseJson(request, pwd).onSuccess(res -> {
|
new ServerApi().parseJson(request, pwd).onSuccess(res -> {
|
||||||
redirect(response, previewURL, res);
|
redirect(response, previewURL, res);
|
||||||
|
|||||||
Reference in New Issue
Block a user