ITPub博客

首页 > 人工智能 > 人工智能 > 技术解读:HarmonyOS 6 ArkUI - conditionIdx和brandIdx用于估价查询Tab中成色和品牌的选择状

技术解读:HarmonyOS 6 ArkUI - conditionIdx和brandIdx用于估价查询Tab中成色和品牌的选择状

人工智能 作者:Flow_Official 时间:2026-10-12 17:29:12 0 删除 编辑

在移动互联网快速发展的今天,二手数码产品(手机、平板、电脑等)的回收与再利用已经成为一个规模巨大的市场。一个优秀的二手回收平台不仅需要提供精准的估价服务,还需要覆盖质检、预约上门、以旧换新、订单管理等完整的业务闭环。本文将以HarmonyOS ArkTS声明式开发框架为基础,深入剖析一个包含6个差异化Tab页面、5种弹框样式、柱状图与占比进度条的完整二手数码回收应用的技术实现细节。

从技术架构层面来看,该应用采用HarmonyOS ArkTS API 24提供的声明式UI开发范式,通过 @Entry 、 @Component 、 @State 、 @Builder 等核心装饰器构建出结构清晰、交互丰富的多页面应用。整个应用以单一自定义组件 RecycleStationApp 为入口,内部通过 currentIndex 状态变量驱动6个Tab页面的切换渲染,每个Tab页面使用独立的 @Builder 方法进行封装,实现了页面逻辑的高度模块化。同时,5种不同样式的弹框(居中结果卡、底部弹窗、表单编辑、删除确认、详情报告)通过 @State 布尔变量控制显示,形成了一套完整的模态交互体系。

在数据模型设计方面,应用定义了 PhoneItem 、 RecycleOrder 、 BrandRate 、 PriceStat 、 QualityItem 五个接口类型,分别描述回收机型、回收订单、品牌回收占比、价格统计和质检标准等业务实体。配色方案采用亮黄 #FFB800 、深蓝 #1B2A4A 和环保绿 #00C853 三色搭配,既体现了转转回收的品牌特征,又通过绿色元素传递环保理念。这些设计决策共同构成了一个业务完整、视觉统一、交互流畅的HarmonyOS原生应用。

一、数据模型与接口定义

在ArkTS开发中,接口类型的定义是构建类型安全应用的基础。该应用在文件顶部定义了五个核心接口,为后续的列表渲染、弹框数据绑定和业务逻辑处理提供了严格的数据契约。

interface
PhoneItem
{
id
:
number
model
:
string
brand
:
string
storage
:
string
color
:
string
estPrice
:
number
maxPrice
:
number
condition
:
string
recycleCount
:
number
icon
:
string
year
:
string
}
interface
RecycleOrder
{
id
:
number
model
:
string
price
:
number
status
:
string
date
:
string
channel
:
string
method
:
string
icon
:
string
}
interface
BrandRate
{
brand
:
string
rate
:
number
icon
:
string
}
interface
PriceStat
{
level
:
string
price
:
number
}
interface
QualityItem
{
title
:
string
desc
:
string
standard
:
string
icon
:
string
}
在这里插入图片描述

PhoneItem 接口是应用中最重要的数据模型,它描述了每一款回收数码产品的完整信息,包括唯一标识 id 、型号名称 model 、品牌 brand 、存储容量 storage 、颜色 color 、估价 estPrice 、最高价 maxPrice 、成色 condition 、回收次数 recycleCount 、图标 icon 和年份 year 。这种设计使得每个列表项都能展示丰富的商品信息。 RecycleOrder 接口则聚焦于订单维度,记录了订单编号、机型、价格、状态、日期、渠道和方式等关键字段,为订单管理Tab提供了完整的数据支撑。 BrandRate 和 PriceStat 接口分别服务于品牌占比和价格分布的图表展示需求,而 QualityItem 则为质检标准Tab提供了结构化的数据支持。

二、组件状态管理与初始化

ArkTS的声明式UI框架通过 @State 装饰器实现响应式数据绑定,当状态变量发生变化时,框架会自动触发UI的重新渲染。该应用的状态管理设计涵盖了页面导航、弹框控制、数据选择等多个维度。

@
Entry
@
Component
struct RecycleStationApp
{
@
State
currentIndex
:
number
=
0
@
State
showQuoteDialog
:
boolean
=
false
@
State
showBookDialog
:
boolean
=
false
@
State
showEditDialog
:
boolean
=
false
@
State
showDeleteDialog
:
boolean
=
false
@
State
showReportDialog
:
boolean
=
false
@
State
selectedPhone
:
PhoneItem
|
null
=
null
@
State
selectedOrder
:
RecycleOrder
|
null
=
null
@
State
modelText
:
string
=
''
@
State
quotePrice
:
number
=
0
@
State
conditionIdx
:
number
=
2
@
State
brandIdx
:
number
=
0
@
State
deleteTarget
:
string
=
''
@
State
orderFilter
:
number
=
0
@
State
bookMethod
:
number
=
0
@
State
pulse
:
boolean
=
false
tabNames
:
string
[
]
=
[
'回收大厅'
,
'估价查询'
,
'质检标准'
,
'以旧换新'
,
'交易订单'
,
'我的'
]
tabIcons
:
string
[
]
=
[
'♻️'
,
'🔍'
,
'📋'
,
'🔄'
,
'📦'
,
'👤'
]
}
在这里插入图片描述

在状态变量设计中, currentIndex 作为核心导航状态控制6个Tab页面的切换显示。5个布尔型状态变量 showQuoteDialog 到 showReportDialog 分别对应5种弹框的显示与隐藏,实现了模态框的独立控制。 selectedPhone 和 selectedOrder 采用 PhoneItem | null 联合类型,在弹框打开时持有选中项的引用,在关闭时置为 null ,确保数据安全。 conditionIdx 和 brandIdx 用于估价查询Tab中成色和品牌的选择状态, orderFilter 用于订单列表的状态筛选, bookMethod 用于预约方式的选择。值得注意的 pulse 状态变量配合 animation 动画属性,为估价金额和横幅图标提供了呼吸式的缩放动画效果,增强了交互的视觉反馈。

三、回收大厅Tab页面实现

回收大厅作为应用的首屏,承载了品牌展示、环保数据、回收方式入口和热门机型列表等核心功能。该页面采用了渐变头部加滚动列表的经典布局结构。

@
Builder
HallTab
(
)
{
Column
(
)
{
Column
(
)
{
Row
(
)
{
Column
(
)
{
Text
(
'♻️ 转转回收'
)
.
fontSize
(
18
)
.
fontWeight
(
FontWeight
.
Bold
)
.
fontColor
(
'#FFFFFF'
)
Text
(
'旧机高价卖 · 环保你我他'
)
.
fontSize
(
10
)
.
fontColor
(
'#BFE3FF'
)
.
margin
(
{
top
:
2
}
)
}
.
alignItems
(
HorizontalAlign
.
Start
)
Column
(
)
{
Text
(
'🏆 环保达人'
)
.
fontSize
(
12
)
.
fontColor
(
'#FFFFFF'
)
}
.
layoutWeight
(
1
)
.
alignItems
(
HorizontalAlign
.
End
)
}
.
width
(
'100%'
)
Row
(
)
{
Text
(
'🔍'
)
.
fontSize
(
12
)
Text
(
'输入手机型号查询回收价'
)
.
fontSize
(
12
)
.
fontColor
(
'#88A0C0'
)
.
margin
(
{
left
:
6
}
)
}
.
width
(
'100%'
)
.
padding
(
{
left
:
12
,
right
:
12
,
top
:
8
,
bottom
:
8
}
)
.
margin
(
{
top
:
12
}
)
.
backgroundColor
(
'#28406A'
)
.
borderRadius
(
14
)
.
onClick
(
(
)
=>
{
this
.
showQuoteDialog
=
true
}
)
}
.
width
(
'100%'
)
.
padding
(
{
left
:
14
,
right
:
14
,
top
:
12
,
bottom
:
14
}
)
.
linearGradient
(
{
angle
:
160
,
colors
:
[
[
'#1B2A4A'
,
0
]
,
[
'#2E5AA8'
,
1
]
]
}
)
}
}
在这里插入图片描述

头部区域使用 linearGradient 线性渐变属性,从 #1B2A4A (深蓝)过渡到 #2E5AA8 (亮蓝),angle设置为160度使渐变方向从左上到右下,营造出科技感的品牌头部。头部内嵌了一个搜索入口,通过 onClick 事件设置 showQuoteDialog = true 打开估价弹框。环保数据卡片区域使用三个 Column 组件均分宽度,分别展示累计回收台数、减少碳排放吨数和环保再利用率,每个数据项使用 #00C853 环保绿色突出显示数值,配合 #666666 灰色标签文字,形成了醒目的数据可视化效果。

回收方式横条通过 ForEach 遍历三种回收方式(上门回收、快递回收、门店回收),每个方式渲染为独立的 Column 卡片,点击后设置 bookMethod 并打开预约弹框。热门回收机型列表是页面的核心内容区域,通过 ForEach 遍历18条 PhoneItem 数据,每条记录渲染为包含图标、型号信息、成色标签、估价价格和查报价按钮的卡片行。列表整体包裹在 Scroll 组件中,并通过 scrollBar(BarState.Off) 隐藏滚动条,保持视觉简洁。

四、估价查询Tab与柱状图实现

估价查询Tab提供了品牌选择、型号输入、成色选择和价格统计柱状图等功能,是应用中数据可视化最丰富的页面之一。

@
Builder
QuoteTab
(
)
{
Column
(
)
{
Column
(
)
{
Row
(
)
{
Text
(
'🔍 估价查询'
)
.
fontSize
(
18
)
.
fontWeight
(
FontWeight
.
Bold
)
.
fontColor
(
'#1B2A4A'
)
Column
(
)
.
layoutWeight
(
1
)
Text
(
'AI智能估价'
)
.
fontSize
(
11
)
.
fontColor
(
'#00C853'
)
}
.
width
(
'100%'
)
.
padding
(
{
left
:
14
,
right
:
14
,
top
:
10
,
bottom
:
10
}
)
}
.
width
(
'100%'
)
.
backgroundColor
(
'#EAF2FF'
)
Scroll
(
)
{
Column
(
)
{
Column
(
)
{
Text
(
'选择品牌'
)
.
fontSize
(
12
)
.
fontColor
(
'#999999'
)
.
width
(
'100%'
)
Row
(
)
{
ForEach
(
[
'Apple'
,
'华为'
,
'小米'
,
'OPPO'
,
'vivo'
,
'三星'
]
,
(
b
:
string
,
idx
:
number
)
=>
{
Text
(
b
)
.
fontSize
(
11
)
.
fontColor
(
this
.
brandIdx
===
idx
?
'#FFFFFF'
:
'#333333'
)
.
backgroundColor
(
this
.
brandIdx
===
idx
?
'#2E5AA8'
:
'#F5F5F5'
)
.
padding
(
{
left
:
10
,
right
:
10
,
top
:
5
,
bottom
:
5
}
)
.
borderRadius
(
8
)
.
margin
(
{
right
:
6
}
)
.
onClick
(
(
)
=>
{
this
.
brandIdx
=
idx
}
)
}
,
(
b
:
string
)
=>
b
)
}
.
width
(
'100%'
)
.
margin
(
{
top
:
8
}
)
Text
(
'选择型号'
)
.
fontSize
(
12
)
.
fontColor
(
'#999999'
)
.
width
(
'100%'
)
.
margin
(
{
top
:
12
}
)
Text
(
'iPhone 15 Pro Max 256G'
)
.
fontSize
(
13
)
.
fontColor
(
'#333333'
)
.
width
(
'100%'
)
.
padding
(
10
)
.
margin
(
{
top
:
6
}
)
.
backgroundColor
(
'#F8F8F8'
)
.
borderRadius
(
8
)
Text
(
'使用情况'
)
.
fontSize
(
12
)
.
fontColor
(
'#999999'
)
.
width
(
'100%'
)
.
margin
(
{
top
:
12
}
)
Row
(
)
{
ForEach
(
[
'全新'
,
'99新'
,
'95新'
,
'9成新'
,
'8成新'
]
,
(
c
:
string
,
idx
:
number
)
=>
{
Text
(
c
)
.
fontSize
(
11
)
.
fontColor
(
this
.
conditionIdx
===
idx
?
'#FFFFFF'
:
'#333333'
)
.
backgroundColor
(
this
.
conditionIdx
===
idx
?
'#00C853'
:
'#F5F5F5'
)
.
padding
(
{
left
:
10
,
right
:
10
,
top
:
5
,
bottom
:
5
}
)
.
borderRadius
(
8
)
.
margin
(
{
right
:
6
}
)
.
onClick
(
(
)
=>
{
this
.
conditionIdx
=
idx
}
)
}
,
(
c
:
string
)
=>
c
)
}
.
width
(
'100%'
)
.
margin
(
{
top
:
8
}
)
Text
(
'开始估价'
)
.
fontSize
(
14
)
.
fontWeight
(
FontWeight
.
Bold
)
.
fontColor
(
'#FFFFFF'
)
.
width
(
'100%'
)
.
textAlign
(
TextAlign
.
Center
)
.
padding
(
{
top
:
11
,
bottom
:
11
}
)
.
backgroundColor
(
'#00C853'
)
.
borderRadius
(
20
)
.
margin
(
{
top
:
16
}
)
.
onClick
(
(
)
=>
{
this
.
quotePrice
=
4250
this
.
showQuoteDialog
=
true
}
)
}
}
}
}
}
在这里插入图片描述

品牌选择和成色选择都采用了标签按钮组的交互模式,通过 brandIdx 和 conditionIdx 两个状态变量记录当前选中项。当用户点击某个标签时,对应的索引值更新, ForEach 重新渲染使选中项获得高亮样式(白字蓝底/白字绿底),未选中项保持默认样式(深字灰底)。这种三元条件样式绑定是ArkTS声明式UI中最常见的交互模式之一。估价按钮使用绿色 #00C853 背景和圆角设计,点击后设置估价金额并打开结果弹框。

价格统计柱状图是估价查询页面的亮点功能,通过纯ArkTS组件堆叠实现了可视化柱状图效果。每个柱子使用 Column 组件,高度通过动态计算 s.price / 1050 * 80 得出比例值,其中1050是最大价格值,80是柱子最大高度。柱子顶部圆角通过 borderRadius({ topLeft: 3, topRight: 3 }) 实现,配合绿色 #00C853 背景。品牌回收占比则使用 Stack 组件叠加灰色背景条和渐变进度条,进度条宽度通过 b.rate / 38 * 100 + '%' 动态计算,渐变从蓝色 #2E5AA8 到绿色 #00C853 ,形成了直观的数据条形图。

五、质检标准与以旧换新Tab

质检标准Tab展示了从全新未拆封到7成新及以下共6个成色等级的详细标准和价格系数,同时提供了质检报告示例的查看入口。

