业务评审里常出现这句话:「打开用一套 API,但预览和编辑要两个入口。」在 HarmonyOS 落地 WPS Open SDK 时,打开能力确实共用 OpenFileRequest + WPSApi.sendRequest,模式差在 enableEdit。本文按产品入口、字段语义、Facade 映射与联调表展开,帮团队把「两个按钮」收成「一个打开函数」,避免两周后再搜出两套构造逻辑。
产品入口不要长成两套 Request
列表「查看」与工具栏「编辑」若各自 new OpenFileRequest,两周后就会出现:一处忘了拷沙箱、一处忘了赋 enableEdit、一处又把水印写死。统一版打开 API 只有一套,分叉应停在参数,而不是停在复制粘贴。
最小验收建议:
- 注册等到
ResultCode.OK - 沙箱路径只读打开成功
- 同一文件再以
enableEdit = true打开 - 再谈水印、
extraOptions、关窗回传
专业版与个人版共用打开 API,差异收在 HAR / 凭据与是否 setWpsFileToken,不要为此复制两套模式逻辑。
字段语义:缺省即只读
对接文档:enableEdit 未设置或 false 为只读;仅 true 可编辑。业务层最稳的写法是永远显式赋值。
typescript
export type OpenMode = 'preview' | 'edit';
function mapEnableEdit(mode: OpenMode): boolean {
return mode === 'edit';
}
不要在页面里写 if (needEdit) req.enableEdit = true 却漏掉 else------漏掉时字段保持未设置,表现仍是只读,和「想编辑却灰掉」高度吻合。
Facade:页面只看见 mode
typescript
import { common } from '@kit.AbilityKit';
import fs from '@ohos.file.fs';
import {
WPSApi,
OpenFileRequest,
Result,
ResultCode,
SdkConstants,
} from '@wps/wps_sdk';
let ready = false;
export function prepareWps(
key: string,
secret: string,
proSn?: string
): Promise<void> {
return new Promise((resolve, reject) => {
if (ready) {
resolve();
return;
}
WPSApi.registerApp(key, secret, {
onCallback: (result: Result): void => {
if (result.code === ResultCode.ERROR_CODE_AUTH_FAILURE) {
reject(new Error(`1013: ${result.msg ?? ''}`));
return;
}
if (result.code !== ResultCode.OK) {
reject(new Error(`register ${result.code}`));
return;
}
if (!SdkConstants.isPersonalSdk() && proSn) {
WPSApi.setWpsFileToken(proSn);
}
ready = true;
resolve();
},
});
});
}
function toSandbox(ctx: common.UIAbilityContext, src: string): string {
const dir = `${ctx.filesDir}/wps_open_mode`;
fs.mkdirSync(dir, true);
const dest = `${dir}/${Date.now()}.docx`;
fs.copyFileSync(src, dest);
return dest;
}
export async function openDoc(
ctx: common.UIAbilityContext,
src: string,
mode: OpenMode
): Promise<Result> {
await prepareWps(APP_KEY, APP_SECRET, PRO_SN_OR_EMPTY);
const path = toSandbox(ctx, src);
const req = new OpenFileRequest(ctx, path);
req.enableEdit = mapEnableEdit(mode);
return WPSApi.sendRequest(req);
}
页面:openDoc(ctx, uri, 'preview') / openDoc(ctx, uri, 'edit')。需要关窗回传时再给 openDoc 增加可选参数,与 mode 独立。未开回传时 OK 且 data 为空属正常。
模式与策略、回传解耦
| 诉求 | 改哪里 |
|---|---|
| 预览 / 编辑 | enableEdit / mode |
| 预览带水印 | 水印参数,仍可只读 |
| 编辑后回传 | wpsTransferType,仍要可编辑 |
| 隐藏部分菜单 | extraOptions,显式赋值 |
一次把模式、水印、回传写满,ResultCode.ERROR 很难归因。联调顺序:注册 → 只读 → 可编辑 → 策略 → 回传。
联调表
| 现象 | 优先查 |
|---|---|
| Promise reject | 是否等 prepareWps |
1013 |
凭据 / 正式包包名 / clean |
| 能开不能改 | enableEdit 是否 true |
| 泛化 ERROR | 是否沙箱路径 |
| OK 但无文件回传 | 是否开了回传 |
日志一行打齐:code / msg / ready / 沙箱 / enableEdit。全仓 new OpenFileRequest 命中应为一。换 HAR 后 clean;Release 不打印完整 secret;不要在 Request 上重复塞 wpsToken。
协作节奏
PR 模板可写:页面不得直接 new OpenFileRequest;预览与编辑必须走同一 openDoc;mode 到 enableEdit 的映射有单测或注释。同一仓库双交付形态时,用 flavor 注入密钥,Facade 保持一份。周五留半小时搜命中数,并用正式包包名跑预览 + 编辑各一次。
把「先只读后可编辑」写进联调清单后,新人合入打开相关改动会稳很多。路径务必先落沙箱;外部 URI 权限不足时常见泛化 ERROR。正式包与调试包包名不同时,凭据批次分开归档。
小结
enableEdit 是 HarmonyOS WPS Open SDK 上预览与编辑的主开关:缺省只读,显式 true 才可编辑。产品两个入口应对齐到一个 Facade 的 mode 参数,而不是两套 Request。策略与回传后叠。字段以官方对接文档为准。技术交流可进 QQ 群对齐实践细节。
接入评审时再确认:HAR 是否与批次一致、沙箱目录是否统一、mode 映射是否显式。缺一环就容易出现「本地绿、上架红」。统一版减少页面层分裂,不会自动完成 URI 到沙箱的拷贝。把 Facade、对照表、PR 模板坚持几周,联调通常会从猜原因变成对表排查。
同一仓库服务双交付形态时,用 flavor 注入 APP_KEY / APP_SECRET / PRO_SN_OR_EMPTY,打开 Facade 保持一份。页面永远只看见 prepare / openDoc(mode)。切换交付形态时,diff 应主要出现在配置,而不是业务页里的 enableEdit 赋值。真机日志固定打 code / msg / ready / isPersonalSdk / 是否沙箱 / enableEdit。策略字段「改了没效果」时,先确认是否显式赋值,再确认当前 HAR 是否允许该能力。
若一周后产品又加「预览也要水印」,仍然只改 openDoc 可选参数,并把联调用例补一行:只读带水印。这样打开阶段立下的 Facade 边界,才不会被临时需求冲垮。路径务必先落沙箱;外部 URI 权限不足时常见泛化 ERROR。正式包与调试包包名不同时,凭据批次分开归档。注释里写清「本项目约定:预览与编辑只走 Facade」,比口头传承更耐看。把这些节奏坚持几周,模式相关误报通常会明显下降。
周五再留半小时:用正式包包名跑一次注册,真机各跑 preview 与 edit,并搜全仓 new OpenFileRequest 与 Request 级 wpsToken。命中数和 1013 有没有复发,比写长周报有用。换 HAR 后 clean;不要在 Release 打印完整 secret。把「先只读再可编辑」写进联调清单后,新人合入打开相关改动会稳很多,打开封装也会从「两处拷贝」收敛到「一处带 mode 的入口」。
阅读建议:已了解鸿蒙 Ability 与 Promise 基础。
官方对接文档:365.kdocs.cn/l/clQl5cek2...
技术交流 QQ 群:628436767