1584aabcc5
## profile-head 组件 头图 / 头像 / 昵称 / 签名 / 帖子关注粉丝 / 养宠数据 / 宠物名片墙, pages/mine 和 pages/user 用的是同一个组件、同一个接口 (GET /users/:id/profile)。 这件事必须一开始就做对:自己看和别人看要是两套渲染,会慢慢长歪, 装扮功能也就失去意义了——你调半天颜色,结果只有自己那页变了。 两边唯一的差别是底部按钮:自己看是「装扮我的主页」,别人看是「关注 TA」。 顺带把 mine 的头部从 /user/summary 切到了 /users/:id/profile。原来两边 字段对不上,装扮效果在「我的」页根本预览不到。 主题只在组件 wxss 里定义 --pf-a/--pf-b/--pf-ink 三个变量,下面所有着色 都走变量。后端存 key 不存色值,就是为了这套配色随时能在前端改。 ## pages/decorate 装扮页 头图上传 / 五套主题色 / 个性签名 60 字 / 宠物墙开关,顶部实时预览。 预览用的就是 profile-head 本身,不是仿一个——仿的迟早会和真的长得不一样。 喂给它一份改过的 card 就行,组件那边不需要知道自己在被预览。 头图有个坑单独处理了:bg_file_id 只在真动过的时候才传。新上传带新 id, 点「恢复默认渐变」带空串,都没动就不传字段。否则「只改个主题色」会把 已有头图冲掉。上传时先用本地临时路径顶上,不让用户对着转圈等。 联调验证(本地 9090,真上传了一张图走完存储链路): 上传 → file id + MinIO url 保存装扮 → bg_url 落库,主题 violet,签名落库 主页读回 → bio/theme/show_pets/bg_url/宠物墙/养宠数据 全对 只改主题 → theme 变 sky,头图还在(没被冲掉) 恢复默认渐变 → bg_url 清空,theme 和 bio 都没被动 别人视角 → is_self=false、followed=false,装扮和宠物墙都能看到 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
60 lines
2.6 KiB
Plaintext
60 lines
2.6 KiB
Plaintext
/* 主题只在这里定义两个变量,下面所有着色都走变量。
|
|
后端存的是 theme key 不是色值,就是为了这套配色能随时在前端改。 */
|
|
.pf{--pf-a:#F5A947;--pf-b:#FFE6BA;--pf-ink:#8A5A18}
|
|
.th-warm{--pf-a:#F5A947;--pf-b:#FFE6BA;--pf-ink:#8A5A18}
|
|
.th-mint{--pf-a:#3FB98A;--pf-b:#D7F3E7;--pf-ink:#1F6B4E}
|
|
.th-sky{--pf-a:#4A9BE0;--pf-b:#D8ECFB;--pf-ink:#245F94}
|
|
.th-violet{--pf-a:#9B7BE0;--pf-b:#E8DFFA;--pf-ink:#5B3F9B}
|
|
.th-ink{--pf-a:#5A5550;--pf-b:#E4DED7;--pf-ink:#2D2925}
|
|
|
|
.pf{
|
|
background:#fff;border-radius:var(--r-lg);overflow:hidden;
|
|
box-shadow:var(--sd-1);margin-bottom:var(--sp-5);
|
|
}
|
|
.pf-bg{height:220rpx;background:linear-gradient(135deg,var(--pf-a),var(--pf-b));position:relative}
|
|
.pf-bg-img{width:100%;height:100%;display:block}
|
|
|
|
.pf-body{padding:0 var(--sp-5) var(--sp-5);text-align:center}
|
|
/* 头像压在头图上,负 margin 提上去一半 */
|
|
.pf-av{
|
|
width:144rpx;height:144rpx;margin:-72rpx auto var(--sp-3);
|
|
border-radius:50%;background:var(--pf-b);color:var(--pf-ink);
|
|
display:flex;align-items:center;justify-content:center;
|
|
font-size:var(--fs-xl);font-weight:var(--fw-b);
|
|
border:6rpx solid #fff;overflow:hidden;box-shadow:var(--sd-1);
|
|
}
|
|
.pf-av-img{width:100%;height:100%;display:block}
|
|
.pf-name{font-size:var(--fs-lg);font-weight:var(--fw-b);color:var(--text)}
|
|
.pf-bio{
|
|
font-size:var(--fs-sm);color:var(--muted);margin-top:6rpx;
|
|
line-height:1.5;word-break:break-all;
|
|
}
|
|
|
|
.pf-stats{display:flex;margin:var(--sp-4) 0}
|
|
.pf-stat{flex:1;display:flex;flex-direction:column;align-items:center;gap:4rpx}
|
|
.pf-n{font-size:var(--fs-lg);font-weight:var(--fw-b);color:var(--text)}
|
|
.pf-l{font-size:var(--fs-cap);color:var(--muted)}
|
|
|
|
.pf-keep{
|
|
display:flex;background:var(--pf-b);border-radius:var(--r-md);
|
|
padding:var(--sp-3) 0;margin-bottom:var(--sp-4);
|
|
}
|
|
.pf-keep-i{flex:1;display:flex;flex-direction:column;align-items:center;gap:2rpx}
|
|
.pf-kn{font-size:var(--fs-md);font-weight:var(--fw-b);color:var(--pf-ink)}
|
|
.pf-kl{font-size:var(--fs-cap);color:var(--pf-ink);opacity:.75}
|
|
|
|
.pf-wall{white-space:nowrap;margin-bottom:var(--sp-4)}
|
|
.pf-pet{
|
|
display:inline-block;width:150rpx;vertical-align:top;
|
|
margin-right:var(--sp-3);white-space:normal;
|
|
}
|
|
.pf-pet:last-child{margin-right:0}
|
|
.pf-pet-av{
|
|
width:112rpx;height:112rpx;margin:0 auto 8rpx;border-radius:var(--r-md);
|
|
background:var(--surface-2);display:flex;align-items:center;justify-content:center;
|
|
font-size:52rpx;overflow:hidden;
|
|
}
|
|
.pf-pet-img{width:100%;height:100%;display:block}
|
|
.pf-pet-n{font-size:var(--fs-cap);font-weight:var(--fw-b);color:var(--text);text-align:center}
|
|
.pf-pet-s{font-size:var(--fs-cap);color:var(--muted);text-align:center}
|