@
Builder
QualityTab
(
)
{
Column
(
)
{
Column
(
)
{
Row
(
)
{
Text
(
'📋 质检标准'
)
.
fontSize
(
18
)
.
fontWeight
(
FontWeight
.
Bold
)
.
fontColor
(
'#FFFFFF'
)
Column
(
)
.
layoutWeight
(
1
)
Text
(
'明码标价 · 童叟无欺'
)
.
fontSize
(
11
)
.
fontColor
(
'#BFE3FF'
)
}
.
width
(
'100%'
)
.
padding
(
{
left
:
14
,
right
:
14
,
top
:
12
,
bottom
:
12
}
)
.
linearGradient
(
{
angle
:
135
,
colors
:
[
[
'#00C853'
,
0
]
,
[
'#2E5AA8'
,
1
]
]
}
)
}
.
width
(
'100%'
)
Scroll
(
)
{
Column
(
)
{
Row
(
)
{
Text
(
'🛡️'
)
.
fontSize
(
30
)
Column
(
)
{
Text
(
'转转质检保障'
)
.
fontSize
(
14
)
.
fontWeight
(
FontWeight
.
Bold
)
.
fontColor
(
'#1B2A4A'
)
Text
(
'专业质检师 + AI 双重检测,杜绝翻新机'
)
.
fontSize
(
10
)
.
fontColor
(
'#666666'
)
.
margin
(
{
top
:
3
}
)
}
.
alignItems
(
HorizontalAlign
.
Start
)
.
margin
(
{
left
:
10
}
)
}
.
width
(
'100%'
)
.
padding
(
14
)
.
margin
(
{
left
:
12
,
right
:
12
,
top
:
10
}
)
.
backgroundColor
(
'#E8F9EF'
)
.
borderRadius
(
12
)
.
border
(
{
width
:
1
,
color
:
'#00C853'
,
radius
:
12
}
)
ForEach
(
this
.
qualityList
,
(
q
:
QualityItem
,
idx
:
number
)
=>
{
Row
(
)
{
Text
(
q
.
icon
)
.
fontSize
(
26
)
.
width
(
46
)
.
height
(
46
)
.
textAlign
(
TextAlign
.
Center
)
.
backgroundColor
(
'#F0F7FF'
)
.
borderRadius
(
10
)
Column
(
)
{
Row
(
)
{
Text
(
q
.
title
)
.
fontSize
(
13
)
.
fontWeight
(
FontWeight
.
Medium
)
.
fontColor
(
'#1B2A4A'
)
Column
(
)
.
layoutWeight
(
1
)
Text
(
q
.
standard
)
.
fontSize
(
10
)
.
fontWeight
(
FontWeight
.
Bold
)
.
fontColor
(
idx
<
3
?
'#00C853'
:
'#FF8F00'
)
}
.
width
(
'100%'
)
Text
(
q
.
desc
)
.
fontSize
(
11
)
.
fontColor
(
'#666666'
)
.
width
(
'100%'
)
.
margin
(
{
top
:
4
}
)
}
.
layoutWeight
(
1
)
.
alignItems
(
HorizontalAlign
.
Start
)
.
margin
(
{
left
:
10
}
)
}
.
width
(
'100%'
)
.
padding
(
12
)
.
margin
(
{
left
:
12
,
right
:
12
,
top
:
8
}
)
.
backgroundColor
(
'#FFFFFF'
)
.
borderRadius
(
12
)
}
,
(
q
:
QualityItem
)
=>
q
.
title
)
}
}
}
}
在这里插入图片描述

质检标准头部使用了从环保绿 #00C853 到深蓝 #2E5AA8 的渐变效果,与回收大厅Tab形成视觉差异化。质检保障横幅采用 #E8F9EF 浅绿色背景配合绿色边框,突出了"专业质检师+AI双重检测"的卖点。成色标准列表通过 ForEach 遍历 qualityList 数据,每项包含图标、标题、价格标准和描述。值得注意的是,价格标准的颜色使用了三元条件 idx < 3 ? '#00C853' : '#FF8F00' ,前三项(全新到95新)使用绿色表示有溢价,后三项(9成新及以下)使用橙色表示折价,这种颜色编码帮助用户快速理解价格区间。

以旧换新Tab的核心是补贴计算横幅,通过"旧机回收价 + 换新补贴 = 合计抵扣"的公式式布局,直观地展示了以旧换新的价格优势。横幅使用 #FFF7E0 浅黄色背景配合 #FFB800 黄色边框,与换新主题色一致。热门换新机型列表复用了 phoneList 的前12条数据,每项增加"以旧换新减¥500"的补贴标签和"换新"按钮,点击后打开预约弹框。

六、交易订单Tab与状态筛选

交易订单Tab提供了订单状态筛选和列表展示功能,通过 orderFilter 状态变量实现了全部、待上门、检测中、已完成四个状态标签的切换筛选。

@
Builder
OrderTab
(
)
{
Column
(
)
{
Column
(
)
{
Row
(
)
{
Text
(
'📦 回收订单'
)
.
fontSize
(
18
)
.
fontWeight
(
FontWeight
.
Bold
)
.
fontColor
(
'#1B2A4A'
)
Column
(
)
.
layoutWeight
(
1
)
Text
(
'共 '
+
this
.
orderList
.
length
+
' 单'
)
.
fontSize
(
11
)
.
fontColor
(
'#999999'
)
}
.
width
(
'100%'
)
.
padding
(
{
left
:
14
,
right
:
14
,
top
:
10
,
bottom
:
8
}
)
}
.
width
(
'100%'
)
.
backgroundColor
(
'#EAF2FF'
)
Row
(
)
{
ForEach
(
this
.
orderFilters
,
(
f
:
string
,
idx
:
number
)
=>
{
Column
(
)
{
Text
(
f
)
.
fontSize
(
12
)
.
fontColor
(
this
.
orderFilter
===
idx
?
'#00C853'
:
'#666666'
)
.
fontWeight
(
this
.
orderFilter
===
idx
?
FontWeight
.
Bold
:
FontWeight
.
Normal
)
if
(
this
.
orderFilter
===
idx
)
{
Column
(
)
.
width
(
18
)
.
height
(
3
)
.
backgroundColor
(
'#00C853'
)
.
borderRadius
(
2
)
.
margin
(
{
top
:
4
}
)
}
else
{
Column
(
)
.
width
(
18
)
.
height
(
3
)
.
margin
(
{
top
:
4
}
)
}
}
.
layoutWeight
(
1
)
.
onClick
(
(
)
=>
{
this
.
orderFilter
=
idx
}
)
}
,
(
f
:
string
)
=>
f
)
}
.
width
(
'100%'
)
.
padding
(
{
top
:
8
,
bottom
:
8
}
)
.
backgroundColor
(
'#FFFFFF'
)
Scroll
(
)
{
Column
(
)
{
ForEach
(
this
.
orderList
,
(
o
:
RecycleOrder
)
=>
{
if
(
this
.
filterOrder
(
o
)
)
{
Row
(
)
{
Text
(
o
.
icon
)
.
fontSize
(
26
)
.
width
(
48
)
.
height
(
48
)
.
textAlign
(
TextAlign
.
Center
)
.
backgroundColor
(
'#F0F7FF'
)
.
borderRadius
(
10
)
Column
(
)
{
Row
(
)
{
Text
(
o
.
model
)
.
fontSize
(
13
)
.
fontWeight
(
FontWeight
.
Medium
)
.
fontColor
(
'#1B2A4A'
)
.
maxLines
(
1
)
.
textOverflow
(
{
overflow
:
TextOverflow
.
Ellipsis
}
)
Column
(
)
.
layoutWeight
(
1
)
Text
(
o
.
status
)
.
fontSize
(
10
)
.
fontColor
(
this
.
orderStatusColor
(
o
.
status
)
)
}
.
width
(
'100%'
)
Row
(
)
{
Text
(
o
.
channel
)
.
fontSize
(
10
)
.
fontColor
(
'#999999'
)
Text
(
o
.
method
)
.
fontSize
(
10
)
.
fontColor
(
'#999999'
)
.
margin
(
{
left
:
8
}
)
}
.
width
(
'100%'
)
.
margin
(
{
top
:
4
}
)
Row
(
)
{
Text
(
'回收价 ¥'
+
o
.
price
)
.
fontSize
(
14
)
.
fontWeight
(
FontWeight
.
Bold
)
.
fontColor
(
'#FF8F00'
)
Column
(
)
.
layoutWeight
(
1
)
Text
(
o
.
date
)
.
fontSize
(
10
)
.
fontColor
(
'#BBBBBB'
)
}
.
width
(
'100%'
)
.
margin
(
{
top
:
5
}
)
}
.
layoutWeight
(
1
)
.
alignItems
(
HorizontalAlign
.
Start
)
.
margin
(
{
left
:
10
}
)
}
.
width
(
'100%'
)
.
padding
(
12
)
.
margin
(
{
left
:
12
,
right
:
12
,
top
:
8
}
)
.
backgroundColor
(
'#FFFFFF'
)
.
borderRadius
(
12
)
.
onClick
(
(
)
=>
{
this
.
selectedOrder
=
o
this
.
showEditDialog
=
true
}
)
}
}
,
(
o
:
RecycleOrder
)
=>
o
.
id
.
toString
(
)
)
}
}
}
}
在这里插入图片描述

状态筛选栏的实现非常巧妙,选中标签不仅改变文字颜色为绿色和加粗,还在下方渲染一个18x3像素的绿色指示条( Column 组件),而未选中标签则渲染同尺寸的透明占位条,保证了标签高度一致。这种设计在电商类应用中非常常见。订单列表通过 if (this.filterOrder(o)) 条件判断实现筛选逻辑, filterOrder 方法根据 orderFilter 的值决定是否显示当前订单。每个订单卡片的状态文字颜色通过 orderStatusColor 方法动态计算:待上门为橙色 #FF8F00 ,检测中为蓝色 #2E5AA8 ,已完成为绿色 #00C853 ,已取消为灰色 #CCCCCC 。点击订单卡片会设置 selectedOrder 并打开编辑弹框,实现了列表项到详情的跳转。

七、弹框系统实现

该应用实现了5种不同样式的弹框,覆盖了居中弹窗、底部弹窗、表单编辑、删除确认和详情报告等常见交互模式,构成了一个完整的模态交互系统。

在线估价弹框(居中结果卡样式)

@
Builder
QuoteDialog
(
)
{
Column
(
)
{
Column
(
)
{
Row
(
)
{
Text
(
'🔍 估价结果'
)
.
fontSize
(
16
)
.
fontWeight
(
FontWeight
.
Bold
)
.
fontColor
(
'#1B2A4A'
)
Column
(
)
.
layoutWeight
(
1
)
Text
(
'✕'
)
.
fontSize
(
16
)
.
fontColor
(
'#999999'
)
.
padding
(
6
)
.
onClick
(
(
)
=>
{
this
.
showQuoteDialog
=
false
}
)
}
.
width
(
'100%'
)
Divider
(
)
.
margin
(
{
top
:
10
,
bottom
:
12
}
)
Text
(
this
.
phoneName
(
)
)
.
fontSize
(
14
)
.
fontWeight
(
FontWeight
.
Medium
)
.
fontColor
(
'#333333'
)
.
width
(
'100%'
)
.
textAlign
(
TextAlign
.
Center
)
Column
(
)
{
Text
(
'预估回收价'
)
.
fontSize
(
11
)
.
fontColor
(
'#999999'
)
Text
(
'¥'
+
this
.
quotePrice
.
toString
(
)
)
.
fontSize
(
40
)
.
fontWeight
(
FontWeight
.
Bold
)
.
fontColor
(
'#FF8F00'
)
.
margin
(
{
top
:
4
}
)
.
scale
(
{
x
:
this
.
pulse
?
1.06
:
0.97
,
y
:
this
.
pulse
?
1.06
:
0.97
}
)
.
animation
(
{
duration
:
800
,
iterations
:
-
1
,
curve
:
Curve
.
EaseInOut
}
)
Text
(
'该价格基于「'
+
this
.
conditionName
(
)
+
'」成色'
)
.
fontSize
(
10
)
.
fontColor
(
'#999999'
)
.
margin
(
{
top
:
4
}
)
}
.
width
(
'100%'
)
.
padding
(
{
top
:
14
,
bottom
:
14
}
)
.
margin
(
{
top
:
10
}
)
.
backgroundColor
(
'#FFF7E0'
)
.
borderRadius
(
12
)
Row
(
)
{
Text
(
'✅ 官方验机'
)
.
fontSize
(
11
)
.
fontColor
(
'#00C853'
)
Text
(
'✅ 快速到账'
)
.
fontSize
(
11
)
.
fontColor
(
'#00C853'
)
.
margin
(
{
left
:
14
}
)
Text
(
'✅ 隐私清除'
)
.
fontSize
(
11
)
.
fontColor
(
'#00C853'
)
.
margin
(
{
left
:
14
}
)
}
.
width
(
'100%'
)
.
margin
(
{
top
:
12
}
)
Row
(
)
{
Text
(
'取消'
)
.
fontSize
(
13
)
.
fontColor
(
'#666666'
)
.
layoutWeight
(
1
)
.
textAlign
(
TextAlign
.
Center
)
.
padding
(
{
top
:
10
,
bottom
:
10
}
)
.
border
(
{
width
:
1
,
color
:
'#DDDDDD'
,
radius
:
18
}
)
.
onClick
(
(
)
=>
{
this
.
showQuoteDialog
=
false
}
)
Text
(
'立即回收'
)
.
fontSize
(
13
)
.
fontColor
(
'#FFFFFF'
)
.
layoutWeight
(
2
)
.
textAlign
(
TextAlign
.
Center
)
.
padding
(
{
top
:
10
,
bottom
:
10
}
)
.
backgroundColor
(
'#00C853'
)
.
borderRadius
(
18
)
.
margin
(
{
left
:
10
}
)
.
onClick
(
(
)
=>
{
this
.
showQuoteDialog
=
false
this
.
showBookDialog
=
true
}
)
}
.
width
(
'100%'
)
.
margin
(
{
top
:
14
}
)
}
.
width
(
'85%'
)
.
padding
(
16
)
.
backgroundColor
(
'#FFFFFF'
)
.
borderRadius
(
14
)
.
constraintSize
(
{
maxHeight
:
'80%'
}
)
}
.
width
(
'100%'
)
.
height
(
'100%'
)
.
justifyContent
(
FlexAlign
.
Center
)
.
backgroundColor
(
'#66000000'
)
}
在这里插入图片描述

估价弹框采用居中展示模式,外层 Column 设置 justifyContent(FlexAlign.Center) 使内容垂直居中, backgroundColor('#66000000') 提供半透明黑色遮罩。内层内容容器宽度设为 85% ,圆角14,并通过 constraintSize({ maxHeight: '80%' }) 限制最大高度防止内容过长溢出。估价金额使用了 scale 缩放动画配合 animation 属性, iterations: -1 表示无限循环, duration: 800 毫秒的动画周期使金额数字产生呼吸式缩放效果,引导用户注意。底部操作栏采用"取消"和"立即回收"双按钮设计,权重比例为1:2,点击"立即回收"会先关闭估价弹框再打开预约弹框,实现了弹框之间的链式跳转。

