Files
digital-psychology/apps/user-h5/src/lib/shareLink.ts
T
jackyu66gitandCursor bd22d9dddd feat: P1 合盘/星座/问答与测测完整设计包及模拟器取证工具
落地 synastry/star/ask API 与 H5 页面,补齐 cece-frontend-re complete-design 证据文档,并加入 Android 模拟器截图抓取脚本。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-03 11:37:53 +08:00

81 lines
2.2 KiB
TypeScript

/** Build / parse client-side share landing query (no server). */
export type PortraitSharePayload = {
type: 'portrait'
title: string
line: string
keywords: string[]
}
export type RelationSharePayload = {
type: 'relation'
me: string
other: string
diff: string
keywords: string[]
}
export type SharePayload = PortraitSharePayload | RelationSharePayload
export function buildSharePath(payload: SharePayload): string {
const q = new URLSearchParams()
q.set('type', payload.type)
if (payload.type === 'portrait') {
if (payload.title) q.set('t', payload.title)
if (payload.line) q.set('l', payload.line)
if (payload.keywords.length) q.set('k', payload.keywords.slice(0, 6).join(','))
} else {
if (payload.me) q.set('me', payload.me)
if (payload.other) q.set('ot', payload.other)
if (payload.diff) q.set('d', payload.diff)
if (payload.keywords.length) q.set('k', payload.keywords.slice(0, 6).join(','))
}
return `/share?${q.toString()}`
}
export function parseShareQuery(query: Record<string, unknown>): SharePayload | null {
const type = String(query.type || '')
const keywords = String(query.k || '')
.split(',')
.map((s) => s.trim())
.filter(Boolean)
if (type === 'portrait') {
const title = String(query.t || '')
const line = String(query.l || '')
if (!title && !line && !keywords.length) return null
return { type: 'portrait', title, line, keywords }
}
if (type === 'relation') {
const me = String(query.me || '')
const other = String(query.ot || '')
const diff = String(query.d || '')
if (!me && !other && !diff) return null
return { type: 'relation', me, other, diff, keywords }
}
return null
}
export async function copyText(text: string): Promise<boolean> {
try {
if (navigator.clipboard?.writeText) {
await navigator.clipboard.writeText(text)
return true
}
} catch {
/* fall through */
}
try {
const ta = document.createElement('textarea')
ta.value = text
ta.style.position = 'fixed'
ta.style.left = '-9999px'
document.body.appendChild(ta)
ta.select()
const ok = document.execCommand('copy')
document.body.removeChild(ta)
return ok
} catch {
return false
}
}