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.
 
 
 
 

832 lines
18 KiB

<template>
<view class="order-list-container">
<!-- Tab切换 -->
<view class="tab-container">
<view
class="tab-item"
:class="[{ active: currentTab == index }]"
v-for="(tab, index) in tabs"
:key="index"
@click="switchTab(index)"
>
<text class="tab-text">{{ tab.name }}</text>
</view>
</view>
<!-- 订单列表 -->
<scroll-view
class="order-scroll"
scroll-y
@scrolltolower="loadMore"
:show-scrollbar="false"
enhanced
>
<!-- 订单项 -->
<view
class="order-item"
v-for="order in orderList"
@click="goToOrderDetail(order)"
>
<!-- 订单头部 - 供应商信息 -->
<view class="order-header">
<view class="supplier-info">
<view class="supplier-name" v-if="order.status==0||order.status==-1">有感商品订单</view>
<view class="supplier-name" v-else>{{
order.supplierName || "默认供应商"
}}</view>
<view class="order-number">订单号:{{ ( order.status==0||order.status==-1)?order.parentOrderNo:order.orderNo }}</view>
</view>
<view class="order-status-wrapper">
<text class="status-name" :class="[getStatusClass(order.status)]">{{
getStatusText(order.status)
}}</text>
</view>
</view>
<!-- 商品列表 -->
<view class="goods-section">
<view class="goods-list">
<view
class="goods-item"
v-for="goods in order.orderItems"
:key="goods.id"
>
<view class="goods-image-container">
<image
v-if="goods.specImage"
class="goods-image"
:src="goods.specImage"
mode="aspectFill"
/>
</view>
<view class="goods-info">
<text class="goods-name">{{ goods.goodsName }}</text>
<view class="goods-specs">
<view class="spec-tag">
{{ goods.specValueOne }}-{{ goods.specValueTwo }}
</view>
</view>
<view class="goods-meta">
<text class="goods-price">¥{{ goods.price }}</text>
<text class="goods-quantity">×{{ goods.quantity || 1 }}</text>
</view>
<!-- 规格信息 -->
</view>
</view>
</view>
</view>
<!-- 订单底部 -->
<view class="order-footer">
<view class="order-info" >
<view class="order-total-section">
<!-- <text class="total-label">{{(order.status==0)?'':'实付'}}</text> -->
<text class="order-total">¥{{ order.payAmount || 0 }}</text>
</view>
<view class="order-time">{{ order.createTime }}</view>
</view>
<view class="order-actions">
<!-- 基于订单状态的操作按钮 -->
<button
class="action-btn"
@click.stop="handleOrderAction(order, 'pay')"
v-if="order.status === 0"
>
去支付
</button>
<button
class="action-btn confirm-btn"
@click.stop="handleOrderAction(order, 'confirm')"
v-if="order.status === 2"
>
确认收货
</button>
<button
class="action-btn secondary-btn"
@click.stop="handleOrderAction(order, 'aftersale')"
v-if="order.status === 3"
>
申请售后
</button>
</view>
</view>
</view>
<!-- 空状态 -->
<view
class="empty-state"
v-if="(orderList && orderList.length == 0) || loading"
>
<image
class="empty-image"
:src="
showImg('/uploads/20250808/c16267f9cc2b7a68bf23713b5847987e.png')
"
mode="aspectFit"
/>
<text class="empty-text">暂无订单</text>
</view>
<!-- 加载更多 -->
<view class="load-more" v-if="hasMore && orderList.length > 0">
<text class="load-text">{{
loading ? "加载中..." : "上拉加载更多"
}}</text>
</view>
<!-- 没有更多数据 -->
<view class="no-more" v-if="!hasMore && orderList.length > 0">
<text class="no-more-text">没有更多数据了</text>
</view>
</scroll-view>
</view>
</template>
<script>
export default {
data() {
return {
currentTab: 0,
tabs: [
{
name: "全部",
status: "",
},
{
name: "待支付",
status: 0,
},
{
name: "已支付",
status: 1,
},
{
name: "已发货",
status: 2,
},
{
name: "已完成",
status: 3,
},
],
orderList: [],
loading: false,
refresherTriggered: false,
hasMore: true,
currentPage: 1,
pageSize: 10,
currentOrder: null, // 当前操作的订单
};
},
onLoad(e) {
if (e.status) {
this.currentTab = e.status;
}
},
onShow() {
this.resetList();
this.loadOrderList();
},
methods: {
showImgJdsz(img) {
if (!img) return;
if (img.indexOf("https://") != -1 || img.indexOf("http://") != -1) {
return img;
} else {
return this.JDSU_IMG_URL + img;
}
},
// 切换Tab
switchTab(index) {
this.currentTab = index;
this.resetList();
this.loadOrderList();
},
// 重置列表
resetList() {
this.orderList = [];
this.currentPage = 1;
this.hasMore = true;
},
// 加载订单列表
async loadOrderList() {
if (this.loading || !this.hasMore) return;
this.loading = true;
try {
const params = {
pageNum: this.currentPage,
pageSize: this.pageSize,
status: this.tabs[this.currentTab].status,
};
let url = ''
if(this.currentTab==0||this.currentTab==1){
url = "/framework/ygOrder/parent/pageList"
}else{
url = "/framework/ygOrder/pageList"
}
this.Post(
{
...params,
},
url,
"DES"
).then((res) => {
if (res.code == 200) {
if(this.currentTab==0||this.currentTab==1){
let orderItems = []
res.rows.forEach(item =>{
item.orderItems = []
item.orders.forEach(_item =>{
item.orderItems.push(..._item.orderItems)
})
})
}
this.orderList.push(...res.rows);
console.log(this.orderList);
this.hasMore = res.rows.length === this.pageSize;
this.currentPage++;
} else {
uni.showToast({
title: res.msg,
icon: "none",
});
}
});
} catch (error) {
console.error("加载订单列表失败:", error);
uni.showToast({
title: "加载失败",
icon: "none",
});
} finally {
this.loading = false;
this.refresherTriggered = false;
}
},
// 上拉加载更多
loadMore() {
this.loadOrderList();
},
// 下拉刷新
onRefresh() {
this.refresherTriggered = true;
this.resetList();
this.loadOrderList();
},
// 获取订单状态文本
getStatusText(status) {
const statusMap = {
"-1": "已取消",
0: "待支付",
1: "已支付",
2: "已发货",
3: "已完成",
};
return statusMap[status] || "未知";
},
// 获取订单状态样式类
getStatusClass(status) {
const classMap = {
"-1": "status-cancelled",
0: "status-pending",
1: "status-paid",
2: "status-shipping",
3: "status-completed",
};
return classMap[status] || "";
},
// 处理订单操作
handleOrderAction(order, action) {
switch (action) {
case "pay":
this.goToPay(order);
break;
case "logistics":
this.viewLogistics(order);
break;
case "confirm":
this.confirmReceipt(order);
break;
case "contact":
this.contactSupplier(order);
break;
case "aftersale":
this.applyAfterSale(order);
break;
}
},
// 去支付
goToPay(order) {
this.Post(
{
method: "POST",
orderNo: order.orderNo,
fromType: 2,
payAmount: order.payAmount,
},
"/framework/wxPay/submitShopPurOrder",
"DES"
).then((res) => {
uni.requestPayment({
nonceStr: res.data.wxInfo.nonceStr,
package: res.data.wxInfo.package,
paySign: res.data.wxInfo.paySign,
signType: res.data.wxInfo.signType,
timeStamp: res.data.wxInfo.timeStamp,
success: () => {
this.resetList();
this.loadOrderList();
},
fail() {
// uni.navigateTo({
// url: '/subPackages/order/trades'
// })
},
});
});
},
// 查看物流
viewLogistics(order) {
uni.navigateTo({
url: `/subPackages/haveFeeling/logistics?orderId=${order.id}`,
});
},
// 确认收货
confirmReceipt(order) {
uni.showModal({
title: "确认收货",
content: "确认已收到所有商品吗?",
success: (res) => {
if (res.confirm) {
this.confirmReceiptApi(order.id);
}
},
});
},
// 确认收货API
confirmReceiptApi(orderId) {
uni.showLoading({
title: "确认中...",
});
this.Post(
{
orderId: orderId,
},
"/framework/haveFeeling/order/confirm",
"DES"
).then((res) => {
uni.hideLoading();
if (res.code == 200) {
uni.showToast({
title: "确认收货成功",
icon: "success",
});
setTimeout(() => {
this.resetList();
this.loadOrderList();
}, 800);
} else {
uni.showToast({
title: res.msg || "确认收货失败",
icon: "none",
});
}
});
},
// 联系供应商
contactSupplier(order) {
uni.showToast({
title: "正在联系供应商",
icon: "none",
});
// 这里可以跳转到聊天页面或者拨打电话
},
// 申请售后
applyAfterSale(order) {
this.currentOrder = order;
// 参考iSoul页面的客服弹窗
uni.showModal({
title: "申请售后",
content:
"客服电话:0515-69186109\n服务时间:周一至周五\n9:00-12:00,13:00-18:00\n\n是否联系客服申请售后?",
confirmText: "联系客服",
success: (res) => {
if (res.confirm) {
// 拨打客服电话
uni.makePhoneCall({
phoneNumber: "0515-69186109",
});
}
},
});
},
// 跳转到订单详情页面
goToOrderDetail(order) {
console.log(order)
if(order.status==-1||order.status==0){
uni.navigateTo({
url: `/subPackages/haveFeeling/detailAll?id=${order.orderNo}`,
});
}else{
uni.navigateTo({
url: `/subPackages/haveFeeling/detail?id=${order.orderNo}`,
});
}
},
},
};
</script>
<style lang="scss" scoped>
// 主题色彩变量
$primary-color: #667eea;
$secondary-color: #f8f9fa;
$text-primary: #2d3748;
$text-secondary: #718096;
$text-muted: #a0aec0;
$border-color: #e2e8f0;
$success-color: #48bb78;
$warning-color: #ed8936;
$danger-color: #f56565;
$bg-light: #f7fafc;
.order-list-container {
min-height: 100vh;
background-color: $bg-light;
}
// Tab样式
.tab-container {
display: flex;
background-color: #ffffff;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
color: black;
position: sticky;
top: 0;
z-index: 10;
}
.tab-item {
flex: 1;
padding: 32rpx 0;
text-align: center;
position: relative;
transition: all 0.3s ease;
color: #333333;
&.active {
.tab-text {
color: #77f3f9;
font-weight: 600;
}
&::after {
content: "";
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 60rpx;
height: 4rpx;
background-color: #77f3f9;
border-radius: 2rpx;
}
}
&:not(.active) {
.tab-text {
opacity: 1;
}
}
}
.tab-text {
font-size: 26rpx;
color: #333333;
font-weight: 600;
transition: all 0.3s ease;
}
// 订单列表样式
.order-scroll {
height: calc(100vh - 120rpx);
padding: 0 24rpx;
width: 702rpx;
}
.order-item {
background-color: #ffffff;
border-radius: 20rpx;
overflow: hidden;
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.08);
border: none;
transition: all 0.3s ease;
margin-top: 40rpx;
&:active {
transform: scale(0.98);
}
}
// 订单头部 - 供应商信息
.order-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 24rpx 28rpx 20rpx;
background: white;
}
.supplier-info {
flex: 1;
}
.supplier-name {
font-size: 30rpx;
color: $text-primary;
font-weight: 600;
margin-bottom: 8rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 490rpx;
}
.order-number {
font-size: 24rpx;
color: $text-secondary;
font-weight: 500;
}
.order-status-wrapper {
display: flex;
align-items: center;
}
.status-name {
font-size: 26rpx;
padding: 12rpx 20rpx;
border-radius: 24rpx;
font-weight: 600;
letter-spacing: 0.5rpx;
&.status-pending {
background: #fff3cd;
color: #856404;
}
&.status-paid {
background: #e6f3ff;
color: #0c5460;
}
&.status-cancelled {
background: #f8d7da;
color: #721c24;
}
&.status-shipping {
background: #d4edda;
color: #155724;
}
&.status-completed {
background: #d1ecf1;
color: #0c5460;
}
}
// 商品部分
.goods-section {
margin: 20rpx 0;
}
.goods-list {
padding: 0 20rpx;
}
.goods-item {
display: flex;
align-items: center;
padding: 20rpx;
margin-bottom: 12rpx;
background: #ffffff;
border-radius: 16rpx;
border: 1px solid rgba(0, 0, 0, 0.05);
transition: all 0.3s ease;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04);
&:last-child {
margin-bottom: 0;
}
}
.goods-image-container {
position: relative;
margin-right: 20rpx;
flex-shrink: 0;
}
.goods-image {
width: 100rpx;
height: 100rpx;
border-radius: 12rpx;
}
.goods-info {
flex: 1;
margin-right: 20rpx;
}
.goods-name {
display: block;
font-size: 26rpx;
color: $text-primary;
font-weight: 600;
margin-bottom: 12rpx;
line-height: 1.4;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 490rpx;
}
.goods-meta {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10rpx;
}
.goods-price {
font-size: 26rpx;
color: $danger-color;
font-weight: 600;
font-family: "SF Mono", "Monaco", "Cascadia Code", monospace;
}
.goods-quantity {
font-size: 22rpx;
color: $text-muted;
font-weight: 500;
}
// 商品规格样式
.goods-specs {
margin-top: 10rpx;
display: flex;
flex-wrap: wrap;
gap: 8rpx;
}
.spec-tag {
background: #f0f8ff;
border: 1rpx solid #e6f3ff;
border-radius: 12rpx;
padding: 4rpx 12rpx;
display: inline-block;
margin-bottom: 6rpx;
font-size: 22rpx;
color: #4a90e2;
font-weight: 500;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 490rpx;
}
// 订单底部
.order-footer {
display: flex;
justify-content: space-between;
align-items: center;
padding: 24rpx 28rpx;
background: white;
margin-top: 20rpx;
}
.order-info {
flex: 1;
display: flex;
flex-direction: column;
gap: 8rpx;
}
.order-total-section {
display: flex;
align-items: center;
gap: 8rpx;
}
.total-label {
font-size: 22rpx;
color: $text-muted;
font-weight: 500;
}
.order-total {
font-size: 32rpx;
color: $danger-color;
font-weight: 600;
font-family: -apple-system, BlinkMacSystemFont, "PingFang SC",
"Helvetica Neue", STHeiti, "Microsoft Yahei", Tahoma, Simsun, sans-serif;
}
.order-time {
font-size: 22rpx;
color: $text-muted;
font-weight: 500;
}
.order-actions {
display: flex;
gap: 12rpx;
flex-direction: column;
.action-btn {
padding: 8rpx 20rpx;
border-radius: 10rpx;
font-size: 24rpx;
font-weight: 600;
border: none;
color: #333333;
transition: all 0.3s ease;
min-width: 100rpx;
text-align: center;
background-color: #77f3f9;
display: flex;
align-items: center;
justify-content: center;
height: 58rpx;
&:active {
transform: scale(0.95);
}
&.confirm-btn {
background-color: $success-color;
color: #ffffff;
}
&.secondary-btn {
background-color: #f5f5f5;
color: #666666;
border: 1rpx solid #ddd;
}
}
}
// 空状态
.empty-state {
text-align: center;
padding: 240rpx 40rpx;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
}
.empty-image {
width: 240rpx;
height: 240rpx;
margin-bottom: 40rpx;
opacity: 0.8;
}
.empty-text {
font-size: 32rpx;
color: $text-muted;
font-weight: 500;
}
// 加载更多
.load-more,
.no-more {
text-align: center;
padding: 40rpx;
}
.load-text,
.no-more-text {
font-size: 28rpx;
color: $text-muted;
font-weight: 500;
}
</style>