HarmonyOS 应用 · 校园宿舍拼单我的页深度解析:渐变用户卡与成就徽章的 ArkUI 实战
HarmonyOS 应用 · 校园宿舍拼单我的页深度解析:渐变用户卡与成就徽章的 ArkUI 实战
本文以 HarmonyOS 6.0(API 23)+ ArkTS 声明式 UI 为技术底座,逐行拆解「校园宿舍拼单」应用"我的"Tab(
ProfileTab)的搭建思路——从渐变用户卡到签到系统,从成就徽章墙到菜单列表。所有截图均来自本人电脑正在运行的 HarmonyOS 模拟器真机画面。
一、项目缘起:为什么"我的"页是品牌感的载体
前 3 个 Tab(首页、拼单、订单)解决的是"用户能不能用"的问题,而"我的"页解决的是"用户愿不愿意用"的问题。一款应用的"我的"页是品牌调性最集中的体现——它不像首页那样追求信息密度,也不像拼单页那样追求流程效率,而是要展现"用户在这个 App 里是什么样的人"。
「校园宿舍拼单」的 ProfileTab 用 6 张卡片回答了这个问题:
- 用户卡:渐变背景 + 等级徽章 + 经验进度条 → 用户是 Lv5 拼单达人
- 统计行:拼单数 / 已省 / 好评 / 好友 → 用户的拼单履历
- 成就徽章:6 个徽章 3 解锁 3 未解锁 → 用户的"成就系统"
- 活跃度:本周拼单趋势 → 用户的活跃节奏
- 菜单列表:6 个常用入口 → 用户的下一步行动
- 版本信息:App 元数据 → 用户与开发者的连接
整个 ProfileTab 位于 entry/src/main/ets/pages/ProfileTab.ets,约 235 行 ArkTS 代码,由 6 个 @Builder 区块组成。

二、整体架构:没有 Header 的全屏滚动
ProfileTab 的结构与前 3 个 Tab 不同——它没有 Header:
build() {
Column() {
Scroll() {
Column({ space: 14 }) {
this.UserCard()
this.StatRow()
this.BadgeWall()
this.WeekChart()
this.MenuList()
this.AboutInfo()
}
.width('100%').padding({ bottom: D.pad + this.safeBottom + 20 })
}.layoutWeight(1).scrollBar(BarState.Off).align(Alignment.Top)
}.width('100%').height('100%').backgroundColor(C.bg)
}
为什么没有 Header?因为 UserCard 本身就是 Header——它的渐变背景延伸到状态栏区域,承担了"顶部标识"的功能。这种"用一个内容组件兼任 Header"的设计,让整个 App 的"我的"页比传统 App 更沉浸、更整体。
整个滚动列表的 space 是 14,与首页一致——因为 ProfileTab 和首页一样是"内容展示型"页面,而非"表单型"页面。
下面这张图,是 HarmonyOS 模拟器里我的页首屏的真实运行效果:
可以看到顶部橙色渐变用户卡(“张同学”+“Lv5 拼单达人”+"签到"按钮+"EXP 68/100"经验条),下方是 4 栏统计卡(28 拼单 / ¥386 已省 / 96% 好评 / 15 好友),再下面是成就徽章墙(拼单达人 / 省钱专家 / 人气王已解锁,速拼之星 / 五星好评 / 团长之王未解锁)。

