This commit is contained in:
@zuopngfei 2025-11-27 18:18:37 +08:00
commit 26563409c9
26 changed files with 251 additions and 127 deletions

View File

@ -22,10 +22,10 @@ function request(url, method = 'GET', data = {}) {
if (res.data.code) {
if (res.data.code == 10103 || res.data.code == 10101) {
wx.removeStorageSync('access_token');
wx.navigateTo({
url: '/pages/login/index',
});
reject(res.data);
// wx.navigateTo({
// url: '/pages/login/index',
// });
// reject(res.data);
return;
}
wx.showToast({

View File

@ -500,6 +500,8 @@ export default {
}
.shop-cart {
color: #fff;
flex: 3;
margin-left: 30rpx;
// color: #fff;

View File

@ -101,31 +101,37 @@
<view class="orders-more" @click="navigateTo('/pages/order/index')">查看全部</view>
</view>
<view class="order-list">
<view class="order-item" v-for="order in orders" :key="order.no">
<view class="order-item" v-for="order in orders" :key="order.order_id || order.id">
<view class="order-top">
<text class="order-no">{{ order.no }}</text>
<text class="order-no">{{ order.order_id || '-' }}</text>
<view class="order-tags">
<view class="order-tag type">{{ order.type }}</view>
<view class="order-tag status" :class="order.statusClass">{{ order.status }}</view>
<!-- <view class="order-tag type">{{ order.typeLabel }}</view> -->
<view class="order-tag status" :class="order.statusClass">{{ order.statusText }}</view>
</view>
<text class="order-date">{{ order.date }}</text>
<text class="order-date">{{ order.displayDate }}</text>
</view>
<view class="order-body">
<view class="order-thumb">60x60</view>
<view class="order-thumb">
<image v-if="order.productImage" :src="order.productImage" mode="aspectFill"></image>
<text v-else>60x60</text>
</view>
<view class="order-info">
<text class="order-name">{{ order.product }}</text>
<text class="order-spec">{{ order.spec }}</text>
<text class="order-name">{{ order.productName }}</text>
<text class="order-spec">{{ order.productSpec }}</text>
</view>
</view>
<view class="order-footer">
<view class="order-amount">
<text class="amount-label">订单总额</text>
<text class="amount-value">{{ order.amount }}</text>
<text class="amount-value">¥{{ order.amountText }}</text>
</view>
<view class="order-actions">
<view class="order-action" v-for="action in order.actions" :key="action.label">
{{ action.label }}
<view class="order-action" v-for="action in order.actions" :key="action.label" @click="handleOrderAction(action, order)">
查看详情
</view>
<!-- <view class="order-action" v-for="action in order.actions" :key="action.label" @click="handleOrderAction(action, order)">
{{ action.label }}
</view> -->
</view>
</view>
</view>
@ -319,41 +325,7 @@ export default {
{ icon: '📄', title: '隐私政策', desc: '查看隐私条款' },
{ icon: '❓', title: '帮助中心', desc: '常见问题解答' }
],
orders: [
{
no: 'ORD20250402001',
type: '拼团订单',
status: '已完成',
statusClass: 'success',
date: '2025-04-02',
product: '经典玫瑰香水30ml',
spec: '¥199 × 1',
amount: '¥199.00',
actions: [{ label: '查看详情' }, { label: '再次购买' }]
},
{
no: 'ORD20250401001',
type: '秒杀订单',
status: '待收货',
statusClass: 'warning',
date: '2025-04-01',
product: '小样体验包',
spec: '¥1 × 1',
amount: '¥1.00',
actions: [{ label: '查看详情' }]
},
{
no: 'ORD20250328001',
type: '普通订单',
status: '待付款',
statusClass: 'pending',
date: '2025-03-28',
product: '薰衣草精油礼盒',
spec: '¥299 × 1',
amount: '¥299.00',
actions: [{ label: '查看详情' }]
}
]
orders: []
};
},
computed: {
@ -381,6 +353,42 @@ export default {
}
},
methods: {
async handleOrderAction(action, order) {
if (!order) return;
if (action.label === '查看详情') {
const orderId = order.order_id || order.id || order.order_no || order.no;
if (!orderId) {
console.warn('缺少订单ID无法跳转详情', order);
return;
}
uni.navigateTo({
url: `/pages/order/detail?id=${orderId}`
});
} else if (action.label === '加入购物车') {
const skuList = order.product_list || order.productList || [];
if (!Array.isArray(skuList) || !skuList.length) {
console.warn('订单中没有商品列表,无法加入购物车', order);
return;
}
for (const sku of skuList) {
try {
await request('xcx/cart', 'POST', {
product_id: sku.product_id || order.product_id,
sku_id: sku.sku_id,
quantity: sku.quantity || 1
});
} catch (error) {
console.error('加入购物车失败', error);
}
}
uni.showToast({
title: '已加入购物车',
icon: 'success'
});
}
},
handleImageError(e) {
// 使
console.log('头像加载失败,使用默认头像', e);
@ -413,60 +421,139 @@ export default {
//
orderList = orderList.slice(0, 3);
//
this.orders = orderList.map(order => {
//
const firstItem = (order.items && order.items.length > 0) ? order.items[0] : order;
//
// 1 2 3 4 5 6 7退
const statusMap = {
'pending': { text: '待付款', class: 'pending' },
//
'pending': { text: '待支付', class: 'pending' },
'paid': { text: '待发货', class: 'warning' },
'shipped': { text: '待收货', class: 'warning' },
'completed': { text: '已完成', class: 'success' },
'cancelled': { text: '已取消', class: 'cancelled' },
'refunded': { text: '已退款', class: 'cancelled' }
'refunded': { text: '已退款', class: 'cancelled' },
//
'1': { text: '待支付', class: 'pending' },
'2': { text: '支付失败', class: 'cancelled' },
'3': { text: '待发货', class: 'warning' },
'4': { text: '待收货', class: 'warning' },
'5': { text: '已完成', class: 'success' },
'6': { text: '已取消', class: 'cancelled' },
'7': { text: '已退款', class: 'cancelled' }
};
const statusInfo = statusMap[order.status] || { text: order.status || '未知', class: '' };
//
const formatPrice = (price) => {
if (!price && price !== 0) return '0.00';
if (price < 1000) return parseFloat(price).toFixed(2);
return (price / 100).toFixed(2);
if (price === null || price === undefined || price === '') return '0.00';
const numericPrice = Number(price);
if (Number.isNaN(numericPrice)) return '0.00';
// if (numericPrice >= 1000 && numericPrice % 100 === 0) {
// return (numericPrice / 100).toFixed(2);
// }
return (numericPrice / 100).toFixed(2);
};
//
const formatDate = (dateStr) => {
if (!dateStr) return '';
const date = new Date(dateStr);
const date = new Date(dateStr.replace(/-/g, '/'));
if (Number.isNaN(date.getTime())) {
return dateStr.split(' ')[0] || dateStr;
}
const year = date.getFullYear();
const month = this.padZero(date.getMonth() + 1);
const day = this.padZero(date.getDate());
return `${year}-${month}-${day}`;
};
//
const getActions = (status) => {
if (status === 'pending') {
const statusNumber = typeof status === 'number' ? status : parseInt(status, 10);
// 1:
if (status === 'pending' || statusNumber === 1) {
return [{ label: '查看详情' }, { label: '立即付款' }];
} else if (status === 'shipped') {
return [{ label: '查看详情' }, { label: '确认收货' }];
} else if (status === 'completed') {
return [{ label: '查看详情' }, { label: '再次购买' }];
}
// 4:
if (status === 'shipped' || statusNumber === 4) {
return [{ label: '查看详情' }, { label: '确认收货' }];
}
// 5:
if (status === 'completed' || statusNumber === 5) {
return [{ label: '查看详情' }, { label: '加入购物车' }];
}
//
return [{ label: '查看详情' }];
};
const getFirstProduct = (order) => {
if (Array.isArray(order.product_list) && order.product_list.length) {
return order.product_list[0];
}
if (Array.isArray(order.productList) && order.productList.length) {
return order.productList[0];
}
if (Array.isArray(order.items) && order.items.length) {
return order.items[0];
}
return order || {};
};
const getFirstValidNumber = (...values) => {
for (let i = 0; i < values.length; i++) {
const value = values[i];
if (value !== undefined && value !== null && value !== '') {
return value;
}
}
return 0;
};
//
this.orders = orderList.map(order => {
const firstItem = getFirstProduct(order);
const orderId = order.order_id || order.orderId || order.order_no || order.no || order.id || '';
// status / order_status / orderStatus / state / order_state
const rawStatus =
order.status !== undefined && order.status !== null
? order.status
: (order.order_status !== undefined && order.order_status !== null
? order.order_status
: (order.orderStatus !== undefined && order.orderStatus !== null
? order.orderStatus
: (order.state !== undefined && order.state !== null
? order.state
: (order.order_state !== undefined && order.order_state !== null
? order.order_state
: ''))));
const statusKey = rawStatus !== '' && rawStatus !== undefined && rawStatus !== null ? String(rawStatus) : '';
const statusInfo = statusMap[statusKey] || statusMap[rawStatus] || {
text: rawStatus === '' || rawStatus === undefined || rawStatus === null ? '未知状态' : String(rawStatus),
class: ''
};
const quantity = firstItem && firstItem.quantity ? firstItem.quantity : (order.quantity || 1);
const skuLabel = firstItem && (firstItem.sku_name || firstItem.spec) ? (firstItem.sku_name || firstItem.spec) : '';
const specParts = [];
if (skuLabel) {
specParts.push(skuLabel);
}
specParts.push(`x${quantity}`);
const amountSource = getFirstValidNumber(
order.payable_amount,
order.total_amount,
order.final_price,
order.total_price,
order.amount
);
return {
no: order.order_no || order.no || order.id,
type: order.order_type || '普通订单',
status: statusInfo.text,
...order,
order_id: orderId,
typeLabel: (firstItem && firstItem.category_name) || order.order_type || '普通订单',
statusText: statusInfo.text,
statusClass: statusInfo.class,
date: formatDate(order.created_at || order.date),
product: firstItem.product_name || firstItem.name || order.product_name || '商品',
spec: firstItem.sku_name || firstItem.spec || `${formatPrice(firstItem.price || order.price)} × ${firstItem.quantity || order.quantity || 1}`,
amount: `¥${formatPrice(order.final_price || order.total_price || order.amount)}`,
displayDate: formatDate(order.created_at || order.date),
productName: (firstItem && (firstItem.product_name || firstItem.name)) || order.product_name || '商品',
productSpec: specParts.join(' · '),
productImage: (firstItem && (firstItem.product_main_image_url || firstItem.image_url)) || '',
amountText: formatPrice(amountSource),
actions: getActions(order.status)
};
});
@ -1558,6 +1645,11 @@ export default {
color: #5a3b00;
}
.order-tag.status.cancelled {
background-color: #c9ced8;
color: #ffffff;
}
.order-date {
margin-left: auto;
font-size: 24rpx;
@ -1581,6 +1673,12 @@ export default {
color: #8c94a3;
}
.order-thumb image {
width: 100%;
height: 100%;
border-radius: 16rpx;
}
.order-info {
display: flex;
flex-direction: column;

View File

@ -16,7 +16,7 @@
</view>
<view class="row amount-row">
<text class="label">应付金额</text>
<text class="amount">¥{{ orderInfo.payableAmount }}</text>
<text class="amount">¥{{ formatPrice(orderInfo.payableAmount) }}</text>
</view>
</view>
@ -47,7 +47,7 @@
<text class="product-sku" v-if="item.skuName">{{ item.skuName }}</text>
<text class="product-desc" v-if="item.desc">{{ item.desc }}</text>
<view class="product-meta">
<text class="product-price">¥{{ item.price }}</text>
<text class="product-price">¥{{ formatPrice(item.price) }}</text>
<text class="product-qty">x{{ item.quantity }}</text>
</view>
</view>
@ -93,19 +93,19 @@
</view>
<view class="row">
<text class="label">商品总额</text>
<text class="value">¥{{ orderInfo.originalAmount }}</text>
<text class="value">¥{{ formatPrice(orderInfo.originalAmount) }}</text>
</view>
<view class="row">
<text class="label">优惠券抵扣</text>
<text class="value">-¥{{ orderInfo.couponAmount }}</text>
<text class="value">-¥{{ formatPrice(orderInfo.couponAmount) }}</text>
</view>
<view class="row" v-if="orderInfo.pointsUsed">
<text class="label">积分抵扣({{ orderInfo.pointsUsed }}积分)</text>
<text class="value">-¥{{ orderInfo.pointsAmount }}</text>
<text class="value">-¥{{ formatPrice(orderInfo.pointsAmount) }}</text>
</view>
<view class="row total-row">
<text class="label">实付金额</text>
<text class="amount">¥{{ orderInfo.payableAmount }}</text>
<text class="amount">¥{{ formatPrice(orderInfo.payableAmount) }}</text>
</view>
</view>
</view>
@ -137,10 +137,10 @@ const STATUS_META = {
};
const SHIPPING_STATUS_META = {
0: '待发货',
1: '已发货',
2: '运输中',
3: '派送中',
1: '待发货',
2: '已发货',
3: '运输中',
// 4: '',
4: '已签收'
};
@ -192,6 +192,19 @@ export default {
this.clearCountdown();
},
methods: {
//
formatPrice(value) {
if (!value && value !== 0) {
return '0.00';
}
//
// if (value < 1000) {
// return parseFloat(value).toFixed(2);
// }
//
value = value / 100;
return value.toFixed(2);
},
async loadOrderDetail(orderId) {
try {
const res = await request(`xcx/order/${orderId}`, 'get');

View File

@ -163,9 +163,9 @@ export default {
return '0.00';
}
//
if (value < 1000) {
return parseFloat(value).toFixed(2);
}
// if (value < 1000) {
// return parseFloat(value).toFixed(2);
// }
//
value = value / 100;
return value.toFixed(2);

View File

@ -19,7 +19,8 @@
<view class="item-price-row">
<view class="item-price">
<text class="price-symbol"></text>
<text class="price-value">{{ formatPrice(item.price) || formatPrice(item.sku_price) }}</text>
<text class="price-value">{{ formatPrice(item.price) || formatPrice(item.sku_price)
}}</text>
</view>
<view class="item-count">
<view class="count-btn" @click="decreaseCount(index)">-</view>
@ -101,13 +102,23 @@ export default {
}
},
onLoad() {
this.loadCartList();
this.getUserIsLogin();
},
onShow() {
//
this.loadCartList();
this.getUserIsLogin();
},
methods: {
async getUserIsLogin() {
const token = await uni.getStorageSync('access_token')
if (token) {
//
this.loadCartList();
} else {
uni.navigateTo({
url: '/pages/login/index'
})
}
},
formatPrice(value) {
if (!value) {
return 0.00;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 558 B

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
static/tabBar/create1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 558 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 552 B

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 552 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 606 B

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 606 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 606 B

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 606 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 808 B

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
static/tabBar/home5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 808 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 822 B

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
static/tabBar/homeAct11.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 822 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 873 B

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
static/tabBar/my6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 873 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 919 B

After

Width:  |  Height:  |  Size: 2.9 KiB

BIN
static/tabBar/myAct7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 919 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB