在 fileId 不变的情况下,让 WPS 重新从服务器获取文件。
通过后端的文件信息接口返回不同的版本号,让 WPS 判断文件已更新,从而重新下载。
WPS 通过以下字段判断是否需要重新下载文件:
如果这些字段发生变化,WPS 会重新下载文件。
用户打开文档:
↓
WPS 调用:GET /v1/3rd/file/info?_w_fileid=28
↓
后端返回:
{
"file": {
"id": "28",
"name": "文档.pdf",
"version": 1, // ← 版本号
"modify_time": 1735545600000,
"size": 1024000
}
}
↓
WPS 检查缓存:
- 缓存中的版本号是 1
- 服务器返回的版本号是 1
- 版本号相同,使用缓存 ✅
用户点击"结束编辑":
↓
前端调用:PUT /wps/callback/v3/3rd/file/28/version
↓
后端更新版本号:version = 2
↓
销毁 WPS 实例
用户重新打开文档:
↓
WPS 调用:GET /v1/3rd/file/info?_w_fileid=28
↓
后端返回:
{
"file": {
"id": "28",
"name": "文档.pdf",
"version": 2, // ← 版本号已更新
"modify_time": 1735545700000,
"size": 1024000
}
}
↓
WPS 检查缓存:
- 缓存中的版本号是 1
- 服务器返回的版本号是 2
- 版本号不同,重新下载 ✅
文件:src/api/system/signature.ts
/**
* 通知后端更新文档版本(用于强制 WPS 刷新)
* @param documentId 文档 ID
*/
export function updateDocumentVersion(documentId: number | string): AxiosPromise<any> {
return request({
url: `/wps/callback/v3/3rd/file/${documentId}/version`,
method: 'put'
});
}
文件:src/components/DocumentAuditDialog/index.vue
const handleEndEdit = async () => {
// ... 确认对话框 ...
try {
// 1. 调用 WPS SDK 的销毁方法
if (wpsInstance.destroy) {
await wpsInstance.destroy();
}
// 2. 通知后端更新文档版本
try {
await updateDocumentVersion(props.document.id);
console.log('[WPS] 文档版本已更新');
} catch (versionErr) {
console.warn('[WPS] 更新文档版本失败(不影响主流程):', versionErr);
}
// 3. 清空实例
wpsInstance = null;
// 4. 显示成功提示并关闭对话框
ElMessage.success('编辑已结束,文档已销毁');
setTimeout(() => {
dialogVisible.value = false;
}, 1000);
} catch (err) {
// 错误处理...
}
};
需要在文档表中添加版本号字段:
ALTER TABLE document ADD COLUMN version INT DEFAULT 1;
或者使用修改时间:
ALTER TABLE document ADD COLUMN modify_time BIGINT;
接口地址:PUT /wps/callback/v3/3rd/file/{documentId}/version
功能:更新文档版本号
实现示例:
@PutMapping("/wps/callback/v3/3rd/file/{documentId}/version")
public R<Void> updateDocumentVersion(@PathVariable Long documentId) {
// 1. 获取文档
Document doc = documentService.getById(documentId);
if (doc == null) {
return R.fail("文档不存在");
}
// 2. 更新版本号
doc.setVersion(doc.getVersion() + 1);
doc.setModifyTime(System.currentTimeMillis());
documentService.updateById(doc);
log.info("文档版本已更新: id={}, version={}", documentId, doc.getVersion());
return R.ok();
}
接口地址:GET /v1/3rd/file/info
修改:返回版本号和修改时间
实现示例:
@GetMapping("/v1/3rd/file/info")
public R<FileInfo> getFileInfo(@RequestParam("_w_fileid") String fileId) {
// 1. 获取文档
Document doc = documentService.getById(fileId);
if (doc == null) {
return R.fail("文档不存在");
}
// 2. 构建文件信息
FileInfo fileInfo = new FileInfo();
fileInfo.setId(doc.getId().toString());
fileInfo.setName(doc.getFileName());
fileInfo.setVersion(doc.getVersion()); // ← 版本号
fileInfo.setModifyTime(doc.getModifyTime()); // ← 修改时间
fileInfo.setSize(doc.getFileSize());
fileInfo.setDownloadUrl(buildDownloadUrl(doc.getOssId()));
return R.ok(fileInfo);
}
返回格式:
{
"code": 200,
"msg": "success",
"data": {
"file": {
"id": "28",
"name": "文档.pdf",
"version": 2,
"modify_time": 1735545700000,
"size": 1024000,
"download_url": "http://your-server.com/resource/oss/downloadWithoutPermission/123"
}
}
}
1. 用户打开文档
↓
2. WPS 调用:GET /v1/3rd/file/info?_w_fileid=28
↓
3. 后端返回:version=1, modify_time=1735545600000
↓
4. WPS 缓存中没有该文档
↓
5. WPS 下载文件:GET /resource/oss/downloadWithoutPermission/123
↓
6. WPS 缓存文件(version=1)
↓
7. 显示文档
1. 用户点击"结束编辑"
↓
2. 前端调用:wpsInstance.destroy()
↓
3. 前端调用:PUT /wps/callback/v3/3rd/file/28/version
↓
4. 后端更新:version=2, modify_time=1735545700000
↓
5. 前端清空实例:wpsInstance = null
↓
6. 关闭对话框
1. 用户重新打开文档
↓
2. WPS 调用:GET /v1/3rd/file/info?_w_fileid=28
↓
3. 后端返回:version=2, modify_time=1735545700000
↓
4. WPS 检查缓存:
- 缓存版本:version=1
- 服务器版本:version=2
- 版本不同!
↓
5. WPS 重新下载文件:GET /resource/oss/downloadWithoutPermission/123
↓
6. WPS 更新缓存(version=2)
↓
7. 显示最新文档 ✅
// 每次更新时递增
doc.setVersion(doc.getVersion() + 1);
优势:
示例:
初始:version = 1
第一次更新:version = 2
第二次更新:version = 3
// 使用当前时间戳作为版本号
doc.setVersion(System.currentTimeMillis());
优势:
示例:
初始:version = 1735545600000
第一次更新:version = 1735545700000
第二次更新:version = 1735545800000
// 只更新 modify_time,不使用 version
doc.setModifyTime(System.currentTimeMillis());
优势:
注意:
version 和 modify_time[WPS] 开始结束编辑,文档 ID: 28
[WPS] 调用 destroy 方法
[WPS] destroy 方法调用成功
[WPS] 通知后端更新文档版本
[WPS] 文档版本已更新
[WPS] 结束编辑成功
[INFO] 收到更新版本请求: documentId=28
[INFO] 当前版本: 1
[INFO] 更新后版本: 2
[INFO] 文档版本已更新: id=28, version=2
[WPS] 获取文件信息: fileId=28
[WPS] 服务器版本: 2
[WPS] 缓存版本: 1
[WPS] 版本不同,重新下载文件
[WPS] 下载完成,更新缓存
1. 打开文档(version=1)
2. 编辑文档
3. 点击"结束编辑"(version 更新为 2)
4. 重新打开文档
5. 预期:WPS 重新下载文件
1. 打开文档(version=1)
2. 结束编辑(version=2)
3. 重新打开(version=2)
4. 结束编辑(version=3)
5. 重新打开(version=3)
6. 预期:每次都重新下载
1. 打开文档(version=1)
2. 点击"结束编辑"
3. 版本更新接口失败(version 仍为 1)
4. 重新打开文档
5. 预期:WPS 使用缓存(因为版本号未变)
答:让 WPS 知道文件已更新,需要重新下载。
答:不必须,只要每次不同即可。但递增更易于理解和调试。
答:不影响主流程,只是下次打开时 WPS 会使用缓存。
答:可以,调用版本更新接口即可。
答:是的,但这不是问题。可以定期重置或使用时间戳。
答:是的,需要添加 version 字段或使用 modify_time 字段。
updateDocumentVersion APIversion 字段到数据库现在点击"结束编辑"后,重新打开文档时 WPS 会从你的服务器重新获取最新文件!