预约回收弹框(底部弹窗样式)

预约回收弹框采用底部弹窗模式,通过 justifyContent(FlexAlign.End) 将内容容器推至屏幕底部,顶部圆角 borderRadius({ topLeft: 18, topRight: 18 }) 形成从底部滑出的视觉效果。弹框内包含回收方式选择(上门、快递、门店)、预约时间选择(今天、明天、后天)和确认按钮,选择项通过 bookMethod 和 bookDay 状态变量记录。底部弹窗在移动端应用中比居中弹窗更符合拇指操作习惯,是该应用交互设计的一大亮点。

质检报告弹框(详情样式)

质检报告弹框以居中方式展示完整的质检结果,包含质检通过标识、报告编号、五项检测清单(外观检查、屏幕检测、功能测试、电池健康、主板检测)和质检师信息。每项检测结果通过 ForEach 遍历渲染为独立的行,统一显示"✅ 正常"状态,使用绿色文字增强可信度。弹框底部提供"下载报告"按钮,与实际业务需求高度契合。

八、底部Tab栏与主构建函数

底部Tab栏是整个应用的导航中枢,通过 ForEach 遍历 tabNames 和 tabIcons 数组渲染6个导航项,每个项包含图标和文字两行布局。

@
Builder
BottomBar
(
)
{
Row
(
)
{
ForEach
(
this
.
tabNames
,
(
t
:
string
,
idx
:
number
)
=>
{
Column
(
)
{
Text
(
this
.
tabIcons
[
idx
]
)
.
fontSize
(
19
)
.
opacity
(
this
.
currentIndex
===
idx
?
1
:
0.5
)
Text
(
t
)
.
fontSize
(
9
)
.
fontColor
(
this
.
currentIndex
===
idx
?
'#00C853'
:
'#999999'
)
.
fontWeight
(
this
.
currentIndex
===
idx
?
FontWeight
.
Bold
:
FontWeight
.
Normal
)
.
margin
(
{
top
:
2
}
)
}
.
layoutWeight
(
1
)
.
padding
(
{
top
:
6
,
bottom
:
6
}
)
.
onClick
(
(
)
=>
{
this
.
currentIndex
=
idx
}
)
}
,
(
t
:
string
)
=>
t
)
}
.
width
(
'100%'
)
.
padding
(
{
top
:
4
,
bottom
:
4
}
)
.
backgroundColor
(
'#FFFFFF'
)
.
border
(
{
width
:
1
,
color
:
'#F0F0F0'
,
radius
:
0
}
)
}
build
(
)
{
Column
(
)
{
Column
(
)
{
if
(
this
.
currentIndex
===
0
)
{
this
.
HallTab
(
)
}
else
if
(
this
.
currentIndex
===
1
)
{
this
.
QuoteTab
(
)
}
else
if
(
this
.
currentIndex
===
2
)
{
this
.
QualityTab
(
)
}
else
if
(
this
.
currentIndex
===
3
)
{
this
.
TradeInTab
(
)
}
else
if
(
this
.
currentIndex
===
4
)
{
this
.
OrderTab
(
)
}
else
{
this
.
ProfileTab
(
)
}
}
.
layoutWeight
(
1
)
.
width
(
'100%'
)
this
.
BottomBar
(
)
}
.
width
(
'100%'
)
.
height
(
'100%'
)
.
backgroundColor
(
'#F7F7F7'
)
if
(
this
.
showQuoteDialog
)
{
this
.
QuoteDialog
(
)
}
if
(
this
.
showBookDialog
)
{
this
.
BookDialog
(
)
}
if
(
this
.
showEditDialog
)
{
this
.
EditDialog
(
)
}
if
(
this
.
showDeleteDialog
)
{
this
.
DeleteDialog
(
)
}
if
(
this
.
showReportDialog
)
{
this
.
ReportDialog
(
)
}
}

Tab栏选中项通过 opacity(1) 和绿色文字加粗突出显示,未选中项使用 opacity(0.5) 和灰色文字弱化。 build 函数是整个应用的渲染入口,采用 if-else if 链式条件判断根据 currentIndex 值决定渲染哪个Tab页面的 @Builder 方法。页面内容区域使用 layoutWeight(1) 占据剩余空间,底部Tab栏固定在底部。5个弹框的 @Builder 方法在 build 函数末尾通过 if 条件判断独立渲染,确保只有对应状态为 true 的弹框才会显示。这种将弹框与主页面分离渲染的设计,保证了弹框可以覆盖在全部内容之上。

流程图:应用核心交互流程

九、辅助函数与业务逻辑封装

应用在组件底部定义了一系列辅助函数,封装了状态筛选、颜色映射、数据获取等业务逻辑,使 @Builder 方法中的代码更加简洁。

filterOrder
(
o
:
RecycleOrder
)
:
boolean
{
let
f
=
this
.
orderFilters
[
this
.
orderFilter
]
if
(
f
===
'全部'
)
{
return
true
}
return
o
.
status
===
f
}
orderStatusColor
(
status
:
string
)
:
string
{
if
(
status
===
'待上门'
)
{
return
'#FF8F00'
}
else
if
(
status
===
'检测中'
)
{
return
'#2E5AA8'
}
else
if
(
status
===
'已完成'
)
{
return
'#00C853'
}
return
'#CCCCCC'
}
phoneName
(
)
:
string
{
if
(
this
.
selectedPhone
!==
null
)
{
return
this
.
selectedPhone
.
model
}
return
'iPhone 15 Pro Max'
}
conditionName
(
)
:
string
{
let
names
:
string
[
]
=
[
'全新'
,
'99新'
,
'95新'
,
'9成新'
,
'8成新'
]
return
names
[
this
.
conditionIdx
]
}
orderNo
(
)
:
string
{
if
(
this
.
selectedOrder
!==
null
)
{
return
'ZX'
+
(
this
.
selectedOrder
.
id
)
.
toString
(
)
+
'X'
}
return
'ZX5001X'
}
orderModel
(
)
:
string
{
if
(
this
.
selectedOrder
!==
null
)
{
return
this
.
selectedOrder
.
model
}
return
'iPhone 15 Pro Max 256G'
}
orderPrice
(
)
:
number
{
if
(
this
.
selectedOrder
!==
null
)
{
return
this
.
selectedOrder
.
price
}
return
0
}

filterOrder 方法实现了订单列表的状态筛选逻辑,通过 orderFilters 数组和 orderFilter 索引的组合,支持"全部"和具体状态两种筛选模式。 orderStatusColor 方法将订单状态映射为颜色值,待上门用橙色表示需要用户行动,检测中用蓝色表示进行中,已完成用绿色表示成功,已取消用灰色表示终结。 phoneName 、 orderNo 、 orderModel 、 orderPrice 等函数采用空值检查模式( if (this.selectedXxx !== null) ),在选中项为 null 时返回默认值,确保弹框在没有数据选择时也能正常渲染默认内容。 conditionName 方法通过索引从数组中获取成色名称,实现了从数字索引到可读文字的转换。

核心技术点对比总结

| 技术维度 | 实现方式 | 关键API/装饰器 | 设计特点 | 适用场景 |
| --- | --- | --- | --- | --- |
| 页面导航 | currentIndex状态驱动if-else渲染 | @State, @Builder, if-else if | 单组件多页面,状态集中管理 | 中小型多Tab应用 |
| 弹框系统 | 5个布尔状态变量控制5种弹框 | @State(boolean), FlexAlign.Center/End | 居中弹窗与底部弹窗混合使用 | 需要多种弹框交互的场景 |
| 列表渲染 | ForEach遍历数据数组+条件筛选 | ForEach, itemGenerator, keyGenerator | 支持筛选过滤和动态样式绑定 | 商品列表、订单列表等 |
| 数据可视化 | Column高度/宽度比例计算+Stack叠加 | linearGradient, borderRadius, Stack | 纯组件堆叠实现柱状图和进度条 | 无图表库依赖的简单数据展示 |
| 动画效果 | pulse状态配合scale+animation | animation, scale, iterations:-1 | 呼吸式缩放动画引导注意力 | 金额展示、图标动效 |
| 渐变背景 | linearGradient属性配置角度和颜色数组 | linearGradient, angle, colors | 多色渐变区分不同Tab主题 | 页面头部、卡片装饰 |
| 状态筛选 | 标签按钮组+状态变量+条件渲染 | ForEach, @State(number), if条件 | 选中态指示条+颜色编码 | 订单状态、分类筛选 |
| 类型安全 | interface接口定义+联合类型 | interface, |null联合类型 | 编译期类型检查防止运行时错误 | 全局数据模型定义 |
| 空值安全 | 辅助函数null检查+默认值返回 | if(xxx !== null), 默认返回值 | 弹框未选中数据时正常渲染 | 弹框数据绑定 |
| 事件链式跳转 | 弹框关闭后设置另一弹框状态 | onClick内连续修改多个@State | 弹框间无缝跳转 | 多步骤流程交互 |

安装DevEco Studio程序

选择目标安装目录:
设置环境变量,但是需要重启一下:
新建一个空白模板:
设置API为24的模板项目: 初始化项目,自动下载相关依赖:
在这里插入图片描述

完整代码:

