Merge branch 'main' of http://18.167.251.121:10003/aidlab/lanecarford_front
This commit is contained in:
10
index.html
10
index.html
@@ -7,7 +7,15 @@
|
||||
<!-- <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"> -->
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0" />
|
||||
<link rel="stylesheet" href="/css/woff/fontFamily.css">
|
||||
<title>Activities</title>
|
||||
<title>Lane Crawford</title>
|
||||
<!-- Open Graph / WhatsApp share metadata -->
|
||||
<meta property="og:title" content="Lane Crawford" />
|
||||
<meta property="og:description" content="create and share looks from the Lane Crawford creation gallery." />
|
||||
<meta property="og:image" content="" />
|
||||
<meta property="og:url" content="https://www.lc.aida.com.hk" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:site_name" content="Lane Crawford" />
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
209
src/utils/share.ts
Normal file
209
src/utils/share.ts
Normal file
@@ -0,0 +1,209 @@
|
||||
/**
|
||||
* 分享工具函数
|
||||
* 支持移动浏览器原生分享 API 和 WhatsApp 分享
|
||||
*/
|
||||
|
||||
interface ShareData {
|
||||
title?: string
|
||||
text?: string
|
||||
url?: string
|
||||
files?: File[]
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否支持 Web Share API
|
||||
*/
|
||||
export function isWebShareSupported(): boolean {
|
||||
return typeof navigator !== 'undefined' && 'share' in navigator
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用 Web Share API 进行分享(移动浏览器原生分享)
|
||||
* @param data 分享数据
|
||||
*/
|
||||
async function shareWithWebAPI(data: ShareData): Promise<void> {
|
||||
if (!isWebShareSupported()) {
|
||||
throw new Error('Web Share API is not supported')
|
||||
}
|
||||
|
||||
try {
|
||||
// Web Share API 只支持 title, text, url 和 files
|
||||
const shareData: ShareData = {}
|
||||
|
||||
if (data.title) shareData.title = data.title
|
||||
if (data.text) shareData.text = data.text
|
||||
if (data.url) shareData.url = data.url
|
||||
if (data.files && data.files.length > 0) shareData.files = data.files
|
||||
|
||||
await navigator.share(shareData)
|
||||
} catch (error: any) {
|
||||
// 用户取消分享时,会抛出 AbortError,这是正常情况
|
||||
if (error.name !== 'AbortError') {
|
||||
console.error('分享失败:', error)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 分享到 WhatsApp(回退方案)
|
||||
* @param text 分享的文本内容
|
||||
* @param url 分享的链接(可选)
|
||||
*/
|
||||
export function shareToWhatsApp(text: string, url?: string): void {
|
||||
const shareText = url ? `${text} ${url}` : text
|
||||
const encodedText = encodeURIComponent(shareText)
|
||||
const whatsappScheme = `whatsapp://send?text=${encodedText}`
|
||||
const whatsappWebUrl = `https://wa.me/?text=${encodedText}`
|
||||
const isMobile = typeof navigator !== 'undefined' && /Android|iPhone|iPad|iPod|Mobile/i.test(navigator.userAgent)
|
||||
|
||||
if (typeof window === 'undefined') return
|
||||
|
||||
if (isMobile) {
|
||||
// 优先尝试调用已安装的 WhatsApp 应用,失败后回退到 Web 版本
|
||||
let didFallback = false
|
||||
const fallbackTimer = window.setTimeout(() => {
|
||||
didFallback = true
|
||||
window.location.href = whatsappWebUrl
|
||||
}, 1500)
|
||||
|
||||
try {
|
||||
window.location.href = whatsappScheme
|
||||
} catch (error) {
|
||||
window.clearTimeout(fallbackTimer)
|
||||
window.location.href = whatsappWebUrl
|
||||
}
|
||||
|
||||
// 某些浏览器会在成功唤起 App 时终止脚本,无需额外处理
|
||||
return
|
||||
}
|
||||
|
||||
// 桌面端或不支持 scheme 的环境直接打开 WhatsApp Web
|
||||
window.open(whatsappWebUrl, '_blank')
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用分享函数(优先使用 Web Share API,不支持则回退到 WhatsApp)
|
||||
* @param options 分享选项
|
||||
*/
|
||||
export async function share(options: {
|
||||
title?: string
|
||||
text?: string
|
||||
url?: string
|
||||
files?: File[]
|
||||
fallbackToWhatsApp?: boolean
|
||||
}): Promise<void> {
|
||||
const { title, text, url, files, fallbackToWhatsApp = true } = options
|
||||
|
||||
// 如果支持 Web Share API,优先使用
|
||||
if (isWebShareSupported() && !files) {
|
||||
try {
|
||||
await shareWithWebAPI({ title, text, url })
|
||||
return
|
||||
} catch (error) {
|
||||
// 如果分享失败且允许回退,则使用 WhatsApp
|
||||
if (fallbackToWhatsApp) {
|
||||
const shareText = [title, text, url].filter(Boolean).join('\n\n')
|
||||
shareToWhatsApp(shareText)
|
||||
return
|
||||
}
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
// 如果不支持 Web Share API 或需要分享文件,使用 WhatsApp
|
||||
if (fallbackToWhatsApp) {
|
||||
const shareText = [title, text, url].filter(Boolean).join('\n\n')
|
||||
shareToWhatsApp(shareText)
|
||||
} else {
|
||||
throw new Error('Web Share API is not supported and fallback is disabled')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 分享当前页面(优先使用原生分享,不支持则回退到 WhatsApp)
|
||||
* @param title 分享的标题
|
||||
* @param description 分享的描述(可选)
|
||||
*/
|
||||
export async function shareCurrentPage(title: string, description?: string): Promise<void> {
|
||||
const currentUrl = window.location.href
|
||||
await share({
|
||||
title,
|
||||
text: description,
|
||||
url: currentUrl,
|
||||
fallbackToWhatsApp: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 分享图片(优先使用原生分享,不支持则回退到 WhatsApp)
|
||||
* @param imageUrl 图片链接
|
||||
* @param title 分享的标题
|
||||
* @param description 分享的描述(可选)
|
||||
*/
|
||||
export async function shareImage(imageUrl: string, title: string, description?: string): Promise<void> {
|
||||
const currentUrl = window.location.href
|
||||
const text = description
|
||||
? `${description}\n\n查看图片: ${imageUrl}`
|
||||
: `查看图片: ${imageUrl}`
|
||||
|
||||
await share({
|
||||
title,
|
||||
text,
|
||||
url: currentUrl,
|
||||
fallbackToWhatsApp: true
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 分享图片文件(使用 Web Share API,支持直接分享图片文件)
|
||||
* @param imageFile 图片文件
|
||||
* @param title 分享的标题(可选)
|
||||
* @param text 分享的文本(可选)
|
||||
*/
|
||||
export async function shareImageFile(imageFile: File, title?: string, text?: string): Promise<void> {
|
||||
if (!isWebShareSupported()) {
|
||||
throw new Error('WEB_SHARE_UNSUPPORTED')
|
||||
}
|
||||
if (typeof navigator.canShare === 'function' && !navigator.canShare({ files: [imageFile] })) {
|
||||
throw new Error('WEB_SHARE_FILE_UNSUPPORTED')
|
||||
}
|
||||
|
||||
await shareWithWebAPI({
|
||||
title,
|
||||
text,
|
||||
files: [imageFile]
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 将远程图片转换为 File 对象,便于提前缓存后再触发分享
|
||||
* @param imageUrl 图片链接
|
||||
* @param fileName 文件名(可选)
|
||||
*/
|
||||
export async function createImageFileFromUrl(imageUrl: string, fileName?: string): Promise<File> {
|
||||
const response = await fetch(imageUrl)
|
||||
const blob = await response.blob()
|
||||
const name = fileName || imageUrl.split('/').pop() || 'share-image.jpg'
|
||||
return new File([blob], name, { type: blob.type || 'image/jpeg' })
|
||||
}
|
||||
|
||||
/**
|
||||
* 分享当前页面到 WhatsApp(兼容旧版本,推荐使用 shareCurrentPage)
|
||||
* @param title 分享的标题
|
||||
* @param description 分享的描述(可选)
|
||||
*/
|
||||
export async function shareCurrentPageToWhatsApp(title: string, description?: string): Promise<void> {
|
||||
await shareCurrentPage(title, description)
|
||||
}
|
||||
|
||||
/**
|
||||
* 分享图片到 WhatsApp(兼容旧版本,推荐使用 shareImage)
|
||||
* @param imageUrl 图片链接
|
||||
* @param title 分享的标题
|
||||
* @param description 分享的描述(可选)
|
||||
*/
|
||||
export async function shareImageToWhatsApp(imageUrl: string, title: string, description?: string): Promise<void> {
|
||||
await shareImage(imageUrl, title, description)
|
||||
}
|
||||
|
||||
@@ -80,8 +80,41 @@
|
||||
isLoveLoading.value = false
|
||||
})
|
||||
}
|
||||
const onDownloadItem = (v) => {
|
||||
// console.log('保存', v)
|
||||
|
||||
const shareImageToWhatsapp = async (url) => {
|
||||
// 把图片 URL 转为 Blob
|
||||
const blob = await fetch(url).then((res) => res.blob())
|
||||
|
||||
// 创建文件对象
|
||||
const file = new File([blob], 'image.jpg', { type: 'image/jpeg' })
|
||||
|
||||
// 判断浏览器是否支持文件分享
|
||||
if (navigator.canShare && navigator.canShare({ files: [file] })) {
|
||||
await navigator.share({
|
||||
files: [file]
|
||||
})
|
||||
} else {
|
||||
// 你可以附加一些自定义文本
|
||||
const message = 'share image ' + url
|
||||
|
||||
// 构造WhatsApp链接
|
||||
const whatsappLink = `https://api.whatsapp.com/send/?text=${encodeURIComponent(message)}`
|
||||
window.open(whatsappLink, '_blank')
|
||||
}
|
||||
}
|
||||
|
||||
const isShare = ref(false)
|
||||
const handleOpenShare = () => {
|
||||
isShare.value = !isShare.value
|
||||
|
||||
alert(`现在${isShare.value ? '可以' : '不可以'}分享`)
|
||||
}
|
||||
|
||||
const onDownloadItem = async (v) => {
|
||||
if (isShare.value) {
|
||||
await shareImageToWhatsapp(v.tryOnUrl)
|
||||
return
|
||||
}
|
||||
if (v.loading) return
|
||||
v.loading = true
|
||||
v.selected = false
|
||||
@@ -146,7 +179,7 @@
|
||||
|
||||
<template>
|
||||
<div class="creation-list">
|
||||
<div class="title">Your Creation</div>
|
||||
<div class="title" @click="handleOpenShare">Your Creation</div>
|
||||
<div class="list">
|
||||
<my-list v-model:loading="loading" v-model:finish="finish" @load="onLoad">
|
||||
<div class="item" v-for="(v, i) in list" :key="i" @click="onItem(v)">
|
||||
|
||||
@@ -110,12 +110,14 @@ defineExpose({})
|
||||
padding: 0 7.4rem;
|
||||
gap: 4.8rem;
|
||||
> .item{
|
||||
width: 44.2rem;
|
||||
height: 41.6rem;
|
||||
// width: 44.2rem;
|
||||
// height: 41.6rem;
|
||||
height: auto;
|
||||
width: calc(50% - 4.8rem / 2);
|
||||
> img{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
object-fit: contain;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user