HarmonyOS WPS Open SDK 实践:把水印与修订收成打开策略层

在鸿蒙应用里嵌文档能力,团队往往先做「能打开」,再做「能改」。下一步产品常见诉求是:预览页必须带水印,或协作场景必须以修订模式进入。WPS Open SDK(@wps/wps_sdk)没有拆出独立的「加水印 API」:水印与修订都挂在同一次 OpenFileRequest 上,分别是 wpsWaterMarkParamsWaterMark)与 wpsRevisionParamsRevision)。本文从工程封装、策略与模式解耦、联调顺序写清楚,避免把策略问题和鉴权、路径混在一起排。

阅读建议:已了解鸿蒙 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 还可配 AngleFontColor(含透明度)、FontSizeRevision 还可配 ShowRevisionPanelEnterRevisionSilent。未开回传时 OK + 空 data 是正常拉起,不是「保存失败」。序列号仍走注册成功后的 setWpsFileToken,不要写回 request.wpsTokenSdkConstants.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 onCreatestartWps。预览: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.tsstartWps / sdkReady)、policy.tsattachWatermark / attachRevision)、open.tsopenWithPolicy)。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 WaterMarknew Revision,确认只落在 policy.ts

技术交流 QQ 群:628436767。申请 SDK HAR 与凭据时注明包名与专业版 / 个人版需求。


基于 WPS Open SDK 鸿蒙版对接实践整理,仅供开发者参考。 官方对接文档:365.kdocs.cn/l/clQl5cek2...

相关推荐
shmily麻瓜小菜鸡1 小时前
JavaScript / TypeScript 易踩坑知识点完全指南 -假值(Falsy Values)完全指南
开发语言·javascript·typescript
sumatch1 小时前
ESP32
android
古夕1 小时前
my-first-ai-web_学习记录05——NextAuth Adapter 存储用户信息
typescript·全栈·next.js
退休倒计时2 小时前
【每日五题】leetcode TypeScript
算法·leetcode·职场和发展·typescript
pengyu2 小时前
【Kotlin 协程修仙录 · 大乘境 · 后阶】 | 死锁天劫:协程同步原语与 ThreadLocal 迁移之道
android·kotlin
事圆则缓2 小时前
Android 常用设计模式速查
android·设计模式
sickworm陈浩2 小时前
日常修改,3秒生效:腾讯音乐 Android 秒编方案 Jugg 开源
android·编译原理·编译器
Android-Flutter2 小时前
android PhoneWindow, DecorView 详解
android
宝杰X72 小时前
Android Umeng 16kb对齐
android