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

148 lines
9.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 分享重构设计(微信/QQ/抖音去 SDK 化 + 剪贴板指引 + 内容对齐原工程)
- 日期:2026-06-27
- 范围:`ShareProvider` 分享链路重构;支付桩边界确认;**契约(handler/DTO)零改动**
- 关联:契约 §8.1 / §10.1 / §12`friendsSharetypeUrlToptitleDescript``sharesuccess``SharetypeBean`);框架 §6.3 / §6.5
## 1. 背景与动机
当前鸿蒙分享与原 Android 工程**没有对齐**
- 微信走 `@tencent/wechat_open_sdk`(网页/图片分享,缺缩略图)。
- QQ/抖音退化为纯 `systemShare` 系统面板,文本用统一 `joinText`(双换行、不含 url),与原工程逐渠道格式不符。
- 缺少原工程「复制内容到剪贴板 + 指引用户去对应 App 粘贴」的链路。
需求变更:三端统一改为「**优先拉起 App 分享界面 → 复制+指引 → 系统分享兜底**」,且微信不依赖 SDK。
## 2. 关键验证结论(决定方案)
经鸿蒙文档 + 各开放平台资料核实:
- 鸿蒙 NEXT **没有** Android `ACTION_SEND + setPackage` 那种「系统级带内容直分享到指定 App」的能力。
- 纯 scheme`weixin://` / `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`(不变):
```jsonc
{
"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" 仅指文本分享**;图片分享按图片走,**绝不降级为文本**。
- `webpageUrl``type "3"`(图片链接)用作图片来源 URL`type "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`/HYPERLINK**。`systemLink` 退役。
## 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_UPLOAD``LocalUploadServer` 截图上传)链路 → 改为走微信指引窗(图片)。
- 新增:`sharefriend` 分流、`buildShareText`(统一 `title\ndescription`)、`writeClipboard`(文本 PLAIN_TEXT / 图片 PIXELMAP)、`showGuide` 经事件投给 UI、`openAppByScheme``canOpenLink`+`openLink`)。
- 图片管线:type2 走 `captureCanvas``saveDataUrlToFile`type3 从 `webpageUrl` 下载→沙箱(复用平台层 `Downloader/HttpClient`,低优先);二者复用 PIXELMAP 写剪贴板 + `systemImage`
- type4 视频:安全空实现(不报错、不出站)。
- 预留空分支:`qqSdkShare()` / `douyinSdkShare()`(注释 TODO,注册到位后接 SDK)。
- 复用:现有 `systemShare` 方法(`systemText/systemImage`**`systemLink`/`systemVideo` 退役不再使用**)、`saveDataUrlToFile``captureCanvas`
- 移除:对 `WeChatApi.sendShare` / `WXMediaMessage` / `WXWebpageObject` / `WXImageObject` / `SendMessageToWXReq` 的全部分享调用。
### 7.2 新增 `entry/.../components/ShareGuideDialog.ets`
- 自绘弹窗:渠道图标(复用 `share_wechat/share_qq/share_douyin`)+ 文案 + 三按钮(打开 App / 用系统分享 / 取消)。
- 文案按内容类型:文本类「内容已复制,请打开 XX 粘贴分享」;图片类「图片已复制,可在 XX 长按粘贴;或点下方用系统分享」。
- 「用系统分享」按钮:文本→`systemText`、图片→`systemImage`
-`EventBus`(仿 `SharePanel``SHOW_PANEL`/一次性回投模式)与 `BridgeGameContainer` 通信。
### 7.3 `feature_capabilities/.../wx/WeChatApi.ets`
- 删除 `sendShare``ShareRespCallback``routeResp``SendMessageToWXResp` 分支及其 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 安全空实现不报错)。
- 设备验证(真机/模拟器):
- `friendsSharetypeUrlToptitleDescript``type`/`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`(系统分享)为可靠交付,剪贴板图片仅尽力而为。待人工真机验证后登记风险册。