M3(T-M3-13): 分享面板对齐原工程——微信SDK + QQ/抖音系统分享

对齐 Android SharePanelHelper 流程:H5 friendsSharetypeUrlToptitleDescript →
原生弹自定义面板(微信/QQ/抖音) → 按所选平台分享。

- common ShareEvents:SHOW_PANEL + SharePanelRequest/Result;ShareProvider 经一次性
  resultEvent 与 entry 容器一对一解耦(双槽实例隔离,避免广播串扰)
- ShareProvider 重构:微信走 SDK(type2 Canvas截图→WXImageObject / 其他→WXWebpageObject;
  scene 好友/朋友圈;回传 sharesuccess);QQ/抖音走 @kit.ShareKit 系统分享(文本/图片/链接/视频,
  不集成对应 SDK、不回传);截图失败统一降级
- 截图:CapabilityContext.captureCanvas(WebSlot 用 controller.runJavaScript 取 canvas
  toDataURL,非激活/出错返回空);FileSystem.writeBytes 落盘;fileUri 给 WXImageObject/系统分享
- entry SharePanel 组件 + BridgeGameContainer 顶层叠加;重复面板/销毁均取消回投防 once 悬挂

真机验证项:微信开放平台注册后的真分享、系统分享面板拉起、canvas 截图

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
lanterngamescn
2026-06-26 08:00:03 +08:00
co-authored by Claude Opus 4.8
parent 01e4c0e99e
commit 5cbe5d4dd0
8 changed files with 478 additions and 21 deletions
@@ -0,0 +1,68 @@
/**
* 自定义分享面板(对齐原 Android SharePanelHelper:底部弹出 + 三按钮 微信/QQ/抖音 + 点空白关闭=取消)。
*
* 纯展示组件:由 BridgeGameContainer 以 @State visible 控制显隐,叠在 Stack 顶层。
* 用户点平台 → onPick(platform);点空白/取消 → onPick('cancel')。无图标资源用文字按钮。
* 不持业务逻辑、不直接发 EventBus——回投由容器统一经一次性 resultEvent 完成(避免组件耦合事件名)。
*/
@Component
export struct SharePanel {
/** 选择回调:'wechat' | 'qq' | 'douyin' | 'cancel'。 */
onPick: (platform: string) => void = () => { };
build() {
// 半透明遮罩:点击空白处取消
Column() {
Blank()
.layoutWeight(1)
.width('100%')
.onClick(() => this.onPick('cancel'))
// 内容区:点击不关闭(消费事件)
Column() {
Text('分享到')
.fontSize(16)
.fontColor('#333333')
.margin({ top: 16, bottom: 16 })
Row() {
this.platformButton('微信', 'wechat', '#07C160')
this.platformButton('QQ', 'qq', '#12B7F5')
this.platformButton('抖音', 'douyin', '#000000')
}
.width('100%')
.justifyContent(FlexAlign.SpaceEvenly)
.margin({ bottom: 12 })
Divider().color('#EEEEEE')
Text('取消')
.fontSize(16)
.fontColor('#666666')
.width('100%')
.textAlign(TextAlign.Center)
.padding({ top: 14, bottom: 14 })
.onClick(() => this.onPick('cancel'))
}
.width('100%')
.backgroundColor(Color.White)
.borderRadius({ topLeft: 16, topRight: 16 })
.onClick(() => { /* 消费点击,避免穿透到遮罩 */ })
}
.width('100%')
.height('100%')
.backgroundColor('rgba(0,0,0,0.45)')
}
@Builder
platformButton(label: string, platform: string, color: string) {
Column() {
Circle({ width: 56, height: 56 }).fill(color)
Text(label)
.fontSize(13)
.fontColor('#333333')
.margin({ top: 8 })
}
.onClick(() => this.onPick(platform))
}
}