在鸿蒙应用里嵌文档能力,团队往往先做「能打开」,再做「能改」。下一步产品常见诉求是:预览页必须带水印,或协作场景必须以修订模式进入。WPS Open SDK(@wps/wps_sdk)没有拆出独立的「加水印 API」:水印与修订都挂在同一次 OpenFileRequest 上,分别是 wpsWaterMarkParams(WaterMark)与 wpsRevisionParams(Revision)。本文从工程封装、策略与模式解耦、联调顺序写清楚,避免把策略问题和鉴权、路径混在一起排。
阅读建议:已了解鸿蒙 Ability 生命周期,并完成过一次 HAR 集成与只读打开。
为什么策略要独立成层
统一版把打开收成一套 API,页面却常复制多份构造逻辑:一份写预览,一份写编辑,一份临时加了水印却漏了 Enable。Code Review 若只看有没有 sendRequest,发现不了布尔默认值与对象是否挂上 Request。把模式(enableEdit)与策略(水印 / 修订)收进单一 helper,比事后对日志更省时间。
调用链仍是:
go
HAR → registerApp OK → (可选) setWpsFileToken → sandbox copy
→ OpenFileRequest → enableEdit → WaterMark/Revision → sendRequest
1013 停在注册层;路径权限问题多表现为泛化 ERROR;策略问题表现为「打得开但看不见水印 / 进不了修订」。三类现象不要共用同一段重试逻辑。
语义对照(可贴进工程注释)
| 策略对象 | 关键开关 | 关键内容 | 与模式关系 |
|---|---|---|---|
WaterMark |
Enable = true |
WaterMaskText 非空 |
可与只读叠加 |
Revision |
EnterReviseMode = true |
UserName 有业务意义 |
通常需 enableEdit = true |
WaterMark 还可配 Angle、FontColor(含透明度)、FontSize。Revision 还可配 ShowRevisionPanel、EnterRevisionSilent。未开回传时 OK + 空 data 是正常拉起,不是「保存失败」。序列号仍走注册成功后的 setWpsFileToken,不要写回 request.wpsToken。SdkConstants.isPersonalSdk() 只决定要不要注入 SN,不改变水印 / 修订字段语义。
封装示例
typescript
import { common } from '@kit.AbilityKit';
import {
WPSApi,
OpenFileRequest,
Result,
ResultCode,
WaterMark,
Revision,
SdkConstants,
} from '@wps/wps_sdk';
let sdkReady = false;
export function startWps(appKey: string, appSecret: string, proSn?: string): void {
WPSApi.registerApp(appKey, appSecret, {
onCallback: (r: Result) => {
if (r.code !== ResultCode.OK) {
console.error('[WPS] register', r.code, r.msg);
return;
}
if (!SdkConstants.isPersonalSdk() && proSn) {
WPSApi.setWpsFileToken(proSn);
}
sdkReady = true;
},
});
}
function attachWatermark(req: OpenFileRequest, text: string): void {
const wm = new WaterMark();
wm.Enable = true;
wm.WaterMaskText = text;
wm.Angle = -30;
wm.FontColor = '#19000000';
wm.FontSize = 24;
req.wpsWaterMarkParams = wm;
}
function attachRevision(req: OpenFileRequest, user: string, silent: boolean): void {
const rev = new Revision();
rev.UserName = user;
rev.EnterReviseMode = true;
rev.ShowRevisionPanel = true;
rev.EnterRevisionSilent = silent;
req.wpsRevisionParams = rev;
}
export interface Policy {
watermark?: string;
revisionUser?: string;
revisionSilent?: boolean;
}
export async function openWithPolicy(
ctx: common.UIAbilityContext,
path: string,
editable: boolean,
policy: Policy = {}
): Promise<Result> {
if (!sdkReady) {
throw new Error('register first');
}
const req = new OpenFileRequest(ctx, path);
req.enableEdit = editable;
if (policy.watermark) {
attachWatermark(req, policy.watermark);
}
if (policy.revisionUser) {
attachRevision(req, policy.revisionUser, !!policy.revisionSilent);
}
return WPSApi.sendRequest(req);
}
Ability onCreate 调 startWps。预览:editable = false + watermark。协作编辑:editable = true + revisionUser。日志同时打 editable、是否带水印、是否进修订,减少口头描述「有的有水印有的没有」。
处理结果时分支清楚:
typescript
export function onOpenResult(r: Result): void {
if (r.code !== ResultCode.OK) {
console.error('[WPS] open fail', r.code, r.msg ?? '');
return;
}
if (r.data == null) {
console.info('[WPS] open ok, no transfer payload');
return;
}
// URI/FD 拷贝回本应用后再入库 ------ 另模块
}
未注册异常进 .catch,不要伪造 Result。
页面绑定与产品文案
- 两个入口共用
openWithPolicy,禁止列表项各自new OpenFileRequest/new WaterMark aboutToAppear只同步sdkReady到@State,不在点击里注册- 只读入口可以暗示「带水印预览」,不要暗示「可保存」
- 可编辑且未开回传不要暗示「已上传」
- PR 勾选:水印必设
Enable、修订通常配合true、全仓无req.wpsToken
联调顺序与现象对照
推荐固定绿点:注册 OK → 沙箱只读 → 只读 + 水印 → 沙箱可编辑 → 可编辑 + 修订 →(可选)回传拷贝。换 HAR 后先只读回归,再叠策略。extraOptions 放到策略双绿之后再叠。
| 现象 | 优先查 |
|---|---|
| 抛异常 | 是否未注册就 sendRequest |
1013 |
Bundle / key / HAR |
| 打不开 | 是否未拷沙箱 |
| 无水印 | Enable / 文字 / 是否赋给 Request |
| 无修订 | EnterReviseMode / 是否可编辑 |
| OK 空 data | 是否未开回传(预期) |
编辑能力与回传能力经常被产品写成同一句话。在 SDK 里这是两步:enableEdit = true 只保证客户端可改;关窗后拿到业务路径还要 wpsTransferType。水印 / 修订不替代回传。UI 应拆成:「已在 WPS 中打开(可含水印 / 修订)」与「已收集编辑结果」。
小结
建议目录:wps/bootstrap.ts(startWps / sdkReady)、policy.ts(attachWatermark / attachRevision)、open.ts(openWithPolicy)。README 写清:预览可叠水印;修订通常需可编辑;策略字段显式赋值。发版 checklist 增加「水印 Enable / 修订 EnterReviseMode」两项。换 HAR 后 CHANGELOG 记录只读+水印与可编辑+修订是否通过。
远程协助一次带齐:Bundle 打印值、HAR 文件名、注册 code/msg、打开 code/msg、本次 enableEdit、水印文字长度、是否进修订、是否已拷沙箱。列齐全再讨论选择器权限或回传。
鸿蒙 WPS 二开里,水印与修订不是第二条 API,而是打开策略层上的两支配置。工程价值在于与 enableEdit 解耦、日志带策略布尔、联调顺序不跳步。统一版仍要求注册门禁与沙箱路径;序列号与策略正交。把对接文档入口写进 README,发版评审同时看 HAR、注册 code 与本次策略赋值。坚持绿点顺序,漏 Enable、只读进修订、空 data 误报上传这类问题会少很多。
列表页多个附件时,循环调用 openWithPolicy,每次带上该条目自己的 editable、水印文案与扩展名。不要在 aboutToAppear 里预先构造一堆 Request。按钮 enabled 绑定 sdkReady;若业务允许未就绪时展示按钮,也要禁用点击并提示「文档组件初始化中」。颜色与角度属于视觉参数:联调先用对比强的组合确认 Enable 生效,再交给设计调淡。修订作者名建议与登录态对齐,静默开关写进需求默认值,避免不同页面各自猜。合入前再搜一遍 new WaterMark 与 new Revision,确认只落在 policy.ts。
技术交流 QQ 群:628436767。申请 SDK HAR 与凭据时注明包名与专业版 / 个人版需求。
基于 WPS Open SDK 鸿蒙版对接实践整理,仅供开发者参考。 官方对接文档:365.kdocs.cn/l/clQl5cek2...