HarmonyOS WPS Open SDK 实践:统一版化解的三类交付痛点

0 阅读5分钟

做鸿蒙文档二开的 ISV 常遇到三种结构性成本:只能覆盖某一类 WPS 客户端、专业版与个人版各维护一套打开代码、以及每次换交付包就要全仓搜 wpsToken 和注册片段。WPS Open SDK 鸿蒙统一版把对外模型对齐到 WPSApi + OpenFileRequest,差异收在 HAR/凭据与 SdkConstants.isPersonalSdk() 分支。本文按「覆盖范围 → 接口一致 → 维护收敛」写工程解法,附可落地的 TypeScript Facade。

痛点 1:用户覆盖窄,交付场景受限

以往若 SDK 只面向专业版 WPS,面向个人用户的 App 要么放弃端内编辑,要么另找绕行方案。统一版在保留专业版能力的前提下,扩容个人版打开路径——厂商按客户场景申请对应 HAR 与凭据,业务代码骨架可共用,换的是依赖与初始化参数,不是重写页面。

工程含义:同一代码仓库可以服务「政企合规」与「大众市场」两条产品线,Adapter 层处理序列号与不落地等差异,UI 层只调 openDoc

痛点 2:两套 API 文档,研发学习曲线翻倍

平行 API 的隐性成本在 Code Review:有人写 request.wpsToken,有人写 setWpsFileToken;有人把注册写在 Activity,有人写在按钮里。统一版把范式固定为:

registerApp → (按需 setWpsFileToken) → OpenFileRequest → sendRequest → Result

全仓只允许一处 new OpenFileRequest,评审时一眼能看出是否绕过 Facade。

痛点 3:长期维护与版本分支

多 flavor、多客户定制时,最怕「A 客户改了水印逻辑,B 客户忘了同步」。把打开策略收进带可选参数的 helper,比复制三份 OpenFileRequest 便宜一个数量级。

import { common } from '@kit.AbilityKit';
import {
  WPSApi,
  RegisterAppRequest,
  OpenFileRequest,
  ResultCode,
  SdkConstants,
  TransferType,
} from '@wps/wps_sdk';

let ready = false;

export async function prepareWps(ctx: common.UIAbilityContext): Promise<void> {
  if (ready) return;
  const r = await WPSApi.sendRequest(
    new RegisterAppRequest(ctx, APP_KEY, APP_SECRET)
  );
  if (r.code === ResultCode.ERROR_CODE_AUTH_FAILURE) {
    throw new Error(`1013 ${r.msg}`);
  }
  if (r.code !== ResultCode.OK) {
    throw new Error(`register ${r.code}`);
  }
  // ToB 凭据:注册 OK 后注入序列号;ToC 通常跳过
  if (!SdkConstants.isPersonalSdk() && ACTIVATION_SN) {
    WPSApi.setWpsFileToken(ACTIVATION_SN);
  }
  ready = true;
}

type OpenOpts = {
  editable?: boolean;
  enableTransfer?: boolean;
};

export async function openDoc(
  ctx: common.UIAbilityContext,
  sandboxPath: string,
  opts: OpenOpts = {}
): Promise<void> {
  await prepareWps(ctx);
  const req = new OpenFileRequest(ctx, sandboxPath);
  req.enableEdit = opts.editable ?? false;
  if (opts.enableTransfer) {
    req.wpsTransferType = TransferType.URI; // 按文档选型
  }
  const r = await WPSApi.sendRequest(req);
  if (r.code !== ResultCode.OK) {
    throw new Error(`open ${r.code} ${r.msg}`);
  }
}

prepareWpsApplication.onCreate 或首屏 aboutToAppearawait 一次;页面只消费 ready 状态。ToB/ToC 差异不要散落在每个 Vue/ArkUI 页面,留在 bootstrap 模块。

四、差异点、联调归因与沙箱拷贝

诚实列三条仍须按场景配置的红线:HAR 与凭据按客户申请;激活序列号在 ToB 常见(setWpsFileToken);不落地/水印走 enableLocalization / wpsWaterMarkParams。统一的是 TypeScript 调用面,不是「一个 HAR 打天下」。申请邮件写清包名,比上线后追 1013 便宜。

reject(未注册)、1013、ERROR 仍会出现。归因顺序:先看 wpsReady,再看沙箱,再看 enableEdit,最后查策略字段。日志带 stage 方便驻场导出。冷启动连点 reject 时,不要急着改打开参数,先确认 Application.onCreate 是否 await prepareWps

沙箱拷贝示例:

import fs from '@ohos.file.fs';

export function copyIntoSandbox(ctx: common.UIAbilityContext, src: string): string {
  const dir = `${ctx.filesDir}/wps_queue`;
  fs.mkdirSync(dir, true);
  const dest = `${dir}/${Date.now()}_${src.split('/').pop() ?? 'doc.docx'}`;
  fs.copyFileSync(src, dest);
  return dest;
}

选择器返回的路径在 WPS 进程未必可读。统一 Facade 里把拷贝做成必经步骤,比在每个页面手写 copyFileSync 更少遗漏。拷贝失败要在 UI 上提示「文件准备失败」,不要继续 sendRequest 浪费一轮联调。

未开 wpsTransferType 时,OK && !data 合法。若产品弹「保存成功」,用户会以为已经上传——这是统一链路里最常见的「非 SDK 问题」。开启回传后,在 sendRequest resolve 再读 data,并同步拷贝到本应用沙箱后再触发上传模块。上传订阅「回传就绪事件」,而不是在打开按钮回调里假设 data 一定有值。

五、评审清单、迁移与小结

PR 模板建议检查:

通过标准
注册仅 bootstrap 调用 RegisterAppRequest
打开仅 Facade 内 new OpenFileRequest
模式编辑入口 enableEdit=true
路径打开前 copyIntoSandbox
日志stage/code/msg,无完整 secret
旧写法全仓无 request.wpsToken

旧工程迁移:若仍有双 Helper,先让两者都转调同一个 openDoc,再把 prepareWps 序列号分支用 SdkConstants.isPersonalSdk() 收口,最后删除平行 Helper。每个 PR 可独立合入,降低迁移风险。合入后全仓搜索 new OpenFileRequest 命中数应为 1;换 HAR 后 clean 重装,避免旧 so 让错误码看起来随机。

对 ISV 而言,统一版解决的是交付模型的重复建设:一套 Facade 覆盖双客户端场景,学习一次 sendRequest 范式,维护时只扩可选参数而不是复制页面。把 prepareWpsopenDoc 提交进基础库,比写十页接入说明更能证明「统一版落在了仓库里」。字段以官方对接文档为准;发版评审同时看 HAR、注册 code 与策略赋值。

落地时建议把 Facade 放进独立 module(如 @app/wps-bridge),业务 Feature 只 import prepareWps / openDoc,禁止直接依赖 @wps/wps_sdk 的 Request 类。这样换 HAR 或调整注册时序,影响面可控。多人协作时冻结「平行 Helper」:新需求只允许扩 OpenOpts,不允许新建 openXxx.ts。每周用全仓 grep 检查 new OpenFileRequest 命中数,若大于 1 则在周会里优先还债。真机联调保留三段日志:注册成功、open-read OK、open-edit OK,作为回归基线贴进 Wiki,减少「我这边能开你那边不能开」的无效往返。若客户同时要求水印与回传,请在 Facade 用可选 OpenOpts 扩展,而不是复制 openApproval.ts;评审时核对 waterMark.EnableenableEdit 是否同时赋值。


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