feat: add bridge service for mini program web-view integration
- Implemented a bridge utility for sharing, copying links, and setting the navigation bar title in mini program web-view. - Added methods for sharing content and copying links to clipboard. - Included error handling for non-mini program environments.
This commit is contained in:
@@ -19,7 +19,8 @@ import { toPng } from "html-to-image";
|
|||||||
import { Card } from "../components/ui/card";
|
import { Card } from "../components/ui/card";
|
||||||
import { Badge } from "../components/ui/badge";
|
import { Badge } from "../components/ui/badge";
|
||||||
import { Button } from "../components/ui/button";
|
import { Button } from "../components/ui/button";
|
||||||
import { generateShareData } from "../services/api";
|
import { generateShareData } from "../services/api"
|
||||||
|
import bridge from "../services/bridge";
|
||||||
|
|
||||||
type SaveStatus = "idle" | "generating" | "success" | "error";
|
type SaveStatus = "idle" | "generating" | "success" | "error";
|
||||||
|
|
||||||
@@ -305,7 +306,26 @@ export function SharePage() {
|
|||||||
|
|
||||||
{/* 底部固定操作栏 */}
|
{/* 底部固定操作栏 */}
|
||||||
<div className="fixed bottom-0 left-0 right-0 bg-white border-t border-gray-200 p-4 pb-safe z-10">
|
<div className="fixed bottom-0 left-0 right-0 bg-white border-t border-gray-200 p-4 pb-safe z-10">
|
||||||
<div className="max-w-md mx-auto">
|
<div className="max-w-md mx-auto space-y-3">
|
||||||
|
{/* 微信分享按钮(仅在 web-view 环境下生效) */}
|
||||||
|
<Button
|
||||||
|
onClick={() => bridge.share({
|
||||||
|
title: '孕育无忧 · 报告解读',
|
||||||
|
summary: shareData?.overall_summary || shareData?.emotional_summary || '',
|
||||||
|
href: window.location.href,
|
||||||
|
scene: 'WXSceneSession',
|
||||||
|
})}
|
||||||
|
className="w-full h-14 rounded-2xl text-base font-semibold flex items-center justify-center gap-2 bg-[#07C160] hover:bg-[#06AD56] text-white shadow-lg shadow-green-300/30"
|
||||||
|
>
|
||||||
|
<Share2 className="w-5 h-5" />
|
||||||
|
<span>分享给微信好友</span>
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
onClick={() => bridge.copyLink(window.location.href)}
|
||||||
|
className="w-full h-12 rounded-2xl text-sm font-medium flex items-center justify-center gap-2 border-2 border-gray-200 bg-white hover:bg-gray-50 text-gray-600"
|
||||||
|
>
|
||||||
|
<span>复制链接分享</span>
|
||||||
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
onClick={handleSaveImage}
|
onClick={handleSaveImage}
|
||||||
disabled={saveStatus === "generating"}
|
disabled={saveStatus === "generating"}
|
||||||
@@ -320,7 +340,7 @@ export function SharePage() {
|
|||||||
{getSaveButtonContent()}
|
{getSaveButtonContent()}
|
||||||
</Button>
|
</Button>
|
||||||
<p className="text-center text-xs text-gray-400 mt-2">
|
<p className="text-center text-xs text-gray-400 mt-2">
|
||||||
图片将保存到您的手机相册中
|
分享到微信或保存图片到相册
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
82
frontend/src/app/services/bridge.ts
Normal file
82
frontend/src/app/services/bridge.ts
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
/**
|
||||||
|
* 小程序 WebView 桥接工具
|
||||||
|
*
|
||||||
|
* 在 H5(app_03)中调用此工具,可实现分享、复制链接等功能。
|
||||||
|
* 小程序侧(crmeb web_view)通过 @message 监听处理。
|
||||||
|
*
|
||||||
|
* 使用方式:
|
||||||
|
* import bridge from '../services/bridge'
|
||||||
|
*
|
||||||
|
* // 分享给好友
|
||||||
|
* bridge.share({ title: '标题', href: window.location.href })
|
||||||
|
*
|
||||||
|
* // 复制链接
|
||||||
|
* bridge.copyLink(window.location.href)
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare const wx: any
|
||||||
|
|
||||||
|
function getMiniProgram() {
|
||||||
|
try {
|
||||||
|
if (typeof wx !== 'undefined' && wx.miniProgram) {
|
||||||
|
return wx.miniProgram
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
const bridge = {
|
||||||
|
postMessage(data: Record<string, any>) {
|
||||||
|
const mp = getMiniProgram()
|
||||||
|
if (mp) {
|
||||||
|
mp.postMessage({ data })
|
||||||
|
} else {
|
||||||
|
console.warn('[bridge] 不在小程序 web-view 环境中')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分享给微信好友 / 朋友圈
|
||||||
|
*/
|
||||||
|
share(opts: {
|
||||||
|
title: string
|
||||||
|
href?: string
|
||||||
|
summary?: string
|
||||||
|
imageUrl?: string
|
||||||
|
scene?: 'WXSceneSession' | 'WXSceneTimeline'
|
||||||
|
}) {
|
||||||
|
this.postMessage({
|
||||||
|
action: 'share',
|
||||||
|
title: opts.title || '',
|
||||||
|
href: opts.href || window.location.href,
|
||||||
|
summary: opts.summary || '',
|
||||||
|
imageUrl: opts.imageUrl || '',
|
||||||
|
scene: opts.scene || 'WXSceneSession',
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 复制链接到剪贴板
|
||||||
|
*/
|
||||||
|
copyLink(link?: string) {
|
||||||
|
this.postMessage({
|
||||||
|
action: 'copyLink',
|
||||||
|
href: link || window.location.href,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置小程序导航栏标题
|
||||||
|
*/
|
||||||
|
setTitle(title: string) {
|
||||||
|
if (!title) return
|
||||||
|
this.postMessage({
|
||||||
|
action: 'setTitle',
|
||||||
|
title,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
export default bridge
|
||||||
Reference in New Issue
Block a user