如果你这周(或这个迭代)已经在鸿蒙工程里接过 @wps/wps_sdk,能力清单大概不会陌生:registerApp、OpenFileRequest、水印、extraOptions、关闭回传。真正容易乱的是「每个页面各加一点」,最后变成多份 Helper。本文按调用顺序做一份能力周回顾:哪些必须做、哪些可选项、怎么收到一套 Facade。阅读建议:已跑通至少一次打开文档。
专业版(ToB)与个人版(ToC)共用同一套 API 设计;差异落在 HAR、凭据、是否 setWpsFileToken、少数字段是否生效。判断可用 SdkConstants.isPersonalSdk(),但业务页尽量不要散落版本分支。
回顾地图:五个能力层
| 层 | 关键词 | 验收信号 |
|---|---|---|
| 接入 | HAR、appKey、appSecret、bundleName | 注册 OK,无 1013 |
| 激活 | setWpsFileToken(按约定) |
专业版打开前已注入 |
| 打开 | 沙箱路径、enableEdit |
只读 / 可编辑符合入口 |
| 策略 | 水印、修订、extraOptions、落地相关 |
显式赋值才生效 |
| 结果 | wpsTransferType、Result.data |
关窗后业务能拿到文件 |
统一版的价值是接口统一 ,不是抹掉交付差异。周回顾时问自己:工程里是否仍只有一处构造 OpenFileRequest?
接入层:换包与凭据仍是高频坑
json5
{
"dependencies": {
"@wps/wps_sdk": "file:./libs/wps_sdk.har"
}
}
操作习惯:替换 HAR → ohpm install → 工程 clean → 用正式包包名再验注册。混用凭据或包名漂移,典型现象是调试包正常、Release 才 1013。激活序列号与 SDK 凭据渠道不同,专业版不要假设「有 key 就够」。
typescript
import {
WPSApi,
Result,
ResultCode,
SdkConstants,
} from '@wps/wps_sdk';
function prepare(key: string, secret: string, proSn?: string): Promise<void> {
return new Promise((resolve, reject) => {
WPSApi.registerApp(key, secret, {
onCallback: (result: Result): void => {
if (result.code !== ResultCode.OK) {
reject(new Error(`${result.code}:${result.msg ?? ''}`));
return;
}
if (!SdkConstants.isPersonalSdk() && proSn) {
WPSApi.setWpsFileToken(proSn);
}
resolve();
},
});
});
}
个人版注册成功即可打开;专业版在成功回调里设 token。全局设置与 request.wpsToken 同时存在时以全局为准------周复盘时搜全仓删掉逐次赋值。
打开与策略:别再复制第三套 Helper
typescript
import { common } from '@kit.AbilityKit';
import fs from '@ohos.file.fs';
import {
WPSApi,
OpenFileRequest,
Result,
TransferType,
OpenFileExtraOptions,
WaterMark,
} from '@wps/wps_sdk';
export class WeekRecapClient {
private ready = false;
async ensure(key: string, secret: string, sn?: string): Promise<void> {
if (this.ready) return;
await prepare(key, secret, sn);
this.ready = true;
}
async open(
ctx: common.UIAbilityContext,
src: string,
opts: {
edit?: boolean;
transfer?: boolean;
watermarkText?: string;
extra?: OpenFileExtraOptions;
}
): Promise<Result> {
if (!this.ready) throw new Error('call ensure first');
const dir = `${ctx.filesDir}/wps_recap`;
fs.mkdirSync(dir, true);
const dest = `${dir}/${Date.now()}.docx`;
fs.copyFileSync(src, dest);
const req = new OpenFileRequest(ctx, dest);
req.enableEdit = !!opts.edit;
if (opts.transfer) {
req.wpsTransferType = TransferType.TRANSFER_TYPE_URI;
}
if (opts.watermarkText) {
const mark = new WaterMark();
mark.text = opts.watermarkText;
mark.fontSize = 24;
req.wpsWaterMarkParams = mark;
}
if (opts.extra) {
req.extraOptions = opts.extra;
}
return WPSApi.sendRequest(req);
}
}
联调顺序建议固定:注册 → 只读 → 可编辑 → 水印 → extraOptions → 回传。enableLocalization 等落地相关字段仅在对应交付形态下改变行为;方案评审先确认约定,再测菜单是否被强制关闭。
回传与周复盘清单
关窗回传打开后,务必在 UI 层处理 Result.data(URI 或 FD 字段不同)。未注册就 sendRequest 会抛异常------这是统一约束,不是「本周新 bug」。
清单(可贴进 PR 模板):
- 正式包
bundleName与申请一致 - Facade 外无第二份
new OpenFileRequest - 无逐次
wpsToken - 预览/编辑共用打开函数
- 回传路径在真机关窗验证过
- Release 不打印完整 secret
工程债怎么消化
周回顾最怕只贴一张能力表。更有效的做法是:把表映射到仓库里的真实符号------prepare、open、是否还有第二份 Helper、Release 日志是否泄露 secret。你可以用 IDE 全局搜索 new OpenFileRequest 与 wpsToken,把命中列表贴进周会;命中数下降,比「感觉改完了」更可靠。
多 flavor 时,构建变体分别注入 APP_KEY、APP_SECRET、可选 PRO_SN,运行时共用同一客户端类。UI 文案可以区分场景,但不要分叉构造路径。回归用例复用「注册成功 / 沙箱只读 / 可编辑 / 回传」骨架,再按交付形态增量覆盖不落地或菜单强制关闭。水印、修订、extraOptions 若原先散落在页面按钮回调里,复盘窗口正好收进 Facade 的可选参数,避免统一版之后继续长出第三套打开路径。正式包至少验证一次关窗回传,确认 Result.data 仍按预期返回。
若同一 App 服务不同客户交付,售前仍按合规与授权选择客户端;开发侧则坚持一套 WeekRecapClient。把 Facade 用法写进 README 两三句话,比口头交接更不容易回退到旧写法。合入前再核对对接文档版本号与当前 HAR 说明,避免示例与交付包行为不一致。也可以把「注册成功 / 沙箱只读 / 可编辑 / 回传」四条用例写进 instrumented test 或手工用例表,每次升级 HAR 后回归一遍,避免小版本变更导致 msg 文案变化而 UI 映射过时。对驻场项目,还可把典型 ERROR 的 msg 整理成内部 wiki,缩短新人上手时间。这样联调时间能从「猜原因」缩短为「对表排查」,上线后工单量也会明显下降。把周复盘结论沉淀进 PR 模板后,下一迭代加字段时成本会明显下降,团队也不容易再复制出第三套打开路径。
小结
周回顾不是写宣传稿,而是把散落能力收回同一调用面:一套 Facade、按层叠加、凭据与 HAR 对齐。统一版降低的是接口学习成本;工程债仍要靠封装纪律消化。更多参数见官方对接文档;申请 HAR 与凭据可联系 m_open_sdk@wps.cn。把本周复盘结论记进 PR 模板后,下一迭代加字段时成本会明显下降。
技术交流 QQ 群:628436767
本文基于 WPS Open SDK 鸿蒙版官方对接实践整理,仅供开发者参考。 官方对接文档:365.kdocs.cn/l/clQl5cek2...