爱简收旧衣按件回收前端代码仓库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

474 lines
11 KiB

<template>
<view class="container">
<!-- 顶部导航 -->
<view class="nav-bar">
<view class="back" @tap="goBack">
<uni-icons type="left" size="20"></uni-icons>
</view>
<text class="title">我的订单</text>
</view>
<!-- 页面内容 -->
<view class="content">
<!-- <view class="page-header">
<text class="page-title">我的订单</text>
<text class="view-all" @tap="viewAll">查看全部 ></text>
</view> -->
<!-- 标签页 -->
<view class="tabs">
<view
v-for="(tab, index) in tabs"
:key="index"
class="tab-item"
:class="{ active: currentTab === index }"
@tap="switchTab(index)"
>
<text>{{ tab.name }}</text>
<text v-if="tab.count > 0" class="badge">{{ tab.count }}</text>
</view>
</view>
<!-- 订单列表 -->
<scroll-view
scroll-y
class="order-list"
@scrolltolower="loadMore"
>
<view
v-for="order in orderList"
:key="order.id"
class="order-card"
@tap="goToDetail(order)"
>
<!-- 订单号 -->
<view class="order-header">
<text class="order-id">
订单编号
<text class="order-ids">{{order.id }} </text>
</text>
</view>
<!-- 订单内容 -->
<view class="order-content">
<image class="order-image" :src="order.image" mode="aspectFill"></image>
<view class="order-arrow">
<text class="iconfont">⇄</text>
</view>
<view class="order-info">
<text class="order-count">{{ order.count }} 件</text>
<text class="order-price">¥ {{ order.priceRange }} /件</text>
<view class="order-estimate">
<text>预估 ¥{{ order.estimatePrice }}</text>
</view>
</view>
</view>
<!-- 订单状态 -->
<view class="order-status">
<image class="status-icon" :src="order.statusIcon" mode="aspectFill"></image>
<view class="status-info">
<text class="status-text">{{ order.statusText }}</text>
<text class="status-time">{{ order.statusTime }}</text>
</view>
</view>
</view>
</scroll-view>
</view>
</view>
</template>
<script>
import pullRefreshMixin from '@/pages/mixins/pullRefreshMixin.js'
export default {
mixins: [pullRefreshMixin],
data() {
return {
tabs: [
{ name: '全部', count: 0 },
{ name: '进行中', count: 2 },
{ name: '已完成', count: 0 }
],
currentTab: 0,
// 所有订单数据
allOrders: [
{
id: 'RE82738127861526',
image: '/static/回收/衣物.png',
count: 8,
priceRange: '3-10',
estimatePrice: '76-80',
statusIcon: '/static/.png',
statusText: '【已取件】快递员正在送至质检',
statusTime: '周四 11:00~13:00',
status: 'collected'
},
{
id: 'RE82738127861525',
image: '/static/回收/衣物.png',
count: 8,
priceRange: '3-10',
estimatePrice: '76-80',
statusIcon: '/static/my/【待取件】快递员正在赶来.png',
statusText: '【待取件】快递员正在赶来',
statusTime: '2025-04-20 11:00~13:00',
status: 'processing'
},{
id: 'RE82738127861525',
image: '/static/回收/衣物.png',
count: 8,
priceRange: '3-10',
estimatePrice: '76-80',
statusIcon: '/static/my/【质检中】质检员正在质检.png',
statusText: '【质检中】质检员正在质检',
statusTime: '2025-04-20 11:00~13:00',
status: 'inspecting'
},
{
id: 'RE82738127861524',
image: '/static/回收/衣物.png',
count: 8,
priceRange: '3-10',
estimatePrice: '76-80',
statusText: '已取消',
cancelled: true,
status: 'cancelled'
},
{
id: 'RE82738127861523',
image: '/static/回收/衣物.png',
count: 8,
priceRange: '3-10',
estimatePrice: '76-80',
statusIcon: '/static/completed-icon.png',
statusText: '【待结款】待平台确认结款项',
statusTime: '2025-03-20 11:00',
status: 'pending_payment'
},
{
id: 'RE82738127861523',
image: '/static/回收/衣物.png',
count: 8,
priceRange: '3-10',
estimatePrice: '76-80',
statusIcon: '/static/my/【已结款】平台已结款至账户.png',
statusText: '【已结款】平台已结款至账户',
statusTime: '2025-03-20 11:00',
status: 'completed'
}
],
orderList: [], // 当前显示的订单列表
loading: false,
page: 1,
pageSize: 10
}
},
created() {
this.initOrderData()
},
methods: {
async onRefresh() {
// 模拟刷新数据
await new Promise(resolve => setTimeout(resolve, 1000))
this.stopPullRefresh()
},
goBack() {
uni.navigateBack()
},
showMore() {
// 显示更多选项
},
onShare() {
// 分享功能
},
viewAll() {
this.switchTab(0) // 切换到全部标签
},
// 初始化订单数据和计数
initOrderData() {
// 计算各状态订单数量
const processingOrders = this.allOrders.filter(order => order.status === 'processing')
const completedOrders = this.allOrders.filter(order => order.status === 'completed')
// 更新标签计数
this.tabs[0].count = this.allOrders.length
this.tabs[1].count = processingOrders.length
this.tabs[2].count = completedOrders.length
// 初始加载全部订单
this.loadOrdersByTab(0)
},
// 切换标签
switchTab(index) {
if (this.currentTab === index) return
this.currentTab = index
this.page = 1 // 重置页码
this.loadOrdersByTab(index)
},
// 根据标签加载对应订单
loadOrdersByTab(tabIndex) {
this.loading = true
let filteredOrders = []
switch(tabIndex) {
case 0: // 全部
filteredOrders = this.allOrders
break
case 1: // 进行中
filteredOrders = this.allOrders.filter(order => order.status === 'processing'|| order.status === 'pending_payment')
break
case 2: // 已完成
filteredOrders = this.allOrders.filter(order => order.status === 'completed')
break
}
// 模拟分页
const start = (this.page - 1) * this.pageSize
const end = start + this.pageSize
const pageOrders = filteredOrders.slice(start, end)
if (this.page === 1) {
this.orderList = pageOrders
} else {
this.orderList = [...this.orderList, ...pageOrders]
}
this.loading = false
},
// 加载更多
loadMore() {
if (this.loading) return
this.page++
this.loadOrdersByTab(this.currentTab)
},
goToDetail(order) {
uni.navigateTo({
url: `/pages/subcomponent/detail?id=${order.id}&status=${order.status}`
})
}
}
}
</script>
<style lang="scss" scoped>
.container {
min-height: 100vh;
background: #f8f8f8;
padding-bottom: calc(140rpx + env(safe-area-inset-bottom));
}
.nav-bar {
display: flex;
align-items: center;
height: calc(88rpx + var(--status-bar-height));
padding: 0 32rpx;
padding-top: var(--status-bar-height);
background: #fff;
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 999;
box-sizing: border-box;
.back {
padding: 20rpx;
margin-left: -20rpx;
}
.title {
flex: 1;
text-align: center;
font-size: 34rpx;
font-weight: 500;
color: #222;
}
.right-btns {
display: flex;
align-items: center;
gap: 32rpx;
.more, .target {
font-size: 40rpx;
color: #333;
}
}
}
.content {
padding: 30rpx;
margin-top: calc(88rpx + var(--status-bar-height));
min-height: calc(100vh - 88rpx - var(--status-bar-height));
box-sizing: border-box;
.page-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 30rpx;
.page-title {
font-size: 34rpx;
font-weight: bold;
}
.view-all {
font-size: 28rpx;
color: #999;
}
}
}
.tabs {
display: flex;
background: #f5f5f5;
border-radius: 8rpx;
margin-bottom: 30rpx;
.tab-item {
flex: 1;
height: 80rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 28rpx;
color: #666;
position: relative;
&.active {
color: #333;
background-color: #e7e7e7;
font-weight: 500;
border-radius: 8rpx;
}
.badge {
position: absolute;
top: 10rpx;
right: 10rpx;
min-width: 32rpx;
height: 32rpx;
line-height: 32rpx;
text-align: center;
background: #ff4d4f;
color: #fff;
border-radius: 16rpx;
font-size: 24rpx;
padding: 0 6rpx;
}
}
}
.order-list {
height: calc(100vh - 400rpx);
}
.order-card {
background: #fff;
border-radius: 16rpx;
padding: 40rpx;
margin-bottom: 20rpx;
.order-header {
margin-bottom: 20rpx;
.order-id {
font-size: 28rpx;
color: #999;
.order-ids{
font-family: PingFang SC;
font-weight: 600;
font-size: 16px;
line-height: 140%;
letter-spacing: 0%;
color: #333;
}
}
}
.order-content {
display: flex;
align-items: center;
margin-bottom: 20rpx;
flex-direction: row;
justify-content: space-between;
.order-image {
width: 160rpx;
height: 160rpx;
border-radius: 8rpx;
// background-color: #fff8ea;
background: #fffbe6;
padding: 20rpx;
box-sizing: border-box;
display: block;
}
.order-arrow {
padding: 0 30rpx;
color: #999;
}
.order-info {
// flex: 1;
display: flex;
flex-direction: column;
text-align: center;
.order-count {
font-size: 32rpx;
font-weight: 500;
margin-bottom: 10rpx;
background-color: #fffaee;
// display: block;
}
.order-price {
font-size: 28rpx;
color: #666;
margin-bottom: 10rpx;
background-color: #fffaee;
// display: block;
}
.order-estimate {
display: inline-block;
background:#ffac07;
color: #fff;
font-size: 26rpx;
padding: 8rpx 20rpx;
border-radius: 20rpx;
}
}
}
.order-status {
display: flex;
align-items: center;
padding: 20rpx;
background: #f4f4f4;
border-radius: 8rpx;
.status-icon {
width: 80rpx;
height: 80rpx;
margin-right: 20rpx;
}
.status-info {
flex: 1;
.status-text {
font-size: 28rpx;
color: #333;
margin-bottom: 6rpx;
display: block;
}
.status-time {
font-size: 26rpx;
color: #999;
}
}
}
}
</style>