三、UserCard:渐变背景 + 等级徽章 + 签到系统
@Builder UserCard() {
Column({ space: 14 }) {
Row({ space: 14 }) {
Stack({ alignContent: Alignment.BottomEnd }) {
Row() { Text('😀').fontSize(36) }
.width(64).height(64).borderRadius(32)
.backgroundColor('#FFFFFF44').justifyContent(FlexAlign.Center)
.border({ width: 3, color: '#FFFFFF' })
Row() { Text('Lv5').fontSize(9).fontColor('#FFFFFF').fontWeight(FontWeight.Bold) }
.width(28).height(20).backgroundColor(C.warn).borderRadius(10)
.border({ width: 2, color: '#FFFFFF' }).justifyContent(FlexAlign.Center)
}.width(64).height(64)
Column({ space: 5 }) {
Text('张同学').fontSize(20).fontWeight(FontWeight.Bold).fontColor('#FFFFFF')
Row({ space: 8 }) {
Text('🏆 拼单达人').fontSize(11).fontColor('#FFFFFFCC')
Text('| ID: 2024001').fontSize(11).fontColor('#FFFFFF99')
}.width('100%')
Text('宿舍楼 3 号楼 402 室').fontSize(12).fontColor('#FFFFFFAA')
}.alignItems(HorizontalAlign.Start).layoutWeight(1)
Button(this.checkedIn ? '已签到' : '签到')
.fontSize(13).fontColor('#FFFFFF')
.backgroundColor(this.checkedIn ? '#33FFFFFF' : '#FFFFFF33')
.borderRadius(16).height(32).enabled(!this.checkedIn)
.onClick(() => {
this.checkedIn = true;
this.xp = Math.min(100, this.xp + 5);
promptAction.showToast({ message: '签到成功 +5 经验' });
})
}.width('100%')
Stack({ alignContent: Alignment.Start }) {
Column().width('100%').height(8).backgroundColor('#33FFFFFF').borderRadius(4)
Column().width(this.xp + '%').height(8).borderRadius(4).backgroundColor('#FFFFFF')
}.width('100%')
Row() {
Text('EXP ' + this.xp + '/100').fontSize(11).fontColor('#FFFFFFCC')
Blank()
Text('距 Lv6 还差 ' + (100 - this.xp) + ' 经验').fontSize(11).fontColor('#FFFFFFAA')
}.width('100%')
}
.width('100%')
.padding({ top: this.safeTop + 20, left: D.pad, right: D.pad, bottom: 30 })
.linearGradient({ angle: 135, colors: [[C.primary, 0.0], [C.accent, 1.0]] })
}
UserCard 是整个 ProfileTab 里代码量最大的 @Builder,承载了 5 个核心元素:用户头像 + 等级徽章、用户信息、签到按钮、经验进度条、底部 EXP 文字。
3.1 头像 + 等级徽章:双层 Stack 叠加
Stack({ alignContent: Alignment.BottomEnd }) {
Row() { Text('😀').fontSize(36) }
.width(64).height(64).borderRadius(32)
.backgroundColor('#FFFFFF44').justifyContent(FlexAlign.Center)
.border({ width: 3, color: '#FFFFFF' })
Row() { Text('Lv5').fontSize(9).fontColor('#FFFFFF').fontWeight(FontWeight.Bold) }
.width(28).height(20).backgroundColor(C.warn).borderRadius(10)
.border({ width: 2, color: '#FFFFFF' }).justifyContent(FlexAlign.Center)
}.width(64).height(64)
头像 64×64vp,半径 32(完全圆形),背景 #FFFFFF44(26% 不透明白色,在橙黄渐变上呈"半透明白圆"效果),3vp 白边让它从背景中"浮"出来。
Stack({ alignContent: Alignment.BottomEnd }) 把右下角让出来给"Lv5"徽章——徽章 28×20vp,警告黄背景 + 白字 + 2vp 白边。整个"头像 + 徽章"的组合在视觉上是一个"戴勋章的运动员",既有个人身份感(emoji 头像),又有等级系统感(Lv5 徽章)。
这种"Stack + 不同对齐方式"实现"角标 / 徽章叠加"是 ArkUI 的基础模式,与首页 GroupCard 上的"热销 / 爆品"角标同源。
3.2 用户信息:3 行文字
Column({ space: 5 }) {
Text('张同学').fontSize(20).fontWeight(FontWeight.Bold).fontColor('#FFFFFF')
Row({ space: 8 }) {
Text('🏆 拼单达人').fontSize(11).fontColor('#FFFFFFCC')
Text('| ID: 2024001').fontSize(11).fontColor('#FFFFFF99')
}.width('100%')
Text('宿舍楼 3 号楼 402 室').fontSize(12).fontColor('#FFFFFFAA')
}.alignItems(HorizontalAlign.Start).layoutWeight(1)
3 行信息:姓名、成就称号 + ID、宿舍地址。3 种不同的白色透明度——#FFFFFF(100%)、#FFFFFFCC(80%)、#FFFFFF99(60%)、#FFFFFFAA(67%)。这种"用透明度而非灰度"模拟层级,是大厂 Banner 设计的经典手法——避免在彩色背景上出现"脏灰色",保持渐变活力。
3.3 签到按钮:状态切换
Button(this.checkedIn ? '已签到' : '签到')
.fontSize(13).fontColor('#FFFFFF')
.backgroundColor(this.checkedIn ? '#33FFFFFF' : '#FFFFFF33')
.borderRadius(16).height(32).enabled(!this.checkedIn)
.onClick(() => {
this.checkedIn = true;
this.xp = Math.min(100, this.xp + 5);
promptAction.showToast({ message: '签到成功 +5 经验' });
})
@State checkedIn: boolean = false 控制按钮状态:
- 未签到:
#FFFFFF33(20% 白)+ 文字"签到",可点击 - 已签到:
#33FFFFFF(20% 白,更深)+ 文字"已签到",enabled(false)禁用
点击触发 3 件事:
this.checkedIn = true:切换按钮状态this.xp = Math.min(100, this.xp + 5):经验 +5,不超过 100 上限promptAction.showToast({ message: '签到成功 +5 经验' }):弹 toast 反馈
这是 ArkUI 表单交互的经典模式——单一动作触发多状态更新。
3.4 经验进度条
Stack({ alignContent: Alignment.Start }) {
Column().width('100%').height(8).backgroundColor('#33FFFFFF').borderRadius(4)
Column().width(this.xp + '%').height(8).borderRadius(4).backgroundColor('#FFFFFF')
}.width('100%')
与首页、订单页的进度条同构:浅色轨道 + 进度填充。但这里的进度条是纯白色填充,因为背景已经是渐变色,再用主色填充会"撞色"。用白条 + 半透明白色轨道,是深色 Banner 上的经典进度条配色。
@State xp: number = 68 初始 68。每次签到 +5,最高 100。经验值达到 100 时,可以升级到 Lv6(虽然代码里没实现升级逻辑,但体验流程是完整的)。
3.5 渐变背景
.linearGradient({ angle: 135, colors: [[C.primary, 0.0], [C.accent, 1.0]] })
与首页 HeroCard 同款渐变(橙红 → 金黄)。这种"主色渐变 + 白色文字"的卡片,几乎是所有"会员中心 / 个人主页"类页面的标配——它在视觉上"宣告"了用户的归属。
padding({ top: this.safeTop + 20, left: D.pad, right: D.pad, bottom: 30 }) 让卡片顶部紧贴状态栏(safeTop 已经在 EntryAbility 里算好),底部 30vp 留出更多空间给接下来的 StatRow"叠"上来。
四、StatRow:4 栏统计卡(叠在 UserCard 上)
@Builder StatRow() {
Row() {
ForEach(this.stats, (s: StatCell, idx: number) => {
Column({ space: 4 }) {
Text(s.value).fontSize(22).fontWeight(FontWeight.Bold).fontColor(s.color)
Text(s.label).fontSize(11).fontColor(C.textDim)
}.layoutWeight(1)
if (idx < this.stats.length - 1) {
Divider().vertical(true).height(28).color(C.stroke)
}
}, (s: StatCell) => s.label)
}
.width('90%').padding({ top: 14, bottom: 14 })
.backgroundColor(C.card).borderRadius(D.rLg)
.border({ width: 1, color: C.stroke }).margin({ top: -28 })
.justifyContent(FlexAlign.Center)
}
注意 margin({ top: -28 })——这是 StatRow 最巧妙的设计。整张卡片向上偏移 28vp,叠在 UserCard 上:
.width('90%').padding({ top: 14, bottom: 14 })
.backgroundColor(C.card).borderRadius(D.rLg)
.border({ width: 1, color: C.stroke }).margin({ top: -28 })
width('90%') 让 StatRow 比 UserCard 窄 10%,形成"卡片宽度窄于顶部卡片"的层级感。margin({ top: -28 }) 让它向上突出 28vp,与 UserCard 重叠——这是国内 App(如小红书、Keep等)常见的"叠加卡片"设计手法,在支付宝等 App 的"我的"页也能见到。
数据驱动:
private stats: StatCell[] = [
{ label: '拼单数', value: '28', color: C.primary },
{ label: '已省', value: '¥386', color: C.danger },
{ label: '好评', value: '96%', color: C.ok },
{ label: '好友', value: '15', color: C.accent }
];
4 个数字用 4 种颜色:橙(主色)、红(强调)、绿(成功)、金黄(点缀)。每个数字有明确含义,且颜色映射出"用户在 App 里的多维成就"。
五、BadgeWall:成就徽章墙
@Builder BadgeWall() {
Column({ space: 14 }) {
Row() {
Text('成就徽章').fontSize(16).fontWeight(FontWeight.Bold).fontColor(C.text)
Blank()
Text('3/6').fontSize(12).fontColor(C.textDim)
}.width('100%')
Row() {
ForEach(this.badges, (b: Badge) => {
Column({ space: 6 }) {
Row() { Text(b.emoji).fontSize(28) }
.width(48).height(48).borderRadius(24)
.backgroundColor(b.unlocked ? C.primarySoft : C.cardSoft)
.justifyContent(FlexAlign.Center)
.opacity(b.unlocked ? 1.0 : 0.35)
.border({ width: 1, color: b.unlocked ? C.primary : C.stroke })
Text(b.name).fontSize(10).fontColor(b.unlocked ? C.text : C.textDim)
}.layoutWeight(1)
}, (b: Badge) => b.id.toString())
}.width('100%')
}
.width('100%').padding(16).backgroundColor(C.card)
.borderRadius(D.rLg).border({ width: 1, color: C.stroke })
}
6 个徽章,3 个已解锁 3 个未解锁:
private badges: Badge[] = [
{ id: 1, emoji: '🏆', name: '拼单达人', unlocked: true },
{ id: 2, emoji: '💰', name: '省钱专家', unlocked: true },
{ id: 3, emoji: '🔥', name: '人气王', unlocked: true },
{ id: 4, emoji: '🚀', name: '速拼之星', unlocked: false },
{ id: 5, emoji: '⭐', name: '五星好评', unlocked: false },
{ id: 6, emoji: '👑', name: '团长之王', unlocked: false }
];
每个徽章的处理非常细致——用 unlocked 字段驱动 4 个视觉维度:
| 维度 | 已解锁 | 未解锁 |
|---|---|---|
| 背景色 | primarySoft(淡橙) | cardSoft(淡灰) |
| 不透明度 | 1.0(饱满) | 0.35(灰蒙) |
| 边框色 | primary(主色) | stroke(灰描边) |
| 文字色 | text(主文) | textDim(暗淡) |
4 重状态差异让"已解锁"和"未解锁"的徽章在视觉上形成强烈对比——已解锁的鲜艳饱满,未解锁的灰暗朦胧。这种"奖励机制"的视觉处理,是游戏化设计(Gamification)的经典手法。
右上角的"3/6"动态显示解锁进度,是给用户的"目标提示"——让用户知道还有 3 个徽章可以努力。
六、WeekChart:本周拼单活跃度
@Builder WeekChart() {
Column({ space: 12 }) {
Row() {
Text('本周拼单活跃度').fontSize(15).fontWeight(FontWeight.Bold).fontColor(C.text)
Blank()
Text('总计 385').fontSize(12).fontColor(C.primary)
}.width('100%')
Row() {
ForEach(this.barData, (b: BarData, idx: number) => {
Column({ space: 6 }) {
Stack({ alignContent: Alignment.Bottom }) {
Column().width(16).height(b.value * 1.0).borderRadius(5)
.linearGradient({
angle: 180,
colors: this.selectedBar === idx
? [[C.primary, 0.0], [C.accent, 1.0]]
: [[C.primarySoft, 0.0], [C.primary, 1.0]]
}).opacity(this.selectedBar === idx ? 1.0 : 0.5)
}.width(24).height(90)
Text(b.day).fontSize(10)
.fontColor(this.selectedBar === idx ? C.primary : C.textDim)
.fontWeight(this.selectedBar === idx ? FontWeight.Bold : FontWeight.Normal)
}.layoutWeight(1).onClick(() => { this.selectedBar = idx; })
}, (b: BarData) => b.day)
}.width('100%')
}
.width('100%').padding(16).backgroundColor(C.card)
.borderRadius(D.rLg).border({ width: 1, color: C.stroke })
}
与首页 WeekChart 同构,但有 4 处细节差异:
- 柱体最大高度 90(首页是 120),更适合"个人活跃度"的紧凑视觉
- 柱体宽度 16(首页是 18),更精致
- 不透明度对比 1.0 vs 0.5(首页是 1.0 vs 0.6),更明显的选中态
- 数据不同:首页是 60/80/45/90/70/100/55(首页日均拼单数),我的页是 30/50/40/70/60/90/45(个人活跃度)
private barData: BarData[] = [
{ day: '一', value: 30 }, { day: '二', value: 50 }, { day: '三', value: 40 },
{ day: '四', value: 70 }, { day: '五', value: 60 }, { day: '六', value: 90 },
{ day: '日', value: 45 }
];
默认值 5(周六),@State selectedBar: number = 5。点击柱子切换选中态,与首页同模式。
注意右上角的"总计 385"——这是 7 天数据的求和 (30+50+40+70+60+90+45=385)。在 UI 上用静态文字展示,但实际上是"前端实时计算"或"后端返回"的——这种"主操作区域右上角显示汇总"是数据看板的常见设计。
七、MenuList:6 个菜单项 + Badge 角标
@Builder MenuList() {
Column({ space: 0 }) {
ForEach(this.menus, (m: MenuItem) => {
Row() {
Text(m.icon).fontSize(20).width(32)
Text(m.label).fontSize(15).fontColor(C.text).layoutWeight(1)
if (m.showBadge) {
Text(m.badge).fontSize(10).fontColor('#FFFFFF')
.padding({ left: 6, right: 6, top: 2, bottom: 2 })
.backgroundColor(m.badgeColor).borderRadius(8)
.margin({ right: 8 })
}
Text('›').fontSize(18).fontColor(C.textDim)
}
.width('100%').height(52)
.padding({ left: 16, right: 16 })
.backgroundColor(C.card)
.onClick(() => { promptAction.showToast({ message: m.label }); })
if (m.id < this.menus.length) {
Divider().color(C.stroke).margin({ left: 48 })
}
}, (m: MenuItem) => m.id.toString())
}
.width('100%').backgroundColor(C.card)
.borderRadius(D.rLg).border({ width: 1, color: C.stroke })
}
6 个菜单项:
private menus: MenuItem[] = [
{ id: 1, icon: '📦', label: '我的订单', badge: '5', badgeColor: C.danger, showBadge: true },
{ id: 2, icon: '❤️', label: '我的收藏', badge: '', badgeColor: '', showBadge: false },
{ id: 3, icon: '👥', label: '我的好友', badge: 'NEW', badgeColor: C.ok, showBadge: true },
{ id: 4, icon: '🎟️', label: '优惠券', badge: '3', badgeColor: C.danger, showBadge: true },
{ id: 5, icon: '📊', label: '消费统计', badge: '', badgeColor: '', showBadge: false },
{ id: 6, icon: '⚙️', label: '设置', badge: '', badgeColor: '', showBadge: false }
];
每个菜单项的视觉结构是 [emoji icon] [label] [optional badge] [chevron ›]。注意几处细节:
- emoji 固定宽度 32:让所有 emoji 头像对齐,整列更整齐
- 可选 badge:
if (m.showBadge)控制是否渲染 badge,支持数字("5"“3”)和文字(“NEW”)两种形态 - chevron ›:所有菜单都有箭头,提示"可点击跳转"
- 分割线:
Divider().color(C.stroke).margin({ left: 48 })—— margin left 48 让分割线从 emoji 后开始,避免"穿过 emoji"的视觉混乱 if (m.id < this.menus.length)边界判断:最后一项不画分割线
MenuItem 接口用 showBadge: boolean 字段控制角标显示,比单纯用 if (badge !== '') 更类型安全——避免空字符串判断的"魔法值"陷阱。
下图是"我的"页底部,可以看到完整菜单列表和版本信息:
可以看到 6 个菜单项(我的订单带红色"5"角标、我的收藏无角标、我的好友带绿色"NEW"、优惠券带红色"3"、消费统计、设置),底部是版本信息"宿舍拼单 v1.0.0" + “HarmonyOS 6.0+ · ArkTS · API 23”。