interface
PhoneItem
{
id
:
number
model
:
string
brand
:
string
storage
:
string
color
:
string
estPrice
:
number
maxPrice
:
number
condition
:
string
recycleCount
:
number
icon
:
string
year
:
string
}
interface
RecycleOrder
{
id
:
number
model
:
string
price
:
number
status
:
string
date
:
string
channel
:
string
method
:
string
icon
:
string
}
interface
BrandRate
{
brand
:
string
rate
:
number
icon
:
string
}
interface
PriceStat
{
level
:
string
price
:
number
}
interface
QualityItem
{
title
:
string
desc
:
string
standard
:
string
icon
:
string
}
@Entry
@Component
struct RecycleStationApp
{
@State currentIndex
:
number
=
0
@State showQuoteDialog
:
boolean
=
false
@State showBookDialog
:
boolean
=
false
@State showEditDialog
:
boolean
=
false
@State showDeleteDialog
:
boolean
=
false
@State showReportDialog
:
boolean
=
false
@State selectedPhone
:
PhoneItem
|
null
=
null
@State selectedOrder
:
RecycleOrder
|
null
=
null
@State modelText
:
string
=
''
@State quotePrice
:
number
=
0
@State conditionIdx
:
number
=
2
@State brandIdx
:
number
=
0
@State deleteTarget
:
string
=
''
@State orderFilter
:
number
=
0
@State bookMethod
:
number
=
0
@State pulse
:
boolean
=
false
tabNames
:
string
[
]
=
[
'回收大厅'
,
'估价查询'
,
'质检标准'
,
'以旧换新'
,
'交易订单'
,
'我的'
]
tabIcons
:
string
[
]
=
[
'♻️'
,
'🔍'
,
'📋'
,
'🔄'
,
'📦'
,
'👤'
]
phoneList
:
PhoneItem
[
]
=
[
{
id
:
1
,
model
:
'iPhone 15 Pro Max'
,
brand
:
'Apple'
,
storage
:
'256G'
,
color
:
'原色钛金属'
,
estPrice
:
6890
,
maxPrice
:
7800
,
condition
:
'95新'
,
recycleCount
:
1523
,
icon
:
'📱'
,
year
:
'2023款'
}
,
{
id
:
2
,
model
:
'iPhone 15'
,
brand
:
'Apple'
,
storage
:
'128G'
,
color
:
'蓝色'
,
estPrice
:
3980
,
maxPrice
:
4580
,
condition
:
'全新'
,
recycleCount
:
2314
,
icon
:
'📱'
,
year
:
'2023款'
}
,
{
id
:
3
,
model
:
'华为 Mate 60 Pro'
,
brand
:
'华为'
,
storage
:
'512G'
,
color
:
'雅丹黑'
,
estPrice
:
4560
,
maxPrice
:
5280
,
condition
:
'95新'
,
recycleCount
:
1876
,
icon
:
'📱'
,
year
:
'2023款'
}
,
{
id
:
4
,
model
:
'小米 14 Ultra'
,
brand
:
'小米'
,
storage
:
'512G'
,
color
:
'龙晶蓝'
,
estPrice
:
3680
,
maxPrice
:
4280
,
condition
:
'99新'
,
recycleCount
:
987
,
icon
:
'📱'
,
year
:
'2024款'
}
,
{
id
:
5
,
model
:
'OPPO Find X7 Ultra'
,
brand
:
'OPPO'
,
storage
:
'256G'
,
color
:
'海阔天空'
,
estPrice
:
2980
,
maxPrice
:
3480
,
condition
:
'95新'
,
recycleCount
:
654
,
icon
:
'📱'
,
year
:
'2024款'
}
,
{
id
:
6
,
model
:
'vivo X100 Pro'
,
brand
:
'vivo'
,
storage
:
'256G'
,
color
:
'星夜黑'
,
estPrice
:
2450
,
maxPrice
:
2890
,
condition
:
'9成新'
,
recycleCount
:
823
,
icon
:
'📱'
,
year
:
'2023款'
}
,
{
id
:
7
,
model
:
'iPhone 14 Pro'
,
brand
:
'Apple'
,
storage
:
'256G'
,
color
:
'深空黑'
,
estPrice
:
4250
,
maxPrice
:
4890
,
condition
:
'95新'
,
recycleCount
:
2654
,
icon
:
'📱'
,
year
:
'2022款'
}
,
{
id
:
8
,
model
:
'三星 Galaxy S24 Ultra'
,
brand
:
'三星'
,
storage
:
'512G'
,
color
:
'钛灰'
,
estPrice
:
4890
,
maxPrice
:
5580
,
condition
:
'99新'
,
recycleCount
:
542
,
icon
:
'📱'
,
year
:
'2024款'
}
,
{
id
:
9
,
model
:
'iPad Pro 12.9'
,
brand
:
'Apple'
,
storage
:
'256G'
,
color
:
'深空灰'
,
estPrice
:
5320
,
maxPrice
:
6080
,
condition
:
'95新'
,
recycleCount
:
456
,
icon
:
'💻'
,
year
:
'2022款'
}
,
{
id
:
10
,
model
:
'MacBook Pro 14寸'
,
brand
:
'Apple'
,
storage
:
'512G'
,
color
:
'深空灰'
,
estPrice
:
7560
,
maxPrice
:
8680
,
condition
:
'9成新'
,
recycleCount
:
328
,
icon
:
'💻'
,
year
:
'2023款'
}
,
{
id
:
11
,
model
:
'华为 MateBook X Pro'
,
brand
:
'华为'
,
storage
:
'1TB'
,
color
:
'拂晓粉'
,
estPrice
:
4680
,
maxPrice
:
5280
,
condition
:
'95新'
,
recycleCount
:
287
,
icon
:
'💻'
,
year
:
'2023款'
}
,
{
id
:
12
,
model
:
'小米 13'
,
brand
:
'小米'
,
storage
:
'256G'
,
color
:
'远山蓝'
,
estPrice
:
1580
,
maxPrice
:
1880
,
condition
:
'8成新'
,
recycleCount
:
1876
,
icon
:
'📱'
,
year
:
'2022款'
}
,
{
id
:
13
,
model
:
'iPhone 13'
,
brand
:
'Apple'
,
storage
:
'128G'
,
color
:
'星光色'
,
estPrice
:
2180
,
maxPrice
:
2580
,
condition
:
'95新'
,
recycleCount
:
3541
,
icon
:
'📱'
,
year
:
'2021款'
}
,
{
id
:
14
,
model
:
'华为 P60 Pro'
,
brand
:
'华为'
,
storage
:
'512G'
,
color
:
'洛可可白'
,
estPrice
:
2650
,
maxPrice
:
3080
,
condition
:
'95新'
,
recycleCount
:
923
,
icon
:
'📱'
,
year
:
'2023款'
}
,
{
id
:
15
,
model
:
'荣耀 Magic6 Pro'
,
brand
:
'荣耀'
,
storage
:
'512G'
,
color
:
'海湖青'
,
estPrice
:
3280
,
maxPrice
:
3780
,
condition
:
'99新'
,
recycleCount
:
612
,
icon
:
'📱'
,
year
:
'2024款'
}
,
{
id
:
16
,
model
:
'Switch OLED 国行'
,
brand
:
'任天堂'
,
storage
:
'64G'
,
color
:
'红蓝'
,
estPrice
:
1280
,
maxPrice
:
1580
,
condition
:
'95新'
,
recycleCount
:
765
,
icon
:
'🎮'
,
year
:
'2022款'
}
,
{
id
:
17
,
model
:
'一加 12'
,
brand
:
'一加'
,
storage
:
'512G'
,
color
:
'留白'
,
estPrice
:
2380
,
maxPrice
:
2780
,
condition
:
'9成新'
,
recycleCount
:
487
,
icon
:
'📱'
,
year
:
'2023款'
}
,
{
id
:
18
,
model
:
'红米 K70 Pro'
,
brand
:
'红米'
,
storage
:
'256G'
,
color
:
'墨羽'
,
estPrice
:
1680
,
maxPrice
:
1980
,
condition
:
'95新'
,
recycleCount
:
1345
,
icon
:
'📱'
,
year
:
'2023款'
}
]
orderList
:
RecycleOrder
[
]
=
[
{
id
:
5001
,
model
:
'iPhone 15 Pro Max 256G'
,
price
:
6890
,
status
:
'待上门'
,
date
:
'08-24 预约'
,
channel
:
'上门回收'
,
method
:
'顺丰上门'
,
icon
:
'📱'
}
,
{
id
:
5002
,
model
:
'华为 Mate 60 Pro 512G'
,
price
:
4560
,
status
:
'检测中'
,
date
:
'08-23 提交'
,
channel
:
'门店回收'
,
method
:
'门店送检'
,
icon
:
'📱'
}
,
{
id
:
5003
,
model
:
'小米 14 Ultra 512G'
,
price
:
3680
,
status
:
'已完成'
,
date
:
'08-22 完成'
,
channel
:
'快递回收'
,
method
:
'邮寄返款'
,
icon
:
'📱'
}
,
{
id
:
5004
,
model
:
'iPhone 14 Pro 256G'
,
price
:
4250
,
status
:
'已完成'
,
date
:
'08-20 完成'
,
channel
:
'上门回收'
,
method
:
'顺丰上门'
,
icon
:
'📱'
}
,
{
id
:
5005
,
model
:
'iPad Pro 12.9 256G'
,
price
:
5320
,
status
:
'检测中'
,
date
:
'08-19 提交'
,
channel
:
'门店回收'
,
method
:
'门店送检'
,
icon
:
'💻'
}
,
{
id
:
5006
,
model
:
'iPhone 13 128G'
,
price
:
2180
,
status
:
'已完成'
,
date
:
'08-18 完成'
,
channel
:
'快递回收'
,
method
:
'邮寄返款'
,
icon
:
'📱'
}
,
{
id
:
5007
,
model
:
'MacBook Pro 14 512G'
,
price
:
7560
,
status
:
'待上门'
,
date
:
'08-18 预约'
,
channel
:
'上门回收'
,
method
:
'顺丰上门'
,
icon
:
'💻'
}
,
{
id
:
5008
,
model
:
'三星 S24 Ultra 512G'
,
price
:
4890
,
status
:
'已完成'
,
date
:
'08-16 完成'
,
channel
:
'门店回收'
,
method
:
'门店送检'
,
icon
:
'📱'
}
,
{
id
:
5009
,
model
:
'vivo X100 Pro 256G'
,
price
:
2450
,
status
:
'已取消'
,
date
:
'08-15 取消'
,
channel
:
'快递回收'
,
method
:
'邮寄返款'
,
icon
:
'📱'
}
,
{
id
:
5010
,
model
:
'荣耀 Magic6 Pro 512G'
,
price
:
3280
,
status
:
'已完成'
,
date
:
'08-14 完成'
,
channel
:
'上门回收'
,
method
:
'顺丰上门'
,
icon
:
'📱'
}
,
{
id
:
5011
,
model
:
'华为 P60 Pro 512G'
,
price
:
2650
,
status
:
'检测中'
,
date
:
'08-13 提交'
,
channel
:
'门店回收'
,
method
:
'门店送检'
,
icon
:
'📱'
}
,
{
id
:
5012
,
model
:
'Switch OLED 国行'
,
price
:
1280
,
status
:
'已完成'
,
date
:
'08-12 完成'
,
channel
:
'快递回收'
,
method
:
'邮寄返款'
,
icon
:
'🎮'
}
,
{
id
:
5013
,
model
:
'小米 13 256G'
,
price
:
1580
,
status
:
'待上门'
,
date
:
'08-11 预约'
,
channel
:
'上门回收'
,
method
:
'顺丰上门'
,
icon
:
'📱'
}
,
{
id
:
5014
,
model
:
'OPPO Find X7 Ultra 256G'
,
price
:
2980
,
status
:
'已完成'
,
date
:
'08-10 完成'
,
channel
:
'门店回收'
,
method
:
'门店送检'
,
icon
:
'📱'
}
,
{
id
:
5015
,
model
:
'一加 12 512G'
,
price
:
2380
,
status
:
'已取消'
,
date
:
'08-09 取消'
,
channel
:
'快递回收'
,
method
:
'邮寄返款'
,
icon
:
'📱'
}
,
{
id
:
5016
,
model
:
'红米 K70 Pro 256G'
,
price
:
1680
,
status
:
'已完成'
,
date
:
'08-08 完成'
,
channel
:
'上门回收'
,
method
:
'顺丰上门'
,
icon
:
'📱'
}
]
brandRates
:
BrandRate
[
]
=
[
{
brand
:
'Apple'
,
rate
:
38
,
icon
:
'🍎'
}
,
{
brand
:
'华为'
,
rate
:
22
,
icon
:
'🌸'
}
,
{
brand
:
'小米'
,
rate
:
18
,
icon
:
'🐒'
}
,
{
brand
:
'OPPO/vivo'
,
rate
:
12
,
icon
:
'📷'
}
,
{
brand
:
'三星'
,
rate
:
6
,
icon
:
'⭐'
}
,
{
brand
:
'其它'
,
rate
:
4
,
icon
:
'🔧'
}
]
priceStats
:
PriceStat
[
]
=
[
{
level
:
'千元以下'
,
price
:
380
}
,
{
level
:
'1-2千'
,
price
:
620
}
,
{
level
:
'2-3千'
,
price
:
880
}
,
{
level
:
'3-4千'
,
price
:
1050
}
,
{
level
:
'4-5千'
,
price
:
760
}
,
{
level
:
'5千以上'
,
price
:
920
}
]
qualityList
:
QualityItem
[
]
=
[
{
title
:
'全新未拆封'
,
desc
:
'塑封完整,配件齐全,未激活'
,
standard
:
'最高价 +15%'
,
icon
:
'📦'
}
,
{
title
:
'99新'
,
desc
:
'使用极少,无任何使用痕迹'
,
standard
:
'最高价 +8%'
,
icon
:
'✨'
}
,
{
title
:
'95新'
,
desc
:
'轻微使用痕迹,无明显划痕'
,
standard
:
'参考价'
,
icon
:
'👍'
}
,
{
title
:
'9成新'
,
desc
:
'有少量划痕或使用痕迹'
,
standard
:
'参考价 -10%'
,
icon
:
'🙂'
}
,
{
title
:
'8成新'
,
desc
:
'明显使用痕迹,功能正常'
,
standard
:
'参考价 -20%'
,
icon
:
'😐'
}
,
{
title
:
'7成新及以下'
,
desc
:
'较多划痕/磕碰,功能正常'
,
standard
:
'参考价 -35%'
,
icon
:
'😟'
}
]
orderFilters
:
string
[
]
=
[
'全部'
,
'待上门'
,
'检测中'
,
'已完成'
]
@Builder
HallTab
(
)
{
Column
(
)
{
Column
(
)
{
Row
(
)
{
Column
(
)
{
Text
(
'♻️ 转转回收'
)
.
fontSize
(
18
)
.
fontWeight
(
FontWeight
.
Bold
)
.
fontColor
(
'#FFFFFF'
)
Text
(
'旧机高价卖 · 环保你我他'
)
.
fontSize
(
10
)
.
fontColor
(
'#BFE3FF'
)
.
margin
(
{
top
:
2
}
)
}
.
alignItems
(
HorizontalAlign
.
Start
)
Column
(
)
{
Text
(
'🏆 环保达人'
)
.
fontSize
(
12
)
.
fontColor
(
'#FFFFFF'
)
}
.
layoutWeight
(
1
)
.
alignItems
(
HorizontalAlign
.
End
)
}
.
width
(
'100%'
)
Row
(
)
{
Text
(
'🔍'
)
.
fontSize
(
12
)
Text
(
'输入手机型号查询回收价'
)
.
fontSize
(
12
)
.
fontColor
(
'#88A0C0'
)
.
margin
(
{
left
:
6
}
)
}
.
width
(
'100%'
)
.
padding
(
{
left
:
12
,
right
:
12
,
top
:
8
,
bottom
:
8
}
)
.
margin
(
{
top
:
12
}
)
.
backgroundColor
(
'#28406A'
)
.
borderRadius
(
14
)
.
onClick
(
(
)
=>
{
this
.
showQuoteDialog
=
true
}
)
}
.
width
(
'100%'
)
.
padding
(
{
left
:
14
,
right
:
14
,
top
:
12
,
bottom
:
14
}
)
.
linearGradient
(
{
angle
:
160
,
colors
:
[
[
'#1B2A4A'
,
0
]
,
[
'#2E5AA8'
,
1
]
]
}
)
Scroll
(
)
{
Column
(
)
{
Row
(
)
{
Column
(
)
{
Text
(
'1260'
)
.
fontSize
(
20
)
.
fontWeight
(
FontWeight
.
Bold
)
.
fontColor
(
'#00C853'
)
Text
(
'累计回收(台)'
)
.
fontSize
(
10
)
.
fontColor
(
'#666666'
)
.
margin
(
{
top
:
2
}
)
}
.
layoutWeight
(
1
)
.
alignItems
(
HorizontalAlign
.
Center
)
Column
(
)
{
Text
(
'35.6'
)
.
fontSize
(
20
)
.
fontWeight
(
FontWeight
.
Bold
)
.
fontColor
(
'#00C853'
)
Text
(
'减少碳排放(吨)'
)
.
fontSize
(
10
)
.
fontColor
(
'#666666'
)
.
margin
(
{
top
:
2
}
)
}
.
layoutWeight
(
1
)
.
alignItems
(
HorizontalAlign
.
Center
)
Column
(
)
{
Text
(
'98%'
)
.
fontSize
(
20
)
.
fontWeight
(
FontWeight
.
Bold
)
.
fontColor
(
'#00C853'
)
Text
(
'环保再利用率'
)
.
fontSize
(
10
)
.
fontColor
(
'#666666'
)
.
margin
(
{
top
:
2
}
)
}
.
layoutWeight
(
1
)
.
alignItems
(
HorizontalAlign
.
Center
)
}
.
width
(
'100%'
)
.
padding
(
{
top
:
14
,
bottom
:
14
}
)
.
margin
(
{
left
:
12
,
right
:
12
,
top
:
10
}
)
.
backgroundColor
(
'#E8F9EF'
)
.
borderRadius
(
12
)
.
border
(
{
width
:
1
,
color
:
'#00C853'
,
radius
:
12
}
)
Row
(
)
{
ForEach
(
[
'🚪 上门回收'
,
'📮 快递回收'
,
'🏪 门店回收'
]
,
(
m
:
string
,
idx
:
number
)
=>
{
Column
(
)
{
Text
(
m
.
split
(
' '
)
[
0
]
)
.
fontSize
(
20
)
Text
(
m
.
split
(
' '
)
[
1
]
)
.
fontSize
(
10
)
.
fontColor
(
'#333333'
)
.
margin
(
{
top
:
3
}
)
}
.
layoutWeight
(
1
)
.
padding
(
{
top
:
12
,
bottom
:
12
}
)
.
backgroundColor
(
'#FFFFFF'
)
.
borderRadius
(
10
)
.
margin
(
{
right
:
8
}
)
.
onClick
(
(
)
=>
{
this
.
bookMethod
=
idx
this
.
showBookDialog
=
true
}
)
}
,
(
m
:
string
)
=>
m
)
}
.
width
(
'100%'
)
.
padding
(
{
left
:
12
,
right
:
4
,
top
:
10
}
)
Row
(
)
{
Text
(
'🔥 热门回收机型'
)
.
fontSize
(
15
)
.
fontWeight
(
FontWeight
.
Bold
)
.
fontColor
(
'#1B2A4A'
)
Column
(
)
.
layoutWeight
(
1
)
Text
(
'回收率实时更新'
)
.
fontSize
(
10
)
.
fontColor
(
'#999999'
)
}
.
width
(
'100%'
)
.
padding
(
{
left
:
14
,
right
:
14
,
top
:
14
,
bottom
:
6
}
)
ForEach
(
this
.
phoneList
,
(
p
:
PhoneItem
)
=>
{
Row
(
)
{
Text
(
p
.
icon
)
.
fontSize
(
26
)
.
width
(
46
)
.
height
(
46
)
.
textAlign
(
TextAlign
.
Center
)
.
backgroundColor
(
'#F0F7FF'
)
.
borderRadius
(
10
)
Column
(
)
{
Row
(
)
{
Text
(
p
.
model
)
.
fontSize
(
13
)
.
fontWeight
(
FontWeight
.
Medium
)
.
fontColor
(
'#1B2A4A'
)
Text
(
p
.
brand
)
.
fontSize
(
9
)
.
fontColor
(
'#FFFFFF'
)
.
backgroundColor
(
'#2E5AA8'
)
.
padding
(
{
left
:
4
,
right
:
4
,
top
:
1
,
bottom
:
1
}
)
.
borderRadius
(
3
)
.
margin
(
{
left
:
6
}
)
}
.
width
(
'100%'
)
Row
(
)
{
Text
(
p
.
storage
+
' · '
+
p
.
color
)
.
fontSize
(
10
)
.
fontColor
(
'#999999'
)
Text
(
p
.
condition
)
.
fontSize
(
9
)
.
fontColor
(
'#00C853'
)
.
border
(
{
width
:
1
,
color
:
'#00C853'
,
radius
:
3
}
)
.
padding
(
{
left
:
3
,
right
:
3
,
top
:
0
,
bottom
:
0
}
)
.
margin
(
{
left
:
6
}
)
}
.
width
(
'100%'
)
.
margin
(
{
top
:
4
}
)
Row
(
)
{
Text
(
'估 ¥'
+
p
.
estPrice
)
.
fontSize
(
15
)
.
fontWeight
(
FontWeight
.
Bold
)
.
fontColor
(
'#FF8F00'
)
Text
(
'最高 ¥'
+
p
.
maxPrice
)
.
fontSize
(
10
)
.
fontColor
(
'#BBBBBB'
)
.
margin
(
{
left
:
6
}
)
Column
(
)
.
layoutWeight
(
1
)
Text
(
'查报价'
)
.
fontSize
(
11
)
.
fontColor
(
'#FFFFFF'
)
.
backgroundColor
(
'#00C853'
)
.
padding
(
{
left
:
12
,
right
:
12
,
top
:
4
,
bottom
:
4
}
)
.
borderRadius
(
10
)
.
onClick
(
(
)
=>
{
this
.
selectedPhone
=
p
this
.
quotePrice
=
p
.
estPrice
this
.
showQuoteDialog
=
true
}
)
}
.
width
(
'100%'
)
.
margin
(
{
top
:
6
}
)
}
.
layoutWeight
(
1
)
.
alignItems
(
HorizontalAlign
.
Start
)
.
margin
(
{
left
:
10
}
)
}
.
width
(
'100%'
)
.
padding
(
12
)
.
margin
(
{
left
:
12
,
right
:
12
,
top
:
8
}
)
.
backgroundColor
(
'#FFFFFF'
)
.
borderRadius
(
12
)
}
,
(
p
:
PhoneItem
)
=>
p
.
id
.
toString
(
)
)
Column
(
)
.
height
(
10
)
}
.
width
(
'100%'
)
}
.
layoutWeight
(
1
)
.
scrollBar
(
BarState
.
Off
)
}
.
width
(
'100%'
)
.
height
(
'100%'
)
}
@Builder
QuoteTab
(
)
{
Column
(
)
{
Column
(
)
{
Row
(
)
{
Text
(
'🔍 估价查询'
)
.
fontSize
(
18
)
.
fontWeight
(
FontWeight
.
Bold
)
.
fontColor
(
'#1B2A4A'
)
Column
(
)
.
layoutWeight
(
1
)
Text
(
'AI智能估价'
)
.
fontSize
(
11
)
.
fontColor
(
'#00C853'
)
}
.
width
(
'100%'
)
.
padding
(
{
left
:
14
,
right
:
14
,
top
:
10
,
bottom
:
10
}
)
}
.
width
(
'100%'
)
.
backgroundColor
(
'#EAF2FF'
)
Scroll
(
)
{
Column
(
)
{
Column
(
)
{
Text
(
'选择品牌'
)
.
fontSize
(
12
)
.
fontColor
(
'#999999'
)
.
width
(
'100%'
)
Row
(
)
{
ForEach
(
[
'Apple'
,
'华为'
,
'小米'
,
'OPPO'
,
'vivo'
,
'三星'
]
,
(
b
:
string
,
idx
:
number
)
=>
{
Text
(
b
)
.
fontSize
(
11
)
.
fontColor
(
this
.
brandIdx
===
idx
?
'#FFFFFF'
:
'#333333'
)
.
backgroundColor
(
this
.
brandIdx
===
idx
?
'#2E5AA8'
:
'#F5F5F5'
)
.
padding
(
{
left
:
10
,
right
:
10
,
top
:
5
,
bottom
:
5
}
)
.
borderRadius
(
8
)
.
margin
(
{
right
:
6
}
)
.
onClick
(
(
)
=>
{
this
.
brandIdx
=
idx
}
)
}
,
(
b
:
string
)
=>
b
)
}
.
width
(
'100%'
)
.
margin
(
{
top
:
8
}
)
Text
(
'选择型号'
)
.
fontSize
(
12
)
.
fontColor
(
'#999999'
)
.
width
(
'100%'
)
.
margin
(
{
top
:
12
}
)
Text
(
'iPhone 15 Pro Max 256G'
)
.
fontSize
(
13
)
.
fontColor
(
'#333333'
)
.
width
(
'100%'
)
.
padding
(
10
)
.
margin
(
{
top
:
6
}
)
.
backgroundColor
(
'#F8F8F8'
)
.
borderRadius
(
8
)
Text
(
'使用情况'
)
.
fontSize
(
12
)
.
fontColor
(
'#999999'
)
.
width
(
'100%'
)
.
margin
(
{
top
:
12
}
)
Row
(
)
{
ForEach
(
[
'全新'
,
'99新'
,
'95新'
,
'9成新'
,
'8成新'
]
,
(
c
:
string
,
idx
:
number
)
=>
{
Text
(
c
)
.
fontSize
(
11
)
.
fontColor
(
this
.
conditionIdx
===
idx
?
'#FFFFFF'
:
'#333333'
)
.
backgroundColor
(
this
.
conditionIdx
===
idx
?
'#00C853'
:
'#F5F5F5'
)
.
padding
(
{
left
:
10
,
right
:
10
,
top
:
5
,
bottom
:
5
}
)
.
borderRadius
(
8
)
.
margin
(
{
right
:
6
}
)
.
onClick
(
(
)
=>
{
this
.
conditionIdx
=
idx
}
)
}
,
(
c
:
string
)
=>
c
)
}
.
width
(
'100%'
)
.
margin
(
{
top
:
8
}
)
Text
(
'开始估价'
)
.
fontSize
(
14
)
.
fontWeight
(
FontWeight
.
Bold
)
.
fontColor
(
'#FFFFFF'
)
.
width
(
'100%'
)
.
textAlign
(
TextAlign
.
Center
)
.
padding
(
{
top
:
11
,
bottom
:
11
}
)
.
backgroundColor
(
'#00C853'
)
.
borderRadius
(
20
)
.
margin
(
{
top
:
16
}
)
.
onClick
(
(
)
=>
{
this
.
quotePrice
=
4250
this
.
showQuoteDialog
=
true
}
)
}
.
width
(
'100%'
)
.
padding
(
14
)
.
margin
(
{
left
:
12
,
right
:
12
,
top
:
10
}
)
.
backgroundColor
(
'#FFFFFF'
)
.
borderRadius
(
12
)
Column
(
)
{
Row
(
)
{
Text
(
'📊 回收价区间分布'
)
.
fontSize
(
14
)
.
fontWeight
(
FontWeight
.
Bold
)
.
fontColor
(
'#1B2A4A'
)
Column
(
)
.
layoutWeight
(
1
)
Text
(
'近30天 · 台'
)
.
fontSize
(
10
)
.
fontColor
(
'#999999'
)
}
.
width
(
'100%'
)
.
padding
(
{
left
:
14
,
right
:
14
,
top
:
12
}
)
Row
(
)
{
ForEach
(
this
.
priceStats
,
(
s
:
PriceStat
)
=>
{
Column
(
)
{
Text
(
s
.
price
.
toString
(
)
)
.
fontSize
(
8
)
.
fontColor
(
'#999999'
)
Column
(
)
.
width
(
20
)
.
height
(
s
.
price
/
1050
*
80
)
.
backgroundColor
(
'#00C853'
)
.
borderRadius
(
{
topLeft
:
3
,
topRight
:
3
}
)
.
margin
(
{
top
:
3
}
)
Text
(
s
.
level
)
.
fontSize
(
8
)
.
fontColor
(
'#666666'
)
.
margin
(
{
top
:
4
}
)
.
width
(
52
)
.
textAlign
(
TextAlign
.
Center
)
}
.
layoutWeight
(
1
)
.
alignItems
(
HorizontalAlign
.
Center
)
}
,
(
s
:
PriceStat
)
=>
s
.
level
)
}
.
width
(
'100%'
)
.
height
(
130
)
.
alignItems
(
VerticalAlign
.
Bottom
)
.
padding
(
{
left
:
10
,
right
:
10
,
bottom
:
12
}
)
}
.
width
(
'100%'
)
.
margin
(
{
left
:
12
,
right
:
12
,
top
:
10
}
)
.
backgroundColor
(
'#FFFFFF'
)
.
borderRadius
(
12
)
Column
(
)
{
Row
(
)
{
Text
(
'🏭 品牌回收占比'
)
.
fontSize
(
14
)
.
fontWeight
(
FontWeight
.
Bold
)
.
fontColor
(
'#1B2A4A'
)
Column
(
)
.
layoutWeight
(
1
)
Text
(
'平台实时数据'
)
.
fontSize
(
10
)
.
fontColor
(
'#999999'
)
}
.
width
(
'100%'
)
.
padding
(
{
left
:
14
,
right
:
14
,
top
:
12
,
bottom
:
8
}
)
ForEach
(
this
.
brandRates
,
(
b
:
BrandRate
)
=>
{
Row
(
)
{
Text
(
b
.
icon
)
.
fontSize
(
14
)
Text
(
b
.
brand
)
.
fontSize
(
11
)
.
fontColor
(
'#333333'
)
.
width
(
80
)
Stack
(
{
alignContent
:
Alignment
.
Start
}
)
{
Column
(
)
.
height
(
8
)
.
width
(
'100%'
)
.
backgroundColor
(
'#F0F7FF'
)
.
borderRadius
(
4
)
Column
(
)
.
height
(
8
)
.
width
(
b
.
rate
/
38
*
100
+
'%'
)
.
linearGradient
(
{
angle
:
90
,
colors
:
[
[
'#2E5AA8'
,
0
]
,
[
'#00C853'
,
1
]
]
}
)
.
borderRadius
(
4
)
}
.
layoutWeight
(
1
)
Text
(
b
.
rate
+
'%'
)
.
fontSize
(
10
)
.
fontColor
(
'#2E5AA8'
)
.
width
(
38
)
.
textAlign
(
TextAlign
.
End
)
}
.
width
(
'100%'
)
.
padding
(
{
left
:
14
,
right
:
14
,
top
:
7
,
bottom
:
7
}
)
}
,
(
b
:
BrandRate
)
=>
b
.
brand
)
Column
(
)
.
height
(
8
)
}
.
width
(
'100%'
)
.
margin
(
{
left
:
12
,
right
:
12
,
top
:
10
}
)
.
backgroundColor
(
'#FFFFFF'
)
.
borderRadius
(
12
)
Column
(
)
.
height
(
10
)
}
.
width
(
'100%'
)
}
.
layoutWeight
(
1
)
.
scrollBar
(
BarState
.
Off
)
}
.
width
(
'100%'
)
.
height
(
'100%'
)
}
@Builder
QualityTab
(
)
{
Column
(
)
{
Column
(
)
{
Row
(
)
{
Text
(
'📋 质检标准'
)
.
fontSize
(
18
)
.
fontWeight
(
FontWeight
.
Bold
)
.
fontColor
(
'#FFFFFF'
)
Column
(
)
.
layoutWeight
(
1
)
Text
(
'明码标价 · 童叟无欺'
)
.
fontSize
(
11
)
.
fontColor
(
'#BFE3FF'
)
}
.
width
(
'100%'
)
.
padding
(
{
left
:
14
,
right
:
14
,
top
:
12
,
bottom
:
12
}
)
.
linearGradient
(
{
angle
:
135
,
colors
:
[
[
'#00C853'
,
0
]
,
[
'#2E5AA8'
,
1
]
]
}
)
}
.
width
(
'100%'
)
Scroll
(
)
{
Column
(
)
{
Row
(
)
{
Text
(
'🛡️'
)
.
fontSize
(
30
)
Column
(
)
{
Text
(
'转转质检保障'
)
.
fontSize
(
14
)
.
fontWeight
(
FontWeight
.
Bold
)
.
fontColor
(
'#1B2A4A'
)
Text
(
'专业质检师 + AI 双重检测,杜绝翻新机'
)
.
fontSize
(
10
)
.
fontColor
(
'#666666'
)
.
margin
(
{
top
:
3
}
)
}
.
alignItems
(
HorizontalAlign
.
Start
)
.
margin
(
{
left
:
10
}
)
}
.
width
(
'100%'
)
.
padding
(
14
)
.
margin
(
{
left
:
12
,
right
:
12
,
top
:
10
}
)
.
backgroundColor
(
'#E8F9EF'
)
.
borderRadius
(
12
)
.
border
(
{
width
:
1
,
color
:
'#00C853'
,
radius
:
12
}
)
ForEach
(
this
.
qualityList
,
(
q
:
QualityItem
,
idx
:
number
)
=>
{
Row
(
)
{
Text
(
q
.
icon
)
.
fontSize
(
26
)
.
width
(
46
)
.
height
(
46
)
.
textAlign
(
TextAlign
.
Center
)
.
backgroundColor
(
'#F0F7FF'
)
.
borderRadius
(
10
)
Column
(
)
{
Row
(
)
{
Text
(
q
.
title
)
.
fontSize
(
13
)
.
fontWeight
(
FontWeight
.
Medium
)
.
fontColor
(
'#1B2A4A'
)
Column
(
)
.
layoutWeight
(
1
)
Text
(
q
.
standard
)
.
fontSize
(
10
)
.
fontWeight
(
FontWeight
.
Bold
)
.
fontColor
(
idx
<
3
?
'#00C853'
:
'#FF8F00'
)
}
.
width
(
'100%'
)
Text
(
q
.
desc
)
.
fontSize
(
11
)
.
fontColor
(
'#666666'
)
.
width
(
'100%'
)
.
margin
(
{
top
:
4
}
)
}
.
layoutWeight
(
1
)
.
alignItems
(
HorizontalAlign
.
Start
)
.
margin
(
{
left
:
10
}
)
}
.
width
(
'100%'
)
.
padding
(
12
)
.
margin
(
{
left
:
12
,
right
:
12
,
top
:
8
}
)
.
backgroundColor
(
'#FFFFFF'
)
.
borderRadius
(
12
)
}
,
(
q
:
QualityItem
)
=>
q
.
title
)
Row
(
)
{
Text
(
'📄 查看质检报告示例'
)
.
fontSize
(
13
)
.
fontWeight
(
FontWeight
.
Medium
)
.
fontColor
(
'#2E5AA8'
)
Column
(
)
.
layoutWeight
(
1
)
Text
(
'查看 >'
)
.
fontSize
(
11
)
.
fontColor
(
'#00C853'
)
}
.
width
(
'100%'
)
.
padding
(
14
)
.
margin
(
{
left
:
12
,
right
:
12
,
top
:
10
}
)
.
backgroundColor
(
'#EAF2FF'
)
.
borderRadius
(
12
)
.
onClick
(
(
)
=>
{
this
.
showReportDialog
=
true
}
)
Column
(
)
.
height
(
10
)
}
.
width
(
'100%'
)
}
.
layoutWeight
(
1
)
.
scrollBar
(
BarState
.
Off
)
}
.
width
(
'100%'
)
.
height
(
'100%'
)
}
@Builder
TradeInTab
(
)
{
Column
(
)
{
Column
(
)
{
Row
(
)
{
Text
(
'🔄 以旧换新'
)
.
fontSize
(
18
)
.
fontWeight
(
FontWeight
.
Bold
)
.
fontColor
(
'#FFFFFF'
)
Column
(
)
.
layoutWeight
(
1
)
Text
(
'最高补贴 ¥1500'
)
.
fontSize
(
11
)
.
fontColor
(
'#FFE066'
)
}
.
width
(
'100%'
)
.
padding
(
{
left
:
14
,
right
:
14
,
top
:
12
,
bottom
:
12
}
)
.
linearGradient
(
{
angle
:
135
,
colors
:
[
[
'#FFB800'
,
0
]
,
[
'#FF8F00'
,
1
]
]
}
)
}
.
width
(
'100%'
)
Scroll
(
)
{
Column
(
)
{
Row
(
)
{
Column
(
)
{
Text
(
'旧机回收价'
)
.
fontSize
(
10
)
.
fontColor
(
'#666666'
)
Text
(
'¥4250'
)
.
fontSize
(
22
)
.
fontWeight
(
FontWeight
.
Bold
)
.
fontColor
(
'#FF8F00'
)
.
margin
(
{
top
:
2
}
)
}
.
layoutWeight
(
1
)
.
alignItems
(
HorizontalAlign
.
Center
)
Text
(
'+'
)
.
fontSize
(
18
)
.
fontColor
(
'#999999'
)
Column
(
)
{
Text
(
'换新补贴'
)
.
fontSize
(
10
)
.
fontColor
(
'#666666'
)
Text
(
'¥500'
)
.
fontSize
(
22
)
.
fontWeight
(
FontWeight
.
Bold
)
.
fontColor
(
'#00C853'
)
.
margin
(
{
top
:
2
}
)
}
.
layoutWeight
(
1
)
.
alignItems
(
HorizontalAlign
.
Center
)
Text
(
'='
)
.
fontSize
(
18
)
.
fontColor
(
'#999999'
)
Column
(
)
{
Text
(
'合计抵扣'
)
.
fontSize
(
10
)
.
fontColor
(
'#666666'
)
Text
(
'¥4750'
)
.
fontSize
(
22
)
.
fontWeight
(
FontWeight
.
Bold
)
.
fontColor
(
'#1B2A4A'
)
.
margin
(
{
top
:
2
}
)
}
.
layoutWeight
(
1
)
.
alignItems
(
HorizontalAlign
.
Center
)
}
.
width
(
'100%'
)
.
padding
(
14
)
.
margin
(
{
left
:
12
,
right
:
12
,
top
:
10
}
)
.
backgroundColor
(
'#FFF7E0'
)
.
borderRadius
(
12
)
.
border
(
{
width
:
1
,
color
:
'#FFB800'
,
radius
:
12
}
)
Row
(
)
{
Text
(
'📱 热门换新机型'
)
.
fontSize
(
15
)
.
fontWeight
(
FontWeight
.
Bold
)
.
fontColor
(
'#1B2A4A'
)
Column
(
)
.
layoutWeight
(
1
)
Text
(
'补贴限时加码'
)
.
fontSize
(
10
)
.
fontColor
(
'#FF8F00'
)
}
.
width
(
'100%'
)
.
padding
(
{
left
:
14
,
right
:
14
,
top
:
14
,
bottom
:
6
}
)
ForEach
(
this
.
phoneList
.
slice
(
0
,
12
)
,
(
p
:
PhoneItem
)
=>
{
Row
(
)
{
Text
(
p
.
icon
)
.
fontSize
(
30
)
.
width
(
54
)
.
height
(
54
)
.
textAlign
(
TextAlign
.
Center
)
.
backgroundColor
(
'#F0F7FF'
)
.
borderRadius
(
10
)
Column
(
)
{
Row
(
)
{
Text
(
p
.
model
)
.
fontSize
(
13
)
.
fontWeight
(
FontWeight
.
Medium
)
.
fontColor
(
'#1B2A4A'
)
Text
(
'新'
)
.
fontSize
(
9
)
.
fontColor
(
'#FFFFFF'
)
.
backgroundColor
(
'#FFB800'
)
.
padding
(
{
left
:
4
,
right
:
4
,
top
:
1
,
bottom
:
1
}
)
.
borderRadius
(
3
)
.
margin
(
{
left
:
6
}
)
}
.
width
(
'100%'
)
Text
(
p
.
storage
+
' · '
+
p
.
color
+
' · '
+
p
.
year
)
.
fontSize
(
10
)
.
fontColor
(
'#999999'
)
.
width
(
'100%'
)
.
margin
(
{
top
:
4
}
)
Row
(
)
{
Text
(
'官方价 ¥'
+
p
.
maxPrice
)
.
fontSize
(
11
)
.
fontColor
(
'#666666'
)
Text
(
'以旧换新减 ¥500'
)
.
fontSize
(
10
)
.
fontWeight
(
FontWeight
.
Bold
)
.
fontColor
(
'#FF8F00'
)
.
margin
(
{
left
:
6
}
)
}
.
width
(
'100%'
)
.
margin
(
{
top
:
4
}
)
}
.
layoutWeight
(
1
)
.
alignItems
(
HorizontalAlign
.
Start
)
.
margin
(
{
left
:
10
}
)
Text
(
'换新'
)
.
fontSize
(
11
)
.
fontColor
(
'#FFFFFF'
)
.
backgroundColor
(
'#FFB800'
)
.
padding
(
{
left
:
12
,
right
:
12
,
top
:
5
,
bottom
:
5
}
)
.
borderRadius
(
10
)
.
onClick
(
(
)
=>
{
this
.
selectedPhone
=
p
this
.
showBookDialog
=
true
}
)
}
.
width
(
'100%'
)
.
padding
(
12
)
.
margin
(
{
left
:
12
,
right
:
12
,
top
:
8
}
)
.
backgroundColor
(
'#FFFFFF'
)
.
borderRadius
(
12
)
}
,
(
p
:
PhoneItem
)
=>
p
.
id
.
toString
(
)
)
Column
(
)
.
height
(
10
)
}
.
width
(
'100%'
)
}
.
layoutWeight
(
1
)
.
scrollBar
(
BarState
.
Off
)
}
.
width
(
'100%'
)
.
height
(
'100%'
)
}
@Builder
OrderTab
(
)
{
Column
(
)
{
Column
(
)
{
Row
(
)
{
Text
(
'📦 回收订单'
)
.
fontSize
(
18
)
.
fontWeight
(
FontWeight
.
Bold
)
.
fontColor
(
'#1B2A4A'
)
Column
(
)
.
layoutWeight
(
1
)
Text
(
'共 '
+
this
.
orderList
.
length
+
' 单'
)
.
fontSize
(
11
)
.
fontColor
(
'#999999'
)
}
.
width
(
'100%'
)
.
padding
(
{
left
:
14
,
right
:
14
,
top
:
10
,
bottom
:
8
}
)
}
.
width
(
'100%'
)
.
backgroundColor
(
'#EAF2FF'
)
Row
(
)
{
ForEach
(
this
.
orderFilters
,
(
f
:
string
,
idx
:
number
)
=>
{
Column
(
)
{
Text
(
f
)
.
fontSize
(
12
)
.
fontColor
(
this
.
orderFilter
===
idx
?
'#00C853'
:
'#666666'
)
.
fontWeight
(
this
.
orderFilter
===
idx
?
FontWeight
.
Bold
:
FontWeight
.
Normal
)
if
(
this
.
orderFilter
===
idx
)
{
Column
(
)
.
width
(
18
)
.
height
(
3
)
.
backgroundColor
(
'#00C853'
)
.
borderRadius
(
2
)
.
margin
(
{
top
:
4
}
)
}
else
{
Column
(
)
.
width
(
18
)
.
height
(
3
)
.
margin
(
{
top
:
4
}
)
}
}
.
layoutWeight
(
1
)
.
onClick
(
(
)
=>
{
this
.
orderFilter
=
idx
}
)
}
,
(
f
:
string
)
=>
f
)
}
.
width
(
'100%'
)
.
padding
(
{
top
:
8
,
bottom
:
8
}
)
.
backgroundColor
(
'#FFFFFF'
)
Scroll
(
)
{
Column
(
)
{
ForEach
(
this
.
orderList
,
(
o
:
RecycleOrder
)
=>
{
if
(
this
.
filterOrder
(
o
)
)
{
Row
(
)
{
Text
(
o
.
icon
)
.
fontSize
(
26
)
.
width
(
48
)
.
height
(
48
)
.
textAlign
(
TextAlign
.
Center
)
.
backgroundColor
(
'#F0F7FF'
)
.
borderRadius
(
10
)
Column
(
)
{
Row
(
)
{
Text
(
o
.
model
)
.
fontSize
(
13
)
.
fontWeight
(
FontWeight
.
Medium
)
.
fontColor
(
'#1B2A4A'
)
.
maxLines
(
1
)
.
textOverflow
(
{
overflow
:
TextOverflow
.
Ellipsis
}
)
Column
(
)
.
layoutWeight
(
1
)
Text
(
o
.
status
)
.
fontSize
(
10
)
.
fontColor
(
this
.
orderStatusColor
(
o
.
status
)
)
}
.
width
(
'100%'
)
Row
(
)
{
Text
(
o
.
channel
)
.
fontSize
(
10
)
.
fontColor
(
'#999999'
)
Text
(
o
.
method
)
.
fontSize
(
10
)
.
fontColor
(
'#999999'
)
.
margin
(
{
left
:
8
}
)
}
.
width
(
'100%'
)
.
margin
(
{
top
:
4
}
)
Row
(
)
{
Text
(
'回收价 ¥'
+
o
.
price
)
.
fontSize
(
14
)
.
fontWeight
(
FontWeight
.
Bold
)
.
fontColor
(
'#FF8F00'
)
Column
(
)
.
layoutWeight
(
1
)
Text
(
o
.
date
)
.
fontSize
(
10
)
.
fontColor
(
'#BBBBBB'
)
}
.
width
(
'100%'
)
.
margin
(
{
top
:
5
}
)
}
.
layoutWeight
(
1
)
.
alignItems
(
HorizontalAlign
.
Start
)
.
margin
(
{
left
:
10
}
)
}
.
width
(
'100%'
)
.
padding
(
12
)
.
margin
(
{
left
:
12
,
right
:
12
,
top
:
8
}
)
.
backgroundColor
(
'#FFFFFF'
)
.
borderRadius
(
12
)
.
onClick
(
(
)
=>
{
this
.
selectedOrder
=
o
this
.
showEditDialog
=
true
}
)
}
}
,
(
o
:
RecycleOrder
)
=>
o
.
id
.
toString
(
)
)
Column
(
)
.
height
(
10
)
}
.
width
(
'100%'
)
}
.
layoutWeight
(
1
)
.
scrollBar
(
BarState
.
Off
)
}
.
width
(
'100%'
)
.
height
(
'100%'
)
}
@Builder
ProfileTab
(
)
{
Column
(
)
{
Column
(
)
{
Row
(
)
{
Column
(
)
{
Text
(
'🌱'
)
.
fontSize
(
38
)
}
.
width
(
58
)
.
height
(
58
)
.
justifyContent
(
FlexAlign
.
Center
)
.
backgroundColor
(
'#FFFFFF'
)
.
borderRadius
(
29
)
Column
(
)
{
Text
(
'环保回收达人'
)
.
fontSize
(
17
)
.
fontWeight
(
FontWeight
.
Bold
)
.
fontColor
(
'#FFFFFF'
)
Text
(
'碳积分 2680 分'
)
.
fontSize
(
11
)
.
fontColor
(
'#BFE3FF'
)
.
margin
(
{
top
:
3
}
)
}
.
alignItems
(
HorizontalAlign
.
Start
)
.
margin
(
{
left
:
12
}
)
Column
(
)
.
layoutWeight
(
1
)
Text
(
'编辑'
)
.
fontSize
(
11
)
.
fontColor
(
'#FFFFFF'
)
.
border
(
{
width
:
1
,
color
:
'#FFFFFF'
,
radius
:
12
}
)
.
padding
(
{
left
:
10
,
right
:
10
,
top
:
4
,
bottom
:
4
}
)
.
onClick
(
(
)
=>
{
this
.
showEditDialog
=
true
}
)
}
.
width
(
'100%'
)
}
.
width
(
'100%'
)
.
padding
(
14
)
.
linearGradient
(
{
angle
:
160
,
colors
:
[
[
'#1B2A4A'
,
0
]
,
[
'#2E5AA8'
,
1
]
]
}
)
Scroll
(
)
{
Column
(
)
{
Row
(
)
{
ForEach
(
[
'♻️ 我的回收'
,
'📱 我的设备'
,
'🏅 碳积分'
,
'🎁 积分商城'
]
,
(
m
:
string
,
idx
:
number
)
=>
{
Column
(
)
{
Text
(
m
.
split
(
' '
)
[
0
]
)
.
fontSize
(
22
)
Text
(
m
.
split
(
' '
)
[
1
]
)
.
fontSize
(
10
)
.
fontColor
(
'#333333'
)
.
margin
(
{
top
:
4
}
)
}
.
layoutWeight
(
1
)
.
padding
(
{
top
:
14
,
bottom
:
14
}
)
.
onClick
(
(
)
=>
{
if
(
idx
===
0
)
{
this
.
currentIndex
=
4
}
}
)
}
,
(
m
:
string
)
=>
m
)
}
.
width
(
'100%'
)
.
margin
(
{
left
:
12
,
right
:
12
,
top
:
10
}
)
.
backgroundColor
(
'#FFFFFF'
)
.
borderRadius
(
12
)
Column
(
)
{
Row
(
)
{
Text
(
'🌱 本月碳减排进度'
)
.
fontSize
(
14
)
.
fontWeight
(
FontWeight
.
Bold
)
.
fontColor
(
'#1B2A4A'
)
Column
(
)
.
layoutWeight
(
1
)
Text
(
'2.4 / 5.0 kg'
)
.
fontSize
(
11
)
.
fontColor
(
'#00C853'
)
}
.
width
(
'100%'
)
.
padding
(
{
left
:
14
,
right
:
14
,
top
:
12
}
)
Stack
(
{
alignContent
:
Alignment
.
Start
}
)
{
Column
(
)
.
height
(
10
)
.
width
(
'100%'
)
.
backgroundColor
(
'#E8F9EF'
)
.
borderRadius
(
5
)
Column
(
)
.
height
(
10
)
.
width
(
'48%'
)
.
linearGradient
(
{
angle
:
90
,
colors
:
[
[
'#00C853'
,
0
]
,
[
'#69E2A0'
,
1
]
]
}
)
.
borderRadius
(
5
)
}
.
width
(
'100%'
)
.
padding
(
{
left
:
14
,
right
:
14
,
top
:
8
}
)
Row
(
)
{
Text
(
'回收 2 台设备 · 累计 5 次回收'
)
.
fontSize
(
10
)
.
fontColor
(
'#999999'
)
Column
(
)
.
layoutWeight
(
1
)
}
.
width
(
'100%'
)
.
padding
(
{
left
:
14
,
right
:
14
,
top
:
8
,
bottom
:
12
}
)
}
.
width
(
'100%'
)
.
margin
(
{
left
:
12
,
right
:
12
,
top
:
10
}
)
.
backgroundColor
(
'#FFFFFF'
)
.
borderRadius
(
12
)
Row
(
)
{
Text
(
'🔧 常用工具'
)
.
fontSize
(
14
)
.
fontWeight
(
FontWeight
.
Bold
)
.
fontColor
(
'#1B2A4A'
)
Column
(
)
.
layoutWeight
(
1
)
}
.
width
(
'100%'
)
.
padding
(
{
left
:
14
,
right
:
14
,
top
:
14
,
bottom
:
6
}
)
Column
(
)
{
ForEach
(
[
'质检报告下载'
,
'发票管理'
,
'客服中心'
,
'关于转转回收'
]
,
(
t
:
string
,
idx
:
number
)
=>
{
Row
(
)
{
Text
(
[
'📄'
,
'🧾'
,
'🎧'
,
'ℹ️'
]
[
idx
]
)
.
fontSize
(
15
)
Text
(
t
)
.
fontSize
(
13
)
.
fontColor
(
'#333333'
)
.
margin
(
{
left
:
10
}
)
Column
(
)
.
layoutWeight
(
1
)
Text
(
'>'
)
.
fontSize
(
12
)
.
fontColor
(
'#CCCCCC'
)
.
onClick
(
(
)
=>
{
if
(
idx
===
0
)
{
this
.
showReportDialog
=
true
}
}
)
}
.
width
(
'100%'
)
.
padding
(
{
left
:
14
,
right
:
14
,
top
:
12
,
bottom
:
12
}
)
.
backgroundColor
(
'#FFFFFF'
)
}
,
(
t
:
string
)
=>
t
)
}
.
width
(
'100%'
)
.
margin
(
{
left
:
12
,
right
:
12
,
top
:
0
}
)
.
borderRadius
(
12
)
Column
(
)
.
height
(
10
)
}
.
width
(
'100%'
)
}
.
layoutWeight
(
1
)
.
scrollBar
(
BarState
.
Off
)
}
.
width
(
'100%'
)
.
height
(
'100%'
)
}
@Builder
QuoteDialog
(
)
{
Column
(
)
{
Column
(
)
{
Row
(
)
{
Text
(
'🔍 估价结果'
)
.
fontSize
(
16
)
.
fontWeight
(
FontWeight
.
Bold
)
.
fontColor
(
'#1B2A4A'
)
Column
(
)
.
layoutWeight
(
1
)
Text
(
'✕'
)
.
fontSize
(
16
)
.
fontColor
(
'#999999'
)
.
padding
(
6
)
.
onClick
(
(
)
=>
{
this
.
showQuoteDialog
=
false
}
)
}
.
width
(
'100%'
)
Divider
(
)
.
margin
(
{
top
:
10
,
bottom
:
12
}
)
Text
(
this
.
phoneName
(
)
)
.
fontSize
(
14
)
.
fontWeight
(
FontWeight
.
Medium
)
.
fontColor
(
'#333333'
)
.
width
(
'100%'
)
.
textAlign
(
TextAlign
.
Center
)
Column
(
)
{
Text
(
'预估回收价'
)
.
fontSize
(
11
)
.
fontColor
(
'#999999'
)
Text
(
'¥'
+
this
.
quotePrice
.
toString
(
)
)
.
fontSize
(
40
)
.
fontWeight
(
FontWeight
.
Bold
)
.
fontColor
(
'#FF8F00'
)
.
margin
(
{
top
:
4
}
)
.
scale
(
{
x
:
this
.
pulse
?
1.06
:
0.97
,
y
:
this
.
pulse
?
1.06
:
0.97
}
)
.
animation
(
{
duration
:
800
,
iterations
:
-
1
,
curve
:
Curve
.
EaseInOut
}
)
Text
(
'该价格基于「'
+
this
.
conditionName
(
)
+
'」成色'
)
.
fontSize
(
10
)
.
fontColor
(
'#999999'
)
.
margin
(
{
top
:
4
}
)
}
.
width
(
'100%'
)
.
padding
(
{
top
:
14
,
bottom
:
14
}
)
.
margin
(
{
top
:
10
}
)
.
backgroundColor
(
'#FFF7E0'
)
.
borderRadius
(
12
)
Row
(
)
{
Text
(
'✅ 官方验机'
)
.
fontSize
(
11
)
.
fontColor
(
'#00C853'
)
Text
(
'✅ 快速到账'
)
.
fontSize
(
11
)
.
fontColor
(
'#00C853'
)
.
margin
(
{
left
:
14
}
)
Text
(
'✅ 隐私清除'
)
.
fontSize
(
11
)
.
fontColor
(
'#00C853'
)
.
margin
(
{
left
:
14
}
)
}
.
width
(
'100%'
)
.
margin
(
{
top
:
12
}
)
Row
(
)
{
Text
(
'取消'
)
.
fontSize
(
13
)
.
fontColor
(
'#666666'
)
.
layoutWeight
(
1
)
.
textAlign
(
TextAlign
.
Center
)
.
padding
(
{
top
:
10
,
bottom
:
10
}
)
.
border
(
{
width
:
1
,
color
:
'#DDDDDD'
,
radius
:
18
}
)
.
onClick
(
(
)
=>
{
this
.
showQuoteDialog
=
false
}
)
Text
(
'立即回收'
)
.
fontSize
(
13
)
.
fontColor
(
'#FFFFFF'
)
.
layoutWeight
(
2
)
.
textAlign
(
TextAlign
.
Center
)
.
padding
(
{
top
:
10
,
bottom
:
10
}
)
.
backgroundColor
(
'#00C853'
)
.
borderRadius
(
18
)
.
margin
(
{
left
:
10
}
)
.
onClick
(
(
)
=>
{
this
.
showQuoteDialog
=
false
this
.
showBookDialog
=
true
}
)
}
.
width
(
'100%'
)
.
margin
(
{
top
:
14
}
)
}
.
width
(
'85%'
)
.
padding
(
16
)
.
backgroundColor
(
'#FFFFFF'
)
.
borderRadius
(
14
)
.
constraintSize
(
{
maxHeight
:
'80%'
}
)
}
.
width
(
'100%'
)
.
height
(
'100%'
)
.
justifyContent
(
FlexAlign
.
Center
)
.
backgroundColor
(
'#66000000'
)
}
@Builder
BookDialog
(
)
{
Column
(
)
{
Column
(
)
{
Row
(
)
{
Text
(
'🚪 预约回收'
)
.
fontSize
(
16
)
.
fontWeight
(
FontWeight
.
Bold
)
.
fontColor
(
'#1B2A4A'
)
Column
(
)
.
layoutWeight
(
1
)
Text
(
'✕'
)
.
fontSize
(
16
)
.
fontColor
(
'#999999'
)
.
padding
(
6
)
.
onClick
(
(
)
=>
{
this
.
showBookDialog
=
false
}
)
}
.
width
(
'100%'
)
Divider
(
)
.
margin
(
{
top
:
10
,
bottom
:
10
}
)
Text
(
this
.
phoneName
(
)
)
.
fontSize
(
13
)
.
fontWeight
(
FontWeight
.
Medium
)
.
fontColor
(
'#333333'
)
.
width
(
'100%'
)
Text
(
'选择回收方式'
)
.
fontSize
(
12
)
.
fontColor
(
'#999999'
)
.
width
(
'100%'
)
.
margin
(
{
top
:
12
}
)
Row
(
)
{
ForEach
(
[
'🚪 上门'
,
'📮 快递'
,
'🏪 门店'
]
,
(
m
:
string
,
idx
:
number
)
=>
{
Column
(
)
{
Text
(
m
.
split
(
' '
)
[
0
]
)
.
fontSize
(
20
)
Text
(
m
.
split
(
' '
)
[
1
]
)
.
fontSize
(
11
)
.
fontColor
(
this
.
bookMethod
===
idx
?
'#00C853'
:
'#333333'
)
.
fontWeight
(
this
.
bookMethod
===
idx
?
FontWeight
.
Bold
:
FontWeight
.
Normal
)
.
margin
(
{
top
:
3
}
)
}
.
layoutWeight
(
1
)
.
padding
(
{
top
:
12
,
bottom
:
12
}
)
.
backgroundColor
(
this
.
bookMethod
===
idx
?
'#E8F9EF'
:
'#F8F8F8'
)
.
borderRadius
(
10
)
.
margin
(
{
right
:
8
}
)
.
border
(
{
width
:
this
.
bookMethod
===
idx
?
1
:
0
,
color
:
'#00C853'
,
radius
:
10
}
)
.
onClick
(
(
)
=>
{
this
.
bookMethod
=
idx
}
)
}
,
(
m
:
string
)
=>
m
)
}
.
width
(
'100%'
)
.
margin
(
{
top
:
8
}
)
Text
(
'预约时间'
)
.
fontSize
(
12
)
.
fontColor
(
'#999999'
)
.
width
(
'100%'
)
.
margin
(
{
top
:
12
}
)
Row
(
)
{
ForEach
(
[
'今天'
,
'明天'
,
'后天'
]
,
(
d
:
string
,
idx
:
number
)
=>
{
Text
(
d
)
.
fontSize
(
11
)
.
fontColor
(
this
.
bookDay
===
idx
?
'#FFFFFF'
:
'#333333'
)
.
backgroundColor
(
this
.
bookDay
===
idx
?
'#2E5AA8'
:
'#F5F5F5'
)
.
padding
(
{
left
:
16
,
right
:
16
,
top
:
6
,
bottom
:
6
}
)
.
borderRadius
(
8
)
.
margin
(
{
right
:
8
}
)
.
onClick
(
(
)
=>
{
this
.
bookDay
=
idx
}
)
}
,
(
d
:
string
)
=>
d
)
}
.
width
(
'100%'
)
.
margin
(
{
top
:
8
}
)
Row
(
)
{
Text
(
'📦 免费顺丰包邮寄回'
)
.
fontSize
(
10
)
.
fontColor
(
'#00C853'
)
Column
(
)
.
layoutWeight
(
1
)
}
.
width
(
'100%'
)
.
margin
(
{
top
:
12
}
)
Row
(
)
{
Text
(
'再想想'
)
.
fontSize
(
13
)
.
fontColor
(
'#666666'
)
.
layoutWeight
(
1
)
.
textAlign
(
TextAlign
.
Center
)
.
padding
(
{
top
:
10
,
bottom
:
10
}
)
.
border
(
{
width
:
1
,
color
:
'#DDDDDD'
,
radius
:
18
}
)
.
onClick
(
(
)
=>
{
this
.
showBookDialog
=
false
}
)
Text
(
'确认预约'
)
.
fontSize
(
13
)
.
fontColor
(
'#FFFFFF'
)
.
layoutWeight
(
2
)
.
textAlign
(
TextAlign
.
Center
)
.
padding
(
{
top
:
10
,
bottom
:
10
}
)
.
backgroundColor
(
'#00C853'
)
.
borderRadius
(
18
)
.
margin
(
{
left
:
10
}
)
.
onClick
(
(
)
=>
{
this
.
showBookDialog
=
false
}
)
}
.
width
(
'100%'
)
.
margin
(
{
top
:
14
}
)
}
.
width
(
'100%'
)
.
padding
(
16
)
.
backgroundColor
(
'#FFFFFF'
)
.
borderRadius
(
{
topLeft
:
18
,
topRight
:
18
}
)
}
.
width
(
'100%'
)
.
height
(
'100%'
)
.
justifyContent
(
FlexAlign
.
End
)
.
backgroundColor
(
'#66000000'
)
}
@Builder
EditDialog
(
)
{
Column
(
)
{
Column
(
)
{
Row
(
)
{
Text
(
'✏️ 订单编辑'
)
.
fontSize
(
16
)
.
fontWeight
(
FontWeight
.
Bold
)
.
fontColor
(
'#1B2A4A'
)
Column
(
)
.
layoutWeight
(
1
)
Text
(
'✕'
)
.
fontSize
(
16
)
.
fontColor
(
'#999999'
)
.
padding
(
6
)
.
onClick
(
(
)
=>
{
this
.
showEditDialog
=
false
}
)
}
.
width
(
'100%'
)
Divider
(
)
.
margin
(
{
top
:
10
,
bottom
:
12
}
)
Text
(
'订单编号'
)
.
fontSize
(
12
)
.
fontColor
(
'#999999'
)
.
width
(
'100%'
)
Text
(
this
.
orderNo
(
)
)
.
fontSize
(
13
)
.
fontColor
(
'#333333'
)
.
width
(
'100%'
)
.
padding
(
10
)
.
margin
(
{
top
:
6
}
)
.
backgroundColor
(
'#F8F8F8'
)
.
borderRadius
(
8
)
Text
(
'回收机型'
)
.
fontSize
(
12
)
.
fontColor
(
'#999999'
)
.
width
(
'100%'
)
.
margin
(
{
top
:
12
}
)
Text
(
this
.
orderModel
(
)
)
.
fontSize
(
13
)
.
fontColor
(
'#333333'
)
.
width
(
'100%'
)
.
padding
(
10
)
.
margin
(
{
top
:
6
}
)
.
backgroundColor
(
'#F8F8F8'
)
.
borderRadius
(
8
)
Text
(
'回收价格'
)
.
fontSize
(
12
)
.
fontColor
(
'#999999'
)
.
width
(
'100%'
)
.
margin
(
{
top
:
12
}
)
Row
(
)
{
Text
(
'¥'
)
.
fontSize
(
13
)
.
fontWeight
(
FontWeight
.
Bold
)
.
fontColor
(
'#FF8F00'
)
Text
(
this
.
orderPrice
(
)
.
toString
(
)
)
.
fontSize
(
14
)
.
fontWeight
(
FontWeight
.
Bold
)
.
fontColor
(
'#333333'
)
.
margin
(
{
left
:
4
}
)
Column
(
)
.
layoutWeight
(
1
)
Text
(
'调整'
)
.
fontSize
(
11
)
.
fontColor
(
'#FFFFFF'
)
.
backgroundColor
(
'#FF8F00'
)
.
padding
(
{
left
:
12
,
right
:
12
,
top
:
5
,
bottom
:
5
}
)
.
borderRadius
(
10
)
.
onClick
(
(
)
=>
{
this
.
modelText
=
'价格已调整'
}
)
}
.
width
(
'100%'
)
.
padding
(
10
)
.
margin
(
{
top
:
6
}
)
.
backgroundColor
(
'#FFF7E0'
)
.
borderRadius
(
8
)
Text
(
'状态说明'
)
.
fontSize
(
12
)
.
fontColor
(
'#999999'
)
.
width
(
'100%'
)
.
margin
(
{
top
:
12
}
)
Text
(
'质检完成后,报价与实付差价将在3个工作日内到账'
)
.
fontSize
(
11
)
.
fontColor
(
'#666666'
)
.
width
(
'100%'
)
.
padding
(
10
)
.
margin
(
{
top
:
6
}
)
.
backgroundColor
(
'#F8F8F8'
)
.
borderRadius
(
8
)
Row
(
)
{
Text
(
'删除订单'
)
.
fontSize
(
13
)
.
fontColor
(
'#FF4D2E'
)
.
layoutWeight
(
1
)
.
textAlign
(
TextAlign
.
Center
)
.
padding
(
{
top
:
10
,
bottom
:
10
}
)
.
border
(
{
width
:
1
,
color
:
'#FF4D2E'
,
radius
:
18
}
)
.
onClick
(
(
)
=>
{
this
.
deleteTarget
=
this
.
orderModel
(
)
this
.
showEditDialog
=
false
this
.
showDeleteDialog
=
true
}
)
Text
(
'保存修改'
)
.
fontSize
(
13
)
.
fontColor
(
'#FFFFFF'
)
.
layoutWeight
(
2
)
.
textAlign
(
TextAlign
.
Center
)
.
padding
(
{
top
:
10
,
bottom
:
10
}
)
.
backgroundColor
(
'#2E5AA8'
)
.
borderRadius
(
18
)
.
margin
(
{
left
:
10
}
)
.
onClick
(
(
)
=>
{
this
.
showEditDialog
=
false
}
)
}
.
width
(
'100%'
)
.
margin
(
{
top
:
14
}
)
}
.
width
(
'85%'
)
.
padding
(
16
)
.
backgroundColor
(
'#FFFFFF'
)
.
borderRadius
(
14
)
.
constraintSize
(
{
maxHeight
:
'80%'
}
)
}
.
width
(
'100%'
)
.
height
(
'100%'
)
.
justifyContent
(
FlexAlign
.
Center
)
.
backgroundColor
(
'#66000000'
)
}
@Builder
DeleteDialog
(
)
{
Column
(
)
{
Column
(
)
{
Text
(
'🗑️'
)
.
fontSize
(
40
)
.
width
(
'100%'
)
.
textAlign
(
TextAlign
.
Center
)
Text
(
'确认删除该订单?'
)
.
fontSize
(
16
)
.
fontWeight
(
FontWeight
.
Bold
)
.
fontColor
(
'#1B2A4A'
)
.
width
(
'100%'
)
.
textAlign
(
TextAlign
.
Center
)
.
margin
(
{
top
:
8
}
)
Text
(
'「'
+
this
.
deleteTarget
+
'」\n删除后订单记录将无法恢复,回收进度也将终止'
)
.
fontSize
(
12
)
.
fontColor
(
'#666666'
)
.
width
(
'100%'
)
.
textAlign
(
TextAlign
.
Center
)
.
margin
(
{
top
:
8
}
)
Row
(
)
{
Text
(
'保留订单'
)
.
fontSize
(
13
)
.
fontColor
(
'#666666'
)
.
layoutWeight
(
1
)
.
textAlign
(
TextAlign
.
Center
)
.
padding
(
{
top
:
10
,
bottom
:
10
}
)
.
border
(
{
width
:
1
,
color
:
'#DDDDDD'
,
radius
:
18
}
)
.
onClick
(
(
)
=>
{
this
.
showDeleteDialog
=
false
}
)
Text
(
'确认删除'
)
.
fontSize
(
13
)
.
fontColor
(
'#FFFFFF'
)
.
layoutWeight
(
2
)
.
textAlign
(
TextAlign
.
Center
)
.
padding
(
{
top
:
10
,
bottom
:
10
}
)
.
backgroundColor
(
'#FF4D2E'
)
.
borderRadius
(
18
)
.
margin
(
{
left
:
10
}
)
.
onClick
(
(
)
=>
{
this
.
showDeleteDialog
=
false
}
)
}
.
width
(
'100%'
)
.
margin
(
{
top
:
14
}
)
}
.
width
(
'78%'
)
.
padding
(
18
)
.
backgroundColor
(
'#FFFFFF'
)
.
borderRadius
(
14
)
.
constraintSize
(
{
maxHeight
:
'80%'
}
)
}
.
width
(
'100%'
)
.
height
(
'100%'
)
.
justifyContent
(
FlexAlign
.
Center
)
.
backgroundColor
(
'#66000000'
)
}
@Builder
ReportDialog
(
)
{
Column
(
)
{
Column
(
)
{
Row
(
)
{
Text
(
'📄 质检报告'
)
.
fontSize
(
16
)
.
fontWeight
(
FontWeight
.
Bold
)
.
fontColor
(
'#1B2A4A'
)
Column
(
)
.
layoutWeight
(
1
)
Text
(
'✕'
)
.
fontSize
(
16
)
.
fontColor
(
'#999999'
)
.
padding
(
6
)
.
onClick
(
(
)
=>
{
this
.
showReportDialog
=
false
}
)
}
.
width
(
'100%'
)
Divider
(
)
.
margin
(
{
top
:
10
,
bottom
:
12
}
)
Column
(
)
{
Text
(
'🛡️'
)
.
fontSize
(
36
)
Text
(
'质检通过'
)
.
fontSize
(
16
)
.
fontWeight
(
FontWeight
.
Bold
)
.
fontColor
(
'#00C853'
)
.
margin
(
{
top
:
4
}
)
Text
(
'编号 ZG20260824001 · 2026-08-24'
)
.
fontSize
(
9
)
.
fontColor
(
'#999999'
)
.
margin
(
{
top
:
4
}
)
}
.
width
(
'100%'
)
.
alignItems
(
HorizontalAlign
.
Center
)
.
padding
(
{
top
:
12
,
bottom
:
12
}
)
.
backgroundColor
(
'#E8F9EF'
)
.
borderRadius
(
10
)
ForEach
(
[
'外观检查'
,
'屏幕检测'
,
'功能测试'
,
'电池健康'
,
'主板检测'
]
,
(
item
:
string
,
idx
:
number
)
=>
{
Row
(
)
{
Text
(
item
)
.
fontSize
(
12
)
.
fontColor
(
'#333333'
)
Column
(
)
.
layoutWeight
(
1
)
Text
(
'✅ 正常'
)
.
fontSize
(
11
)
.
fontColor
(
'#00C853'
)
}
.
width
(
'100%'
)
.
padding
(
{
top
:
8
,
bottom
:
8
}
)
.
border
(
{
width
:
1
,
color
:
'#F0F0F0'
,
radius
:
8
}
)
.
margin
(
{
top
:
6
}
)
}
,
(
item
:
string
)
=>
item
)
Text
(
'质检师: 王师傅 · 专业等级 S'
)
.
fontSize
(
10
)
.
fontColor
(
'#999999'
)
.
width
(
'100%'
)
.
margin
(
{
top
:
10
}
)
Text
(
'下载报告'
)
.
fontSize
(
13
)
.
fontColor
(
'#FFFFFF'
)
.
width
(
'100%'
)
.
textAlign
(
TextAlign
.
Center
)
.
padding
(
{
top
:
10
,
bottom
:
10
}
)
.
backgroundColor
(
'#2E5AA8'
)
.
borderRadius
(
18
)
.
margin
(
{
top
:
12
}
)
.
onClick
(
(
)
=>
{
this
.
showReportDialog
=
false
}
)
}
.
width
(
'85%'
)
.
padding
(
16
)
.
backgroundColor
(
'#FFFFFF'
)
.
borderRadius
(
14
)
.
constraintSize
(
{
maxHeight
:
'80%'
}
)
}
.
width
(
'100%'
)
.
height
(
'100%'
)
.
justifyContent
(
FlexAlign
.
Center
)
.
backgroundColor
(
'#66000000'
)
}
@Builder
BottomBar
(
)
{
Row
(
)
{
ForEach
(
this
.
tabNames
,
(
t
:
string
,
idx
:
number
)
=>
{
Column
(
)
{
Text
(
this
.
tabIcons
[
idx
]
)
.
fontSize
(
19
)
.
opacity
(
this
.
currentIndex
===
idx
?
1
:
0.5
)
Text
(
t
)
.
fontSize
(
9
)
.
fontColor
(
this
.
currentIndex
===
idx
?
'#00C853'
:
'#999999'
)
.
fontWeight
(
this
.
currentIndex
===
idx
?
FontWeight
.
Bold
:
FontWeight
.
Normal
)
.
margin
(
{
top
:
2
}
)
}
.
layoutWeight
(
1
)
.
padding
(
{
top
:
6
,
bottom
:
6
}
)
.
onClick
(
(
)
=>
{
this
.
currentIndex
=
idx
}
)
}
,
(
t
:
string
)
=>
t
)
}
.
width
(
'100%'
)
.
padding
(
{
top
:
4
,
bottom
:
4
}
)
.
backgroundColor
(
'#FFFFFF'
)
.
border
(
{
width
:
1
,
color
:
'#F0F0F0'
,
radius
:
0
}
)
}
filterOrder
(
o
:
RecycleOrder
)
:
boolean
{
let
f
=
this
.
orderFilters
[
this
.
orderFilter
]
if
(
f
===
'全部'
)
{
return
true
}
return
o
.
status
===
f
}
orderStatusColor
(
status
:
string
)
:
string
{
if
(
status
===
'待上门'
)
{
return
'#FF8F00'
}
else
if
(
status
===
'检测中'
)
{
return
'#2E5AA8'
}
else
if
(
status
===
'已完成'
)
{
return
'#00C853'
}
return
'#CCCCCC'
}
phoneName
(
)
:
string
{
if
(
this
.
selectedPhone
!==
null
)
{
return
this
.
selectedPhone
.
model
}
return
'iPhone 15 Pro Max'
}
conditionName
(
)
:
string
{
let
names
:
string
[
]
=
[
'全新'
,
'99新'
,
'95新'
,
'9成新'
,
'8成新'
]
return
names
[
this
.
conditionIdx
]
}
orderNo
(
)
:
string
{
if
(
this
.
selectedOrder
!==
null
)
{
return
'ZX'
+
(
this
.
selectedOrder
.
id
)
.
toString
(
)
+
'X'
}
return
'ZX5001X'
}
orderModel
(
)
:
string
{
if
(
this
.
selectedOrder
!==
null
)
{
return
this
.
selectedOrder
.
model
}
return
'iPhone 15 Pro Max 256G'
}
orderPrice
(
)
:
number
{
if
(
this
.
selectedOrder
!==
null
)
{
return
this
.
selectedOrder
.
price
}
return
0
}
@State bookDay
:
number
=
0
build
(
)
{
Column
(
)
{
Column
(
)
{
Column
(
)
{
if
(
this
.
currentIndex
===
0
)
{
this
.
HallTab
(
)
}
else
if
(
this
.
currentIndex
===
1
)
{
this
.
QuoteTab
(
)
}
else
if
(
this
.
currentIndex
===
2
)
{
this
.
QualityTab
(
)
}
else
if
(
this
.
currentIndex
===
3
)
{
this
.
TradeInTab
(
)
}
else
if
(
this
.
currentIndex
===
4
)
{
this
.
OrderTab
(
)
}
else
{
this
.
ProfileTab
(
)
}
}
.
layoutWeight
(
1
)
.
width
(
'100%'
)
this
.
BottomBar
(
)
}
.
width
(
'100%'
)
.
height
(
'100%'
)
.
backgroundColor
(
'#F7F7F7'
)
if
(
this
.
showQuoteDialog
)
{
this
.
QuoteDialog
(
)
}
if
(
this
.
showBookDialog
)
{
this
.
BookDialog
(
)
}
if
(
this
.
showEditDialog
)
{
this
.
EditDialog
(
)
}
if
(
this
.
showDeleteDialog
)
{
this
.
DeleteDialog
(
)
}
if
(
this
.
showReportDialog
)
{
this
.
ReportDialog
(
)
}
}
}
}
在这里插入图片描述

