Compare commits

...

2 Commits

Author SHA1 Message Date
d55ed60907 checkpoint: pre-refactor state before fixing P0/P1 issues 2026-06-11 18:40:59 +08:00
2c3c2653fa style: 按毛玻璃设计稿重做广场/附近/发布/汪友/我的五大页面视觉
参照 wangquan_glass_redesign_mockup.html 的玻璃拟态(glassmorphism)设计语言重写前端展示样式:
- app.wxss: 引入 coral/tangerine/lemon/mint/sky/lilac 色板与 .glass/.glass-strong/.sticker-tag 毛玻璃工具类,背景改为纯白
- custom-tab-bar: 改为悬浮玻璃浮岛(.tab-dock),含液态光泽动画与渐变发布按钮(FAB)
- feed: 故事条改为方形圆角描边+conic渐变,顶部操作按钮、骨架屏改为玻璃质感
- post-card 组件: 卡片/贴纸标签/操作按钮全面玻璃化,点赞按钮改为渐变高亮
- nearby: 地图控件、宠物弹窗、列表项、预览条统一为毛玻璃卡片
- post: 上传区/输入框/标签pill/心情选择器改为玻璃质感+渐变选中态
- friends: 空态与好友列表项改为玻璃卡片
- profile: 用户信息区改为带渐变光斑的玻璃英雄卡,统计/宠物卡/动态网格同步玻璃化

未改动页面结构(WXML)与业务逻辑(TS),仅升级视觉样式(WXSS),保持程序可运行。
2026-06-08 11:36:38 +08:00
41 changed files with 1317 additions and 941 deletions

View File

@@ -27,6 +27,11 @@ exports.main = async (event, context) => {
updatedAt: db.serverDate(), updatedAt: db.serverDate(),
} }
// geo.near 距离查询字段;无定位时整个字段省略(写 null 会让地理索引构建失败)
if (location && typeof location.latitude === 'number' && typeof location.longitude === 'number') {
post.geo = db.Geo.Point(location.longitude, location.latitude)
}
const res = await db.collection('posts').add({ data: post }) const res = await db.collection('posts').add({ data: post })
// 更新用户帖子统计 // 更新用户帖子统计

View File

