import Taro from '@tarojs/taro'; import { applyShareTitleTemplate, DEFAULT_SHARE_DESC, DEFAULT_SHARE_HINT, DEFAULT_SHARE_TITLE, resolveMiniShareRuntime, type ClientRuntimeConfig, type MiniShareRuntime, type MiniShareSceneConfig, } from '@dukang/shared-types'; import { toast } from './api'; import { getBrandAssetsSync, loadBrandAssets } from './brand-assets'; import { fetchClientConfig } from './pay-wechat'; export type ShareScene = | 'home' | 'stores' | 'storeDetail' | 'benefit' | 'mine' | 'productDetail' | 'orderDetail'; export { DEFAULT_SHARE_TITLE, DEFAULT_SHARE_DESC }; export const WECHAT_SHARE_HINT = DEFAULT_SHARE_HINT; const FALLBACK_SHARE: MiniShareRuntime = resolveMiniShareRuntime({}); let shareCached: MiniShareRuntime | null = null; export function getShareRuntimeSync(): MiniShareRuntime { return shareCached ?? FALLBACK_SHARE; } export function applyShareFromClientConfig(config?: ClientRuntimeConfig | null) { if (config?.share) { shareCached = config.share; return shareCached; } return getShareRuntimeSync(); } export async function loadShareConfig(force = false): Promise { if (!force && shareCached) return shareCached; try { const cfg = await fetchClientConfig(); if (cfg?.share) { shareCached = cfg.share; return shareCached; } } catch { /* ignore */ } shareCached = FALLBACK_SHARE; return shareCached; } export function getDefaultShareImageUrl(): string { const share = getShareRuntimeSync(); return share.default.imageUrl || getBrandAssetsSync().brandLogoUrl; } export function getShareHint(): string { return getShareRuntimeSync().hint || DEFAULT_SHARE_HINT; } export function prefetchShareBrandAssets() { void loadBrandAssets(); void loadShareConfig(); } function sceneConfig(scene?: ShareScene): MiniShareSceneConfig { const runtime = getShareRuntimeSync(); if (!scene) return runtime.default; return runtime[scene] ?? runtime.default; } export type PageSharePayload = { title?: string; desc?: string; path?: string; imgUrl?: string; link?: string; }; export function buildSceneSharePayload( scene: ShareScene, options?: { path?: string; dynamicTitle?: string | null; dynamicDesc?: string | null; dynamicImageUrl?: string | null; titleVars?: Record; }, ): PageSharePayload { const def = getShareRuntimeSync().default; const sc = sceneConfig(scene); const preferEntity = scene === 'productDetail' || scene === 'storeDetail'; let title: string; if (preferEntity) { title = (options?.dynamicTitle || '').trim() || def.title; } else { title = (sc.title || '').trim(); if (title && options?.titleVars) { const vars = options.titleVars; const missingRequired = Object.entries(vars).some( ([key, value]) => title.includes(`{${key}}`) && !(value != null && String(value).trim()), ); title = missingRequired ? '' : applyShareTitleTemplate(title, vars); } if (!title) { title = (options?.dynamicTitle || '').trim() || def.title; } } const desc = (sc.desc || '').trim() || (options?.dynamicDesc || '').trim() || def.desc; const imgUrl = preferEntity ? (options?.dynamicImageUrl || '').trim() || def.imageUrl || getDefaultShareImageUrl() : (sc.imageUrl || '').trim() || (options?.dynamicImageUrl || '').trim() || def.imageUrl || getDefaultShareImageUrl(); return { title, desc, path: options?.path, imgUrl, }; } export async function applyWechatShare(): Promise { /* weapp 使用原生分享菜单,无 H5 JSSDK */ } export async function handleShareButtonClick( payload?: PageSharePayload, ): Promise<{ showGuide: boolean }> { try { await Taro.showShareMenu({ withShareTicket: true, showShareItems: ['shareAppMessage', 'shareTimeline'], }); } catch { try { await Taro.showShareMenu({ withShareTicket: true }); } catch { /* ignore */ } } toast(getShareHint()); void payload; return { showGuide: false }; } export function toWeappShareMessage(payload?: PageSharePayload) { const def = getShareRuntimeSync().default; return { title: payload?.title || def.title, path: payload?.path || '/pages/home/index', imageUrl: payload?.imgUrl || getDefaultShareImageUrl(), }; } export function toWeappShareTimeline(payload?: PageSharePayload, query = '') { const def = getShareRuntimeSync().default; return { title: payload?.title || def.title, query, imageUrl: payload?.imgUrl || getDefaultShareImageUrl(), }; }