八、AboutInfo:版本信息
@Builder AboutInfo() {
Column({ space: 4 }) {
Text('宿舍拼单 v1.0.0').fontSize(12).fontColor(C.textDim)
Text('HarmonyOS 6.0+ · ArkTS · API 23').fontSize(11).fontColor(C.textDim)
}.width('100%').alignItems(HorizontalAlign.Center).padding({ top: 10 })
}
极简的版本信息——2 行文字居中显示。alignItems(HorizontalAlign.Center) 让文字水平居中,padding({ top: 10 }) 与上方 MenuList 留 10vp 间距。
这种"低调的版本信息"放在页面最底部,符合"用户不关心但不删会显得不完整"的处理原则——既提供了开发者与用户的连接点,又不会抢走主要内容的风头。

九、状态管理:3 个 @State 字段
整个 ProfileTab 用 3 个 @State:
@State checkedIn: boolean = false;
@State selectedBar: number = 5;
@State xp: number = 68;
checkedIn:签到状态selectedBar:活跃度图选中柱下标xp:经验值(默认 68,签到后 +5)
加上 4 个数据接口(barData / stats / badges / menus),整张页面的"事实来源"清晰简单。注意 xp 的更新逻辑用了 Math.min(100, this.xp + 5) 这种"上限保护"——避免经验值超过 100 导致进度条溢出。
十、ArkTS 工程化细节
ProfileTab 同样严格遵循项目规范:
- 接口先行:
MenuItem、Badge、BarData、StatCell4 个接口显式声明。 - ForEach 第三参数必填:所有
ForEach都传了 keyGenerator。 - 无类型断言:全文没有
as any等逃生舱口。 #XXXXXX44等 8 位十六进制色值:ArkUI 支持带 alpha 通道的颜色字符串,前六位是 RGB,后两位是 alpha(00-FF),例如#FFFFFF44表示白色 RGB=FFFFFF、alpha=44(约 27% 不透明度)。ArkUI 和 CSS 都支持在颜色字符串中带 alpha 通道(CSS Color Level 4 同样支持#RRGGBBAA格式)。
特别值得一提的是 opacity 与 backgroundColor alpha 的区别——opacity(0.35) 控制整个组件(包括文字、边框)的不透明度,而 backgroundColor('#FFFFFF44') 只控制背景的透明度。在徽章墙的设计中,已解锁和未解锁用 opacity(0.35) 一起处理 emoji + 背景 + 边框的"整体灰蒙"效果,是最经济的方式。
十一、可演进方向
ProfileTab 已经是一个相当完整的"个人中心",但还有以下可演进方向:
- 签到日历:当前是单次按钮,可以升级为"7 天签到日历",连续签到额外奖励经验。
- 徽章点击查看详情:点击未解锁徽章弹层展示"解锁条件"(如"再发起 5 次拼单即可解锁")。
- 菜单项跳转:当前菜单点击只弹 toast,可以接入路由跳转到对应子页面。
- 头像上传:当前是 emoji 头像,可以接入图片选择器让用户上传真实头像。
- 设置页面:从菜单项"设置"跳转到完整的设置页(主题切换、消息推送、隐私设置等)。
- 数据可视化升级:当前 WeekChart 是简单的条形图,可以拓展为"日 / 周 / 月"维度切换,或加入更多维度的趋势图。
十二、写在最后
回到开篇的两张真机截图——
从顶部渐变用户卡(橙红 → 金黄,“张同学” Lv5),到 4 栏统计叠卡(28 / ¥386 / 96% / 15),再到 6 个成就徽章(3 解锁 / 3 未解锁)和本周活跃度条形图,最后到 6 个带 badge 的菜单项,整张"我的"页用约 235 行 ArkTS 代码,构建出了一个"既完整又有品牌感"的个人中心。
它最值得借鉴的设计有 4 处:
- 没有 Header,用 UserCard 兼任:渐变背景延伸至状态栏,让整个页面更沉浸。
- StatRow 向上叠加:
margin({ top: -28 })让统计卡"挂"在用户卡下方,形成国内 App 常见的叠加层次。 - 徽章的多重视觉反馈:用
opacity+backgroundColor+border+ 文字色 4 重差异区分"已解锁 / 未解锁",让奖励机制非常醒目。 - 菜单项的 Badge 模式:用
showBadge: boolean+badgeColor接口字段,让菜单项能动态显示"5"“NEW”"3"等多种角标,是"通知中心"类设计的基础模式。
如果你也在做 HarmonyOS 个人中心页,不妨从"渐变 + 叠加 + 徽章 + 菜单"这四个组件开始搭骨架。当你把"我的"页打磨到这种程度,整个 App 的品牌感就已经立住了。
更多推荐



所有评论(0)