Files
youle_app_ohos/docs/superpowers/specs/2026-06-27-分享重构-design.md
lanterngamescnandClaude Opus 4.8 b0277e902e docs: 分享 spec 终稿——文本统一单换行、图片不降级、视频不实现、图片走系统分享兜底
三端文本统一 title\ndescription(单换行,无url);图片(type2/3)剪贴板PIXELMAP尽力
+指引窗内systemImage可靠兜底;type4视频H5未用安全空实现;systemLink/systemVideo退役。
附图片剪贴板粘贴不可保证的验证结论与真机验证项。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27 13:04:12 +08:00

9.9 KiB
Raw Permalink Blame History

分享重构设计(微信/QQ/抖音去 SDK 化 + 剪贴板指引 + 内容对齐原工程)

  • 日期:2026-06-27
  • 范围:ShareProvider 分享链路重构;支付桩边界确认;契约(handler/DTO)零改动
  • 关联:契约 §8.1 / §10.1 / §12friendsSharetypeUrlToptitleDescriptsharesuccessSharetypeBean);框架 §6.3 / §6.5

1. 背景与动机

当前鸿蒙分享与原 Android 工程没有对齐

  • 微信走 @tencent/wechat_open_sdk(网页/图片分享,缺缩略图)。
  • QQ/抖音退化为纯 systemShare 系统面板,文本用统一 joinText(双换行、不含 url),与原工程逐渠道格式不符。
  • 缺少原工程「复制内容到剪贴板 + 指引用户去对应 App 粘贴」的链路。

需求变更:三端统一改为「优先拉起 App 分享界面 → 复制+指引 → 系统分享兜底」,且微信不依赖 SDK。

2. 关键验证结论(决定方案)

经鸿蒙文档 + 各开放平台资料核实:

  • 鸿蒙 NEXT 没有 Android ACTION_SEND + setPackage 那种「系统级带内容直分享到指定 App」的能力。
  • 纯 schemeweixin:// / mqqapi:// / snssdk1128://只能打开 App 或某页面,不能携带分享内容发起分享
  • 「拉起 App 分享界面 + 预填内容 + 选好友直接分享」只能靠各家官方鸿蒙 SDK
    • 微信 Open SDK(用户要求不使用 → 放弃直分享)
    • QQ 互联 @tencent/qq-open-sdk v1.0.3+shareToQQ 可预填)
    • 抖音开放平台 SDK(仅「拉起编辑/发布页发布作品」,无选好友私信能力
    • 三者均需 AppId 注册 / 签名指纹 / AppLinking 配置(属已登记的延期外部依赖)。

决策(已确认):本期不接任何分享 SDK,三端统一走「剪贴板 + 指引窗 → 系统分享」,代码内预留 SDK 接入点;SDK 接入列为后续延期项。

3. 对外契约(零改动,铁律判据)

方向 handler 数据 说明
入站 friendsSharetypeUrlToptitleDescript JSON(SharetypeBean) 触发分享
出站 sharesuccess {success:int, type:int} 仅微信success 2 成功 / 3 取消;type 1 好友 / 2 朋友圈

SharetypeBean(不变):

{
  "sharefriend": "1",      // "1" 弹面板选目标 / "2" 朋友圈直发微信
  "type": "1",             // "1" 网页/文本 / "2" Canvas截图 / "3" 图片链接 / "4" 视频(抖音)
  "sharetype": "",         // 截图子类型(canvasId)
  "webpageUrl": "https://...",
  "title": "标题",
  "description": "描述"
}

4. 交互流程

H5 → friendsSharetypeUrlToptitleDescript(SharetypeBean)
  ├─ sharefriend=="2"  → 微信渠道(朋友圈语义, 回传 type=2) → ShareGuideDialog(wechat)
  └─ sharefriend=="1"  → SharePanel(微信/QQ/抖音/取消)
        └─ 选定渠道 → 按渠道+type 组装内容 + 写剪贴板 → ShareGuideDialog(platform)
              ├─「打开 微信/QQ/抖音」 canOpenLink + openLink(scheme) best-effort 打开 App,用户自行粘贴
              ├─「用系统分享」       systemText(文本) / systemImage(图片)(可靠兜底)
              └─「取消」
  • sharefriend=="1" 弹自有 SharePanel(沿用现状);=="2" 不弹、直接微信指引窗。
  • 指引窗展示前先把可分享内容写入剪贴板(文本 PLAIN_TEXT / 图片 PIXELMAP,尽力);图片粘贴不可保证,指引窗内「系统分享」按钮(systemImage)作可靠交付。

5. 内容组装

5.1 文本格式(三端统一)

buildShareText(bean) = title\ndescription单换行、三端完全一致、不含 webpageUrl)。空字段跳过对应行,避免多余空行。

  • "不含 url" 仅指文本分享;图片分享按图片走,绝不降级为文本
  • webpageUrltype "3"(图片链接)用作图片来源 URLtype "1" 文本不使用;type "4" 视频 H5 未用、不实现。

5.2 类型处理

type H5 用途 内容来源 第二层(剪贴板+指引窗) 第三层(指引窗内「系统分享」按钮)
1 网页/文本 buildShareText(无 url PLAIN_TEXT 文本 systemText(PLAIN_TEXT, 无 url)
2 Canvas 截图 captureCanvas(sharetype)saveDataUrlToFile 沙箱图片 PIXELMAP尽力,对方支持才可粘贴) systemImage可靠主交付
3 图片链接(低优先) webpageUrl 下载图片 → 沙箱,同 type2 图片管线 PIXELMAP(尽力) systemImage
4 视频 H5 未使用 —— ——
  • 图片(type2/3)走「剪贴板图片(尽力) + 指引窗」:复制 PIXELMAP(对方支持则可长按粘贴),指引窗同时提供「用系统分享」按钮 → systemImage 作可靠兜底(系统把图片文件交给目标 App)。理由:经验证微信/QQ 鸿蒙版能否粘贴 PIXELMAP 不可保证(§10),systemImage 才是确定能把图片交付的路径。
  • type4 视频H5 未用,分支安全空实现(不报错、不出站),不实现视频分享。
  • 系统分享统一不下发 url:文本 systemText(title+description)、图片 systemImage不再使用 systemLink/HYPERLINKsystemLink 退役。

