Files
digital-psychology/apps/user-h5/src/pages/SharePage.vue
T
jackyu66gitandCursor 53eb4577b3 feat: 按测测功能重构 H5 首页与各子页,并修正顶栏「+」添加档案菜单
对齐测测交互:首页「+」支持邀请填档案/添加档案/邀请合盘;各 Tab 与工具页按同一视觉与功能标准落地;本地对照截图目录显式忽略。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-05 14:32:35 +08:00

141 lines
3.9 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<PageShell>
<template #hero>
<div class="top-row">
<BackButton />
<span class="who-static">分享</span>
<span class="spacer" />
</div>
</template>
<div class="body">
<template v-if="!payload">
<div class="empty-hero">
<HomeToolIcon name="ask" :size="64" />
<h1 class="hero-title">分享内容无效</h1>
<p class="hero-sub">链接可能已过期你可以从首页重新开始</p>
<router-link class="cta" to="/">回首页</router-link>
</div>
</template>
<template v-else>
<div class="hero-block">
<HomeToolIcon :name="payload.type === 'relation' ? 'relation' : 'portrait'" :size="64" />
<h1 class="hero-title">{{ shareTitle }}</h1>
<p class="hero-sub">{{ shareSub }}</p>
</div>
<ShareCard v-bind="cardProps" />
<div class="actions">
<router-link class="cta" :to="ctaTo">{{ ctaText }}</router-link>
<router-link class="ghost-link" to="/">先逛逛首页</router-link>
</div>
<p class="yxg-disc">本内容为自我探索与生活方式参考不构成医疗建议亦非占卜预测</p>
</template>
</div>
</PageShell>
</template>
<script setup lang="ts">
import { computed } from 'vue'
import { useRoute } from 'vue-router'
import BackButton from '../components/BackButton.vue'
import HomeToolIcon from '../components/HomeToolIcon.vue'
import PageShell from '../components/PageShell.vue'
import ShareCard from '../components/ShareCard.vue'
import { parseShareQuery } from '../lib/shareLink'
const route = useRoute()
const payload = computed(() => parseShareQuery(route.query as Record<string, unknown>))
const shareTitle = computed(() => {
const p = payload.value
if (!p) return '分享'
return p.type === 'relation' ? '关系理解分享' : '个人画像分享'
})
const shareSub = computed(() => {
const p = payload.value
if (!p) return ''
return p.type === 'relation' ? '朋友分享了一段关系理解' : '朋友分享了一份个人画像'
})
const cardProps = computed(() => {
const p = payload.value
if (!p) return {}
if (p.type === 'portrait') {
return {
type: 'portrait' as const,
title: p.title,
line: p.line,
keywords: p.keywords,
ctaLabel: '查看完整成长报告',
}
}
return {
type: 'relation' as const,
title: '我的方式 vs TA 的方式',
rows: [p.me ? `我:${p.me}` : '', p.other ? `TA${p.other}` : '', p.diff || ''].filter(Boolean),
keywords: p.keywords,
ctaLabel: '了解彼此 → 查看关系理解',
}
})
const ctaTo = computed(() => (payload.value?.type === 'relation' ? '/relation' : '/'))
const ctaText = computed(() =>
payload.value?.type === 'relation' ? '开始关系理解' : '生成我的个人画像',
)
</script>
<style scoped>
.top-row {
display: flex;
align-items: center;
gap: 10px;
padding-bottom: 4px;
}
.who-static { flex: 1; font-size: 16px; font-weight: 700; text-align: center; }
.spacer { width: 36px; }
.body { padding: 8px 16px 24px; }
.hero-block, .empty-hero {
text-align: center;
padding: 20px 12px 16px;
}
.hero-title {
font-family: var(--font-display);
font-size: 22px;
font-weight: 700;
margin-top: 10px;
letter-spacing: 0.06em;
color: #222;
}
.hero-sub {
font-size: 13px;
color: #888;
margin-top: 8px;
line-height: 1.5;
}
.cta {
display: block;
width: 100%;
margin-top: 18px;
padding: 13px;
border-radius: 22px;
text-align: center;
color: #fff;
font-size: 15px;
font-weight: 600;
background: linear-gradient(135deg, #ff7a6e, var(--color-primary));
box-shadow: 0 6px 16px rgba(229, 77, 66, 0.28);
}
.actions { margin-top: 8px; }
.ghost-link {
display: block;
text-align: center;
margin-top: 12px;
font-size: 13px;
color: #999;
}
.empty-hero .cta { max-width: 280px; margin: 18px auto 0; }
</style>