@@ -2,49 +2,119 @@ const cloud = require('wx-server-sdk')
cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV })
const db = cloud.database() const db = cloud.database()
const _ = db.command const _ = db.command
const $ = db.command.aggregate
const PAGE_SIZE = 10 const PAGE_SIZE = 10
// 按 where 条件取一页,时间倒序(关注流 / 个人主页 / 附近兜底共用)
async function listByWhere(where, skip) {
const col = db.collection('posts').where(where)
const countRes = await col.count()
const res = await col
.orderBy('createdAt', 'desc')
.skip(skip)
.limit(PAGE_SIZE)
.get()
return {
posts: res.data,
total: countRes.total,
hasMore: skip + res.data.length < countRes.total,
}
}
// 热门:热度分 = (点赞×3 + 评论×5 + 1) / (帖龄小时数 + 2)^1.5
// 类 Hacker News 的重力衰减,互动加分、随时间下沉;同分按发布时间倒序
async function listHot(skip) {
const countRes = await db.collection('posts').count()
const res = await db.collection('posts').aggregate()
.addFields({
hotScore: $.divide([
$.add([
$.multiply([$.ifNull(['$likeCount', 0]), 3]),
$.multiply([$.ifNull(['$commentCount', 0]), 5]),
1,
]),
$.pow([
$.add([
$.divide([$.subtract([new Date(), '$createdAt']), 3600000]),
2,
]),
1.5,
]),
]),
})
.sort({ hotScore: -1, createdAt: -1 })
.skip(skip)
.limit(PAGE_SIZE)
.end()
return {
posts: res.list,
total: countRes.total,
hasMore: skip + res.list.length < countRes.total,
}
}
// 附近geo.near 按距离由近到远,依赖 posts.geo 的地理位置索引;
// 索引未建或查询失败时回退为矩形围栏 + 时间倒序。
// $near 不支持 count用多取一条判断 hasMoretotal 为近似值
async function listNearby(latitude, longitude, skip) {
try {
const res = await db.collection('posts')
.where({
geo: _.geoNear({
geometry: db.Geo.Point(longitude, latitude),
maxDistance: 10000,
}),
})
.skip(skip)
.limit(PAGE_SIZE + 1)
.get()
const hasMore = res.data.length > PAGE_SIZE
const posts = hasMore ? res.data.slice(0, PAGE_SIZE) : res.data
return { posts, total: skip + posts.length + (hasMore ? 1 : 0), hasMore }
} catch (e) {
return listByWhere(
_.and([
{ 'location.latitude': _.gt(latitude - 0.1) },
{ 'location.latitude': _.lt(latitude + 0.1) },
{ 'location.longitude': _.gt(longitude - 0.15) },
{ 'location.longitude': _.lt(longitude + 0.15) },
]),
skip
)
}
}
exports.main = async (event, context) => { exports.main = async (event, context) => {
const { OPENID } = cloud.getWXContext() const { OPENID } = cloud.getWXContext()
const { page = 0, type = 'hot', userId, latitude, longitude } = event const { page = 0, type = 'hot', userId, latitude, longitude } = event
const skip = page * PAGE_SIZE
try { try {
let query = db.collection('posts') let result
const skip = page * PAGE_SIZE
if (userId) { if (userId) {
// 某用户的帖子 // 某用户的帖子
query = query.where({ authorId: userId }) result = await listByWhere({ authorId: userId }, skip)
} else if (type === 'feed') { } else if (type === 'feed') {
// 关注的用户帖子 // 关注流:我关注的人 + 自己
const followsRes = await db.collection('follows') const followsRes = await db.collection('follows')
.where({ followerId: OPENID }) .where({ followerId: OPENID })
.field({ followeeId: true }) .field({ followeeId: true })
.get() .get()
const followeeIds = followsRes.data.map(f => f.followeeId) const followeeIds = followsRes.data.map(f => f.followeeId)
followeeIds.push(OPENID) followeeIds.push(OPENID)
query = query.where({ authorId: _.in(followeeIds) }) result = await listByWhere({ authorId: _.in(followeeIds) }, skip)
} else if (type === 'nearby' && latitude && longitude) { } else if (type === 'nearby' && latitude && longitude) {
// 附近帖子:使用地理围栏查询(简化版,用 geo_near result = await listNearby(latitude, longitude, skip)
query = query.where( } else {
_.and([ result = await listHot(skip)
{ 'location.latitude': _.gt(latitude - 0.1) },
{ 'location.latitude': _.lt(latitude + 0.1) },
{ 'location.longitude': _.gt(longitude - 0.15) },
{ 'location.longitude': _.lt(longitude + 0.15) },
])
)
} }
// type === 'hot' 全量按热度排序
const total = await query.count() const { posts, total, hasMore } = result
const postsRes = await query
.orderBy('createdAt', 'desc')
.skip(skip)
.limit(PAGE_SIZE)
.get()
const posts = postsRes.data if (posts.length === 0) {
return { code: 0, data: { list: [], total, hasMore: false } }
}
// 批量获取作者信息 // 批量获取作者信息
const authorIds = [...new Set(posts.map(p => p.authorId))] const authorIds = [...new Set(posts.map(p => p.authorId))]
@@ -71,11 +141,7 @@ exports.main = async (event, context) => {
return { return {
code: 0, code: 0,
data: { data: { list: enriched, total, hasMore },
list: enriched,
total: total.total,
hasMore: skip + posts.length < total.total,
},
} }
} catch (e) { } catch (e) {
return { code: -1, message: e.message } return { code: -1, message: e.message }

11
i18n/base.json Normal file
View File

@@ -0,0 +1,11 @@
{
"ios": {
"name": "汪圈"
},
"android": {
"name": "汪圈"
},
"common": {
"name": "汪圈"
}
}

View File

@@ -18,8 +18,8 @@
], ],
"tabBar": { "tabBar": {
"custom": true, "custom": true,
"color": "#9b8fa8", "color": "#b9bdc6",
"selectedColor": "#ff4f91", "selectedColor": "#2b2b30",
"backgroundColor": "#ffffff", "backgroundColor": "#ffffff",
"list": [ "list": [
{ "pagePath": "pages/feed/feed", "text": "广场" }, { "pagePath": "pages/feed/feed", "text": "广场" },
@@ -31,7 +31,7 @@
"window": { "window": {
"navigationStyle": "custom", "navigationStyle": "custom",
"backgroundTextStyle": "dark", "backgroundTextStyle": "dark",
"backgroundColor": "#fff9fb" "backgroundColor": "#f1f2f6"
}, },
"permission": { "permission": {
"scope.userLocation": { "scope.userLocation": {

View File

@@ -0,0 +1,5 @@
{
"adapteByMiniprogram": {
"userName": "gh_994b4ce3ce01"
}
}

View File

@@ -1,38 +1,63 @@
/* ── 全局设计令牌 ── */ /* ── 全局设计令牌:Vital 风格(参考 vital_style_reference.md)──
单一紫色主色 + 黑白灰层级:强调动作用黑,品牌用紫,其余靠灰度撑层级 */
page { page {
--pink: #ff4f91; /* 主色板 */
--pink-light: #ffe5f0; --purple: #8b7cf6;
--orange: #ff9f1c; --purple-light: #a99bf8;
--yellow: #ffe15a; --purple-deep: #7563e0;
--green: #2fd37a; --accent-dark: #2b2b30;
--mint: #67e8c9;
--blue: #4d8dff;
--violet: #8c5cff;
--ink: #272235;
--bg-primary: #fff9fb; /* 兼容旧变量名:六彩体系全部收敛到 Vital 色板,
--bg-page: linear-gradient(180deg, #fff8f2 0%, #fff4fb 50%, #f5f0ff 100%); 旧渐变 coral→tangerine 自动变为 紫→浅紫 */
--coral: var(--purple);
--tangerine: var(--purple-light);
--lemon: var(--purple-light);
--mint: #4bbe9a;
--sky: var(--purple);
--lilac: var(--purple);
--text-primary: #272235; --pink: var(--purple);
--text-secondary: #6a6178; --pink-light: rgba(139, 124, 246, 0.12);
--text-tertiary: #9b8fa8; --orange: var(--purple-light);
--yellow: var(--purple-light);
--green: var(--mint);
--blue: var(--purple);
--violet: var(--purple);
--ink: #1b1b20;
--border-card: rgba(255, 255, 255, 0.72); --bg-primary: #f1f2f6;
--border-subtle: rgba(43, 37, 61, 0.08); --bg-page: #f1f2f6;
--shadow-soft: 0 18rpx 40rpx rgba(95, 49, 104, 0.12); --text-primary: #1b1b20;
--shadow-card: 0 10rpx 28rpx rgba(78, 56, 96, 0.10); --text-secondary: #6e7280;
--shadow-pop: 0 10rpx 22rpx rgba(255, 79, 145, 0.28); --text-tertiary: #b9bdc6;
--radius-sm: 16rpx; /* 紫底上的半透明白(头部胶囊、次级卡片) */
--radius-md: 28rpx; --on-primary: rgba(255, 255, 255, 0.22);
--radius-lg: 44rpx; --on-primary-strong: rgba(255, 255, 255, 0.32);
/* 旧玻璃变量 → 实底白卡 */
--glass: #ffffff;
--glass-strong: #ffffff;
--glass-edge: rgba(255, 255, 255, 0);
--border-card: rgba(255, 255, 255, 0);
--border-subtle: rgba(27, 27, 32, 0.06);
/* 中性阴影:大模糊、低不透明度,光源一致来自上方 */
--shadow-soft: 0 16rpx 48rpx rgba(27, 27, 32, 0.06);
--shadow-card: 0 16rpx 48rpx rgba(27, 27, 32, 0.06);
--shadow-pop: 0 12rpx 32rpx rgba(43, 43, 48, 0.22);
--radius-sm: 20rpx;
--radius-md: 32rpx;
--radius-lg: 48rpx;
--radius-full: 9999rpx; --radius-full: 9999rpx;
--tab-h: 112rpx; --tab-h: 112rpx;
font-family: "PingFang SC", "Helvetica Neue", Arial, sans-serif; font-family: "PingFang SC", "Helvetica Neue", Arial, sans-serif;
background: var(--bg-primary); background: var(--bg-page);
color: var(--text-primary); color: var(--text-primary);
font-size: 28rpx; font-size: 28rpx;
line-height: 1.5; line-height: 1.5;
@@ -57,26 +82,92 @@ button::after {
border: none; border: none;
} }
/* ── 通用卡片 ── */ /* ── 通用卡片:纯白实底、大圆角、柔和中性阴影 ── */
.card { .card {
background: rgba(255, 255, 255, 0.86); background: #ffffff;
border: 1rpx solid var(--border-card);
border-radius: var(--radius-lg); border-radius: var(--radius-lg);
box-shadow: var(--shadow-soft); box-shadow: var(--shadow-soft);
overflow: hidden; overflow: hidden;
} }
/* ── 渐变按钮 ── */ /* ── 旧玻璃工具类 → 实底白卡(Vital 无毛玻璃,靠层叠和阴影做深度) ── */
.glass {
background: #ffffff;
box-shadow: var(--shadow-soft);
}
.glass-strong {
background: #ffffff;
box-shadow: var(--shadow-soft);
}
/* ── 标签:白色小胶囊,不再旋转 ── */
.sticker-tag {
position: absolute;
background: #ffffff;
color: var(--text-primary);
font-size: 22rpx;
font-weight: 600;
padding: 10rpx 22rpx;
border-radius: var(--radius-full);
box-shadow: var(--shadow-soft);
}
.sticker-tag.tilt-r {
transform: none;
}
/* ── 主按钮:黑色胶囊(Vital 的 CTA 用强调黑,不用主题色) ── */
.btn-primary { .btn-primary {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
background: linear-gradient(135deg, var(--pink), var(--orange)); background: var(--accent-dark);
color: #fff; color: #fff;
border-radius: var(--radius-full); border-radius: var(--radius-full);
font-size: 28rpx; font-size: 28rpx;
font-weight: 800; font-weight: 600;
box-shadow: var(--shadow-pop); box-shadow: var(--shadow-pop);
transition: transform 0.15s ease, opacity 0.15s ease;
}
.btn-primary:active {
transform: scale(0.98);
opacity: 0.9;
}
/* ── 数字分级排版:整数超大加粗 + 小数/单位缩小变灰 ── */
.num-xl {
font-size: 96rpx;
font-weight: 700;
letter-spacing: -2rpx;
line-height: 1;
color: var(--text-primary);
font-variant-numeric: tabular-nums;
}
.num-sub {
font-size: 40rpx;
font-weight: 600;
color: var(--text-tertiary);
font-variant-numeric: tabular-nums;
}
/* ── 信息行:左数字、右说明 + chevron,中间渐隐细线 ── */
.row-line {
flex: 1;
height: 2rpx;
margin: 0 20rpx;
background: linear-gradient(90deg, rgba(27, 27, 32, 0.10), rgba(27, 27, 32, 0.02));
}
.chevron {
width: 16rpx;
height: 16rpx;
border-top: 4rpx solid var(--text-tertiary);
border-right: 4rpx solid var(--text-tertiary);
transform: rotate(45deg);
flex-shrink: 0;
} }
/* ── 页面顶部状态栏占位 ── */ /* ── 页面顶部状态栏占位 ── */
@@ -84,39 +175,44 @@ button::after {
height: env(safe-area-inset-top, 44rpx); height: env(safe-area-inset-top, 44rpx);
} }
/* ── 紫色渐变淡出头部:从顶部主色向下融入页面背景,无分界线 ── */
.hero-fade {
background: linear-gradient(180deg, #9181f4 0%, #a99bf8 55%, rgba(169, 155, 248, 0) 100%);
}
/* ── 滚动区通用 ── */ /* ── 滚动区通用 ── */
.scroll-view { .scroll-view {
width: 100%; width: 100%;
} }
/* ── Hashtag 标签 ── */ /* ── Hashtag 标签:主色淡紫底 ── */
.hashtag { .hashtag {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
font-size: 22rpx; font-size: 22rpx;
font-weight: 800; font-weight: 600;
color: #8b3cff; color: var(--purple-deep);
background: #f0e8ff; background: var(--pink-light);
border-radius: var(--radius-full); border-radius: var(--radius-full);
padding: 6rpx 14rpx; padding: 6rpx 14rpx;
} }
/* ── 在线绿点 ── */ /* ── 在线绿点(语义色,保留但降饱和) ── */
.online-dot { .online-dot {
width: 14rpx; width: 14rpx;
height: 14rpx; height: 14rpx;
border-radius: 50%; border-radius: 50%;
background: var(--green); background: var(--mint);
flex-shrink: 0; flex-shrink: 0;
box-shadow: 0 0 0 5rpx rgba(47, 211, 122, 0.18); box-shadow: 0 0 0 5rpx rgba(75, 190, 154, 0.16);
} }
/* ── 骨架屏占位 ── */ /* ── 骨架屏占位:中性冷灰 ── */
.skeleton { .skeleton {
background: linear-gradient(90deg, #f0eef5 25%, #e8e4f0 50%, #f0eef5 75%); background: linear-gradient(90deg, #ebecf1 25%, #e2e4ea 50%, #ebecf1 75%);
background-size: 200% 100%; background-size: 200% 100%;
animation: skeleton-shine 1.4s infinite; animation: skeleton-shine 1.4s infinite;
border-radius: 8rpx; border-radius: 12rpx;
} }
@keyframes skeleton-shine { @keyframes skeleton-shine {
@@ -124,6 +220,84 @@ button::after {
100% { background-position: -200% 0; } 100% { background-position: -200% 0; }
} }
/* ── 固定顶栏:液态玻璃,置于图层顶层,高度固定(状态栏 + 导航栏) ──
下层内容滚动/下拉时始终钉在顶部 */
.glass-topbar {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 100;
background:
radial-gradient(120% 180% at 18% -50%, rgba(255, 255, 255, 0.42), transparent 60%),
rgba(255, 255, 255, 0.52);
backdrop-filter: blur(40rpx) saturate(180%);
-webkit-backdrop-filter: blur(40rpx) saturate(180%);
border-bottom: 1rpx solid rgba(255, 255, 255, 0.55);
box-shadow:
0 8rpx 28rpx rgba(27, 27, 32, 0.05),
inset 0 1rpx 0 rgba(255, 255, 255, 0.7);
}
/* 顶栏上的标题:玻璃上用深色文字 */
.glass-topbar .topbar-logo,
.glass-topbar .navbar-title {
color: #1b1b20;
}
.glass-topbar .logo-accent {
color: var(--purple);
}
/* ── 顶栏图标按钮:线条化图标,右侧紧贴小程序胶囊按钮 ── */
.navbar-action {
margin-left: auto;
margin-right: 8rpx;
width: 64rpx;
height: 64rpx;
display: flex;
align-items: center;
justify-content: center;
position: relative;
}
.navbar-action:active {
opacity: 0.6;
}
/* 线条图标:单色 alpha 蒙版 + background-color 上色 */
.icon-line {
width: 44rpx;
height: 44rpx;
background-color: #1b1b20;
-webkit-mask-repeat: no-repeat;
-webkit-mask-position: center;
-webkit-mask-size: contain;
}
/* 搜索:线条放大镜 */
.icon-search-line {
-webkit-mask-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0OCA0OCI+PGcgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9IjMuNiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIj48Y2lyY2xlIGN4PSIyMSIgY3k9IjIxIiByPSIxMi41Ii8+PHBhdGggZD0iTTMwLjUgMzAuNUw0MSA0MSIvPjwvZz48L3N2Zz4=");
}
/* 通知:线条铃铛 */
.icon-bell-line {
-webkit-mask-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0OCA0OCI+PGcgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9IjMuNiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIj48cGF0aCBkPSJNMjQgN2ExMyAxMyAwIDAgMC0xMyAxM3Y3LjVMNyAzNWgzNGwtNC03LjVWMjBBMTMgMTMgMCAwIDAgMjQgN1oiLz48cGF0aCBkPSJNMTkuNSAzOC41YTQuOCA0LjggMCAwIDAgOSAwIi8+PC9nPjwvc3ZnPg==");
}
/* 图标按钮上的未读红点 */
.navbar-action.has-badge::after {
content: '';
position: absolute;
top: 6rpx;
right: 6rpx;
width: 14rpx;
height: 14rpx;
border-radius: 50%;
background: var(--purple);
border: 2rpx solid #fff;
}
/* ── 安全区 ── */ /* ── 安全区 ── */
.safe-top { .safe-top {
background: transparent; background: transparent;

View File

@@ -1,10 +1,10 @@
/* ── 帖子卡片:纯白实底、大圆角、中性柔和阴影(Vital 风格) ── */
.post-card { .post-card {
margin: 0 28rpx 32rpx; margin: 0 28rpx 32rpx;
background: rgba(255, 255, 255, 0.88); background: #ffffff;
border-radius: 48rpx; border-radius: 48rpx;
border: 1rpx solid rgba(255, 255, 255, 0.72);
overflow: hidden; overflow: hidden;
box-shadow: 0 18rpx 40rpx rgba(95, 49, 104, 0.12); box-shadow: 0 16rpx 48rpx rgba(27, 27, 32, 0.06);
} }
/* 头部 */ /* 头部 */
@@ -16,17 +16,16 @@
} }
.post-avatar { .post-avatar {
width: 76rpx; width: 80rpx;
height: 76rpx; height: 80rpx;
border-radius: 28rpx; border-radius: 30rpx;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
font-size: 32rpx; font-size: 32rpx;
font-weight: 800; font-weight: 700;
color: rgba(39, 34, 53, 0.72); color: rgba(27, 27, 32, 0.65);
flex-shrink: 0; flex-shrink: 0;
box-shadow: inset 0 0 0 2rpx rgba(255, 255, 255, 0.8);
} }
.post-meta { .post-meta {
@@ -37,8 +36,8 @@
.post-username { .post-username {
display: block; display: block;
font-size: 28rpx; font-size: 28rpx;
font-weight: 800; font-weight: 600;
color: #272235; color: #1b1b20;
} }
.post-loc { .post-loc {
@@ -52,7 +51,7 @@
.loc-text { .loc-text {
font-size: 22rpx; font-size: 22rpx;
color: #9b8fa8; color: #b9bdc6;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
@@ -60,7 +59,7 @@
.post-time { .post-time {
font-size: 22rpx; font-size: 22rpx;
color: #9b8fa8; color: #b9bdc6;
flex-shrink: 0; flex-shrink: 0;
} }
@@ -73,19 +72,21 @@
width: 100%; width: 100%;
height: 360rpx; height: 360rpx;
display: block; display: block;
background: #f0eef5; background: #eef0f5;
} }
/* 心情标签:白色小胶囊,不旋转 */
.post-tag-chip { .post-tag-chip {
position: absolute; position: absolute;
top: 20rpx; top: 22rpx;
left: 20rpx; left: 22rpx;
background: rgba(39, 34, 53, 0.88); background: #ffffff;
color: #fff; color: #1b1b20;
font-size: 20rpx; font-size: 21rpx;
font-weight: 800; font-weight: 600;
padding: 8rpx 18rpx; padding: 10rpx 22rpx;
border-radius: 999rpx; border-radius: 999rpx;
box-shadow: 0 10rpx 26rpx rgba(27, 27, 32, 0.12);
} }
.post-img-grid { .post-img-grid {
@@ -116,7 +117,7 @@
.img-grid-item { .img-grid-item {
width: 100%; width: 100%;
height: 100%; height: 100%;
background: #f0eef5; background: #eef0f5;
} }
/* 正文区 */ /* 正文区 */
@@ -127,7 +128,7 @@
.post-caption { .post-caption {
display: block; display: block;
font-size: 28rpx; font-size: 28rpx;
color: #272235; color: #1b1b20;
line-height: 1.6; line-height: 1.6;
margin-bottom: 16rpx; margin-bottom: 16rpx;
} }
@@ -143,9 +144,9 @@
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
font-size: 22rpx; font-size: 22rpx;
font-weight: 800; font-weight: 600;
color: #8b3cff; color: #7563e0;
background: #f0e8ff; background: rgba(139, 124, 246, 0.12);
border-radius: 999rpx; border-radius: 999rpx;
padding: 6rpx 14rpx; padding: 6rpx 14rpx;
} }
@@ -153,9 +154,9 @@
/* 操作栏 */ /* 操作栏 */
.post-actions { .post-actions {
display: flex; display: flex;
gap: 16rpx; gap: 14rpx;
padding-top: 18rpx; padding-top: 20rpx;
border-top: 1rpx solid rgba(43, 37, 61, 0.07); border-top: 1rpx solid rgba(27, 27, 32, 0.06);
} }
.action-btn { .action-btn {
@@ -163,16 +164,23 @@
align-items: center; align-items: center;
gap: 8rpx; gap: 8rpx;
font-size: 24rpx; font-size: 24rpx;
font-weight: 800; font-weight: 600;
color: #6a6178; color: #6e7280;
background: #f7f3ff; background: #f1f2f6;
border-radius: 999rpx; border-radius: 999rpx;
padding: 10rpx 18rpx; padding: 12rpx 22rpx;
transition: transform 0.18s ease, background 0.18s ease, color 0.18s ease;
} }
.action-btn:active {
transform: scale(0.95);
}
/* 已赞:强调黑胶囊(动作强调不用主题色) */
.action-btn.liked { .action-btn.liked {
color: #ff4f91; color: #fff;
background: #ffe5f0; background: #2b2b30;
box-shadow: 0 10rpx 24rpx rgba(43, 43, 48, 0.24);
} }
.action-icon { .action-icon {
@@ -182,4 +190,5 @@
.action-count { .action-count {
font-size: 24rpx; font-size: 24rpx;
font-variant-numeric: tabular-nums;
} }

View File

@@ -12,7 +12,8 @@ Component({
methods: { methods: {
onTab(e: WechatMiniprogram.CustomEvent) { onTab(e: WechatMiniprogram.CustomEvent) {
const index = e.currentTarget.dataset.index as number // dataset 取出的是字符串,必须转数字,否则 WXML 中 selected === n 严格比较失败
const index = Number(e.currentTarget.dataset.index)
const path = e.currentTarget.dataset.path as string const path = e.currentTarget.dataset.path as string
if (index === this.data.selected) return if (index === this.data.selected) return
this.setData({ selected: index }) this.setData({ selected: index })

View File

@@ -1,23 +1,16 @@
<view class="tab-bar"> <view class="tab-dock">
<!-- 广场 --> <!-- 广场 -->
<view class="tab-item {{selected === 0 ? 'active' : ''}}" bindtap="onTab" data-index="0" data-path="/pages/feed/feed"> <view class="tab-pill {{selected === 0 ? 'active' : ''}}" bindtap="onTab" data-index="0" data-path="/pages/feed/feed">
<view class="icon-wrap"> <view class="icon-wrap">
<view class="icon-grid"> <view class="tab-icon icon-feed"></view>
<view class="sq"></view><view class="sq"></view>
<view class="sq"></view><view class="sq"></view>
</view>
</view> </view>
<text class="tab-label">广场</text> <text class="tab-label">广场</text>
</view> </view>
<!-- 附近 --> <!-- 附近 -->
<view class="tab-item {{selected === 1 ? 'active' : ''}}" bindtap="onTab" data-index="1" data-path="/pages/nearby/nearby"> <view class="tab-pill {{selected === 1 ? 'active' : ''}}" bindtap="onTab" data-index="1" data-path="/pages/nearby/nearby">
<view class="icon-wrap"> <view class="icon-wrap">
<view class="icon-pin"> <view class="tab-icon icon-nearby"></view>
<view class="pin-head"></view>
<view class="pin-tail"></view>
</view>
</view> </view>
<text class="tab-label">附近</text> <text class="tab-label">附近</text>
</view> </view>
@@ -25,30 +18,23 @@
<!-- 发布 FAB --> <!-- 发布 FAB -->
<view class="tab-fab-wrap"> <view class="tab-fab-wrap">
<view class="tab-fab" bindtap="onPost"> <view class="tab-fab" bindtap="onPost">
<text class="fab-plus"></text> <view class="fab-paw"></view>
</view> </view>
</view> </view>
<!-- 汪友 --> <!-- 汪友 -->
<view class="tab-item {{selected === 2 ? 'active' : ''}}" bindtap="onTab" data-index="2" data-path="/pages/friends/friends"> <view class="tab-pill {{selected === 2 ? 'active' : ''}}" bindtap="onTab" data-index="2" data-path="/pages/friends/friends">
<view class="icon-wrap" style="position:relative"> <view class="icon-wrap" style="position:relative">
<view class="icon-ppl"> <view class="tab-icon icon-friends"></view>
<view class="ppl-head ppl-head-l"></view>
<view class="ppl-head ppl-head-r"></view>
<view class="ppl-body"></view>
</view>
<view wx:if="{{unreadCount > 0}}" class="badge">{{unreadCount > 99 ? '99+' : unreadCount}}</view> <view wx:if="{{unreadCount > 0}}" class="badge">{{unreadCount > 99 ? '99+' : unreadCount}}</view>
</view> </view>
<text class="tab-label">汪友</text> <text class="tab-label">汪友</text>
</view> </view>
<!-- 我的 --> <!-- 我的 -->
<view class="tab-item {{selected === 3 ? 'active' : ''}}" bindtap="onTab" data-index="3" data-path="/pages/profile/profile"> <view class="tab-pill {{selected === 3 ? 'active' : ''}}" bindtap="onTab" data-index="3" data-path="/pages/profile/profile">
<view class="icon-wrap"> <view class="icon-wrap">
<view class="icon-user"> <view class="tab-icon icon-profile"></view>
<view class="user-head"></view>
<view class="user-body"></view>
</view>
</view> </view>
<text class="tab-label">我的</text> <text class="tab-label">我的</text>
</view> </view>

View File

@@ -1,204 +1,157 @@
/* ── 底部导航栏 ── */ /* ── 底部导航:白色悬浮浮岛(Vital 风格)──
.tab-bar { 纯白实底 + 中性柔和阴影,激活态用强调黑胶囊,不用主题色 */
display: flex; .tab-dock {
align-items: center;
border-top: 1rpx solid rgba(255, 255, 255, 0.65);
background: rgba(255, 255, 255, 0.90);
padding: 10rpx 0 calc(10rpx + env(safe-area-inset-bottom));
box-shadow: 0 -10rpx 24rpx rgba(110, 78, 131, 0.08);
position: fixed; position: fixed;
bottom: 0; left: 16rpx;
left: 0; right: 16rpx;
right: 0; bottom: calc(28rpx + env(safe-area-inset-bottom) * 0.5);
z-index: 999; z-index: 999;
}
/* ── Tab 项 ── */
.tab-item {
flex: 1;
display: flex; display: flex;
flex-direction: column;
align-items: center; align-items: center;
gap: 5rpx; justify-content: space-around;
border-radius: 22rpx; border-radius: 56rpx;
padding: 8rpx 0 6rpx; padding: 12rpx 10rpx;
overflow: hidden;
background: #ffffff;
box-shadow: 0 20rpx 50rpx rgba(27, 27, 32, 0.10);
}
/* ── Tab 项:展开胶囊 ──
未选中 = 浅灰图标;选中 = 横向展开为黑色胶囊(白图标 + 白文字) */
.tab-pill {
position: relative; position: relative;
z-index: 1;
flex: 0 0 auto;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
gap: 0;
border-radius: 999rpx;
padding: 10rpx 16rpx;
transition:
background 0.32s cubic-bezier(.34, 1.4, .64, 1),
padding 0.32s cubic-bezier(.34, 1.4, .64, 1),
box-shadow 0.32s ease;
} }
.tab-item.active { .tab-pill.active {
background: linear-gradient(180deg, rgba(255, 79, 145, 0.12), rgba(255, 225, 90, 0.08)); background: #2b2b30;
padding: 10rpx 26rpx;
box-shadow: 0 12rpx 26rpx rgba(43, 43, 48, 0.28);
} }
.tab-pill:active {
transform: scale(0.94);
}
/* 文字标签:默认折叠隐藏,选中时从图标右侧平滑展开 */
.tab-label { .tab-label {
font-size: 20rpx; max-width: 0;
font-weight: 700; overflow: hidden;
color: #9b8fa8; white-space: nowrap;
font-size: 24rpx;
font-weight: 600;
color: transparent;
line-height: 1; line-height: 1;
opacity: 0;
margin-left: 0;
transition:
max-width 0.32s cubic-bezier(.34, 1.4, .64, 1),
opacity 0.24s ease,
margin-left 0.32s cubic-bezier(.34, 1.4, .64, 1);
} }
.tab-item.active .tab-label { .tab-pill.active .tab-label {
color: #ff4f91; max-width: 140rpx;
font-weight: 900; opacity: 1;
color: #fff;
margin-left: 12rpx;
} }
/* ── 图标容器 ── */ /* ── 图标容器 ── */
.icon-wrap { .icon-wrap {
width: 44rpx; width: 66rpx;
height: 44rpx; height: 66rpx;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
} }
/* ── 广场图标2×2 圆角方块网格 ── */ /* ── Tab 图标:狗主题线性描边 SVG(base64 蒙版)──
.icon-grid { 单色 alpha 蒙版 + background-color 上色,
width: 34rpx; 选中时浅灰→白平滑过渡,任意尺寸保持清晰 */
height: 34rpx; .tab-icon {
display: grid; width: 52rpx;
grid-template-columns: 1fr 1fr; height: 52rpx;
grid-template-rows: 1fr 1fr; background-color: #b9bdc6;
gap: 5rpx; transition: background-color 0.2s;
-webkit-mask-repeat: no-repeat;
-webkit-mask-position: center;
-webkit-mask-size: contain;
} }
.icon-grid .sq { .tab-pill.active .tab-icon {
background: #9b8fa8; background-color: #fff;
border-radius: 4rpx;
transition: background 0.2s;
} }
.tab-item.active .icon-grid .sq { /* 广场:狗窝(拱形门 + 门上小骨头) */
background: #ff4f91; .icon-feed {
-webkit-mask-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0OCA0OCI+PGcgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9IjMuNCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIj48cGF0aCBkPSJNNi41IDIxLjVWMzZhNS41IDUuNSAwIDAgMCA1LjUgNS41aDI0YTUuNSA1LjUgMCAwIDAgNS41LTUuNVYyMS41Ii8+PHBhdGggZD0iTTQgMTkuNUwyNCA0LjVMNDQgMTkuNSIvPjxwYXRoIGQ9Ik0xNy41IDQxLjV2LTcuNWE2LjUgNi41IDAgMCAxIDEzIDB2Ny41Ii8+PHBhdGggZD0iTTE5LjUgMTUuMmg5IiBzdHJva2Utd2lkdGg9IjQuNiIvPjwvZz48L3N2Zz4=");
} }
/* ── 附近图标:地图 Pin ── */ /* 附近:定位水滴 + 爪印 */
.icon-pin { .icon-nearby {
display: flex; -webkit-mask-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0OCA0OCI+PHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9IjMuNCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgZD0iTTI0IDQ0QzEzLjUgMzQgOCAyNi44IDggMjBhMTYgMTYgMCAwIDEgMzIgMEM0MCAyNi44IDM0LjUgMzQgMjQgNDRaIi8+PGcgZmlsbD0iIzAwMCI+PGNpcmNsZSBjeD0iMTcuNiIgY3k9IjE1LjQiIHI9IjIuMyIvPjxjaXJjbGUgY3g9IjI0IiBjeT0iMTMiIHI9IjIuNSIvPjxjaXJjbGUgY3g9IjMwLjQiIGN5PSIxNS40IiByPSIyLjMiLz48cGF0aCBkPSJNMjQgMTkuMmMyLjkgMCA1LjIgMS45IDUuMiA0LjNjMCAyLjQtMi4zIDQuMi01LjIgNC4yYy0yLjkgMC01LjItMS44LTUuMi00LjJjMC0yLjQgMi4zLTQuMyA1LjItNC4zWiIvPjwvZz48L3N2Zz4=");
flex-direction: column;
align-items: center;
gap: 0;
} }
.pin-head { /* 汪友:交叉双骨头(前后交叠,交叠处留缝) */
width: 22rpx; .icon-friends {
height: 22rpx; -webkit-mask-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0OCA0OCI+PGRlZnM+PG1hc2sgaWQ9Im0iPjxyZWN0IHdpZHRoPSI0OCIgaGVpZ2h0PSI0OCIgZmlsbD0iI2ZmZiIvPjxwYXRoIGQ9Ik0tNC4zNCAtMi42QTQuMiA0LjIgMCAxIDAgLTExLjIgMEE0LjIgNC4yIDAgMSAwIC00LjM0IDIuNkg0LjM0QTQuMiA0LjIgMCAxIDAgMTEuMiAwQTQuMiA0LjIgMCAxIDAgNC4zNCAtMi42WiIgZmlsbD0iIzAwMCIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9IjYuNSIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjQgMjQpIHJvdGF0ZSgtNDUpIHNjYWxlKDEuMykiLz48L21hc2s+PC9kZWZzPjxnIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIyLjUiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxnIG1hc2s9InVybCgjbSkiPjxwYXRoIGQ9Ik0tNC4zNCAtMi42QTQuMiA0LjIgMCAxIDAgLTExLjIgMEE0LjIgNC4yIDAgMSAwIC00LjM0IDIuNkg0LjM0QTQuMiA0LjIgMCAxIDAgMTEuMiAwQTQuMiA0LjIgMCAxIDAgNC4zNCAtMi42WiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjQgMjQpIHJvdGF0ZSg0NSkgc2NhbGUoMS4zKSIvPjwvZz48cGF0aCBkPSJNLTQuMzQgLTIuNkE0LjIgNC4yIDAgMSAwIC0xMS4yIDBBNC4yIDQuMiAwIDEgMCAtNC4zNCAyLjZINC4zNEE0LjIgNC4yIDAgMSAwIDExLjIgMEE0LjIgNC4yIDAgMSAwIDQuMzQgLTIuNloiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDI0IDI0KSByb3RhdGUoLTQ1KSBzY2FsZSgxLjMpIi8+PC9nPjwvc3ZnPg==");
border-radius: 50% 50% 50% 0;
background: #9b8fa8;
transform: rotate(-45deg);
transition: background 0.2s;
} }
.pin-tail { /* 我的:项圈 + 爱心狗牌 */
width: 4rpx; .icon-profile {
height: 8rpx; -webkit-mask-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0OCA0OCI+PGcgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9IjMuNCI+PGNpcmNsZSBjeD0iMjQiIGN5PSIxNy41IiByPSIxMS40Ii8+PGNpcmNsZSBjeD0iMjQiIGN5PSIzNi41IiByPSI2LjQiLz48L2c+PHBhdGggZmlsbD0iIzAwMCIgZD0iTTI0IDQwYy0yLjItMS42LTMuMy0yLjctMy4zLTRhMS45IDEuOSAwIDAgMSAzLjMtMS4yYTEuOSAxLjkgMCAwIDEgMy4zIDEuMmMwIDEuMy0xLjEgMi40LTMuMyA0WiIvPjwvc3ZnPg==");
background: #9b8fa8;
border-radius: 0 0 4rpx 4rpx;
margin-top: -2rpx;
transition: background 0.2s;
} }
.tab-item.active .pin-head, /* ── 发布按钮:黑色圆底 + 白色爪印(CTA 用强调黑) ── */
.tab-item.active .pin-tail {
background: #ff4f91;
}
/* ── 汪友图标:双人轮廓 ── */
.icon-ppl {
width: 36rpx;
height: 30rpx;
position: relative;
}
.ppl-head {
position: absolute;
width: 14rpx;
height: 14rpx;
border-radius: 50%;
background: #9b8fa8;
top: 0;
transition: background 0.2s;
}
.ppl-head-l { left: 2rpx; }
.ppl-head-r { right: 2rpx; }
.ppl-body {
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 14rpx;
background: #9b8fa8;
border-radius: 8rpx 8rpx 0 0;
transition: background 0.2s;
}
.tab-item.active .ppl-head,
.tab-item.active .ppl-body {
background: #ff4f91;
}
/* ── 我的图标:单人轮廓 ── */
.icon-user {
width: 28rpx;
height: 34rpx;
display: flex;
flex-direction: column;
align-items: center;
gap: 4rpx;
}
.user-head {
width: 18rpx;
height: 18rpx;
border-radius: 50%;
background: #9b8fa8;
transition: background 0.2s;
}
.user-body {
width: 28rpx;
height: 14rpx;
border-radius: 8rpx 8rpx 0 0;
background: #9b8fa8;
transition: background 0.2s;
}
.tab-item.active .user-head,
.tab-item.active .user-body {
background: #ff4f91;
}
/* ── 发布 FAB ── */
.tab-fab-wrap { .tab-fab-wrap {
flex: 1; flex: 0 0 auto;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
padding-bottom: 4rpx; padding: 0 8rpx;
} }
.tab-fab { .tab-fab {
width: 92rpx; position: relative;
height: 92rpx; width: 84rpx;
height: 84rpx;
border-radius: 50%; border-radius: 50%;
background: linear-gradient(135deg, #ff4f91, #ff9f1c 55%, #ffe15a); background: #2b2b30;
border: 4rpx solid rgba(255, 255, 255, 0.90);
box-shadow: 0 10rpx 22rpx rgba(255, 79, 145, 0.28);
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
margin-bottom: 4rpx; box-shadow: 0 10rpx 24rpx rgba(43, 43, 48, 0.30);
transition: transform 0.2s ease;
} }
.fab-plus { .tab-fab:active {
font-size: 52rpx; transform: scale(0.9);
color: #fff;
font-weight: 300;
line-height: 1;
margin-top: -4rpx;
} }
/* ── 未读角标 ── */ /* 白色爪印(base64 SVG),任意尺寸保持清晰 */
.fab-paw {
width: 52rpx;
height: 52rpx;
background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0OCA0OCI+PGcgZmlsbD0iI2ZmZiI+PGNpcmNsZSBjeD0iMTEuNSIgY3k9IjE4LjUiIHI9IjMuNiIvPjxjaXJjbGUgY3g9IjE5LjUiIGN5PSIxMy41IiByPSIzLjkiLz48Y2lyY2xlIGN4PSIyOC41IiBjeT0iMTMuNSIgcj0iMy45Ii8+PGNpcmNsZSBjeD0iMzYuNSIgY3k9IjE4LjUiIHI9IjMuNiIvPjxwYXRoIGQ9Ik0yNCAyMmM1IDAgOSAzLjQgOSA3LjZjMCA0LjItNCA3LjQtOSA3LjRjLTUgMC05LTMuMi05LTcuNGMwLTQuMiA0LTcuNiA5LTcuNloiLz48L2c+PC9zdmc+");
background-repeat: no-repeat;
background-position: center;
background-size: contain;
}
/* ── 未读角标:主色紫 ── */
.badge { .badge {
position: absolute; position: absolute;
top: -4rpx; top: -4rpx;
@@ -206,10 +159,10 @@
min-width: 30rpx; min-width: 30rpx;
height: 30rpx; height: 30rpx;
border-radius: 15rpx; border-radius: 15rpx;
background: #ff4f91; background: #8b7cf6;
color: #fff; color: #fff;
font-size: 18rpx; font-size: 18rpx;
font-weight: 800; font-weight: 600;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;

View File

@@ -1,16 +1,18 @@
.chat-page { display: flex; flex-direction: column; height: 100vh; background: #f5f0ff; } /* ── 聊天页:Vital 风格 ──
.chat-nav { display: flex; align-items: center; padding: 16rpx 28rpx; background: rgba(255,255,255,0.90); border-bottom: 1rpx solid rgba(43,37,61,0.08); } 我的气泡 = 主色紫,对方 = 白卡;发送按钮 = 强调黑 */
.nav-back { font-size: 60rpx; color: #272235; font-weight: 300; padding: 0 10rpx; line-height: 1; } .chat-page { display: flex; flex-direction: column; height: 100vh; background: #f1f2f6; }
.nav-title { flex: 1; font-size: 32rpx; font-weight: 900; color: #272235; text-align: center; } .chat-nav { display: flex; align-items: center; padding: 16rpx 28rpx; background: #ffffff; border-bottom: 1rpx solid rgba(27, 27, 32, 0.06); }
.nav-more { font-size: 36rpx; color: #9b8fa8; padding: 0 10rpx; } .nav-back { font-size: 60rpx; color: #1b1b20; font-weight: 300; padding: 0 10rpx; line-height: 1; }
.nav-title { flex: 1; font-size: 32rpx; font-weight: 700; color: #1b1b20; text-align: center; }
.nav-more { font-size: 36rpx; color: #b9bdc6; padding: 0 10rpx; }
.msg-scroll { flex: 1; padding: 20rpx 28rpx; } .msg-scroll { flex: 1; padding: 20rpx 28rpx; }
.msg-row { display: flex; margin-bottom: 20rpx; } .msg-row { display: flex; margin-bottom: 20rpx; }
.msg-right { justify-content: flex-end; } .msg-right { justify-content: flex-end; }
.msg-left { justify-content: flex-start; } .msg-left { justify-content: flex-start; }
.msg-bubble { max-width: 75%; padding: 18rpx 24rpx; border-radius: 28rpx; font-size: 28rpx; line-height: 1.5; } .msg-bubble { max-width: 75%; padding: 18rpx 24rpx; border-radius: 28rpx; font-size: 28rpx; line-height: 1.5; }
.bubble-me { background: linear-gradient(135deg, #ff4f91, #ff9f1c); color: #fff; border-bottom-right-radius: 8rpx; } .bubble-me { background: linear-gradient(135deg, #8b7cf6, #a99bf8); color: #fff; border-bottom-right-radius: 8rpx; box-shadow: 0 10rpx 24rpx rgba(139, 124, 246, 0.22); }
.bubble-peer { background: rgba(255,255,255,0.90); color: #272235; border-bottom-left-radius: 8rpx; box-shadow: 0 6rpx 14rpx rgba(78,56,96,0.09); } .bubble-peer { background: #ffffff; color: #1b1b20; border-bottom-left-radius: 8rpx; box-shadow: 0 6rpx 14rpx rgba(27, 27, 32, 0.06); }
.input-bar { display: flex; align-items: center; gap: 14rpx; padding: 16rpx 28rpx; padding-bottom: calc(16rpx + env(safe-area-inset-bottom)); background: rgba(255,255,255,0.92); border-top: 1rpx solid rgba(43,37,61,0.08); } .input-bar { display: flex; align-items: center; gap: 14rpx; padding: 16rpx 28rpx; padding-bottom: calc(16rpx + env(safe-area-inset-bottom)); background: #ffffff; border-top: 1rpx solid rgba(27, 27, 32, 0.06); }
.msg-input { flex: 1; height: 80rpx; background: rgba(255,255,255,0.80); border: 1rpx solid rgba(43,37,61,0.10); border-radius: 999rpx; padding: 0 24rpx; font-size: 28rpx; color: #272235; } .msg-input { flex: 1; height: 80rpx; background: #f1f2f6; border-radius: 999rpx; padding: 0 24rpx; font-size: 28rpx; color: #1b1b20; }
.send-btn { background: linear-gradient(135deg, #ff4f91, #ff9f1c); color: #fff; border-radius: 999rpx; padding: 18rpx 30rpx; font-size: 28rpx; font-weight: 800; flex-shrink: 0; } .send-btn { background: #2b2b30; color: #fff; border-radius: 999rpx; padding: 18rpx 30rpx; font-size: 28rpx; font-weight: 600; flex-shrink: 0; }
.send-disabled { background: #e8e4f0; color: #9b8fa8; } .send-disabled { background: #e7e9ef; color: #b9bdc6; }

View File

@@ -1,15 +1,16 @@
.page { min-height: 100vh; background: linear-gradient(180deg, #fff8f2 0%, #f5f0ff 100%); } /* ── 资料编辑:Vital 风格表单页 ── */
.page { min-height: 100vh; background: #f1f2f6; }
.nav { display: flex; align-items: center; padding: 14rpx 28rpx; gap: 16rpx; } .nav { display: flex; align-items: center; padding: 14rpx 28rpx; gap: 16rpx; }
.nav-back { font-size: 28rpx; font-weight: 700; color: #9b8fa8; } .nav-back { font-size: 28rpx; font-weight: 600; color: #6e7280; }
.nav-title { flex: 1; font-size: 32rpx; font-weight: 900; color: #272235; text-align: center; } .nav-title { flex: 1; font-size: 32rpx; font-weight: 700; color: #1b1b20; text-align: center; }
.nav-save { font-size: 28rpx; font-weight: 900; color: #ff4f91; } .nav-save { font-size: 28rpx; font-weight: 700; color: #7563e0; }
.form { padding: 24rpx 28rpx; } .form { padding: 24rpx 28rpx; }
.field-group { background: rgba(255,255,255,0.90); border-radius: 36rpx; border: 1rpx solid rgba(255,255,255,0.72); overflow: hidden; box-shadow: 0 12rpx 26rpx rgba(78,56,96,0.08); } .field-group { background: #ffffff; border-radius: 36rpx; overflow: hidden; box-shadow: var(--shadow-soft); }
.field-item { display: flex; align-items: center; justify-content: space-between; padding: 24rpx 28rpx; border-bottom: 1rpx solid rgba(43,37,61,0.06); } .field-item { display: flex; align-items: center; justify-content: space-between; padding: 24rpx 28rpx; border-bottom: 1rpx solid rgba(27, 27, 32, 0.05); }
.field-item:last-child { border-bottom: none; } .field-item:last-child { border-bottom: none; }
.field-item-col { flex-direction: column; align-items: flex-start; gap: 14rpx; } .field-item-col { flex-direction: column; align-items: flex-start; gap: 14rpx; }
.field-label { font-size: 28rpx; font-weight: 700; color: #272235; flex-shrink: 0; margin-right: 20rpx; } .field-label { font-size: 28rpx; font-weight: 600; color: #1b1b20; flex-shrink: 0; margin-right: 20rpx; }
.field-input { flex: 1; font-size: 28rpx; color: #272235; text-align: right; } .field-input { flex: 1; font-size: 28rpx; color: #1b1b20; text-align: right; }
.field-textarea { width: 100%; min-height: 80rpx; font-size: 28rpx; color: #272235; line-height: 1.6; } .field-textarea { width: 100%; min-height: 80rpx; font-size: 28rpx; color: #1b1b20; line-height: 1.6; }
.field-picker-val { flex: 1; font-size: 28rpx; color: #272235; text-align: right; } .field-picker-val { flex: 1; font-size: 28rpx; color: #1b1b20; text-align: right; }
.field-picker-val.placeholder { color: #c4b8d0; } .field-picker-val.placeholder { color: #b9bdc6; }

View File

@@ -26,8 +26,7 @@ Page({
refreshing: false, refreshing: false,
hasMore: true, hasMore: true,
page: 0, page: 0,
hasUnread: false, myAvatarGradient: 'linear-gradient(135deg, #d9d2fb, #efedfd)',
myAvatarGradient: 'linear-gradient(135deg, #ffd6e8, #fff1a6)',
myEmoji: '🐶', myEmoji: '🐶',
}, },
@@ -49,10 +48,6 @@ Page({
tabBar?.setSelected?.(0) tabBar?.setSelected?.(0)
}, },
onPullDownRefresh() {
this.onRefresh()
},
async onRefresh() { async onRefresh() {
this.setData({ refreshing: true, page: 0, hasMore: true }) this.setData({ refreshing: true, page: 0, hasMore: true })
await this.loadFeed(true) await this.loadFeed(true)
@@ -121,10 +116,6 @@ Page({
wx.navigateTo({ url: '/pages/search/search' }) wx.navigateTo({ url: '/pages/search/search' })
}, },
onNotify() {
wx.navigateTo({ url: '/pages/notifications/notifications' })
},
onMyStory() { onMyStory() {
wx.navigateTo({ url: '/pages/post/post?type=story' }) wx.navigateTo({ url: '/pages/post/post?type=story' })
}, },

View File

@@ -1,68 +1,71 @@
<view class="feed-page"> <view class="feed-page">
<!-- 状态栏占位 --> <!-- 固定液态玻璃顶栏:标题 + 搜索图标(紧贴胶囊按钮) -->
<view style="height: {{statusBarHeight}}px; flex-shrink: 0;"></view> <view class="glass-topbar">
<view style="height: {{statusBarHeight}}px;"></view>
<!-- 主导航栏:与胶囊按钮同高,右侧留出胶囊空间 --> <view class="navbar" style="height: {{navbarHeight}}px; padding-right: {{navbarPaddingRight}}px;">
<view class="navbar" style="height: {{navbarHeight}}px; padding-right: {{navbarPaddingRight}}px;"> <view class="topbar-logo">汪<text class="logo-accent">圈</text></view>
<view class="topbar-logo">汪<text class="logo-accent">圈</text></view> <view class="navbar-action" bindtap="onSearch">
</view> <view class="icon-line icon-search-line"></view>
</view>
<!-- 次级菜单栏:位于胶囊按钮下方,全宽可用 -->
<view class="subbar">
<view class="topbar-tabs">
<view
wx:for="{{feedTabs}}"
wx:key="key"
class="feed-tab {{activeTab === item.key ? 'feed-tab-active' : ''}}"
bindtap="onSwitchTab"
data-key="{{item.key}}"
>{{item.label}}</view>
</view>
<view class="topbar-actions">
<view class="topbar-btn" bindtap="onSearch">🔍</view>
<view class="topbar-btn {{hasUnread ? 'has-badge' : ''}}" bindtap="onNotify">🔔</view>
</view> </view>
</view> </view>
<!-- 故事圈 --> <!-- 顶栏占位 -->
<scroll-view class="stories-scroll" scroll-x="true" enhanced="true" show-scrollbar="false"> <view style="height: {{statusBarHeight + navbarHeight}}px; flex-shrink: 0;"></view>
<!-- 我的故事 -->
<view class="story" bindtap="onMyStory">
<view class="story-ring story-ring-me">
<view class="story-inner" style="background: {{myAvatarGradient}}">
<text class="story-emoji">{{myEmoji}}</text>
</view>
</view>
<text class="story-name">我的</text>
</view>
<!-- 关注的宠物故事 -->
<view
wx:for="{{stories}}"
wx:key="_id"
class="story"
bindtap="onStoryTap"
data-id="{{item._id}}"
>
<view class="story-ring {{item.hasNew ? '' : 'story-ring-seen'}}">
<view class="story-inner" style="background: {{item.gradient}}">
<text class="story-emoji">{{item.emoji}}</text>
</view>
</view>
<text class="story-name">{{item.name}}</text>
</view>
</scroll-view>
<!-- 信息流 --> <!-- 信息流:tabs、故事圈与帖子同在滚动区,下拉刷新只在真正顶部触发 -->
<scroll-view <scroll-view
class="feed-scroll" class="feed-scroll"
scroll-y="true" scroll-y="true"
enhanced="true" enhanced="true"
bounces="{{false}}"
show-scrollbar="false" show-scrollbar="false"
bindscrolltolower="onLoadMore" bindscrolltolower="onLoadMore"
refresher-enabled="true" refresher-enabled="true"
bindrefresherrefresh="onRefresh" bindrefresherrefresh="onRefresh"
refresher-triggered="{{refreshing}}" refresher-triggered="{{refreshing}}"
> >
<!-- 次级菜单栏:信息流 tabs -->
<view class="subbar">
<view class="topbar-tabs">
<view
wx:for="{{feedTabs}}"
wx:key="key"
class="feed-tab {{activeTab === item.key ? 'feed-tab-active' : ''}}"
bindtap="onSwitchTab"
data-key="{{item.key}}"
>{{item.label}}</view>
</view>
</view>
<!-- 故事圈 -->
<scroll-view class="stories-scroll" scroll-x="true" enhanced="true" show-scrollbar="false">
<!-- 我的故事 -->
<view class="story" bindtap="onMyStory">
<view class="story-ring story-ring-me">
<view class="story-inner" style="background: {{myAvatarGradient}}">
<text class="story-emoji">{{myEmoji}}</text>
</view>
</view>
<text class="story-name">我的</text>
</view>
<!-- 关注的宠物故事 -->
<view
wx:for="{{stories}}"
wx:key="_id"
class="story"
bindtap="onStoryTap"
data-id="{{item._id}}"
>
<view class="story-ring {{item.hasNew ? '' : 'story-ring-seen'}}">
<view class="story-inner" style="background: {{item.gradient}}">
<text class="story-emoji">{{item.emoji}}</text>
</view>
</view>
<text class="story-name">{{item.name}}</text>
</view>
</scroll-view>
<!-- 骨架屏 --> <!-- 骨架屏 -->
<view wx:if="{{loading && posts.length === 0}}" class="skeleton-wrap"> <view wx:if="{{loading && posts.length === 0}}" class="skeleton-wrap">
<view wx:for="{{[1,2,3]}}" wx:key="index" class="skeleton-card"> <view wx:for="{{[1,2,3]}}" wx:key="index" class="skeleton-card">

View File

@@ -1,11 +1,16 @@
/* ── 广场页:Vital 风格 ──
顶部紫色渐变向下淡出融入灰底,白卡信息流叠压其上 */
.feed-page { .feed-page {
min-height: 100vh; height: 100vh;
background: linear-gradient(180deg, #fff8f2 0%, #fff4fb 50%, #f5f0ff 100%); background-color: #f1f2f6;
background-image: linear-gradient(180deg, #9181f4 0%, #a99bf8 52%, rgba(241, 242, 246, 0) 100%);
background-repeat: no-repeat;
background-size: 100% 520rpx;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
/* 主导航栏与胶囊按钮同高右侧避让胶囊 */ /* 主导航栏:与胶囊按钮同高,右侧避让胶囊 */
.navbar { .navbar {
display: flex; display: flex;
align-items: center; align-items: center;
@@ -14,7 +19,7 @@
box-sizing: border-box; box-sizing: border-box;
} }
/* 次级菜单栏胶囊按钮下方全宽 */ /* 次级菜单栏:胶囊按钮下方,全宽 */
.subbar { .subbar {
display: flex; display: flex;
align-items: center; align-items: center;
@@ -23,15 +28,14 @@
flex-shrink: 0; flex-shrink: 0;
} }
/* logo:玻璃顶栏上的深色标题(颜色由 .glass-topbar 统一控制) */
.topbar-logo { .topbar-logo {
font-size: 44rpx; font-size: 46rpx;
font-weight: 900; font-weight: 700;
color: #272235; letter-spacing: -0.5rpx;
flex-shrink: 0; flex-shrink: 0;
} }
.logo-accent { color: #ff4f91; }
.topbar-tabs { .topbar-tabs {
flex: 1; flex: 1;
display: flex; display: flex;
@@ -39,50 +43,21 @@
justify-content: center; justify-content: center;
} }
/* 紫底上的 tab:半透明白文字,激活态为白色胶囊 + 黑字 */
.feed-tab { .feed-tab {
font-size: 26rpx; font-size: 26rpx;
font-weight: 700; font-weight: 600;
color: #9b8fa8; color: rgba(255, 255, 255, 0.72);
padding: 8rpx 20rpx; padding: 8rpx 20rpx;
border-radius: 999rpx; border-radius: 999rpx;
transition: all 0.2s; transition: all 0.2s;
} }
.feed-tab-active { .feed-tab-active {
color: #ff4f91; color: #1b1b20;
background: rgba(255, 79, 145, 0.10); background: #ffffff;
font-weight: 900; font-weight: 700;
} box-shadow: 0 8rpx 20rpx rgba(27, 27, 32, 0.10);
.topbar-actions {
display: flex;
gap: 12rpx;
flex-shrink: 0;
}
.topbar-btn {
width: 60rpx;
height: 60rpx;
border-radius: 50%;
background: rgba(255, 255, 255, 0.72);
box-shadow: 0 8rpx 18rpx rgba(78, 56, 96, 0.10);
display: flex;
align-items: center;
justify-content: center;
font-size: 32rpx;
position: relative;
}
.has-badge::after {
content: '';
position: absolute;
top: 6rpx;
right: 6rpx;
width: 14rpx;
height: 14rpx;
border-radius: 50%;
background: #ff4f91;
border: 2rpx solid #fff;
} }
/* 故事圈 */ /* 故事圈 */
@@ -101,43 +76,45 @@
white-space: normal; white-space: normal;
} }
/* 故事环:未读 = 紫色渐变环(单一主色家族),已读 = 浅灰 */
.story-ring { .story-ring {
width: 112rpx; width: 116rpx;
height: 112rpx; height: 116rpx;
border-radius: 50%; border-radius: 40rpx;
padding: 5rpx; padding: 6rpx;
box-sizing: border-box; box-sizing: border-box;
background: conic-gradient(from 120deg, #ff4f91, #ff9f1c, #ffe15a, #67e8c9, #4d8dff, #8c5cff, #ff4f91); background: linear-gradient(135deg, #7563e0, #a99bf8);
box-shadow: 0 10rpx 18rpx rgba(96, 60, 115, 0.16); box-shadow: 0 16rpx 36rpx rgba(27, 27, 32, 0.10);
} }
.story-ring-seen { .story-ring-seen {
background: #e8e4f0; background: rgba(27, 27, 32, 0.10);
} }
/* 我的故事:强调黑(与发布 CTA 呼应) */
.story-ring-me { .story-ring-me {
background: linear-gradient(135deg, #ff4f91, #ff9f1c); background: #2b2b30;
} }
.story-inner { .story-inner {
width: 100%; width: 100%;
height: 100%; height: 100%;
border-radius: 50%; border-radius: 32rpx;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
border: 4rpx solid rgba(255, 255, 255, 0.90); border: 5rpx solid rgba(255, 255, 255, 0.92);
} }
.story-emoji { .story-emoji {
font-size: 44rpx; font-size: 46rpx;
line-height: 1; line-height: 1;
} }
.story-name { .story-name {
font-size: 22rpx; font-size: 21rpx;
font-weight: 700; font-weight: 600;
color: #6a6178; color: #6e7280;
} }
/* 信息流 */ /* 信息流 */
@@ -153,8 +130,9 @@
.skeleton-card { .skeleton-card {
margin: 0 28rpx 32rpx; margin: 0 28rpx 32rpx;
background: rgba(255, 255, 255, 0.8); background: #ffffff;
border-radius: 48rpx; border-radius: 48rpx;
box-shadow: 0 16rpx 48rpx rgba(27, 27, 32, 0.06);
overflow: hidden; overflow: hidden;
padding-bottom: 20rpx; padding-bottom: 20rpx;
} }
@@ -196,7 +174,7 @@
.w40 { width: 40%; } .w40 { width: 40%; }
.skeleton { .skeleton {
background: linear-gradient(90deg, #f0eef5 25%, #e8e4f0 50%, #f0eef5 75%); background: linear-gradient(90deg, #ebecf1 25%, #e2e4ea 50%, #ebecf1 75%);
background-size: 200% 100%; background-size: 200% 100%;
animation: shine 1.4s infinite; animation: shine 1.4s infinite;
} }
@@ -218,7 +196,7 @@
width: 16rpx; width: 16rpx;
height: 16rpx; height: 16rpx;
border-radius: 50%; border-radius: 50%;
background: #ff4f91; background: var(--purple);
animation: bounce 1.2s infinite; animation: bounce 1.2s infinite;
} }
@@ -234,7 +212,7 @@
.end-tip { .end-tip {
text-align: center; text-align: center;
font-size: 24rpx; font-size: 24rpx;
color: #c4b8d0; color: var(--text-tertiary);
padding: 32rpx; padding: 32rpx;
} }
@@ -254,13 +232,13 @@
.empty-title { .empty-title {
font-size: 34rpx; font-size: 34rpx;
font-weight: 900; font-weight: 700;
color: #272235; color: var(--text-primary);
} }
.empty-desc { .empty-desc {
font-size: 26rpx; font-size: 26rpx;
color: #9b8fa8; color: var(--text-tertiary);
text-align: center; text-align: center;
line-height: 1.6; line-height: 1.6;
} }
@@ -269,5 +247,5 @@
margin-top: 24rpx; margin-top: 24rpx;
padding: 22rpx 60rpx; padding: 22rpx 60rpx;
font-size: 28rpx; font-size: 28rpx;
font-weight: 800; font-weight: 600;
} }

View File

@@ -16,6 +16,7 @@ Page({
followersCount: 0, followersCount: 0,
loading: false, loading: false,
refreshing: false, refreshing: false,
hasUnread: false,
}, },
onLoad() { onLoad() {
@@ -84,6 +85,10 @@ Page({
wx.switchTab({ url: '/pages/nearby/nearby' }) wx.switchTab({ url: '/pages/nearby/nearby' })
}, },
onNotify() {
wx.navigateTo({ url: '/pages/notifications/notifications' })
},
onGoNearby() { onGoNearby() {
wx.switchTab({ url: '/pages/nearby/nearby' }) wx.switchTab({ url: '/pages/nearby/nearby' })
}, },

View File

@@ -1,12 +1,18 @@
<view class="friends-page"> <view class="friends-page">
<!-- 状态栏占位 --> <!-- 固定液态玻璃顶栏:标题 + 通知铃铛(紧贴胶囊按钮) -->
<view style="height: {{statusBarHeight}}px; flex-shrink: 0;"></view> <view class="glass-topbar">
<view style="height: {{statusBarHeight}}px;"></view>
<!-- 主导航栏:与胶囊等高,右侧避让胶囊 --> <view class="navbar" style="height: {{navbarHeight}}px; padding-right: {{navbarPaddingRight}}px;">
<view class="navbar" style="height: {{navbarHeight}}px; padding-right: {{navbarPaddingRight}}px;"> <view class="topbar-logo">汪<text class="logo-accent">友</text></view>
<view class="topbar-logo">汪<text class="logo-accent">友</text></view> <view class="navbar-action {{hasUnread ? 'has-badge' : ''}}" bindtap="onNotify">
<view class="icon-line icon-bell-line"></view>
</view>
</view>
</view> </view>
<!-- 顶栏占位 -->
<view style="height: {{statusBarHeight + navbarHeight}}px; flex-shrink: 0;"></view>
<!-- 次级菜单栏:位于胶囊下方,全宽可用 --> <!-- 次级菜单栏:位于胶囊下方,全宽可用 -->
<view class="subbar"> <view class="subbar">
<view class="topbar-tabs"> <view class="topbar-tabs">
@@ -36,6 +42,7 @@
scroll-y="true" scroll-y="true"
class="friends-scroll" class="friends-scroll"
enhanced="true" enhanced="true"
bounces="{{false}}"
show-scrollbar="false" show-scrollbar="false"
refresher-enabled="true" refresher-enabled="true"
bindrefresherrefresh="onRefresh" bindrefresherrefresh="onRefresh"

View File

@@ -1,6 +1,11 @@
/* ── 汪友页:Vital 风格 ──
紫色渐变淡出头部 + 白卡列表叠压 */
.friends-page { .friends-page {
min-height: 100vh; height: 100vh;
background: linear-gradient(180deg, #fff8f2 0%, #f5f0ff 100%); background-color: #f1f2f6;
background-image: linear-gradient(180deg, #9181f4 0%, #a99bf8 52%, rgba(241, 242, 246, 0) 100%);
background-repeat: no-repeat;
background-size: 100% 420rpx;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
@@ -21,36 +26,45 @@
flex-shrink: 0; flex-shrink: 0;
} }
.topbar-logo { font-size: 44rpx; font-weight: 900; color: #272235; } /* logo:玻璃顶栏上的深色标题(颜色由 .glass-topbar 统一控制) */
.topbar-logo {
.logo-accent { color: #ff4f91; } font-size: 46rpx;
font-weight: 700;
letter-spacing: -0.5rpx;
}
.topbar-tabs { flex: 1; display: flex; gap: 6rpx; } .topbar-tabs { flex: 1; display: flex; gap: 6rpx; }
/* 紫底 tab:激活态为白色胶囊 + 黑字 */
.ftab { .ftab {
font-size: 28rpx; font-size: 28rpx;
font-weight: 700; font-weight: 600;
color: #9b8fa8; color: rgba(255, 255, 255, 0.72);
padding: 10rpx 20rpx; padding: 10rpx 20rpx;
border-radius: 999rpx; border-radius: 999rpx;
} }
.ftab-active { color: #ff4f91; background: rgba(255, 79, 145, 0.10); font-weight: 900; } .ftab-active {
color: #1b1b20;
background: #ffffff;
font-weight: 700;
box-shadow: 0 8rpx 20rpx rgba(27, 27, 32, 0.10);
}
.ftab-count { font-size: 22rpx; font-weight: 800; } .ftab-count { font-size: 22rpx; font-weight: 600; font-variant-numeric: tabular-nums; }
/* 添加按钮:紫底上的半透明白 */
.topbar-btn { .topbar-btn {
width: 60rpx; width: 64rpx;
height: 60rpx; height: 64rpx;
border-radius: 50%; border-radius: 26rpx;
background: linear-gradient(135deg, #ff4f91, #ff9f1c); background: rgba(255, 255, 255, 0.22);
color: #fff; color: #fff;
font-size: 40rpx; font-size: 40rpx;
font-weight: 200; font-weight: 200;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
box-shadow: 0 8rpx 16rpx rgba(255, 79, 145, 0.28);
} }
/* 空态 */ /* 空态 */
@@ -65,40 +79,54 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
gap: 16rpx; gap: 18rpx;
padding: 0 60rpx; padding: 48rpx 60rpx;
text-align: center;
} }
.empty-emoji { font-size: 80rpx; } .empty-emoji {
font-size: 64rpx;
background: #ffffff;
border-radius: 40rpx;
padding: 28rpx;
box-shadow: var(--shadow-soft);
}
.empty-title { font-size: 34rpx; font-weight: 900; color: #272235; } .empty-title { font-size: 34rpx; font-weight: 700; color: #1b1b20; }
.empty-desc { font-size: 26rpx; color: #9b8fa8; text-align: center; line-height: 1.6; } .empty-desc { font-size: 26rpx; color: #6e7280; text-align: center; line-height: 1.6; }
.go-btn { margin-top: 20rpx; padding: 22rpx 60rpx; font-size: 28rpx; font-weight: 800; } .go-btn {
margin-top: 12rpx;
padding: 22rpx 60rpx;
font-size: 26rpx;
font-weight: 600;
}
/* 好友列表 */ /* 好友列表:白卡 */
.friends-scroll { flex: 1; } .friends-scroll { flex: 1; }
.friend-item { .friend-item {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 20rpx; gap: 20rpx;
padding: 20rpx 28rpx; padding: 22rpx;
background: rgba(255, 255, 255, 0.80); margin: 0 28rpx 20rpx;
border-bottom: 1rpx solid rgba(43, 37, 61, 0.05); background: #ffffff;
border-radius: 44rpx;
box-shadow: var(--shadow-soft);
} }
.friend-avatar { .friend-avatar {
width: 88rpx; width: 92rpx;
height: 88rpx; height: 92rpx;
border-radius: 28rpx; border-radius: 32rpx;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
font-size: 36rpx; font-size: 36rpx;
font-weight: 800; font-weight: 700;
color: rgba(39, 34, 53, 0.72); color: rgba(27, 27, 32, 0.65);
flex-shrink: 0; flex-shrink: 0;
} }
@@ -111,38 +139,45 @@
margin-bottom: 6rpx; margin-bottom: 6rpx;
} }
.friend-name { font-size: 28rpx; font-weight: 800; color: #272235; } .friend-name { font-size: 28rpx; font-weight: 600; color: #1b1b20; }
.online-tag { .online-tag {
font-size: 20rpx; font-size: 20rpx;
font-weight: 800; font-weight: 600;
color: #2fd37a; color: #2f9c7d;
background: rgba(47, 211, 122, 0.12); background: rgba(75, 190, 154, 0.14);
border-radius: 999rpx; border-radius: 999rpx;
padding: 4rpx 12rpx; padding: 4rpx 12rpx;
} }
.friend-bio { .friend-bio {
font-size: 24rpx; font-size: 24rpx;
color: #9b8fa8; color: #b9bdc6;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
display: block; display: block;
} }
/* 关注:强调黑胶囊;已关注:浅灰静默态 */
.follow-btn { .follow-btn {
background: linear-gradient(135deg, #ff4f91, #ff9f1c); background: #2b2b30;
color: #fff; color: #fff;
border-radius: 999rpx; border-radius: 999rpx;
padding: 14rpx 28rpx; padding: 14rpx 28rpx;
font-size: 24rpx; font-size: 24rpx;
font-weight: 800; font-weight: 600;
flex-shrink: 0; flex-shrink: 0;
box-shadow: 0 12rpx 24rpx rgba(43, 43, 48, 0.22);
transition: transform 0.18s ease;
}
.follow-btn:active {
transform: scale(0.94);
} }
.follow-btn.following { .follow-btn.following {
background: rgba(255, 255, 255, 0.80); background: #f1f2f6;
border: 1rpx solid rgba(43, 37, 61, 0.12); color: #6e7280;
color: #9b8fa8; box-shadow: none;
} }

View File

@@ -1,6 +1,8 @@
/* ── 登录页:品牌主场(Vital 风格) ──
整屏紫色渐变向下淡出,白卡特性列表 + 黑色 CTA */
.login-page { .login-page {
min-height: 100vh; min-height: 100vh;
background: linear-gradient(160deg, #fff8bd 0%, #ffd6e8 34%, #cff7ff 68%, #e9ddff 100%); background: linear-gradient(180deg, #9181f4 0%, #a99bf8 55%, #f1f2f6 100%);
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
@@ -8,32 +10,11 @@
position: relative; position: relative;
} }
/* 背景光晕 */ /* 旧版彩色光晕已停用 */
.login-bg { position: absolute; inset: 0; pointer-events: none; } .login-bg { position: absolute; inset: 0; pointer-events: none; }
.bg-blob { .bg-blob {
position: absolute; display: none;
border-radius: 50%;
filter: blur(60rpx);
opacity: 0.5;
}
.blob1 {
width: 400rpx; height: 400rpx;
background: rgba(255, 79, 145, 0.25);
top: -80rpx; left: -80rpx;
}
.blob2 {
width: 360rpx; height: 360rpx;
background: rgba(103, 232, 201, 0.30);
bottom: -60rpx; right: -60rpx;
}
.blob3 {
width: 300rpx; height: 300rpx;
background: rgba(255, 225, 90, 0.30);
bottom: 20%; left: 10%;
} }
/* 内容 */ /* 内容 */
@@ -47,7 +28,7 @@
width: 100%; width: 100%;
} }
/* Logo */ /* Logo:紫底白字 */
.app-logo { .app-logo {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@@ -59,23 +40,24 @@
font-size: 120rpx; font-size: 120rpx;
line-height: 1; line-height: 1;
margin-bottom: 20rpx; margin-bottom: 20rpx;
filter: drop-shadow(0 20rpx 30rpx rgba(95, 49, 104, 0.25)); filter: drop-shadow(0 20rpx 30rpx rgba(27, 27, 32, 0.18));
} }
.logo-text { .logo-text {
font-size: 80rpx; font-size: 80rpx;
font-weight: 900; font-weight: 700;
color: #272235; letter-spacing: -2rpx;
color: #ffffff;
line-height: 1; line-height: 1;
margin-bottom: 12rpx; margin-bottom: 12rpx;
} }
.logo-accent { color: #ff4f91; } .logo-accent { color: rgba(255, 255, 255, 0.72); }
.logo-tagline { .logo-tagline {
font-size: 28rpx; font-size: 28rpx;
color: #6a6178; color: rgba(255, 255, 255, 0.78);
font-weight: 600; font-weight: 500;
} }
/* 宠物 emoji 装饰 */ /* 宠物 emoji 装饰 */
@@ -83,18 +65,16 @@
font-size: 52rpx; font-size: 52rpx;
letter-spacing: 16rpx; letter-spacing: 16rpx;
margin-bottom: 56rpx; margin-bottom: 56rpx;
text-shadow: 0 10rpx 20rpx rgba(0, 0, 0, 0.08);
} }
/* 特性列表 */ /* 特性列表:白卡叠压在渐变上 */
.feature-list { .feature-list {
width: 100%; width: 100%;
background: rgba(255, 255, 255, 0.65); background: #ffffff;
border: 1rpx solid rgba(255, 255, 255, 0.72);
border-radius: 40rpx; border-radius: 40rpx;
padding: 32rpx 36rpx; padding: 32rpx 36rpx;
margin-bottom: 48rpx; margin-bottom: 48rpx;
box-shadow: 0 18rpx 40rpx rgba(95, 49, 104, 0.10); box-shadow: 0 20rpx 50rpx rgba(27, 27, 32, 0.12);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 24rpx; gap: 24rpx;
@@ -110,20 +90,20 @@
.f-text { .f-text {
font-size: 28rpx; font-size: 28rpx;
font-weight: 700; font-weight: 600;
color: #272235; color: #1b1b20;
} }
/* 登录按钮 */ /* 登录按钮:强调黑胶囊 CTA */
.login-btn { .login-btn {
width: 100%; width: 100%;
height: 96rpx; height: 96rpx;
background: linear-gradient(135deg, #ff4f91, #ff9f1c 55%, #ffe15a) !important; background: #2b2b30 !important;
border-radius: 999rpx !important; border-radius: 999rpx !important;
font-size: 32rpx !important; font-size: 32rpx !important;
font-weight: 900 !important; font-weight: 600 !important;
color: #fff !important; color: #fff !important;
box-shadow: 0 16rpx 32rpx rgba(255, 79, 145, 0.35) !important; box-shadow: 0 16rpx 36rpx rgba(43, 43, 48, 0.30) !important;
border: none !important; border: none !important;
margin-bottom: 28rpx !important; margin-bottom: 28rpx !important;
display: flex; display: flex;
@@ -137,12 +117,12 @@
/* 隐私 */ /* 隐私 */
.privacy-tip { .privacy-tip {
font-size: 22rpx; font-size: 22rpx;
color: #9b8fa8; color: #6e7280;
text-align: center; text-align: center;
line-height: 1.6; line-height: 1.6;
} }
.link-text { .link-text {
color: #4d8dff; color: #7563e0;
font-weight: 700; font-weight: 600;
} }

View File

@@ -57,8 +57,8 @@ Page({
longitude: loc.longitude, longitude: loc.longitude,
radius: NEARBY_RADIUS_KM * 1000, radius: NEARBY_RADIUS_KM * 1000,
strokeWidth: 2, strokeWidth: 2,
strokeColor: 'rgba(255, 79, 145, 0.3)', strokeColor: 'rgba(139, 124, 246, 0.3)',
fillColor: 'rgba(255, 79, 145, 0.05)', fillColor: 'rgba(139, 124, 246, 0.05)',
}], }],
}) })
app.globalData.currentLocation = loc app.globalData.currentLocation = loc
@@ -117,7 +117,7 @@ Page({
color: '#ffffff', color: '#ffffff',
fontSize: 11, fontSize: 11,
borderRadius: 12, borderRadius: 12,
bgColor: '#ff4f91', bgColor: '#8b7cf6',
padding: 6, padding: 6,
display: 'ALWAYS', display: 'ALWAYS',
}, },
@@ -133,7 +133,7 @@ Page({
height: 36, height: 36,
callout: { callout: {
content: item.petName, content: item.petName,
color: '#272235', color: '#1b1b20',
fontSize: 11, fontSize: 11,
borderRadius: 12, borderRadius: 12,
bgColor: 'rgba(255,255,255,0.92)', bgColor: 'rgba(255,255,255,0.92)',

View File

@@ -1,12 +1,15 @@
<view class="nearby-page"> <view class="nearby-page">
<!-- 状态栏占位 --> <!-- 固定液态玻璃顶栏:标题 -->
<view style="height: {{statusBarHeight}}px; flex-shrink: 0;"></view> <view class="glass-topbar">
<view style="height: {{statusBarHeight}}px;"></view>
<!-- 主导航栏:与胶囊等高,右侧避让胶囊 --> <view class="navbar" style="height: {{navbarHeight}}px; padding-right: {{navbarPaddingRight}}px;">
<view class="navbar" style="height: {{navbarHeight}}px; padding-right: {{navbarPaddingRight}}px;"> <view class="topbar-logo">附<text class="logo-accent">近</text></view>
<view class="topbar-logo">附<text class="logo-accent">近</text></view> </view>
</view> </view>
<!-- 顶栏占位 -->
<view style="height: {{statusBarHeight + navbarHeight}}px; flex-shrink: 0;"></view>
<!-- 次级菜单栏:位于胶囊下方,全宽可用 --> <!-- 次级菜单栏:位于胶囊下方,全宽可用 -->
<view class="subbar"> <view class="subbar">
<view class="view-toggle"> <view class="view-toggle">

View File

@@ -1,77 +1,78 @@
/* ── 附近页:Vital 风格工具页 ──
浅灰底 + 白卡,地图浮层全部实底白卡,动作按钮用强调黑 */
.nearby-page { .nearby-page {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: 100vh; height: 100vh;
background: linear-gradient(180deg, #c9f7df 0%, #d8efff 40%, #fff1a6 100%); background: #f1f2f6;
overflow: hidden; overflow: hidden;
} }
/* 主导航栏与胶囊等高右侧避让胶囊 */ /* 主导航栏:与胶囊等高,右侧避让胶囊 */
.navbar { .navbar {
display: flex; display: flex;
align-items: center; align-items: center;
padding-left: 28rpx; padding-left: 28rpx;
flex-shrink: 0; flex-shrink: 0;
box-sizing: border-box; box-sizing: border-box;
background: rgba(255, 255, 255, 0.72);
} }
/* 次级菜单栏胶囊下方全宽 */ /* 次级菜单栏:胶囊下方,全宽 */
.subbar { .subbar {
display: flex; display: flex;
align-items: center; align-items: center;
padding: 8rpx 28rpx 12rpx; padding: 8rpx 28rpx 16rpx;
gap: 16rpx; gap: 16rpx;
flex-shrink: 0; flex-shrink: 0;
background: rgba(255, 255, 255, 0.72);
} }
/* logo:玻璃顶栏上的深色标题(颜色由 .glass-topbar 统一控制) */
.topbar-logo { .topbar-logo {
font-size: 44rpx; font-size: 46rpx;
font-weight: 900; font-weight: 700;
color: #272235; letter-spacing: -0.5rpx;
flex-shrink: 0; flex-shrink: 0;
} }
.logo-accent { color: #ff4f91; } /* 视图切换:灰底分段控件,激活为白色胶囊 */
.view-toggle { .view-toggle {
flex: 1; flex: 1;
display: flex; display: flex;
background: rgba(255, 255, 255, 0.60); background: #e7e9ef;
border-radius: 999rpx; border-radius: 999rpx;
padding: 4rpx; padding: 6rpx;
gap: 4rpx; gap: 4rpx;
border: 1rpx solid rgba(255, 255, 255, 0.80);
} }
.toggle-btn { .toggle-btn {
flex: 1; flex: 1;
text-align: center; text-align: center;
font-size: 24rpx; font-size: 24rpx;
font-weight: 700; font-weight: 600;
color: #9b8fa8; color: #6e7280;
padding: 12rpx 0; padding: 12rpx 0;
border-radius: 999rpx; border-radius: 999rpx;
transition: all 0.2s ease;
} }
.toggle-active { .toggle-active {
background: rgba(255, 255, 255, 0.90); background: #ffffff;
color: #272235; color: #1b1b20;
font-weight: 900; font-weight: 700;
box-shadow: 0 4rpx 10rpx rgba(78, 56, 96, 0.10); box-shadow: 0 8rpx 18rpx rgba(27, 27, 32, 0.08);
} }
.topbar-btn { .topbar-btn {
width: 60rpx; width: 64rpx;
height: 60rpx; height: 64rpx;
border-radius: 50%; border-radius: 26rpx;
background: rgba(255, 255, 255, 0.72); background: #ffffff;
box-shadow: 0 8rpx 18rpx rgba(78, 56, 96, 0.10); box-shadow: var(--shadow-soft);
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
font-size: 30rpx; font-size: 28rpx;
color: #6e7280;
} }
/* 地图 */ /* 地图 */
@@ -98,18 +99,17 @@
} }
.map-ctrl-btn { .map-ctrl-btn {
width: 72rpx; width: 76rpx;
height: 72rpx; height: 76rpx;
background: rgba(255, 255, 255, 0.90); background: #ffffff;
border: 1rpx solid rgba(255, 255, 255, 0.80); border-radius: 26rpx;
border-radius: 22rpx; box-shadow: 0 12rpx 32rpx rgba(27, 27, 32, 0.12);
box-shadow: 0 10rpx 20rpx rgba(82, 66, 105, 0.16);
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
font-size: 30rpx; font-size: 30rpx;
font-weight: 800; font-weight: 700;
color: #4d8dff; color: #2b2b30;
} }
/* 宠物弹窗 */ /* 宠物弹窗 */
@@ -118,14 +118,13 @@
bottom: 300rpx; bottom: 300rpx;
left: 50%; left: 50%;
transform: translateX(-50%); transform: translateX(-50%);
background: rgba(255, 255, 255, 0.92); background: #ffffff;
border: 1rpx solid rgba(255, 255, 255, 0.72); border-radius: 36rpx;
border-radius: 30rpx; padding: 22rpx 26rpx;
padding: 20rpx 24rpx;
display: flex; display: flex;
align-items: center; align-items: center;
gap: 18rpx; gap: 18rpx;
box-shadow: 0 18rpx 40rpx rgba(95, 49, 104, 0.18); box-shadow: 0 20rpx 50rpx rgba(27, 27, 32, 0.14);
min-width: 520rpx; min-width: 520rpx;
z-index: 20; z-index: 20;
} }
@@ -146,21 +145,21 @@
.popup-name { .popup-name {
display: block; display: block;
font-size: 28rpx; font-size: 28rpx;
font-weight: 800; font-weight: 600;
color: #272235; color: #1b1b20;
} }
.popup-sub { .popup-sub {
display: block; display: block;
font-size: 22rpx; font-size: 22rpx;
color: #9b8fa8; color: #b9bdc6;
margin-top: 4rpx; margin-top: 4rpx;
} }
.popup-hi { .popup-hi {
padding: 16rpx 24rpx; padding: 16rpx 24rpx;
font-size: 24rpx; font-size: 24rpx;
font-weight: 800; font-weight: 600;
border-radius: 999rpx; border-radius: 999rpx;
flex-shrink: 0; flex-shrink: 0;
} }
@@ -170,13 +169,13 @@
position: absolute; position: absolute;
top: 20rpx; top: 20rpx;
left: 20rpx; left: 20rpx;
background: rgba(255, 255, 255, 0.90); background: #ffffff;
border-radius: 999rpx; border-radius: 999rpx;
padding: 10rpx 20rpx; padding: 10rpx 22rpx;
font-size: 22rpx; font-size: 22rpx;
font-weight: 800; font-weight: 600;
color: #ff4f91; color: #7563e0;
box-shadow: 0 8rpx 16rpx rgba(78, 56, 96, 0.12); box-shadow: var(--shadow-soft);
z-index: 10; z-index: 10;
} }
@@ -187,8 +186,8 @@
left: 0; left: 0;
right: 0; right: 0;
z-index: 15; z-index: 15;
background: rgba(255, 255, 255, 0.85); background: #ffffff;
border-top: 1rpx solid rgba(255, 255, 255, 0.72); border-top: 1rpx solid rgba(27, 27, 32, 0.06);
padding: 20rpx 0; padding: 20rpx 0;
} }
@@ -201,12 +200,10 @@
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
gap: 12rpx; gap: 12rpx;
background: rgba(255, 255, 255, 0.80); background: #f1f2f6;
border: 1rpx solid rgba(255, 255, 255, 0.72); border-radius: 26rpx;
border-radius: 24rpx;
padding: 14rpx 18rpx; padding: 14rpx 18rpx;
margin-right: 16rpx; margin-right: 16rpx;
box-shadow: 0 8rpx 16rpx rgba(78, 56, 96, 0.08);
} }
.preview-avatar { .preview-avatar {
@@ -228,20 +225,21 @@
.preview-name { .preview-name {
font-size: 26rpx; font-size: 26rpx;
font-weight: 800; font-weight: 600;
color: #272235; color: #1b1b20;
} }
.preview-dist { .preview-dist {
font-size: 20rpx; font-size: 20rpx;
color: #4d8dff; color: #7563e0;
font-weight: 700; font-weight: 600;
font-variant-numeric: tabular-nums;
} }
/* 列表视图 */ /* 列表视图 */
.list-scroll { .list-scroll {
flex: 1; flex: 1;
background: linear-gradient(180deg, #fff9fb 0%, #f5f0ff 100%); background: #f1f2f6;
} }
.list-header { .list-header {
@@ -252,37 +250,37 @@
} }
.list-title { .list-title {
font-size: 30rpx; font-size: 32rpx;
font-weight: 900; font-weight: 700;
color: #272235; color: #1b1b20;
} }
/* 在线数:淡紫静默胶囊 */
.online-chip { .online-chip {
font-size: 24rpx; font-size: 24rpx;
font-weight: 700; font-weight: 600;
color: #ff4f91; color: #7563e0;
background: #ffe5f0; background: rgba(139, 124, 246, 0.12);
border-radius: 999rpx; border-radius: 999rpx;
padding: 8rpx 16rpx; padding: 10rpx 22rpx;
} }
/* 列表项 */ /* 列表项:白卡 */
.nearby-item { .nearby-item {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 18rpx; gap: 18rpx;
background: rgba(255, 255, 255, 0.80); background: #ffffff;
border: 1rpx solid rgba(255, 255, 255, 0.72); border-radius: 48rpx;
border-radius: 40rpx;
margin: 0 28rpx 20rpx; margin: 0 28rpx 20rpx;
padding: 20rpx; padding: 22rpx;
box-shadow: 0 12rpx 26rpx rgba(80, 58, 108, 0.09); box-shadow: var(--shadow-soft);
} }
.nearby-avatar { .nearby-avatar {
width: 88rpx; width: 92rpx;
height: 88rpx; height: 92rpx;
border-radius: 30rpx; border-radius: 32rpx;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
@@ -303,17 +301,17 @@
.nearby-pet-name { .nearby-pet-name {
font-size: 28rpx; font-size: 28rpx;
font-weight: 900; font-weight: 600;
color: #272235; color: #1b1b20;
} }
.breed-chip { .breed-chip {
font-size: 20rpx; font-size: 20rpx;
font-weight: 800; font-weight: 600;
background: #ffe5f0; color: #7563e0;
color: #a91d5b; background: rgba(139, 124, 246, 0.12);
border-radius: 999rpx; border-radius: 999rpx;
padding: 4rpx 12rpx; padding: 4rpx 14rpx;
} }
.nearby-sub { .nearby-sub {
@@ -321,16 +319,16 @@
align-items: center; align-items: center;
gap: 8rpx; gap: 8rpx;
font-size: 22rpx; font-size: 22rpx;
color: #9b8fa8; color: #b9bdc6;
} }
.online-dot { .online-dot {
width: 14rpx; width: 14rpx;
height: 14rpx; height: 14rpx;
border-radius: 50%; border-radius: 50%;
background: #2fd37a; background: #4bbe9a;
flex-shrink: 0; flex-shrink: 0;
box-shadow: 0 0 0 4rpx rgba(47, 211, 122, 0.18); box-shadow: 0 0 0 4rpx rgba(75, 190, 154, 0.16);
} }
.nearby-right { .nearby-right {
@@ -343,25 +341,31 @@
.dist-text { .dist-text {
font-size: 22rpx; font-size: 22rpx;
font-weight: 800; font-weight: 600;
color: #4d8dff; color: #7563e0;
font-variant-numeric: tabular-nums;
} }
/* 打招呼:强调黑胶囊 */
.say-hi { .say-hi {
background: linear-gradient(135deg, #fff, #fff4b7); background: #2b2b30;
border: 1rpx solid rgba(255, 255, 255, 0.8);
border-radius: 999rpx; border-radius: 999rpx;
padding: 12rpx 22rpx; padding: 14rpx 26rpx;
font-size: 22rpx; font-size: 22rpx;
font-weight: 800; font-weight: 600;
color: #272235; color: #fff;
box-shadow: 0 8rpx 16rpx rgba(255, 159, 28, 0.14); box-shadow: 0 12rpx 28rpx rgba(43, 43, 48, 0.24);
transition: transform 0.18s ease;
}
.say-hi:active {
transform: scale(0.94);
} }
/* 骨架 */ /* 骨架 */
.nearby-skeleton { .nearby-skeleton {
height: 128rpx; height: 128rpx;
background: linear-gradient(90deg, #f0eef5 25%, #e8e4f0 50%, #f0eef5 75%); background: linear-gradient(90deg, #ebecf1 25%, #e2e4ea 50%, #ebecf1 75%);
background-size: 200% 100%; background-size: 200% 100%;
animation: shine 1.4s infinite; animation: shine 1.4s infinite;
border-radius: 40rpx; border-radius: 40rpx;
@@ -386,13 +390,13 @@
.empty-title { .empty-title {
font-size: 34rpx; font-size: 34rpx;
font-weight: 900; font-weight: 700;
color: #272235; color: #1b1b20;
} }
.empty-desc { .empty-desc {
font-size: 26rpx; font-size: 26rpx;
color: #9b8fa8; color: #b9bdc6;
text-align: center; text-align: center;
line-height: 1.6; line-height: 1.6;
} }

View File

@@ -1,12 +1,20 @@
import { api } from '../../utils/api' import { api } from '../../utils/api'
import { getAvatarGradient, formatTime } from '../../utils/format' import { getAvatarGradient, formatTime } from '../../utils/format'
import { AppGlobalData } from '../../types/index'
const app = getApp<{ globalData: AppGlobalData }>()
Page({ Page({
data: { statusBarHeight: 0, list: [] as any[] }, data: {
statusBarHeight: 0,
navbarHeight: 44,
navbarPaddingRight: 0,
list: [] as any[],
},
onLoad() { onLoad() {
const info = wx.getSystemInfoSync() const { statusBarHeight, navbarHeight, navbarPaddingRight } = app.globalData.navBarInfo
this.setData({ statusBarHeight: info.statusBarHeight }) this.setData({ statusBarHeight, navbarHeight, navbarPaddingRight })
this.loadNotifications() this.loadNotifications()
}, },

View File

@@ -1,10 +1,17 @@
<view class="page"> <view class="page">
<view class="safe-top" style="height: {{statusBarHeight}}px"></view> <!-- 固定液态玻璃顶栏:返回 + 标题 + 全部已读(右侧避让胶囊按钮) -->
<view class="nav"> <view class="glass-topbar">
<view class="nav-back" bindtap="onBack"></view> <view style="height: {{statusBarHeight}}px;"></view>
<view class="nav-title">消息通知</view> <view class="navbar" style="height: {{navbarHeight}}px; padding-right: {{navbarPaddingRight}}px;">
<view class="nav-right" bindtap="onReadAll">全部已读</view> <view class="nav-back" bindtap="onBack"></view>
<view class="navbar-title">消息通知</view>
<view class="nav-right" bindtap="onReadAll">全部已读</view>
</view>
</view> </view>
<!-- 顶栏占位 -->
<view style="height: {{statusBarHeight + navbarHeight}}px;"></view>
<scroll-view scroll-y="true" enhanced="true" show-scrollbar="false"> <scroll-view scroll-y="true" enhanced="true" show-scrollbar="false">
<view wx:if="{{list.length === 0}}" class="empty"> <view wx:if="{{list.length === 0}}" class="empty">
<text class="empty-emoji">🔔</text> <text class="empty-emoji">🔔</text>

View File

@@ -1,15 +1,29 @@
.page { min-height: 100vh; background: linear-gradient(180deg, #fff8f2 0%, #f5f0ff 100%); } /* ── 通知页:Vital 风格 ── */
.nav { display: flex; align-items: center; padding: 14rpx 28rpx; gap: 16rpx; } .page { min-height: 100vh; background: #f1f2f6; }
.nav-back { font-size: 60rpx; color: #272235; font-weight: 300; line-height: 1; }
.nav-title { flex: 1; font-size: 32rpx; font-weight: 900; color: #272235; text-align: center; } /* 顶栏内导航行:返回 + 标题 + 全部已读(玻璃样式由 .glass-topbar 提供) */
.nav-right { font-size: 26rpx; color: #9b8fa8; } .navbar {
display: flex;
align-items: center;
gap: 8rpx;
padding-left: 20rpx;
box-sizing: border-box;
}
.navbar-title { font-size: 36rpx; font-weight: 700; }
.nav-back { font-size: 60rpx; color: #1b1b20; font-weight: 300; line-height: 1; padding: 0 10rpx; }
/* 全部已读:靠右紧贴胶囊 */
.nav-right { margin-left: auto; margin-right: 8rpx; font-size: 26rpx; color: #6e7280; padding: 10rpx 0; }
.nav-right:active { opacity: 0.6; }
.empty { display: flex; flex-direction: column; align-items: center; padding: 120rpx 60rpx; gap: 20rpx; } .empty { display: flex; flex-direction: column; align-items: center; padding: 120rpx 60rpx; gap: 20rpx; }
.empty-emoji { font-size: 80rpx; } .empty-emoji { font-size: 80rpx; }
.empty-tip { font-size: 28rpx; color: #9b8fa8; } .empty-tip { font-size: 28rpx; color: #b9bdc6; }
.notify-item { display: flex; align-items: center; gap: 20rpx; padding: 22rpx 28rpx; background: rgba(255,255,255,0.80); border-bottom: 1rpx solid rgba(43,37,61,0.05); } .notify-item { display: flex; align-items: center; gap: 20rpx; padding: 22rpx 28rpx; background: #ffffff; border-bottom: 1rpx solid rgba(27, 27, 32, 0.04); }
.notify-item.unread { background: rgba(255,229,240,0.40); } .notify-item.unread { background: rgba(139, 124, 246, 0.08); }
.n-avatar { width: 80rpx; height: 80rpx; border-radius: 26rpx; display: flex; align-items: center; justify-content: center; font-size: 34rpx; font-weight: 800; color: rgba(39,34,53,0.72); flex-shrink: 0; } .n-avatar { width: 80rpx; height: 80rpx; border-radius: 26rpx; display: flex; align-items: center; justify-content: center; font-size: 34rpx; font-weight: 700; color: rgba(27, 27, 32, 0.65); flex-shrink: 0; }
.n-body { flex: 1; } .n-body { flex: 1; }
.n-text { display: block; font-size: 28rpx; color: #272235; line-height: 1.5; } .n-text { display: block; font-size: 28rpx; color: #1b1b20; line-height: 1.5; }
.n-time { display: block; font-size: 22rpx; color: #9b8fa8; margin-top: 6rpx; } .n-time { display: block; font-size: 22rpx; color: #b9bdc6; margin-top: 6rpx; }
.unread-dot { width: 14rpx; height: 14rpx; border-radius: 50%; background: #ff4f91; flex-shrink: 0; } .unread-dot { width: 14rpx; height: 14rpx; border-radius: 50%; background: #8b7cf6; flex-shrink: 0; }

View File

@@ -1,29 +1,30 @@
.detail-page { min-height: 100vh; background: linear-gradient(180deg, #fff8f2 0%, #f5f0ff 100%); } /* ── 用户/宠物详情:Vital 风格 ── */
.detail-page { min-height: 100vh; background: #f1f2f6; }
.detail-nav { display: flex; align-items: center; padding: 16rpx 28rpx; gap: 16rpx; } .detail-nav { display: flex; align-items: center; padding: 16rpx 28rpx; gap: 16rpx; }
.nav-back { font-size: 60rpx; color: #272235; font-weight: 300; padding: 0 10rpx; line-height: 1; } .nav-back { font-size: 60rpx; color: #1b1b20; font-weight: 300; padding: 0 10rpx; line-height: 1; }
.nav-title { flex: 1; font-size: 32rpx; font-weight: 900; color: #272235; text-align: center; } .nav-title { flex: 1; font-size: 32rpx; font-weight: 700; color: #1b1b20; text-align: center; }
.nav-more { font-size: 36rpx; color: #9b8fa8; padding: 0 10rpx; } .nav-more { font-size: 36rpx; color: #b9bdc6; padding: 0 10rpx; }
.detail-scroll { min-height: 80vh; } .detail-scroll { min-height: 80vh; }
.user-card { margin: 0 28rpx 28rpx; background: rgba(255,255,255,0.88); border-radius: 48rpx; border: 1rpx solid rgba(255,255,255,0.72); padding: 28rpx; box-shadow: 0 18rpx 40rpx rgba(95,49,104,0.12); } .user-card { margin: 0 28rpx 28rpx; background: #ffffff; border-radius: 48rpx; padding: 28rpx; box-shadow: 0 16rpx 48rpx rgba(27, 27, 32, 0.06); }
.card-top { display: flex; gap: 24rpx; margin-bottom: 24rpx; } .card-top { display: flex; gap: 24rpx; margin-bottom: 24rpx; }
.card-avatar { width: 120rpx; height: 120rpx; border-radius: 36rpx; display: flex; align-items: center; justify-content: center; font-size: 52rpx; font-weight: 800; color: rgba(39,34,53,0.72); flex-shrink: 0; } .card-avatar { width: 120rpx; height: 120rpx; border-radius: 36rpx; display: flex; align-items: center; justify-content: center; font-size: 52rpx; font-weight: 700; color: rgba(27, 27, 32, 0.65); flex-shrink: 0; }
.card-meta { flex: 1; } .card-meta { flex: 1; }
.card-name { display: block; font-size: 34rpx; font-weight: 900; color: #272235; margin-bottom: 8rpx; } .card-name { display: block; font-size: 34rpx; font-weight: 700; color: #1b1b20; margin-bottom: 8rpx; }
.card-location { display: block; font-size: 24rpx; color: #9b8fa8; margin-bottom: 10rpx; } .card-location { display: block; font-size: 24rpx; color: #b9bdc6; margin-bottom: 10rpx; }
.card-bio { display: block; font-size: 26rpx; color: #6a6178; line-height: 1.5; } .card-bio { display: block; font-size: 26rpx; color: #6e7280; line-height: 1.5; }
.pets-row { display: flex; gap: 16rpx; flex-wrap: wrap; margin-bottom: 24rpx; } .pets-row { display: flex; gap: 16rpx; flex-wrap: wrap; margin-bottom: 24rpx; }
.pet-chip { display: flex; align-items: center; gap: 12rpx; background: linear-gradient(135deg, rgba(255,255,255,0.8), rgba(201,247,223,0.6)); border: 1rpx solid rgba(255,255,255,0.72); border-radius: 24rpx; padding: 16rpx 20rpx; } .pet-chip { display: flex; align-items: center; gap: 12rpx; background: #f6f7fa; border-radius: 24rpx; padding: 16rpx 20rpx; }
.chip-emoji { font-size: 36rpx; } .chip-emoji { font-size: 36rpx; }
.chip-name { display: block; font-size: 26rpx; font-weight: 800; color: #272235; } .chip-name { display: block; font-size: 26rpx; font-weight: 600; color: #1b1b20; }
.chip-breed { display: block; font-size: 22rpx; color: #9b8fa8; } .chip-breed { display: block; font-size: 22rpx; color: #b9bdc6; }
.action-row { display: flex; gap: 16rpx; } .action-row { display: flex; gap: 16rpx; }
.follow-action { flex: 1; background: linear-gradient(135deg, #ff4f91, #ff9f1c); color: #fff; border-radius: 999rpx; padding: 20rpx; text-align: center; font-size: 28rpx; font-weight: 800; box-shadow: 0 10rpx 22rpx rgba(255,79,145,0.28); } .follow-action { flex: 1; background: #2b2b30; color: #fff; border-radius: 999rpx; padding: 20rpx; text-align: center; font-size: 28rpx; font-weight: 600; box-shadow: 0 12rpx 28rpx rgba(43, 43, 48, 0.24); }
.follow-action.following { background: rgba(255,255,255,0.80); border: 1rpx solid rgba(43,37,61,0.12); color: #9b8fa8; box-shadow: none; } .follow-action.following { background: #f1f2f6; color: #6e7280; box-shadow: none; }
.msg-action { flex: 1; background: rgba(255,255,255,0.80); border: 1rpx solid rgba(43,37,61,0.10); border-radius: 999rpx; padding: 20rpx; text-align: center; font-size: 28rpx; font-weight: 800; color: #272235; } .msg-action { flex: 1; background: #f1f2f6; border-radius: 999rpx; padding: 20rpx; text-align: center; font-size: 28rpx; font-weight: 600; color: #1b1b20; }
.section-hd { padding: 20rpx 28rpx 10rpx; } .section-hd { padding: 20rpx 28rpx 10rpx; }
.section-title { font-size: 26rpx; font-weight: 900; color: #9b8fa8; } .section-title { font-size: 26rpx; font-weight: 600; color: #b9bdc6; }
.empty-posts { text-align: center; font-size: 26rpx; color: #9b8fa8; padding: 60rpx; } .empty-posts { text-align: center; font-size: 26rpx; color: #b9bdc6; padding: 60rpx; }

View File

@@ -253,7 +253,7 @@ Page({
title: '删除宠物档案', title: '删除宠物档案',
content: '确定要删除吗?', content: '确定要删除吗?',
confirmText: '删除', confirmText: '删除',
confirmColor: '#ff4f91', confirmColor: '#d4596a',
success: res => { success: res => {
if (!res.confirm) return if (!res.confirm) return
wx.showLoading({ title: '删除中...' }) wx.showLoading({ title: '删除中...' })

View File

@@ -14,7 +14,7 @@
<!-- 宠物头像 --> <!-- 宠物头像 -->
<view class="avatar-section" bindtap="onChoosePhoto"> <view class="avatar-section" bindtap="onChoosePhoto">
<view class="pet-avatar" style="background: linear-gradient(135deg, #c9f7df, #d9d2ff);"> <view class="pet-avatar" style="background: linear-gradient(135deg, #d9d2fb, #efedfd);">
<text class="pet-emoji-big">{{form.emoji || '🐾'}}</text> <text class="pet-emoji-big">{{form.emoji || '🐾'}}</text>
</view> </view>
<text class="avatar-tip">点击更换照片</text> <text class="avatar-tip">点击更换照片</text>

View File

@@ -1,44 +1,46 @@
.page { min-height: 100vh; background: linear-gradient(180deg, #fff8f2 0%, #f5f0ff 100%); } /* ── 宠物编辑:Vital 风格表单页 ── */
.page { min-height: 100vh; background: #f1f2f6; }
.nav { display: flex; align-items: center; padding: 14rpx 28rpx; gap: 16rpx; } .nav { display: flex; align-items: center; padding: 14rpx 28rpx; gap: 16rpx; }
.nav-back { font-size: 28rpx; font-weight: 700; color: #9b8fa8; } .nav-back { font-size: 28rpx; font-weight: 600; color: #6e7280; }
.nav-title { flex: 1; font-size: 32rpx; font-weight: 900; color: #272235; text-align: center; } .nav-title { flex: 1; font-size: 32rpx; font-weight: 700; color: #1b1b20; text-align: center; }
.nav-save { font-size: 28rpx; font-weight: 900; color: #ff4f91; } .nav-save { font-size: 28rpx; font-weight: 700; color: #7563e0; }
.scroll { } .scroll { }
.form { padding: 0 28rpx; } .form { padding: 0 28rpx; }
.avatar-section { display: flex; flex-direction: column; align-items: center; padding: 28rpx 0 32rpx; gap: 12rpx; } .avatar-section { display: flex; flex-direction: column; align-items: center; padding: 28rpx 0 32rpx; gap: 12rpx; }
.pet-avatar { width: 140rpx; height: 140rpx; border-radius: 44rpx; display: flex; align-items: center; justify-content: center; box-shadow: 0 12rpx 24rpx rgba(78,56,96,0.15); } .pet-avatar { width: 140rpx; height: 140rpx; border-radius: 44rpx; display: flex; align-items: center; justify-content: center; box-shadow: 0 12rpx 28rpx rgba(27, 27, 32, 0.10); }
.pet-emoji-big { font-size: 72rpx; line-height: 1; } .pet-emoji-big { font-size: 72rpx; line-height: 1; }
.avatar-tip { font-size: 24rpx; color: #9b8fa8; } .avatar-tip { font-size: 24rpx; color: #b9bdc6; }
.field-group { background: rgba(255,255,255,0.90); border-radius: 36rpx; border: 1rpx solid rgba(255,255,255,0.72); overflow: hidden; box-shadow: 0 12rpx 26rpx rgba(78,56,96,0.08); margin-bottom: 24rpx; } .field-group { background: #ffffff; border-radius: 36rpx; overflow: hidden; box-shadow: var(--shadow-soft); margin-bottom: 24rpx; }
.field-item { display: flex; align-items: center; justify-content: space-between; padding: 24rpx 28rpx; border-bottom: 1rpx solid rgba(43,37,61,0.06); } .field-item { display: flex; align-items: center; justify-content: space-between; padding: 24rpx 28rpx; border-bottom: 1rpx solid rgba(27, 27, 32, 0.05); }
.field-item:last-child { border-bottom: none; } .field-item:last-child { border-bottom: none; }
.field-item-col { flex-direction: column; align-items: flex-start; gap: 14rpx; } .field-item-col { flex-direction: column; align-items: flex-start; gap: 14rpx; }
.field-label { font-size: 28rpx; font-weight: 700; color: #272235; flex-shrink: 0; } .field-label { font-size: 28rpx; font-weight: 600; color: #1b1b20; flex-shrink: 0; }
.field-input { flex: 1; font-size: 28rpx; color: #272235; text-align: right; } .field-input { flex: 1; font-size: 28rpx; color: #1b1b20; text-align: right; }
.field-select { display: flex; align-items: center; gap: 8rpx; font-size: 28rpx; color: #9b8fa8; } .field-select { display: flex; align-items: center; gap: 8rpx; font-size: 28rpx; color: #6e7280; }
.select-arrow { font-size: 36rpx; color: #c4b8d0; font-weight: 300; } .select-arrow { font-size: 36rpx; color: #b9bdc6; font-weight: 300; }
.field-textarea { width: 100%; min-height: 100rpx; font-size: 28rpx; color: #272235; line-height: 1.6; } .field-textarea { width: 100%; min-height: 100rpx; font-size: 28rpx; color: #1b1b20; line-height: 1.6; }
.gender-btns { display: flex; gap: 14rpx; } .gender-btns { display: flex; gap: 14rpx; }
.gender-btn { background: rgba(255,255,255,0.80); border: 1rpx solid rgba(43,37,61,0.12); border-radius: 999rpx; padding: 12rpx 24rpx; font-size: 26rpx; color: #9b8fa8; font-weight: 700; } .gender-btn { background: #f1f2f6; border-radius: 999rpx; padding: 12rpx 24rpx; font-size: 26rpx; color: #6e7280; font-weight: 600; }
.g-active { background: #ffe5f0; border-color: #ffb6d0; color: #a91d5b; } .g-active { background: #2b2b30; color: #fff; }
.placeholder-text { color: #c4b8d0; } .placeholder-text { color: #b9bdc6; }
.tags-section { margin-bottom: 28rpx; } .tags-section { margin-bottom: 28rpx; }
.tags-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 16rpx; } .tags-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 16rpx; }
.tags-title { font-size: 26rpx; font-weight: 900; color: #9b8fa8; } .tags-title { font-size: 26rpx; font-weight: 600; color: #b9bdc6; }
.tags-count { font-size: 22rpx; color: #c4b8d0; } .tags-count { font-size: 22rpx; color: #b9bdc6; font-variant-numeric: tabular-nums; }
.tag-grid { display: flex; gap: 14rpx; flex-wrap: wrap; margin-bottom: 20rpx; } .tag-grid { display: flex; gap: 14rpx; flex-wrap: wrap; margin-bottom: 20rpx; }
.tag-chip { background: rgba(255,255,255,0.80); border: 1rpx solid rgba(43,37,61,0.10); border-radius: 999rpx; padding: 12rpx 24rpx; font-size: 26rpx; color: #6a6178; font-weight: 700; } .tag-chip { background: #ffffff; border-radius: 999rpx; padding: 12rpx 24rpx; font-size: 26rpx; color: #6e7280; font-weight: 600; }
.tag-on { background: #f0e8ff; border-color: #d4b8ff; color: #8c5cff; } .tag-on { background: rgba(139, 124, 246, 0.12); color: #7563e0; }
.custom-tag-row { display: flex; gap: 14rpx; align-items: center; margin-top: 4rpx; } .custom-tag-row { display: flex; gap: 14rpx; align-items: center; margin-top: 4rpx; }
.custom-tag-input { flex: 1; height: 68rpx; background: rgba(255,255,255,0.80); border: 1rpx solid rgba(43,37,61,0.10); border-radius: 999rpx; padding: 0 24rpx; font-size: 26rpx; color: #272235; } .custom-tag-input { flex: 1; height: 68rpx; background: #ffffff; border-radius: 999rpx; padding: 0 24rpx; font-size: 26rpx; color: #1b1b20; }
.custom-tag-add { background: linear-gradient(135deg, #ff4f91, #ff9f1c); color: #fff; border-radius: 999rpx; padding: 14rpx 30rpx; font-size: 26rpx; font-weight: 800; flex-shrink: 0; } .custom-tag-add { background: #2b2b30; color: #fff; border-radius: 999rpx; padding: 14rpx 30rpx; font-size: 26rpx; font-weight: 600; flex-shrink: 0; }
.add-disabled { background: #e8e4f0; color: #9b8fa8; } .add-disabled { background: #e7e9ef; color: #b9bdc6; }
.delete-btn { text-align: center; font-size: 28rpx; color: #ff4f91; background: rgba(255,79,145,0.08); border-radius: 999rpx; padding: 24rpx; margin-top: 40rpx; } /* 删除:唯一保留的警示色,降饱和处理 */
.delete-btn { text-align: center; font-size: 28rpx; color: #d4596a; background: rgba(212, 89, 106, 0.08); border-radius: 999rpx; padding: 24rpx; margin-top: 40rpx; }

View File

@@ -1,46 +1,47 @@
.page { display: flex; flex-direction: column; min-height: 100vh; background: linear-gradient(180deg, #fff8f2 0%, #f5f0ff 100%); } /* ── 帖子详情:Vital 风格 ── */
.page { display: flex; flex-direction: column; min-height: 100vh; background: #f1f2f6; }
.nav { display: flex; align-items: center; padding: 14rpx 28rpx; gap: 16rpx; } .nav { display: flex; align-items: center; padding: 14rpx 28rpx; gap: 16rpx; }
.nav-back { font-size: 60rpx; color: #272235; font-weight: 300; line-height: 1; padding-right: 10rpx; } .nav-back { font-size: 60rpx; color: #1b1b20; font-weight: 300; line-height: 1; padding-right: 10rpx; }
.nav-title { flex: 1; font-size: 32rpx; font-weight: 900; color: #272235; text-align: center; } .nav-title { flex: 1; font-size: 32rpx; font-weight: 700; color: #1b1b20; text-align: center; }
.nav-more { font-size: 36rpx; color: #9b8fa8; } .nav-more { font-size: 36rpx; color: #b9bdc6; }
.scroll { flex: 1; } .scroll { flex: 1; }
.post-wrap { margin: 0 28rpx; background: rgba(255,255,255,0.90); border-radius: 48rpx; border: 1rpx solid rgba(255,255,255,0.72); padding: 28rpx; box-shadow: 0 18rpx 40rpx rgba(95,49,104,0.10); } .post-wrap { margin: 0 28rpx; background: #ffffff; border-radius: 48rpx; padding: 28rpx; box-shadow: 0 16rpx 48rpx rgba(27, 27, 32, 0.06); }
.post-header { display: flex; align-items: center; gap: 20rpx; margin-bottom: 20rpx; } .post-header { display: flex; align-items: center; gap: 20rpx; margin-bottom: 20rpx; }
.avatar { width: 80rpx; height: 80rpx; border-radius: 28rpx; display: flex; align-items: center; justify-content: center; font-size: 34rpx; font-weight: 800; color: rgba(39,34,53,0.72); flex-shrink: 0; } .avatar { width: 80rpx; height: 80rpx; border-radius: 28rpx; display: flex; align-items: center; justify-content: center; font-size: 34rpx; font-weight: 700; color: rgba(27, 27, 32, 0.65); flex-shrink: 0; }
.meta { flex: 1; } .meta { flex: 1; }
.uname { display: block; font-size: 28rpx; font-weight: 800; color: #272235; } .uname { display: block; font-size: 28rpx; font-weight: 600; color: #1b1b20; }
.utime { display: block; font-size: 22rpx; color: #9b8fa8; margin-top: 4rpx; } .utime { display: block; font-size: 22rpx; color: #b9bdc6; margin-top: 4rpx; }
.content { display: block; font-size: 30rpx; color: #272235; line-height: 1.65; margin-bottom: 20rpx; } .content { display: block; font-size: 30rpx; color: #1b1b20; line-height: 1.65; margin-bottom: 20rpx; }
.images { display: flex; flex-wrap: wrap; gap: 8rpx; margin-bottom: 20rpx; border-radius: 24rpx; overflow: hidden; } .images { display: flex; flex-wrap: wrap; gap: 8rpx; margin-bottom: 20rpx; border-radius: 24rpx; overflow: hidden; }
.img-full { width: 100%; height: 360rpx; border-radius: 24rpx; background: #f0eef5; } .img-full { width: 100%; height: 360rpx; border-radius: 24rpx; background: #eef0f5; }
.img-grid { width: calc(50% - 4rpx); height: 240rpx; background: #f0eef5; } .img-grid { width: calc(50% - 4rpx); height: 240rpx; background: #eef0f5; }
.tags-row { display: flex; gap: 10rpx; flex-wrap: wrap; margin-bottom: 20rpx; } .tags-row { display: flex; gap: 10rpx; flex-wrap: wrap; margin-bottom: 20rpx; }
.hashtag { font-size: 22rpx; font-weight: 800; color: #8b3cff; background: #f0e8ff; border-radius: 999rpx; padding: 6rpx 14rpx; } .hashtag { font-size: 22rpx; font-weight: 600; color: #7563e0; background: rgba(139, 124, 246, 0.12); border-radius: 999rpx; padding: 6rpx 14rpx; }
.loc-tag { font-size: 22rpx; color: #9b8fa8; background: rgba(255,255,255,0.80); border: 1rpx solid rgba(43,37,61,0.10); border-radius: 999rpx; padding: 6rpx 14rpx; } .loc-tag { font-size: 22rpx; color: #6e7280; background: #f1f2f6; border-radius: 999rpx; padding: 6rpx 14rpx; }
.mood-tag { font-size: 22rpx; color: #6f4b00; background: #fff0a8; border-radius: 999rpx; padding: 6rpx 14rpx; } .mood-tag { font-size: 22rpx; color: #6e7280; background: #f1f2f6; border-radius: 999rpx; padding: 6rpx 14rpx; }
.actions { display: flex; gap: 16rpx; padding-top: 20rpx; border-top: 1rpx solid rgba(43,37,61,0.07); } .actions { display: flex; gap: 16rpx; padding-top: 20rpx; border-top: 1rpx solid rgba(27, 27, 32, 0.06); }
.action-btn { display: flex; align-items: center; gap: 8rpx; font-size: 24rpx; font-weight: 800; color: #6a6178; background: #f7f3ff; border-radius: 999rpx; padding: 10rpx 18rpx; } .action-btn { display: flex; align-items: center; gap: 8rpx; font-size: 24rpx; font-weight: 600; color: #6e7280; background: #f1f2f6; border-radius: 999rpx; padding: 10rpx 18rpx; }
.action-btn.liked { color: #ff4f91; background: #ffe5f0; } .action-btn.liked { color: #fff; background: #2b2b30; }
.act-count { font-size: 24rpx; } .act-count { font-size: 24rpx; font-variant-numeric: tabular-nums; }
.divider { height: 16rpx; background: rgba(43,37,61,0.04); margin: 16rpx 0; } .divider { height: 16rpx; background: rgba(27, 27, 32, 0.03); margin: 16rpx 0; }
.comments-section { padding: 0 28rpx; } .comments-section { padding: 0 28rpx; }
.comments-title { display: block; font-size: 26rpx; font-weight: 900; color: #9b8fa8; margin-bottom: 20rpx; } .comments-title { display: block; font-size: 26rpx; font-weight: 600; color: #b9bdc6; margin-bottom: 20rpx; }
.no-comment { text-align: center; font-size: 26rpx; color: #9b8fa8; padding: 40rpx 0; } .no-comment { text-align: center; font-size: 26rpx; color: #b9bdc6; padding: 40rpx 0; }
.comment-item { display: flex; gap: 16rpx; margin-bottom: 24rpx; } .comment-item { display: flex; gap: 16rpx; margin-bottom: 24rpx; }
.c-avatar { width: 64rpx; height: 64rpx; border-radius: 20rpx; display: flex; align-items: center; justify-content: center; font-size: 28rpx; font-weight: 800; color: rgba(39,34,53,0.72); flex-shrink: 0; } .c-avatar { width: 64rpx; height: 64rpx; border-radius: 20rpx; display: flex; align-items: center; justify-content: center; font-size: 28rpx; font-weight: 700; color: rgba(27, 27, 32, 0.65); flex-shrink: 0; }
.c-body { flex: 1; background: rgba(255,255,255,0.80); border-radius: 24rpx; padding: 16rpx 20rpx; } .c-body { flex: 1; background: #ffffff; border-radius: 24rpx; padding: 16rpx 20rpx; }
.c-name { display: block; font-size: 24rpx; font-weight: 800; color: #272235; margin-bottom: 6rpx; } .c-name { display: block; font-size: 24rpx; font-weight: 600; color: #1b1b20; margin-bottom: 6rpx; }
.c-text { display: block; font-size: 26rpx; color: #272235; line-height: 1.5; margin-bottom: 8rpx; } .c-text { display: block; font-size: 26rpx; color: #1b1b20; line-height: 1.5; margin-bottom: 8rpx; }
.c-time { display: block; font-size: 20rpx; color: #9b8fa8; } .c-time { display: block; font-size: 20rpx; color: #b9bdc6; }
.input-bar { position: fixed; bottom: 0; left: 0; right: 0; display: flex; align-items: center; gap: 14rpx; padding: 16rpx 28rpx; padding-bottom: calc(16rpx + env(safe-area-inset-bottom)); background: rgba(255,255,255,0.92); border-top: 1rpx solid rgba(43,37,61,0.08); z-index: 100; } .input-bar { position: fixed; bottom: 0; left: 0; right: 0; display: flex; align-items: center; gap: 14rpx; padding: 16rpx 28rpx; padding-bottom: calc(16rpx + env(safe-area-inset-bottom)); background: #ffffff; border-top: 1rpx solid rgba(27, 27, 32, 0.06); z-index: 100; }
.comment-input { flex: 1; height: 80rpx; background: rgba(255,255,255,0.80); border: 1rpx solid rgba(43,37,61,0.12); border-radius: 999rpx; padding: 0 24rpx; font-size: 28rpx; color: #272235; } .comment-input { flex: 1; height: 80rpx; background: #f1f2f6; border-radius: 999rpx; padding: 0 24rpx; font-size: 28rpx; color: #1b1b20; }
.send-btn { background: linear-gradient(135deg, #ff4f91, #ff9f1c); color: #fff; border-radius: 999rpx; padding: 18rpx 30rpx; font-size: 28rpx; font-weight: 800; flex-shrink: 0; } .send-btn { background: #2b2b30; color: #fff; border-radius: 999rpx; padding: 18rpx 30rpx; font-size: 28rpx; font-weight: 600; flex-shrink: 0; }
.send-off { background: #e8e4f0; color: #9b8fa8; } .send-off { background: #e7e9ef; color: #b9bdc6; }

View File

@@ -1,48 +1,52 @@
/* ── 发布页:Vital 风格工具页 ──
浅灰底 + 白卡输入区,选中态统一为强调黑胶囊 */
.post-page { .post-page {
min-height: 100vh; min-height: 100vh;
background: linear-gradient(180deg, #fff8f2 0%, #fff4fb 100%); background: #f1f2f6;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
/* 顶部高度和右侧 padding 由 JS 动态设置避让系统胶囊按钮 */ /* 顶部:高度和右侧 padding 由 JS 动态设置,避让系统胶囊按钮 */
.post-header { .post-header {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
padding-left: 28rpx; padding-left: 28rpx;
border-bottom: 1rpx solid rgba(255, 255, 255, 0.72); background: #ffffff;
background: rgba(255, 255, 255, 0.60); border-radius: 0 0 40rpx 40rpx;
box-shadow: 0 8rpx 24rpx rgba(27, 27, 32, 0.04);
flex-shrink: 0; flex-shrink: 0;
box-sizing: border-box; box-sizing: border-box;
} }
.cancel-btn { .cancel-btn {
font-size: 28rpx; font-size: 28rpx;
font-weight: 700; font-weight: 600;
color: #9b8fa8; color: #6e7280;
padding: 10rpx; padding: 10rpx;
} }
.header-title { .header-title {
font-size: 32rpx; font-size: 32rpx;
font-weight: 900; font-weight: 700;
color: #272235; color: #1b1b20;
} }
/* 发布:强调黑胶囊 */
.submit-btn { .submit-btn {
background: linear-gradient(135deg, #ff4f91, #ff9f1c); background: #2b2b30;
color: #fff; color: #fff;
border-radius: 999rpx; border-radius: 999rpx;
padding: 14rpx 34rpx; padding: 14rpx 34rpx;
font-size: 26rpx; font-size: 26rpx;
font-weight: 900; font-weight: 600;
box-shadow: 0 10rpx 22rpx rgba(255, 79, 145, 0.28); box-shadow: 0 12rpx 28rpx rgba(43, 43, 48, 0.24);
} }
.submit-disabled { .submit-disabled {
background: #e8e4f0; background: #e7e9ef;
color: #9b8fa8; color: #b9bdc6;
box-shadow: none; box-shadow: none;
} }
@@ -59,28 +63,33 @@
.upload-placeholder { .upload-placeholder {
width: 100%; width: 100%;
height: 320rpx; height: 320rpx;
background: linear-gradient(135deg, #fff0a8, #ffd6e8 48%, #c9f7df); background: #ffffff;
border: 3rpx dashed rgba(39, 34, 53, 0.18); border: 3rpx dashed rgba(27, 27, 32, 0.14);
border-radius: 48rpx; border-radius: 48rpx;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
gap: 16rpx; gap: 18rpx;
box-shadow: inset 0 0 0 2rpx rgba(255, 255, 255, 0.65), 0 16rpx 32rpx rgba(83, 62, 100, 0.09);
} }
.upload-icon { font-size: 64rpx; } .upload-icon {
font-size: 56rpx;
color: var(--purple);
background: rgba(139, 124, 246, 0.10);
border-radius: 28rpx;
padding: 18rpx;
}
.upload-hint { .upload-hint {
font-size: 28rpx; font-size: 28rpx;
font-weight: 800; font-weight: 600;
color: #272235; color: #1b1b20;
} }
.upload-sub { .upload-sub {
font-size: 22rpx; font-size: 22rpx;
color: #9b8fa8; color: #b9bdc6;
} }
/* 图片网格 */ /* 图片网格 */
@@ -100,7 +109,7 @@
.img-preview { .img-preview {
width: 100%; width: 100%;
height: 100%; height: 100%;
background: #f0eef5; background: #eef0f5;
} }
.img-remove { .img-remove {
@@ -110,13 +119,13 @@
width: 44rpx; width: 44rpx;
height: 44rpx; height: 44rpx;
border-radius: 50%; border-radius: 50%;
background: rgba(39, 34, 53, 0.72); background: rgba(27, 27, 32, 0.65);
color: #fff; color: #fff;
font-size: 28rpx; font-size: 28rpx;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
font-weight: 700; font-weight: 600;
} }
.img-uploading { .img-uploading {
@@ -131,8 +140,8 @@
.upload-spinner { .upload-spinner {
width: 40rpx; width: 40rpx;
height: 40rpx; height: 40rpx;
border: 4rpx solid rgba(255, 79, 145, 0.2); border: 4rpx solid rgba(139, 124, 246, 0.2);
border-top-color: #ff4f91; border-top-color: var(--purple);
border-radius: 50%; border-radius: 50%;
animation: spin 0.8s linear infinite; animation: spin 0.8s linear infinite;
} }
@@ -142,8 +151,8 @@
.image-add { .image-add {
aspect-ratio: 1; aspect-ratio: 1;
border-radius: 20rpx; border-radius: 20rpx;
background: rgba(255, 255, 255, 0.72); background: #ffffff;
border: 3rpx dashed rgba(39, 34, 53, 0.18); border: 3rpx dashed rgba(27, 27, 32, 0.14);
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
@@ -151,48 +160,47 @@
.add-plus { .add-plus {
font-size: 60rpx; font-size: 60rpx;
color: #9b8fa8; color: #b9bdc6;
font-weight: 200; font-weight: 200;
} }
/* 文字输入 */ /* 文字输入:白卡 */
.content-input { .content-input {
width: 100%; width: 100%;
min-height: 160rpx; min-height: 160rpx;
background: rgba(255, 255, 255, 0.80); background: #ffffff;
border: 1rpx solid rgba(255, 255, 255, 0.72); border-radius: 40rpx;
border-radius: 36rpx;
padding: 24rpx 28rpx; padding: 24rpx 28rpx;
font-size: 30rpx; font-size: 30rpx;
color: #272235; color: #1b1b20;
font-family: "PingFang SC", sans-serif; font-family: "PingFang SC", sans-serif;
line-height: 1.6; line-height: 1.6;
box-shadow: 0 10rpx 24rpx rgba(78, 56, 96, 0.07); box-shadow: var(--shadow-soft);
margin-bottom: 8rpx; margin-bottom: 8rpx;
} }
.input-placeholder { color: #c4b8d0; } .input-placeholder { color: #b9bdc6; }
.word-count { .word-count {
text-align: right; text-align: right;
font-size: 22rpx; font-size: 22rpx;
color: #9b8fa8; color: #b9bdc6;
margin-bottom: 28rpx; margin-bottom: 28rpx;
font-variant-numeric: tabular-nums;
} }
/* 通用 section */ /* 通用 section */
.section-title { .section-title {
font-size: 24rpx; font-size: 22rpx;
font-weight: 900; font-weight: 600;
color: #9b8fa8; color: #b9bdc6;
letter-spacing: 0.5rpx; letter-spacing: 0.6rpx;
margin-bottom: 14rpx; margin-bottom: 16rpx;
text-transform: uppercase;
} }
.tag-row { .tag-row {
display: flex; display: flex;
gap: 14rpx; gap: 16rpx;
flex-wrap: wrap; flex-wrap: wrap;
margin-bottom: 28rpx; margin-bottom: 28rpx;
align-items: center; align-items: center;
@@ -202,32 +210,32 @@
display: flex; display: flex;
align-items: center; align-items: center;
gap: 10rpx; gap: 10rpx;
background: rgba(255, 255, 255, 0.78); background: #ffffff;
border: 1rpx solid rgba(255, 255, 255, 0.72);
border-radius: 999rpx; border-radius: 999rpx;
padding: 14rpx 24rpx; padding: 16rpx 26rpx;
font-size: 26rpx; font-size: 24rpx;
font-weight: 800; font-weight: 600;
color: #6a6178; color: #6e7280;
} }
/* 选中:强调黑 */
.tag-selected { .tag-selected {
background: #ffe5f0; background: #2b2b30;
border-color: #ffb6d0; color: #fff;
color: #a91d5b; box-shadow: 0 12rpx 28rpx rgba(43, 43, 48, 0.24);
} }
.tag-remove { .tag-remove {
width: 44rpx; width: 44rpx;
height: 44rpx; height: 44rpx;
border-radius: 50%; border-radius: 50%;
background: #ffe5f0; background: rgba(139, 124, 246, 0.12);
color: #ff4f91; color: #7563e0;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
font-size: 28rpx; font-size: 28rpx;
font-weight: 700; font-weight: 600;
} }
/* 话题 */ /* 话题 */
@@ -242,22 +250,21 @@
.hashtag-input { .hashtag-input {
flex: 1; flex: 1;
height: 72rpx; height: 72rpx;
background: rgba(255, 255, 255, 0.80); background: #ffffff;
border: 1rpx solid rgba(255, 255, 255, 0.72);
border-radius: 999rpx; border-radius: 999rpx;
padding: 0 24rpx; padding: 0 24rpx;
font-size: 26rpx; font-size: 26rpx;
color: #272235; color: #1b1b20;
} }
.hashtag-add-btn { .hashtag-add-btn {
background: rgba(255, 255, 255, 0.80); background: #ffffff;
border: 1rpx solid rgba(255, 255, 255, 0.72);
border-radius: 999rpx; border-radius: 999rpx;
padding: 14rpx 28rpx; padding: 14rpx 28rpx;
font-size: 26rpx; font-size: 26rpx;
font-weight: 800; font-weight: 600;
color: #272235; color: #1b1b20;
box-shadow: var(--shadow-soft);
} }
.hashtag-chip { .hashtag-chip {
@@ -265,17 +272,17 @@
align-items: center; align-items: center;
gap: 8rpx; gap: 8rpx;
font-size: 24rpx; font-size: 24rpx;
font-weight: 800; font-weight: 600;
color: #8b3cff; color: #7563e0;
background: #f0e8ff; background: rgba(139, 124, 246, 0.12);
border-radius: 999rpx; border-radius: 999rpx;
padding: 8rpx 16rpx; padding: 8rpx 16rpx;
} }
.chip-remove { .chip-remove {
font-size: 26rpx; font-size: 26rpx;
color: #8b3cff; color: #7563e0;
font-weight: 700; font-weight: 600;
} }
.hot-tags { .hot-tags {
@@ -288,14 +295,13 @@
.hot-tags-label { .hot-tags-label {
font-size: 22rpx; font-size: 22rpx;
color: #9b8fa8; color: #b9bdc6;
} }
.hot-tag { .hot-tag {
font-size: 22rpx; font-size: 22rpx;
color: #9b8fa8; color: #6e7280;
background: rgba(255, 255, 255, 0.72); background: #ffffff;
border: 1rpx solid rgba(43, 37, 61, 0.10);
border-radius: 999rpx; border-radius: 999rpx;
padding: 6rpx 16rpx; padding: 6rpx 16rpx;
} }
@@ -309,17 +315,22 @@
} }
.mood-pill { .mood-pill {
background: rgba(255, 255, 255, 0.78); background: #ffffff;
border: 1rpx solid rgba(255, 255, 255, 0.72);
border-radius: 999rpx; border-radius: 999rpx;
padding: 14rpx 26rpx; padding: 16rpx 28rpx;
font-size: 26rpx; font-size: 24rpx;
font-weight: 800; font-weight: 600;
color: #6a6178; color: #6e7280;
transition: transform 0.18s ease;
} }
.mood-on { .mood-pill:active {
background: #fff0a8; transform: scale(0.95);
border-color: #ffe15a; }
color: #6f4b00;
/* 选中:强调黑(与标签选中态一致) */
.mood-on {
background: #2b2b30;
color: #fff;
box-shadow: 0 12rpx 28rpx rgba(43, 43, 48, 0.24);
} }

View File

@@ -19,7 +19,7 @@ Page({
pets: [], pets: [],
} as any, } as any,
formattedLikes: '0', formattedLikes: '0',
avatarGradient: 'linear-gradient(135deg, #ffd6e8, #fff1a6)', avatarGradient: 'linear-gradient(135deg, #d9d2fb, #efedfd)',
posts: [] as Post[], posts: [] as Post[],
postView: 'grid' as 'grid' | 'list', postView: 'grid' as 'grid' | 'list',
loading: false, loading: false,

View File

@@ -1,17 +1,21 @@
<view class="profile-page"> <view class="profile-page">
<!-- 状态栏占位 --> <!-- 固定液态玻璃顶栏:标题 + 设置按钮(紧贴胶囊按钮) -->
<view style="height: {{statusBarHeight}}px; flex-shrink: 0;"></view> <view class="glass-topbar">
<view style="height: {{statusBarHeight}}px;"></view>
<!-- 主导航栏:与胶囊等高,右侧避让胶囊,放置设置按钮 --> <view class="navbar" style="height: {{navbarHeight}}px; padding-right: {{navbarPaddingRight}}px;">
<view class="navbar" style="height: {{navbarHeight}}px; padding-right: {{navbarPaddingRight}}px;"> <view class="navbar-title">我的</view>
<view class="navbar-title">我的</view> <view class="navbar-action" bindtap="onSettings">⚙️</view>
<view class="settings-btn" bindtap="onSettings">⚙️</view> </view>
</view> </view>
<!-- 顶栏占位 -->
<view style="height: {{statusBarHeight + navbarHeight}}px; flex-shrink: 0;"></view>
<scroll-view <scroll-view
scroll-y="true" scroll-y="true"
class="profile-scroll" class="profile-scroll"
enhanced="true" enhanced="true"
bounces="{{false}}"
show-scrollbar="false" show-scrollbar="false"
refresher-enabled="true" refresher-enabled="true"
bindrefresherrefresh="onRefresh" bindrefresherrefresh="onRefresh"
@@ -19,6 +23,8 @@
> >
<!-- 用户信息区(移除原来的 header-topbar已移至 navbar--> <!-- 用户信息区(移除原来的 header-topbar已移至 navbar-->
<view class="profile-header"> <view class="profile-header">
<view class="hero-blob hb1"></view>
<view class="hero-blob hb2"></view>
<!-- 头像 + 基本信息 --> <!-- 头像 + 基本信息 -->
<view class="user-top"> <view class="user-top">
@@ -73,7 +79,7 @@
bindtap="onPetTap" bindtap="onPetTap"
data-pid="{{item._id}}" data-pid="{{item._id}}"
> >
<view class="pet-avatar" style="background: {{item.gradient || 'linear-gradient(135deg, #c9f7df, #d9d2ff)'}}"> <view class="pet-avatar" style="background: {{item.gradient || 'linear-gradient(135deg, #d9d2fb, #efedfd)'}}">
<text class="pet-emoji">{{item.emoji || '🐾'}}</text> <text class="pet-emoji">{{item.emoji || '🐾'}}</text>
</view> </view>
<view class="pet-info"> <view class="pet-info">

View File

@@ -1,47 +1,51 @@
/* ── 我的页:Vital 风格 ──
紫色渐变淡出头部,白色英雄卡叠压其上,统计用大数字锚点 */
.profile-page { .profile-page {
min-height: 100vh; height: 100vh;
background: linear-gradient(180deg, #fff8f2 0%, #fff4fb 50%, #f5f0ff 100%); background-color: #f1f2f6;
background-image: linear-gradient(180deg, #9181f4 0%, #a99bf8 52%, rgba(241, 242, 246, 0) 100%);
background-repeat: no-repeat;
background-size: 100% 460rpx;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
/* 主导航栏与胶囊等高右侧避让胶囊 */ /* 主导航栏:与胶囊等高,右侧避让胶囊 */
.navbar { .navbar {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between;
padding-left: 28rpx; padding-left: 28rpx;
flex-shrink: 0; flex-shrink: 0;
box-sizing: border-box; box-sizing: border-box;
} }
/* 标题颜色由 .glass-topbar 统一控制 */
.navbar-title { .navbar-title {
font-size: 36rpx; font-size: 36rpx;
font-weight: 900; font-weight: 700;
color: #272235;
}
.settings-btn {
width: 60rpx;
height: 60rpx;
border-radius: 50%;
background: rgba(255, 255, 255, 0.72);
box-shadow: 0 8rpx 18rpx rgba(78, 56, 96, 0.10);
display: flex;
align-items: center;
justify-content: center;
font-size: 30rpx;
} }
.profile-scroll { flex: 1; } .profile-scroll { flex: 1; }
/* 用户信息区 */ /* 用户信息区:白色英雄卡叠压在紫色头部上 */
.profile-header { .profile-header {
padding: 16rpx 28rpx 28rpx; position: relative;
background: linear-gradient(180deg, rgba(255, 225, 90, 0.18), transparent); margin: 8rpx 28rpx 20rpx;
padding: 32rpx 28rpx 26rpx;
overflow: hidden;
border-radius: 48rpx;
background: #ffffff;
box-shadow: 0 20rpx 50rpx rgba(27, 27, 32, 0.10);
}
/* 旧版渐变光斑已停用(Vital 用纯白卡面) */
.hero-blob {
display: none;
} }
.user-top { .user-top {
position: relative;
z-index: 1;
display: flex; display: flex;
align-items: flex-start; align-items: flex-start;
gap: 24rpx; gap: 24rpx;
@@ -54,30 +58,30 @@
} }
.user-avatar { .user-avatar {
width: 128rpx; width: 132rpx;
height: 128rpx; height: 132rpx;
border-radius: 40rpx; border-radius: 44rpx;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
box-shadow: 0 12rpx 24rpx rgba(98, 60, 118, 0.18); box-shadow: 0 14rpx 32rpx rgba(27, 27, 32, 0.10);
} }
.avatar-text { .avatar-text {
font-size: 56rpx; font-size: 56rpx;
font-weight: 800; font-weight: 700;
color: rgba(39, 34, 53, 0.72); color: rgba(27, 27, 32, 0.65);
} }
.avatar-edit { .avatar-edit {
position: absolute; position: absolute;
bottom: -6rpx; bottom: -6rpx;
right: -6rpx; right: -6rpx;
width: 44rpx; width: 46rpx;
height: 44rpx; height: 46rpx;
border-radius: 50%; border-radius: 50%;
background: #fff; background: #ffffff;
box-shadow: 0 4rpx 10rpx rgba(78, 56, 96, 0.16); box-shadow: 0 8rpx 18rpx rgba(27, 27, 32, 0.14);
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
@@ -98,40 +102,41 @@
} }
.user-name { .user-name {
font-size: 36rpx; font-size: 34rpx;
font-weight: 900; font-weight: 700;
color: #272235; color: #1b1b20;
} }
.user-handle { .user-handle {
display: block; display: block;
font-size: 24rpx; font-size: 24rpx;
color: #9b8fa8; color: #b9bdc6;
margin-bottom: 10rpx; margin-bottom: 10rpx;
} }
.user-bio { .user-bio {
display: block; display: block;
font-size: 26rpx; font-size: 24rpx;
color: #6a6178; color: #6e7280;
line-height: 1.5; line-height: 1.6;
} }
/* 编辑资料:浅灰静默胶囊 */
.edit-profile-btn { .edit-profile-btn {
background: rgba(255, 255, 255, 0.80); background: #f1f2f6;
border: 1rpx solid rgba(255, 255, 255, 0.72);
border-radius: 999rpx; border-radius: 999rpx;
padding: 14rpx 28rpx; padding: 14rpx 28rpx;
font-size: 24rpx; font-size: 24rpx;
font-weight: 800; font-weight: 600;
color: #272235; color: #1b1b20;
flex-shrink: 0; flex-shrink: 0;
box-shadow: 0 8rpx 18rpx rgba(78, 56, 96, 0.08);
align-self: flex-start; align-self: flex-start;
} }
/* 数据统计 */ /* 数据统计:大数字锚点(整数大、标签小且灰) */
.stats-row { .stats-row {
position: relative;
z-index: 1;
display: flex; display: flex;
gap: 16rpx; gap: 16rpx;
align-items: center; align-items: center;
@@ -139,26 +144,26 @@
.stat-item { .stat-item {
flex: 1; flex: 1;
padding: 24rpx 0; padding: 22rpx 0;
text-align: center; text-align: center;
background: rgba(255, 255, 255, 0.78); background: #f6f7fa;
border: 1rpx solid rgba(255, 255, 255, 0.72); border-radius: 32rpx;
border-radius: 30rpx;
box-shadow: 0 10rpx 22rpx rgba(78, 56, 96, 0.07);
} }
.stat-num { .stat-num {
display: block; display: block;
font-size: 40rpx; font-size: 44rpx;
font-weight: 900; font-weight: 700;
color: #ff4f91; letter-spacing: -1rpx;
color: #1b1b20;
font-variant-numeric: tabular-nums;
} }
.stat-label { .stat-label {
display: block; display: block;
font-size: 22rpx; font-size: 21rpx;
font-weight: 700; font-weight: 600;
color: #9b8fa8; color: #b9bdc6;
margin-top: 4rpx; margin-top: 4rpx;
} }
@@ -175,23 +180,22 @@
} }
.section-title { .section-title {
font-size: 26rpx; font-size: 22rpx;
font-weight: 900; font-weight: 600;
color: #9b8fa8; color: #b9bdc6;
letter-spacing: 0.5rpx; letter-spacing: 0.6rpx;
text-transform: uppercase;
} }
.add-pet-btn { .add-pet-btn {
font-size: 24rpx; font-size: 24rpx;
font-weight: 800; font-weight: 600;
color: #ff4f91; color: #7563e0;
background: #ffe5f0; background: rgba(139, 124, 246, 0.12);
border-radius: 999rpx; border-radius: 999rpx;
padding: 8rpx 20rpx; padding: 8rpx 20rpx;
} }
/* 宠物卡片 */ /* 宠物卡片:白卡 */
.pets-scroll { .pets-scroll {
white-space: nowrap; white-space: nowrap;
padding: 0 28rpx 16rpx; padding: 0 28rpx 16rpx;
@@ -201,33 +205,33 @@
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
gap: 18rpx; gap: 18rpx;
background: linear-gradient(135deg, rgba(255, 255, 255, 0.82), rgba(201, 247, 223, 0.72)); background: #ffffff;
border: 1rpx solid rgba(255, 255, 255, 0.72); border-radius: 40rpx;
border-radius: 36rpx;
padding: 20rpx 24rpx; padding: 20rpx 24rpx;
margin-right: 20rpx; margin-right: 20rpx;
box-shadow: 0 12rpx 26rpx rgba(78, 56, 96, 0.09); box-shadow: var(--shadow-soft);
white-space: normal; white-space: normal;
vertical-align: top; vertical-align: top;
max-width: 560rpx; max-width: 560rpx;
} }
.pet-card-empty { .pet-card-empty {
background: rgba(255, 255, 255, 0.60); background: transparent;
border: 3rpx dashed rgba(43, 37, 61, 0.16); border: 3rpx dashed rgba(27, 27, 32, 0.14);
box-shadow: none;
} }
.pet-avatar { .pet-avatar {
width: 84rpx; width: 84rpx;
height: 84rpx; height: 84rpx;
border-radius: 28rpx; border-radius: 30rpx;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
flex-shrink: 0; flex-shrink: 0;
} }
.pet-avatar-add { background: rgba(255, 255, 255, 0.60); color: #9b8fa8; } .pet-avatar-add { background: #f1f2f6; border: 2.5rpx dashed rgba(27, 27, 32, 0.14); color: #b9bdc6; }
.pet-emoji { font-size: 44rpx; line-height: 1; } .pet-emoji { font-size: 44rpx; line-height: 1; }
@@ -236,61 +240,61 @@
.pet-name { .pet-name {
display: block; display: block;
font-size: 28rpx; font-size: 28rpx;
font-weight: 900; font-weight: 600;
color: #272235; color: #1b1b20;
margin-bottom: 6rpx; margin-bottom: 6rpx;
} }
.pet-breed { .pet-breed {
display: block; display: block;
font-size: 22rpx; font-size: 22rpx;
color: #9b8fa8; color: #b9bdc6;
} }
/* 宠物徽章:淡紫静默胶囊,不旋转 */
.pet-badge { .pet-badge {
background: #ffe5f0; background: rgba(139, 124, 246, 0.12);
color: #7563e0;
border-radius: 999rpx; border-radius: 999rpx;
padding: 8rpx 16rpx; padding: 10rpx 18rpx;
font-size: 20rpx; font-size: 20rpx;
color: #a91d5b; font-weight: 600;
font-weight: 900;
flex-shrink: 0; flex-shrink: 0;
} }
/* 视图切换 */ /* 视图切换:灰底分段控件 */
.view-toggle { .view-toggle {
display: flex; display: flex;
background: rgba(255, 255, 255, 0.60); background: #e7e9ef;
border: 1rpx solid rgba(43, 37, 61, 0.10); border-radius: 18rpx;
border-radius: 14rpx;
overflow: hidden; overflow: hidden;
} }
.toggle-item { .toggle-item {
padding: 10rpx 20rpx; padding: 10rpx 20rpx;
font-size: 24rpx; font-size: 24rpx;
color: #9b8fa8; color: #6e7280;
} }
.toggle-item.active { .toggle-item.active {
background: rgba(255, 79, 145, 0.12); background: #ffffff;
color: #ff4f91; color: #1b1b20;
font-weight: 800; font-weight: 700;
} }
/* 动态网格 */ /* 动态网格 */
.post-grid { .post-grid {
display: grid; display: grid;
grid-template-columns: repeat(3, 1fr); grid-template-columns: repeat(3, 1fr);
gap: 6rpx; gap: 9rpx;
padding: 0 28rpx 20rpx; padding: 0 28rpx 20rpx;
} }
.grid-item { .grid-item {
aspect-ratio: 1; aspect-ratio: 1;
border-radius: 28rpx; border-radius: 26rpx;
overflow: hidden; overflow: hidden;
background: #f0eef5; background: #ffffff;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
@@ -301,7 +305,7 @@
.grid-no-img { .grid-no-img {
padding: 12rpx; padding: 12rpx;
font-size: 20rpx; font-size: 20rpx;
color: #9b8fa8; color: #b9bdc6;
text-align: center; text-align: center;
line-height: 1.4; line-height: 1.4;
} }
@@ -317,6 +321,6 @@
.empty-emoji { font-size: 72rpx; } .empty-emoji { font-size: 72rpx; }
.empty-tip { font-size: 26rpx; color: #9b8fa8; } .empty-tip { font-size: 26rpx; color: #b9bdc6; }
.post-btn { padding: 18rpx 48rpx; font-size: 26rpx; font-weight: 800; margin-top: 8rpx; } .post-btn { padding: 18rpx 48rpx; font-size: 26rpx; font-weight: 600; margin-top: 8rpx; }

View File

@@ -1,9 +1,14 @@
import { api } from '../../utils/api' import { api } from '../../utils/api'
import { getAvatarGradient } from '../../utils/format' import { getAvatarGradient } from '../../utils/format'
import { AppGlobalData } from '../../types/index'
const app = getApp<{ globalData: AppGlobalData }>()
Page({ Page({
data: { data: {
statusBarHeight: 0, statusBarHeight: 0,
navbarHeight: 44,
navbarPaddingRight: 0,
keyword: '', keyword: '',
resultTab: 'posts' as 'posts' | 'users', resultTab: 'posts' as 'posts' | 'users',
postResults: [] as any[], postResults: [] as any[],
@@ -13,8 +18,8 @@ Page({
}, },
onLoad() { onLoad() {
const info = wx.getSystemInfoSync() const { statusBarHeight, navbarHeight, navbarPaddingRight } = app.globalData.navBarInfo
this.setData({ statusBarHeight: info.statusBarHeight }) this.setData({ statusBarHeight, navbarHeight, navbarPaddingRight })
this.loadHotTopics() this.loadHotTopics()
}, },

View File

@@ -1,7 +1,18 @@
<view class="page"> <view class="page">
<view class="safe-top" style="height: {{statusBarHeight}}px"></view> <!-- 固定液态玻璃顶栏:返回 + 标题,右侧避让小程序胶囊按钮 -->
<view class="glass-topbar">
<view style="height: {{statusBarHeight}}px;"></view>
<view class="navbar" style="height: {{navbarHeight}}px; padding-right: {{navbarPaddingRight}}px;">
<view class="back" bindtap="onBack"></view>
<view class="navbar-title">搜索</view>
</view>
</view>
<!-- 顶栏占位 -->
<view style="height: {{statusBarHeight + navbarHeight}}px;"></view>
<!-- 搜索框:位于标题栏下方,全宽可用,不受胶囊遮挡 -->
<view class="search-bar"> <view class="search-bar">
<view class="back" bindtap="onBack"></view>
<view class="input-wrap"> <view class="input-wrap">
<text class="search-icon">🔍</text> <text class="search-icon">🔍</text>
<input <input

View File

@@ -1,30 +1,45 @@
.page { min-height: 100vh; background: linear-gradient(180deg, #fff8f2 0%, #f5f0ff 100%); } /* ── 搜索页:Vital 风格 ── */
.page { min-height: 100vh; background: #f1f2f6; }
/* 顶栏内导航行:返回 + 标题(玻璃样式由 .glass-topbar 提供) */
.navbar {
display: flex;
align-items: center;
gap: 8rpx;
padding-left: 20rpx;
box-sizing: border-box;
}
.navbar-title { font-size: 36rpx; font-weight: 700; }
.back { font-size: 60rpx; color: #1b1b20; font-weight: 300; line-height: 1; padding: 0 10rpx; }
/* 搜索框行:标题栏下方,全宽 */
.search-bar { display: flex; align-items: center; gap: 14rpx; padding: 14rpx 28rpx; } .search-bar { display: flex; align-items: center; gap: 14rpx; padding: 14rpx 28rpx; }
.back { font-size: 60rpx; color: #272235; font-weight: 300; line-height: 1; } .input-wrap { flex: 1; display: flex; align-items: center; background: #ffffff; border-radius: 999rpx; padding: 0 20rpx; height: 76rpx; gap: 10rpx; box-shadow: var(--shadow-soft); }
.input-wrap { flex: 1; display: flex; align-items: center; background: rgba(255,255,255,0.88); border: 1rpx solid rgba(255,255,255,0.72); border-radius: 999rpx; padding: 0 20rpx; height: 76rpx; gap: 10rpx; box-shadow: 0 8rpx 18rpx rgba(78,56,96,0.08); }
.search-icon { font-size: 30rpx; } .search-icon { font-size: 30rpx; }
.search-input { flex: 1; font-size: 28rpx; color: #272235; } .search-input { flex: 1; font-size: 28rpx; color: #1b1b20; }
.clear { font-size: 36rpx; color: #9b8fa8; } .clear { font-size: 36rpx; color: #b9bdc6; }
.search-btn { font-size: 28rpx; font-weight: 800; color: #ff4f91; padding: 0 6rpx; } .search-btn { font-size: 28rpx; font-weight: 600; color: #7563e0; padding: 0 6rpx; }
.hot-section { padding: 20rpx 28rpx; } .hot-section { padding: 20rpx 28rpx; }
.section-title { display: block; font-size: 26rpx; font-weight: 900; color: #9b8fa8; margin-bottom: 20rpx; } .section-title { display: block; font-size: 26rpx; font-weight: 600; color: #b9bdc6; margin-bottom: 20rpx; }
.hot-tags { display: flex; flex-direction: column; gap: 0; background: rgba(255,255,255,0.88); border-radius: 36rpx; overflow: hidden; border: 1rpx solid rgba(255,255,255,0.72); box-shadow: 0 12rpx 26rpx rgba(78,56,96,0.08); } .hot-tags { display: flex; flex-direction: column; gap: 0; background: #ffffff; border-radius: 36rpx; overflow: hidden; box-shadow: var(--shadow-soft); }
.hot-tag { display: flex; align-items: center; gap: 20rpx; padding: 22rpx 28rpx; border-bottom: 1rpx solid rgba(43,37,61,0.05); } .hot-tag { display: flex; align-items: center; gap: 20rpx; padding: 22rpx 28rpx; border-bottom: 1rpx solid rgba(27, 27, 32, 0.04); }
.hot-tag:last-child { border-bottom: none; } .hot-tag:last-child { border-bottom: none; }
.tag-rank { font-size: 30rpx; font-weight: 900; color: #ff4f91; width: 32rpx; text-align: center; } .tag-rank { font-size: 30rpx; font-weight: 700; color: #7563e0; width: 32rpx; text-align: center; font-variant-numeric: tabular-nums; }
.hot-tag:nth-child(n+4) .tag-rank { color: #9b8fa8; } .hot-tag:nth-child(n+4) .tag-rank { color: #b9bdc6; }
.tag-text { flex: 1; font-size: 28rpx; font-weight: 700; color: #272235; } .tag-text { flex: 1; font-size: 28rpx; font-weight: 600; color: #1b1b20; }
.tag-count { font-size: 24rpx; color: #9b8fa8; } .tag-count { font-size: 24rpx; color: #b9bdc6; font-variant-numeric: tabular-nums; }
.results-tabs { display: flex; padding: 0 28rpx 20rpx; gap: 8rpx; } .results-tabs { display: flex; padding: 0 28rpx 20rpx; gap: 8rpx; }
.rtab { font-size: 28rpx; font-weight: 700; color: #9b8fa8; padding: 10rpx 20rpx; border-radius: 999rpx; } .rtab { font-size: 28rpx; font-weight: 600; color: #6e7280; padding: 10rpx 20rpx; border-radius: 999rpx; }
.rtab-on { color: #ff4f91; background: rgba(255,79,145,0.10); font-weight: 900; } .rtab-on { color: #1b1b20; background: #ffffff; font-weight: 700; box-shadow: 0 8rpx 18rpx rgba(27, 27, 32, 0.08); }
.user-result { display: flex; align-items: center; gap: 20rpx; padding: 20rpx 28rpx; background: rgba(255,255,255,0.80); border-bottom: 1rpx solid rgba(43,37,61,0.05); } .user-result { display: flex; align-items: center; gap: 20rpx; padding: 20rpx 28rpx; background: #ffffff; border-bottom: 1rpx solid rgba(27, 27, 32, 0.04); }
.u-avatar { width: 88rpx; height: 88rpx; border-radius: 28rpx; display: flex; align-items: center; justify-content: center; font-size: 36rpx; font-weight: 800; color: rgba(39,34,53,0.72); flex-shrink: 0; } .u-avatar { width: 88rpx; height: 88rpx; border-radius: 28rpx; display: flex; align-items: center; justify-content: center; font-size: 36rpx; font-weight: 700; color: rgba(27, 27, 32, 0.65); flex-shrink: 0; }
.u-name { display: block; font-size: 28rpx; font-weight: 800; color: #272235; } .u-name { display: block; font-size: 28rpx; font-weight: 600; color: #1b1b20; }
.u-bio { display: block; font-size: 24rpx; color: #9b8fa8; margin-top: 4rpx; } .u-bio { display: block; font-size: 24rpx; color: #b9bdc6; margin-top: 4rpx; }
.empty { text-align: center; font-size: 26rpx; color: #9b8fa8; padding: 80rpx; } .empty { text-align: center; font-size: 26rpx; color: #b9bdc6; padding: 80rpx; }
.results-scroll { } .results-scroll { }

View File

@@ -1,10 +1,10 @@
.story-page { width: 100vw; height: 100vh; background: #111; position: relative; overflow: hidden; } .story-page { width: 100vw; height: 100vh; background: #121214; position: relative; overflow: hidden; }
.progress-row { position: absolute; top: calc(env(safe-area-inset-top, 44rpx) + 16rpx); left: 16rpx; right: 16rpx; display: flex; gap: 6rpx; z-index: 10; } .progress-row { position: absolute; top: calc(env(safe-area-inset-top, 44rpx) + 16rpx); left: 16rpx; right: 16rpx; display: flex; gap: 6rpx; z-index: 10; }
.progress-bar { flex: 1; height: 4rpx; background: rgba(255,255,255,0.35); border-radius: 2rpx; overflow: hidden; } .progress-bar { flex: 1; height: 4rpx; background: rgba(255,255,255,0.35); border-radius: 2rpx; overflow: hidden; }
.progress-fill { height: 100%; background: #fff; border-radius: 2rpx; transition: width 0.1s linear; } .progress-fill { height: 100%; background: #fff; border-radius: 2rpx; transition: width 0.1s linear; }
.story-nav { position: absolute; top: calc(env(safe-area-inset-top, 44rpx) + 28rpx); left: 20rpx; right: 20rpx; display: flex; align-items: center; gap: 14rpx; z-index: 10; } .story-nav { position: absolute; top: calc(env(safe-area-inset-top, 44rpx) + 28rpx); left: 20rpx; right: 20rpx; display: flex; align-items: center; gap: 14rpx; z-index: 10; }
.story-avatar { width: 72rpx; height: 72rpx; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 32rpx; font-weight: 800; color: rgba(39,34,53,0.72); border: 3rpx solid rgba(255,255,255,0.72); } .story-avatar { width: 72rpx; height: 72rpx; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 32rpx; font-weight: 700; color: rgba(27, 27, 32, 0.65); border: 3rpx solid rgba(255,255,255,0.72); }
.story-author { display: block; font-size: 28rpx; font-weight: 800; color: #fff; } .story-author { display: block; font-size: 28rpx; font-weight: 700; color: #fff; }
.story-time { display: block; font-size: 22rpx; color: rgba(255,255,255,0.72); } .story-time { display: block; font-size: 22rpx; color: rgba(255,255,255,0.72); }
.close-btn { margin-left: auto; font-size: 40rpx; color: rgba(255,255,255,0.80); padding: 10rpx; } .close-btn { margin-left: auto; font-size: 40rpx; color: rgba(255,255,255,0.80); padding: 10rpx; }
.story-content { width: 100%; height: 100%; } .story-content { width: 100%; height: 100%; }

View File

@@ -37,12 +37,13 @@ export function formatCount(n: number): string {
} }
export function getAvatarGradient(seed: string): string { export function getAvatarGradient(seed: string): string {
// 紫/冷灰单色家族,深浅交错保证相邻头像可区分
const gradients = [ const gradients = [
'linear-gradient(135deg, #ffd6e8, #fff1a6)', 'linear-gradient(135deg, #d9d2fb, #efedfd)',
'linear-gradient(135deg, #ffe7a0, #b7f4d2)', 'linear-gradient(135deg, #e3e5ec, #f4f5f8)',
'linear-gradient(135deg, #c9f7df, #d9d2ff)', 'linear-gradient(135deg, #cfc6fa, #e9e6fc)',
'linear-gradient(135deg, #cfe8ff, #ffd6e8)', 'linear-gradient(135deg, #d8dbe4, #eef0f5)',
'linear-gradient(135deg, #e3d8ff, #c9f7df)', 'linear-gradient(135deg, #e6e1fd, #f3f1fe)',
] ]
let hash = 0 let hash = 0
for (let i = 0; i < seed.length; i++) hash = (hash * 31 + seed.charCodeAt(i)) & 0xffffffff for (let i = 0; i < seed.length; i++) hash = (hash * 31 + seed.charCodeAt(i)) & 0xffffffff

View File

@@ -47,8 +47,10 @@
"compileWorklet": false, "compileWorklet": false,
"minifyWXML": true, "minifyWXML": true,
"localPlugins": false, "localPlugins": false,
"useCompilerPlugins": ["typescript"], "useCompilerPlugins": [
"condition": false, "typescript"
],
"condition": true,
"swc": false, "swc": false,
"disableSWC": true "disableSWC": true
}, },
@@ -59,5 +61,6 @@
}, },
"miniprogramRoot": "miniprogram/", "miniprogramRoot": "miniprogram/",
"srcMiniprogramRoot": "miniprogram/", "srcMiniprogramRoot": "miniprogram/",
"simulatorPluginLibVersion": {} "simulatorPluginLibVersion": {},
"projectArchitecture": "multiPlatform"
} }

68
project.miniapp.json Normal file
View File

@@ -0,0 +1,68 @@
{
"miniVersion": "v2",
"name": "%name%",
"version": "0.0.1",
"versionCode": 100,
"i18nFilePath": "i18n",
"mini-ohos": {
"sdkVersion": "0.5.1"
},
"mini-android": {
"resourcePath": "miniapp/android/nativeResources",
"sdkVersion": "1.6.24",
"toolkitVersion": "0.11.0",
"useExtendedSdk": {
"media": false,
"bluetooth": false,
"network": false,
"scanner": false,
"xweb": false
},
"icons": {
"hdpi": "",
"xhdpi": "",
"xxhdpi": "",
"xxxhdpi": ""
},
"splashscreen": {
"hdpi": "",
"xhdpi": "",
"xxhdpi": ""
},
"enableVConsole": "open",
"privacy": {
"enable": true
}
},
"mini-ios": {
"sdkVersion": "1.7.0",
"toolkitVersion": "0.0.9",
"useExtendedSdk": {
"WeAppOpenFuns": true,
"WeAppNetwork": false,
"WeAppBluetooth": false,
"WeAppMedia": false,
"WeAppLBS": false,
"WeAppOthers": false
},
"enableVConsole": "open",
"icons": {
"mainIcon120": "",
"mainIcon180": "",
"spotlightIcon80": "",
"spotlightIcon120": "",
"settingsIcon58": "",
"settingsIcon87": "",
"notificationIcon40": "",
"notificationIcon60": "",
"appStore1024": ""
},
"splashScreen": {
"customImage": ""
},
"privacy": {
"enable": false
},
"enableOpenUrlNavigate": true
}
}