总结

本文深入解析了一个基于HarmonyOS ArkTS API 24开发的二手数码回收平台应用的完整技术实现。该应用以 RecycleStationApp 自定义组件为入口,通过 currentIndex 状态变量驱动6个差异化Tab页面的渲染切换,覆盖了回收大厅、估价查询、质检标准、以旧换新、交易订单和个人中心等完整业务场景。每个Tab页面采用独立的 @Builder 方法封装,实现了页面逻辑的模块化组织,同时通过统一的配色方案(亮黄、深蓝、环保绿)和渐变背景保持了视觉一致性。

在交互层面,应用实现了5种不同样式的弹框系统,包括居中结果卡、底部弹窗、表单编辑、删除确认和详情报告,通过5个布尔型 @State 变量独立控制显示。弹框之间支持链式跳转(如估价弹框点击"立即回收"后跳转到预约弹框),形成了流畅的多步骤业务流程。数据可视化方面,应用通过纯ArkTS组件堆叠实现了柱状图和进度条效果,利用 Column 组件的高度/宽度比例计算和 Stack 组件的叠加技术,在不依赖第三方图表库的情况下完成了价格区间分布和品牌回收占比的可视化展示。

从架构设计角度来看,该应用展示了HarmonyOS声明式UI开发的核心模式:通过 @State 实现响应式数据绑定,通过 @Builder 实现UI逻辑的模块化封装,通过 ForEach 实现列表数据的动态渲染,通过 if 条件判断实现页面切换和列表筛选。辅助函数的空值安全设计、状态颜色的条件映射、动画属性的灵活运用等技术细节,共同构成了一个结构清晰、交互丰富、视觉统一的HarmonyOS原生应用范例。这些模式和技巧可以广泛应用于其他电商类、回收类和服务类HarmonyOS应用的开发实践。


转载声明:本文为转载整理,原文版权归原作者及原站点所有。

原文来源:CSDN HarmonyOS

原创地址:https://blog.csdn.net/2501_92985290/article/details/164029091

原文作者:柠落少女2440;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2022-08-02

  • 博文量
    36
  • 访问量
    33804