HomeLease/pages/myOrder/myOrder.vue

376 lines
8.5 KiB
Vue
Raw Normal View History

2025-08-22 15:59:01 +08:00
<template>
<view class="container">
2025-08-25 11:47:28 +08:00
<!-- 加载状态 -->
2025-08-25 18:06:33 +08:00
<view v-if="loading && list.length === 0" class="loading-container">
2025-08-25 11:47:28 +08:00
<text class="loading-text">正在加载...</text>
</view>
2025-08-25 14:12:27 +08:00
2025-08-25 11:47:28 +08:00
<!-- 空数据状态 -->
2025-08-25 18:06:33 +08:00
<view v-else-if="isEmpty" class="empty-container">
2025-08-25 11:47:28 +08:00
<view class="empty-icon">📋</view>
<text class="empty-text">暂无订单数据</text>
</view>
2025-08-25 14:12:27 +08:00
2025-08-25 11:47:28 +08:00
<!-- 订单列表 -->
<view v-else>
<view v-for="item in list" :key="item.id" class="order-item" @click="onClick(item)">
<view class="order-header">
<view class="order-title">
<text class="title-text">{{ item.typeName || '订单详情' }}</text>
2025-08-25 14:12:27 +08:00
<text :class="getStatusClass(item.status)" class="status-text">
2025-08-25 11:47:28 +08:00
{{ mapOrderStatus('status', item.status) }}
</text>
</view>
<text class="order-time">{{ formatTime(item.createTime) }}</text>
</view>
2025-08-25 14:12:27 +08:00
2025-08-25 11:47:28 +08:00
<view class="order-content">
<view class="order-info">
<text class="order-id">订单号{{ item.orderNumber || item.id }}</text>
<text class="order-amount">¥{{ item.amount || '0.00' }}</text>
</view>
2025-08-25 14:12:27 +08:00
2025-08-25 11:47:28 +08:00
<view class="order-details">
<view class="detail-item">
<text class="label">租赁套餐</text>
<text class="value">{{ item.suitName }}</text>
</view>
<view class="detail-item">
<text class="label">租赁时间</text>
<text class="value">{{ formatTime(item.leaseTime) }}</text>
</view>
<view class="detail-item">
<text class="label">到期时间</text>
<text class="value">{{ formatTime(item.expirationTime) }}</text>
</view>
<!-- <view class="detail-item">-->
<!-- <text class="label">物流状态</text>-->
<!-- <text :class="getLogisticClass(item.logisticStatus)" class="value">-->
<!-- {{ mapOrderStatus('logistic', item.logisticStatus) }}-->
<!-- </text>-->
<!-- </view>-->
2025-08-25 11:47:28 +08:00
</view>
</view>
</view>
2025-08-22 15:59:01 +08:00
</view>
2025-08-25 18:06:33 +08:00
<!-- 分页组件 -->
<pagination
2025-08-26 09:11:00 +08:00
:current-page="pagination.currentPage"
2025-08-25 18:06:33 +08:00
:list="list"
:loading="loading"
2025-08-26 09:11:00 +08:00
:mode="'loadMore'"
2025-08-25 18:06:33 +08:00
:no-more="noMore"
:page-size="pagination.pageSize"
2025-08-26 09:11:00 +08:00
:total="pagination.total"
2025-08-25 18:06:33 +08:00
@page-change="handlePageChange"
/>
2025-08-22 15:59:01 +08:00
</view>
</template>
<script setup>
2025-08-26 09:11:00 +08:00
import { onMounted } from 'vue'
import { onReachBottom } from '@dcloudio/uni-app'
2025-08-22 15:59:01 +08:00
import { getMyOrder } from '@/api/order/myOrder.js'
import { usePagination } from '@/composables/usePagination.js'
2025-08-26 09:38:47 +08:00
import Pagination from '@/components/pagination/pagination.vue'
2025-08-25 18:06:33 +08:00
// 使用分页组合式函数
2025-08-29 14:50:22 +08:00
2025-08-26 09:11:00 +08:00
const { list, loading, noMore, pagination, getList, loadMore } = usePagination({
2025-08-25 18:06:33 +08:00
fetchData: getMyOrder,
defaultParams: {
orderByColumn: 'createTime',
2025-08-26 09:11:00 +08:00
isAsc: 'descending',
2025-08-25 18:06:33 +08:00
},
mode: 'loadMore',
2025-08-26 09:11:00 +08:00
pageSize: 6,
2025-08-25 18:06:33 +08:00
})
2025-08-22 15:59:01 +08:00
2025-08-25 18:06:33 +08:00
// 页面加载时获取数据
onMounted(() => {
getList()
})
// 上拉加载更多
onReachBottom(() => {
loadMore()
})
// 处理页码变化
2025-08-26 09:11:00 +08:00
const handlePageChange = page => {
2025-08-25 18:06:33 +08:00
console.log('页码变化:', page)
}
2025-08-25 11:47:28 +08:00
/**
* 订单状态/物流状态映射工具
* @param {string} type - 'status'订单状态 'logistic'物流状态
* @param {string|number} value - 状态值数字或中文
* @returns {string|number} 转换后的值
*/
function mapOrderStatus(type, value) {
const maps = {
status: {
2025-08-25 14:12:27 +08:00
1: '未支付',
2: '支付成功',
3: '退款',
未支付: '1',
支付成功: '2',
退款: '3',
2025-08-25 11:47:28 +08:00
},
logistic: {
2025-08-25 14:12:27 +08:00
1: '未签收',
2: '已签收',
3: '已归还',
未签收: '1',
已签收: '2',
已归还: '3',
2025-08-25 11:47:28 +08:00
},
}
2025-08-25 18:06:33 +08:00
return maps[type]?.[value] || '未知状态'
2025-08-25 11:47:28 +08:00
}
/**
* 获取订单状态样式类
* @param {string} status - 状态值
* @returns {string} 样式类名
*/
function getStatusClass(status) {
const statusMap = {
2025-08-25 14:12:27 +08:00
1: 'status-pending',
2: 'status-success',
3: 'status-refund',
2025-08-25 11:47:28 +08:00
}
return statusMap[status] || 'status-unknown'
}
/**
* 获取物流状态样式类
* @param {string} status - 状态值
* @returns {string} 样式类名
*/
function getLogisticClass(status) {
const statusMap = {
2025-08-25 14:12:27 +08:00
1: 'logistic-pending',
2: 'logistic-success',
3: 'logistic-returned',
2025-08-25 11:47:28 +08:00
}
return statusMap[status] || 'logistic-unknown'
}
/**
* 格式化时间
* @param {string} timeStr - 时间字符串
* @returns {string} 格式化后的时间
*/
function formatTime(timeStr) {
if (!timeStr) return '--'
2025-08-25 14:12:27 +08:00
2025-08-25 11:47:28 +08:00
try {
// 处理iOS兼容性问题将 "yyyy-MM-dd HH:mm:ss" 转换为 "yyyy/MM/dd HH:mm:ss"
let normalizedTimeStr = timeStr
if (typeof timeStr === 'string' && timeStr.includes('-') && timeStr.includes(' ')) {
// 将 "2027-08-22 17:17:01" 转换为 "2027/08/22 17:17:01"
normalizedTimeStr = timeStr.replace(/-/g, '/')
}
2025-08-25 14:12:27 +08:00
2025-08-25 11:47:28 +08:00
const date = new Date(normalizedTimeStr)
2025-08-25 14:12:27 +08:00
2025-08-25 11:47:28 +08:00
// 检查日期是否有效
if (isNaN(date.getTime())) {
return timeStr
}
2025-08-25 14:12:27 +08:00
2025-08-25 11:47:28 +08:00
const year = date.getFullYear()
const month = String(date.getMonth() + 1).padStart(2, '0')
const day = String(date.getDate()).padStart(2, '0')
const hours = String(date.getHours()).padStart(2, '0')
const minutes = String(date.getMinutes()).padStart(2, '0')
2025-08-25 14:12:27 +08:00
2025-08-25 11:47:28 +08:00
return `${year}-${month}-${day} ${hours}:${minutes}`
} catch (error) {
console.error('时间格式化错误:', error, '原始时间:', timeStr)
return timeStr
}
}
2025-08-22 15:59:01 +08:00
2025-08-25 11:47:28 +08:00
// 点击订单卡片
2025-08-25 14:12:27 +08:00
const onClick = item => {
2025-08-25 11:47:28 +08:00
console.log('点击订单:', item)
// 跳转到订单详情页
uni.navigateTo({
2025-08-25 14:12:27 +08:00
url: `/pages/myOrder/orderDetail?id=${item.id}`,
2025-08-25 11:47:28 +08:00
})
}
2025-08-22 15:59:01 +08:00
</script>
<style lang="scss" scoped>
.container {
overflow: hidden;
padding: 20rpx;
2025-08-25 11:47:28 +08:00
min-height: 100vh;
background-color: #f5f5f5;
}
.loading-container {
display: flex;
justify-content: center;
align-items: center;
height: 200rpx;
2025-08-25 14:12:27 +08:00
2025-08-25 11:47:28 +08:00
.loading-text {
font-size: 28rpx;
color: #666;
}
}
.empty-container {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 400rpx;
2025-08-25 14:12:27 +08:00
2025-08-25 11:47:28 +08:00
.empty-icon {
font-size: 80rpx;
margin-bottom: 20rpx;
}
2025-08-25 14:12:27 +08:00
2025-08-25 11:47:28 +08:00
.empty-text {
font-size: 28rpx;
color: #999;
}
2025-08-22 15:59:01 +08:00
}
2025-08-25 11:47:28 +08:00
.order-item {
background-color: #fff;
border-radius: 16rpx;
2025-08-22 15:59:01 +08:00
margin-bottom: 20rpx;
2025-08-25 11:47:28 +08:00
padding: 30rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.08);
2025-08-25 14:12:27 +08:00
2025-08-25 11:47:28 +08:00
&:active {
background-color: #f8f8f8;
}
2025-08-22 15:59:01 +08:00
}
2025-08-25 11:47:28 +08:00
.order-header {
margin-bottom: 20rpx;
2025-08-25 14:12:27 +08:00
2025-08-25 11:47:28 +08:00
.order-title {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10rpx;
2025-08-25 14:12:27 +08:00
2025-08-25 11:47:28 +08:00
.title-text {
font-size: 32rpx;
font-weight: 600;
color: #333;
}
2025-08-25 14:12:27 +08:00
2025-08-25 11:47:28 +08:00
.status-text {
font-size: 24rpx;
padding: 6rpx 12rpx;
border-radius: 20rpx;
font-weight: 500;
2025-08-25 14:12:27 +08:00
2025-08-25 11:47:28 +08:00
&.status-pending {
background-color: #fff7e6;
color: #fa8c16;
}
2025-08-25 14:12:27 +08:00
2025-08-25 11:47:28 +08:00
&.status-success {
background-color: #f6ffed;
color: #52c41a;
}
2025-08-25 14:12:27 +08:00
2025-08-25 11:47:28 +08:00
&.status-refund {
background-color: #fff2f0;
color: #ff4d4f;
}
2025-08-25 14:12:27 +08:00
2025-08-25 11:47:28 +08:00
&.status-unknown {
background-color: #f5f5f5;
color: #999;
}
}
}
2025-08-25 14:12:27 +08:00
2025-08-25 11:47:28 +08:00
.order-time {
font-size: 24rpx;
color: #999;
}
}
.order-content {
.order-info {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20rpx;
padding-bottom: 15rpx;
border-bottom: 1rpx solid #f0f0f0;
2025-08-25 14:12:27 +08:00
2025-08-25 11:47:28 +08:00
.order-id {
font-size: 26rpx;
color: #666;
}
2025-08-25 14:12:27 +08:00
2025-08-25 11:47:28 +08:00
.order-amount {
font-size: 32rpx;
color: #f15a04;
font-weight: bold;
}
}
2025-08-25 14:12:27 +08:00
2025-08-25 11:47:28 +08:00
.order-details {
.detail-item {
display: flex;
justify-content: space-between;
margin-bottom: 12rpx;
2025-08-25 14:12:27 +08:00
2025-08-25 11:47:28 +08:00
.label {
font-size: 26rpx;
color: #666;
min-width: 140rpx;
}
2025-08-25 14:12:27 +08:00
2025-08-25 11:47:28 +08:00
.value {
font-size: 26rpx;
color: #333;
flex: 1;
text-align: right;
2025-08-25 14:12:27 +08:00
2025-08-25 11:47:28 +08:00
&.logistic-pending {
color: #fa8c16;
}
2025-08-25 14:12:27 +08:00
2025-08-25 11:47:28 +08:00
&.logistic-success {
color: #52c41a;
}
2025-08-25 14:12:27 +08:00
2025-08-25 11:47:28 +08:00
&.logistic-returned {
color: #1890ff;
}
2025-08-25 14:12:27 +08:00
2025-08-25 11:47:28 +08:00
&.logistic-unknown {
color: #999;
}
}
}
}
}
.load-more {
margin-top: 20rpx;
text-align: center;
2025-08-25 14:12:27 +08:00
2025-08-25 11:47:28 +08:00
.no-more-text {
font-size: 24rpx;
color: #999;
}
2025-08-22 15:59:01 +08:00
}
</style>