6. sharesuccess 回传(仅微信,乐观)

  • 用户在微信指引窗点「打开微信」或「用系统分享」即视为已发起 → callHandler('sharesuccess', {success:2, type})
  • type = (sharefriend=='1') ? 1 : 2
  • 点「取消」 / 微信未安装且无法打开 → {success:3, type}
  • QQ、抖音不回传(与契约一致)。

7. 组件与改动清单

7.1 重写 feature_capabilities/.../providers/ShareProvider.ets

  • 保留:FriendsShare 注册、PHOTO_UPLOADLocalUploadServer 截图上传)链路 → 改为走微信指引窗(图片)。
  • 新增:sharefriend 分流、buildShareText(统一 title\ndescription)、writeClipboard(文本 PLAIN_TEXT / 图片 PIXELMAP)、showGuide 经事件投给 UI、openAppBySchemecanOpenLink+openLink)。
  • 图片管线:type2 走 captureCanvassaveDataUrlToFiletype3 从 webpageUrl 下载→沙箱(复用平台层 Downloader/HttpClient,低优先);二者复用 PIXELMAP 写剪贴板 + systemImage
  • type4 视频:安全空实现(不报错、不出站)。
  • 预留空分支:qqSdkShare() / douyinSdkShare()(注释 TODO,注册到位后接 SDK)。
  • 复用:现有 systemShare 方法(systemText/systemImagesystemLink/systemVideo 退役不再使用)、saveDataUrlToFilecaptureCanvas
  • 移除:对 WeChatApi.sendShare / WXMediaMessage / WXWebpageObject / WXImageObject / SendMessageToWXReq 的全部分享调用。

7.2 新增 entry/.../components/ShareGuideDialog.ets

  • 自绘弹窗:渠道图标(复用 share_wechat/share_qq/share_douyin)+ 文案 + 三按钮(打开 App / 用系统分享 / 取消)。
  • 文案按内容类型:文本类「内容已复制,请打开 XX 粘贴分享」;图片类「图片已复制,可在 XX 长按粘贴;或点下方用系统分享」。
  • 「用系统分享」按钮:文本→systemText、图片→systemImage
  • EventBus(仿 SharePanelSHOW_PANEL/一次性回投模式)与 BridgeGameContainer 通信。

7.3 feature_capabilities/.../wx/WeChatApi.ets

  • 删除 sendShareShareRespCallbackrouteRespSendMessageToWXResp 分支及其 import。
  • 保留授权登录路径(sendAuth/handleWant/SendAuthResp)。

7.4 entry/src/main/module.json5

  • querySchemes 增加 "mqqapi""snssdk1128"(连同现有 "weixin")。

7.5 依赖

  • 保留 @tencent/wechat_open_sdk(登录仍依赖;登录代码不动)。

7.6 支付边界(确认现状已满足,无需删依赖)

  • PayStubProvider 已是 void 空桩(PayBrowser/GetGameplay noop、不出站、无 SDK)。
  • 全工程无独立支付依赖;module.json5 无支付 scheme。
  • 结论:支付「移除依赖和逻辑、留空桩」诉求已天然满足,本期不改支付代码;仅在 spec 记录该结论。

8. 不做(YAGNI / 延期)

  • 不接微信/QQ/抖音任何分享 SDK(tier1 直分享、选好友)→ 后续延期项(依赖外部注册)。
  • 不实现 QQ/抖音 sharesuccess 回传(契约允许其无回传)。
  • 不新增任何对外 handler;不改 H5。

9. 测试与验收

  • 单元测试(entry/src/test,纯逻辑):buildShareText 统一格式、空字段裁剪、type/sharefriend 分支映射(含 type4 安全空实现不报错)。
  • 设备验证(真机/模拟器):
    • friendsSharetypeUrlToptitleDescripttype/sharefriend 组合弹窗正确、剪贴板内容正确、指引窗「系统分享」可拉起(文本 systemText / 图片 systemImage)。
    • 人工真机验证(需配合):图片 PIXELMAP 复制后能否在微信/QQ 鸿蒙版对话框长按粘贴出图片——结果登记到风险册,决定是否保留剪贴板图片这条尽力路径。
    • 微信渠道 sharesuccess 乐观回传时机正确;QQ/抖音不回传。
    • devecocli build 通过、code-linter 无新增告警。
  • 验收基线:H5 调用全程不报错、不卡死(DefaultHandler 兜底仍在)。

10. 风险

  • 拉起 App 仅"打开"不预填openLink(scheme) 只能打开 App,用户需手动粘贴;体验弱于原工程微信 SDK,已与用户确认接受。
  • scheme 可用性mqqapi/snssdk1128 能否 canOpenLink 取决于对方鸿蒙版注册情况;不可用时指引窗降级为纯文案提示,不报错。
  • 图片剪贴板粘贴不可保证:微信/QQ 鸿蒙版是否支持读取 PIXELMAP 类型剪贴板未知(且 API 12+ 读剪贴板有权限管控);故图片以指引窗内 systemImage(系统分享)为可靠交付,剪贴板图片仅尽力而为。待人工真机验证后登记风险册。