微信/抖音 第二三层均不带 webpageUrl;webpageUrl 仅作 type4 本地视频路径; 系统分享统一 PLAIN_TEXT(title+description)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
8.4 KiB
8.4 KiB
分享重构设计(微信/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-sdkv1.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,用户自行粘贴
├─「更多分享方式」 systemShare 系统面板(兜底)
└─「取消」
sharefriend=="1"弹自有SharePanel(沿用现状);=="2"不弹、直接微信指引窗。- 指引窗对所有
type都先把可分享内容写入剪贴板(文本/图片/视频 URI),再展示。
5. 内容组装(逐渠道对齐原工程)
文本拼接函数 buildShareText(bean, platform) —— 三端文本一律不含 webpageUrl:
| 渠道 | 文本(type1,3) 格式 | 备注 |
|---|---|---|
| 微信 | title\ndescription |
单换行、不含 url(第二/三层均不带);无缩略图概念 |
title\n\ndescription |
双换行、不含 url(对齐原工程) | |
| 抖音 | title\ndescription |
单换行、不含 url(第二/三层均不带) |
- 空字段跳过对应行,避免多余空行。三端差异仅在换行数(QQ 双、微信/抖音 单)。
webpageUrl不再出现在任何文本/链接分享路径;仅作 type4 的本地视频文件路径使用。type "3"(图片链接)按纯文本(title+description)处理,不带 url。
类型处理:
| type | 内容 | 剪贴板 | 系统分享兜底 |
|---|---|---|---|
| 1 网页/文本 | buildShareText(无 url) |
PLAIN_TEXT | systemText(PLAIN_TEXT, 无 url) |
| 2 Canvas 截图 | captureCanvas(sharetype) → saveDataUrlToFile 沙箱 |
PIXELMAP | systemImage |
| 3 图片链接 | 同 type1(纯文本, 无 url) | PLAIN_TEXT | systemText |
| 4 视频(抖音) | 本地视频 webpageUrl |
文件 URI | systemVideo;远程视频降级为 systemText(无 url) |
系统分享(第三层)统一用
PLAIN_TEXT(title+description),不再使用systemLink/HYPERLINK(即不下发 url)。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逐渠道、writeClipboard(文本/PIXELMAP/URI)、showGuide经事件投给 UI、openAppByScheme(canOpenLink+openLink)。 - 预留空分支:
qqSdkShare()/douyinSdkShare()(注释 TODO,注册到位后接 SDK)。 - 复用:现有
systemShare方法(systemText/systemImage/systemVideo,systemLink退役不再使用)、saveDataUrlToFile、captureCanvas。 - 移除:对
WeChatApi.sendShare/WXMediaMessage/WXWebpageObject/WXImageObject/SendMessageToWXReq的全部分享调用。
7.2 新增 entry/.../components/ShareGuideDialog.ets
- 自绘弹窗:渠道图标(复用
share_wechat/share_qq/share_douyin)+「内容已复制,请打开 XX 粘贴分享」+ 三按钮(打开 App / 更多分享方式 / 取消)。 - 经
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/GetGameplaynoop、不出站、无 SDK)。- 全工程无独立支付依赖;module.json5 无支付 scheme。
- 结论:支付「移除依赖和逻辑、留空桩」诉求已天然满足,本期不改支付代码;仅在 spec 记录该结论。
8. 不做(YAGNI / 延期)
- 不接微信/QQ/抖音任何分享 SDK(tier1 直分享、选好友)→ 后续延期项(依赖外部注册)。
- 不实现 QQ/抖音
sharesuccess回传(契约允许其无回传)。 - 不新增任何对外 handler;不改 H5。
9. 测试与验收
- 单元测试(
entry/src/test,纯逻辑):buildShareText三渠道格式、空字段裁剪、type分支映射。 - 设备验证(真机/模拟器):
friendsSharetypeUrlToptitleDescript各type/sharefriend组合弹窗正确、剪贴板内容正确、系统分享面板可拉起。- 微信渠道
sharesuccess乐观回传时机正确;QQ/抖音不回传。 devecocli build通过、code-linter无新增告警。
- 验收基线:H5 调用全程不报错、不卡死(
DefaultHandler兜底仍在)。
10. 风险
- 拉起 App 仅"打开"不预填:
openLink(scheme)只能打开 App,用户需手动粘贴;体验弱于原工程微信 SDK,已与用户确认接受。 - scheme 可用性:
mqqapi/snssdk1128能否canOpenLink取决于对方鸿蒙版注册情况;不可用时指引窗降级为纯文案提示,不报错。