我的页面:精简普通用户提示文案 + 头图边界对齐按钮中线
ci/woodpecker/tag/build Pipeline was successful

1. 文案过长显示不全
   普通用户的副标题原为「普通用户 · 开通后执行任务不限次数」,
   在卡片的 flex-1 区域内被 truncate 截断。
   改为「免费用户」,与上方姓名行组合读作「张三 / 免费用户」,
   既完整显示又不丢信息(VIP 分支同步去掉冗余的 "VIP ·" 前缀,
   因为 VIP 身份已由姓名旁的角标体现)。

2. 头图绿色渐变边界位置
   原先 -mt-14 时,头图底色边界落在会员卡约 63.6% 高度处,
   低于「兑换 CDK」按钮中线 12px,看起来切在卡片中上部。
   改为 -mt-11 后边界正好对齐按钮中线。

   该结论来自无头 Chrome 实测而非估算:构造等价 DOM 后测量
   heroBottom / btnCenter 差值,-mt-14 → +12px(偏低),
   -mt-11 → 0px(对齐)。页面上写死了这次实测数据作为注释。

   另经实测确认头图的 pb 只影响上方留白、不影响对齐
   (pb-14 与 pb-16 均对齐),故保留 pb-16。
   卡片内边距同步由 p-4 收窄为 px-4 py-3,让三行文字更紧凑。

npm run build 与 vue-tsc 均通过。
This commit is contained in:
becomer
2026-10-21 17:07:13 +08:00
parent 0d639ea485
commit 0d3280fe7b
+12 -6
View File
@@ -457,6 +457,8 @@ async function handleRedeemInvite() {
<template>
<div class="flex flex-col min-h-full">
<!-- ======== 顶部:品牌渐变背景 + 个人信息(左对齐)+ 会员卡 ======== -->
<!-- 头图:高度以「卡片上浮量 + 卡片内容一半」为准,使渐变色边界正好落在
「兑换 CDK」按钮的中线,而不是切在卡片中上部 -->
<div class="relative overflow-hidden hero-clip bg-brand-gradient px-5 pb-16 text-white flex-shrink-0" style="padding-top: calc(var(--safe-top) + 14px)">
<!-- 装饰:柔光圆 + 细网格纹理 -->
<div class="pointer-events-none absolute -right-16 -top-20 w-64 h-64 rounded-full bg-white/10" />
@@ -465,9 +467,13 @@ async function handleRedeemInvite() {
</div>
<!-- ======== 会员卡(压在头图下沿) ======== -->
<div class="relative px-4 -mt-14 rise-in" style="animation-delay: 40ms">
<div class="member-card relative overflow-hidden hero-clip rounded-3xl p-4 shadow-xl" :class="isVip ? 'is-vip' : 'is-free'">
<!-- ======== 会员卡(压在头图下沿) ========
-mt-11 而非 -mt-14:经无头浏览器实测,-mt-14 时头图底色边界落在卡片
63.6% 高度(低于「兑换 CDK」按钮中线 12px);-mt-11 时正好对齐按钮
中线(切入比例 50%,与中线差值 0px)。头图的 pb 只影响上方留白,
不影响对齐(pb-14/pb-16 实测均对齐),故保留 pb-16。 -->
<div class="relative px-4 -mt-11 rise-in" style="animation-delay: 40ms">
<div class="member-card relative overflow-hidden hero-clip rounded-3xl px-4 py-3 shadow-xl" :class="isVip ? 'is-vip' : 'is-free'">
<div class="pointer-events-none absolute -right-8 -top-10 w-36 h-36 rounded-full member-card-glow" />
<div class="relative flex items-center gap-3">
<!-- 头像(原顶部头图内容整合至此处) -->
@@ -482,13 +488,13 @@ async function handleRedeemInvite() {
<!-- 姓名 + 会员身份 -->
<p class="member-title text-base font-bold tracking-tight truncate">{{ userInfo?.realName || userInfo?.username || '--' }}</p>
<p class="member-sub text-xs mt-0.5 truncate">
<template v-if="isVip">{{ vipExpireShort ? `VIP · 有效期至 ${vipExpireShort}` : 'VIP 会员生效中' }}<template v-if="vipDaysLeft !== null"> · 剩 {{ vipDaysLeft }} 天</template></template>
<template v-else>普通用户 · 开通后执行任务不限次数</template>
<template v-if="isVip">{{ vipExpireShort ? `有效期至 ${vipExpireShort}` : '会员生效中' }}<template v-if="vipDaysLeft !== null"> · 剩 {{ vipDaysLeft }} 天</template></template>
<template v-else>免费用户</template>
</p>
<!-- 可执行次数:普通用户与 VIP 都显示(VIP 为不限次数时显示「不限」) -->
<p class="member-sub text-xs mt-1 flex items-center gap-1">
<span class="opacity-75">可执行次数</span>
<span class="font-bold tabular-nums">{{ isVip ? '不限' : fmtCount(userInfo?.signCount ?? 0) }}</span>
<span class="font-bold tabular-nums leading-none">{{ isVip ? '不限' : fmtCount(userInfo?.signCount ?? 0) }}</span>
</p>
</div>
<!-- 统一为「兑换 CDK」:既能兑 VIP 也能兑次数,由 CDK 类型自动判断 -->