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

在鸿蒙应用里嵌文档能力,团队往往先做「能打开」,再做「能改」。下一步产品常见诉求是:预览页必须带水印,或协作场景必须以修订模式进入。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...

相关推荐
濮水大叔7 小时前
NestJS Dynamic Providers 与 Cabloy/Vona Provider Scene:同接口多实现的两种装配哲学
typescript·node.js·nestjs
程序猿追8 小时前
kotlin-retry 接入鸿蒙后,怎样确认它真的会停止重试
开发语言·kotlin·harmonyos
jack1868910 小时前
安卓手机忘记锁屏密码怎么办? 无需密码也可解锁
android·智能手机
懿路向前11 小时前
HarmonyOS 粒子特效实战:emitter.size 是双刃剑:粒子精确定位 [0,0] 与条带随机出生(HarmonyOS)
华为·harmonyos
马剑威(威哥爱编程)11 小时前
【共创稿事节】HarmonyOS 7 Agent 开发实战 04:云端 RAG 搭企业私有知识库问答
人工智能·华为·harmonyos
const_qiu11 小时前
第一章 1.1-1.2:基础模型调用与 TypeScript 入门 —— Java 开发者的视角
java·javascript·typescript
贾伟康12 小时前
【晨迹相机|20】HarmonyOS ArkTS AppGallery 发布复查实战:核对包名、版本、设备、素材和离线声明
harmonyos·arkts·appgallery·发布审核·上架复查
特立独行的猫a13 小时前
用仓颉写桌面应用:从 npx 建工程到串口实时示波器
开源·harmonyos·tauri·仓颉·cj-tarui
应用市场13 小时前
不用一张图片的像素小游戏:小人是字符串,房间是矩形,平衡靠两千个假玩家
android·kotlin·游戏开发
stevenzqzq14 小时前
android 对渠道的理解
android