Files
apple 079076a70e miao33: 从 main 同步 single_uniapp22miao,dart-sass 兼容修复,DEPLOY.md 更新
- 从 main 获取 single_uniapp22miao 子项目
- dart-sass: /deep/ -> ::v-deep,calc 运算符加空格
- DEPLOY.md 采用 shccd159 版本(4 子项目架构说明)

Made-with: Cursor
2026-03-16 11:16:42 +08:00

606 lines
16 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="order-list-page">
<!-- 买卖方切换 -->
<view class="role-tabs">
<view class="role-tab" :class="{ 'active': userRole === 0 }" @click="switchRole(0)">买方</view>
<view class="role-tab" :class="{ 'active': userRole === 1 }" @click="switchRole(1)">卖方</view>
</view>
<!-- 状态Tab切换 -->
<view class="status-tabs">
<view v-for="(tab, index) in statusTabs" :key="index" class="status-tab" :class="{ 'active': currentTab === index }" @click="switchTab(index)">
{{ tab }}
</view>
</view>
<!-- 订单列表 -->
<scroll-view scroll-y class="scroll-view" @scrolltolower="loadMore">
<view class="order-list">
<!-- 订单列表项 -->
<view v-for="(order, index) in orderList" :key="order.id" class="order-item" @click="viewOrderDetail(order)">
<!-- 订单头部 -->
<view class="order-header">
<view class="order-no">订单编号{{ order.order_no }}</view>
<view class="order-status">待支付</view>
</view>
<!-- 商品信息 -->
<view class="goods-info">
<image :src="order.goods_image || order.image" class="goods-image"></image>
<view class="goods-detail">
<view class="goods-name">{{ order.goods_name || order.name }}</view>
<view class="goods-price">商品价格¥{{ order.price }}</view>
<!-- 卖家信息 -->
<view class="user-info">
<view class="user-label">卖家</view>
<view class="user-name">{{ order.seller_name || order.seller }}</view>
</view>
<view class="user-phone">卖家电话{{ order.seller_phone || order.seller_tel }}</view>
<!-- 买家信息 -->
<view class="user-info">
<view class="user-label">买家</view>
<view class="user-name">{{ order.buyer_name || order.buyer }}</view>
</view>
<view class="user-phone">买家电话{{ order.buyer_phone || order.buyer_tel }}</view>
</view>
</view>
<!-- 订单时间 -->
<view class="order-time">
<view class="time-item">下单时间{{ formatTime(order.created_at) }}</view>
<view class="time-item">抢单时间{{ formatTime(order.created_at) }}</view>
</view>
<!-- 操作按钮 -->
<view class="order-actions">
<button class="action-btn cancel" @click.stop="cancelOrder(order, index)">取消</button>
<button class="action-btn primary" @click.stop="payOrder(order)">去支付</button>
</view>
</view>
<!-- 加载更多 -->
<view class="load-more" v-if="orderList.length > 0">
<text v-if="loading">加载中...</text>
<text v-else-if="noMore">没有更多了</text>
</view>
<!-- 空状态 -->
<view class="empty-state" v-if="orderList.length === 0 && !loading">
<text class="icon">📦</text>
<text class="text">暂无订单</text>
</view>
</view>
</scroll-view>
</view>
</template>
<script>
import { getOrderList, cancelOrder, payOrder } from '@/api/miao.js';
export default {
data() {
return {
userRole: 0, // 0: 买方, 1: 卖方
statusTabs: ['寄卖中/交易中', '已完成'],
// 注意当前type参数定义为1:寄卖中/交易中2:已完成
currentTab: 0,
// 新增参数用于直接从URL获取
cate: 1, // 1: 买方, 2: 卖方
type: 1, // 1: 仓库, 2: 交易中, 3: 已完成
orderList: [],
page: 1,
limit: 20,
loading: false,
noMore: false
}
},
onLoad(options) {
// 从URL参数中获取cate和type
if (options.cate) {
this.cate = parseInt(options.cate);
// 根据cate设置用户角色1=买方2=卖方
this.userRole = this.cate === 2 ? 1 : 0;
}
if (options.type) {
this.type = parseInt(options.type);
// 根据type设置当前标签页1=寄卖中/交易中2=已完成
this.currentTab = this.type - 1;
}
// 兼容旧参数格式
if (options.userRole) {
this.userRole = parseInt(options.userRole);
this.cate = this.userRole === 1 ? 2 : 1;
}
if (options.tab) {
this.currentTab = parseInt(options.tab);
// 转换旧tab为新type参数格式
this.type = this.currentTab === 0 ? 1 : 2; // 仓库和交易中合并为1
}
this.loadOrderList();
},
methods: {
// 切换买卖方
switchRole(role) {
if (this.userRole === role) return;
this.userRole = role;
// 同步更新cate参数
this.cate = role === 1 ? 2 : 1;
this.page = 1;
this.noMore = false;
this.orderList = [];
this.loadOrderList();
},
// 切换Tab
switchTab(index) {
if (this.currentTab === index) return;
this.currentTab = index;
// 同步更新type参数1=寄卖中/交易中2=已完成
this.type = index + 1;
this.page = 1;
this.noMore = false;
this.orderList = [];
this.loadOrderList();
},
// 格式化时间
formatTime(time) {
if (!time) return '';
const date = new Date(time);
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');
const seconds = String(date.getSeconds()).padStart(2, '0');
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
},
// 加载订单列表
async loadOrderList() {
if (this.loading || this.noMore) return;
this.loading = true;
try {
// 直接使用data中的cate和type参数
const res = await getOrderList({
page: this.page,
limit: this.limit,
cate: this.cate,
type: this.type
});
if (res.code === 0) {
const list = res.data.list || [];
// 处理数据,确保字段一致性
const processedList = list.map(item => ({
...item,
// 确保有必要的字段
id: item.id || item.order_id || '',
order_no: item.order_no || item.order_id || '',
goods_image: item.goods_image || item.image || '',
goods_name: item.goods_name || item.name || '商品',
price: item.price || item.goods_price || '0.00',
created_at: item.created_at || item.create_time || new Date().toISOString(),
seller_name: item.seller_name || item.seller || '未知',
seller_phone: item.seller_phone || item.seller_tel || '',
buyer_name: item.buyer_name || item.buyer || '未知',
buyer_phone: item.buyer_phone || item.buyer_tel || ''
}));
if (processedList.length < this.limit) {
this.noMore = true;
}
this.orderList = this.page === 1 ? processedList : [...this.orderList, ...processedList];
}
} catch (error) {
console.error('加载订单失败:', error);
uni.showToast({
title: error.msg || '加载失败,请重试',
icon: 'none'
});
} finally {
this.loading = false;
}
},
// 加载更多
loadMore() {
if (!this.loading && !this.noMore) {
this.page++;
this.loadOrderList();
}
},
// 确认收货和确认发货功能暂时隐藏,根据参考图不显示这些按钮
// 确认收货功能已移除
// 确认发货功能已移除
// 转卖功能已移除
// 查看订单详情
viewOrderDetail(order) {
uni.navigateTo({
url: `/pages/sub-pages/rushing-order/detail?id=${order.id}`
});
},
// 取消订单
cancelOrder(order, index) {
uni.showModal({
title: '提示',
content: '确定要取消该订单吗?',
success: async (res) => {
if (res.confirm) {
try {
const result = await cancelOrder({
id: order.id
});
if (result.code === 0) {
this.orderList[index].status = 3;
uni.showToast({
title: '订单已取消',
icon: 'success'
});
}
} catch (error) {
uni.showToast({
title: error.msg || '取消失败',
icon: 'none'
});
}
}
}
});
},
// 支付订单
payOrder(order) {
uni.navigateTo({
url: `/pages/sub-pages/rushing-order/detail?id=${order.id}&pay=1`
});
},
// 确认收货
confirmOrder(order, index) {
// 由于方法命名冲突这里改为使用导入的confirmOrder接口
const confirmOrderApi = async () => {
try {
const result = await this.$http.post('/api/order/confirm', {
id: order.id
});
if (result.code === 0) {
this.orderList[index].status = 2;
uni.showToast({
title: '确认成功',
icon: 'success'
});
}
} catch (error) {
uni.showToast({
title: error.msg || '确认失败',
icon: 'none'
});
}
};
uni.showModal({
title: '提示',
content: '确认收到货物了吗?',
success: async (res) => {
if (res.confirm) {
await confirmOrderApi();
}
}
});
},
// 确认发货
deliverOrder(order, index) {
uni.showModal({
title: '提示',
content: '确认已发货了吗?',
success: async (res) => {
if (res.confirm) {
try {
const result = await this.$http.post('/api/order/deliver', {
id: order.id
});
if (result.code === 0) {
this.orderList.splice(index, 1);
uni.showToast({
title: '发货成功',
icon: 'success'
});
}
} catch (error) {
uni.showToast({
title: error.msg || '操作失败',
icon: 'none'
});
}
}
}
});
},
// 转卖订单
resellOrder(order) {
uni.showModal({
title: '提示',
content: '确定要将该订单转卖吗?',
success: async (res) => {
if (res.confirm) {
try {
const result = await this.$http.post('/api/order/resell', {
id: order.id
});
if (result.code === 0) {
uni.showToast({
title: '转卖成功',
icon: 'success'
});
// 刷新列表
this.page = 1;
this.noMore = false;
this.orderList = [];
this.loadOrderList();
}
} catch (error) {
uni.showToast({
title: error.msg || '转卖失败',
icon: 'none'
});
}
}
}
});
}
}
}
</script>
<style lang="scss" scoped>
.order-list-page {
height: 100vh;
display: flex;
flex-direction: column;
background-color: #f5f5f5;
}
/* 买卖方切换 */
.role-tabs {
display: flex;
background-color: #fff;
padding: 20rpx;
margin-bottom: 20rpx;
.role-tab {
flex: 1;
height: 70rpx;
line-height: 70rpx;
text-align: center;
font-size: 32rpx;
color: #333;
border-radius: 35rpx;
background-color: #f5f5f5;
margin: 0 10rpx;
transition: all 0.3s;
&.active {
background-color: #ff6666;
color: #fff;
font-weight: bold;
}
}
}
/* 状态Tab切换 */
.status-tabs {
display: flex;
background-color: #fff;
border-bottom: 1px solid #f0f0f0;
.status-tab {
flex: 1;
height: 90rpx;
line-height: 90rpx;
text-align: center;
font-size: 28rpx;
color: #666;
position: relative;
&.active {
color: #ff6666;
font-weight: bold;
&::after {
content: '';
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 60rpx;
height: 4rpx;
background-color: #ff6666;
border-radius: 2rpx;
}
}
}
}
.scroll-view {
flex: 1;
}
.order-list {
padding: 20rpx 30rpx;
}
.order-item {
background-color: #fff;
border-radius: 20rpx;
padding: 30rpx;
margin-bottom: 20rpx;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
.order-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 30rpx;
padding-bottom: 20rpx;
border-bottom: 1px solid #f5f5f5;
.order-no {
font-size: 28rpx;
color: #333;
}
.order-status {
font-size: 28rpx;
color: #ff6666;
font-weight: bold;
}
}
.goods-info {
display: flex;
margin-bottom: 30rpx;
.goods-image {
width: 200rpx;
height: 200rpx;
border-radius: 10rpx;
margin-right: 25rpx;
background-color: #f5f5f5;
}
.goods-detail {
flex: 1;
display: flex;
flex-direction: column;
.goods-name {
font-size: 32rpx;
color: #333;
line-height: 1.4;
margin-bottom: 20rpx;
}
.goods-price {
font-size: 36rpx;
color: #ff6666;
font-weight: bold;
margin-bottom: 20rpx;
}
.user-info {
display: flex;
align-items: center;
margin-bottom: 10rpx;
.user-label {
background-color: #ff6666;
color: #fff;
padding: 4rpx 20rpx;
border-radius: 15rpx;
font-size: 22rpx;
margin-right: 15rpx;
}
.user-name {
font-size: 28rpx;
color: #333;
}
}
.user-phone {
font-size: 26rpx;
color: #666;
margin-bottom: 10rpx;
}
}
}
.order-time {
margin-bottom: 30rpx;
.time-item {
font-size: 26rpx;
color: #999;
margin-bottom: 8rpx;
}
}
.order-actions {
display: flex;
justify-content: flex-end;
gap: 20rpx;
.action-btn {
height: 70rpx;
line-height: 70rpx;
padding: 0 40rpx;
border-radius: 35rpx;
border: none;
font-size: 28rpx;
&.cancel {
background-color: #f5f5f5;
color: #666;
}
&.primary {
background-color: #ff6666;
color: #fff;
font-weight: bold;
}
}
}
}
.load-more {
padding: 30rpx;
text-align: center;
font-size: 26rpx;
color: #999;
}
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 200rpx 0;
.icon {
font-size: 120rpx;
margin-bottom: 20rpx;
}
.text {
font-size: 28rpx;
color: #999;
}
}
</style>