Initial commit

This commit is contained in:
sjk
2025-11-17 13:32:54 +08:00
commit e788eab6eb
1659 changed files with 171560 additions and 0 deletions

View File

@@ -0,0 +1,807 @@
import { OrderStatus } from '../config';
import { fetchOrders, fetchOrdersCount } from '../../../services/order/orderList';
import { cosThumb } from '../../../utils/util';
import config from '../../../config/index';
Page({
page: {
size: 5,
num: 1,
},
data: {
tabs: [
{ key: -1, text: '全部' },
{ key: 1, text: '未付款', info: '' },
{ key: 2, text: '已付款', info: '' },
{ key: 3, text: '待发货', info: '' },
{ key: 4, text: '已发货', info: '' },
{ key: 5, text: '待收货', info: '' },
{ key: 6, text: '已完成', info: '' },
{ key: 9, text: '已退款', info: '' },
],
curTab: -1,
orderList: [],
listLoading: 0,
pullDownRefreshing: false,
emptyImg: 'https://tdesign.gtimg.com/miniprogram/template/retail/order/empty-order-list.png',
backRefresh: false,
status: -1,
// 合并订单相关数据
mergeMode: false,
selectedOrders: [],
// 空状态配置
emptyStateConfig: {
title: '暂无订单',
description: '快去挑选心仪的商品吧~',
buttonText: '去购物',
showButton: true,
icon: 'shop'
},
},
onLoad(query) {
console.log('[订单列表] 页面加载开始', { query, timestamp: new Date().toISOString() });
let status = parseInt(query.status);
status = this.data.tabs.map((t) => t.key).includes(status) ? status : -1;
console.log('[订单列表] 解析状态参数', {
originalStatus: query.status,
parsedStatus: status,
availableStatuses: this.data.tabs.map((t) => t.key)
});
// 初始化空状态配置
this.updateEmptyStateConfig(status);
this.init(status);
this.pullDownRefresh = this.selectComponent('#wr-pull-down-refresh');
console.log('[订单列表] 页面加载完成', { status });
},
onShow() {
console.log('[订单列表] 页面显示', {
backRefresh: this.data.backRefresh,
timestamp: new Date().toISOString()
});
if (!this.data.backRefresh) return;
this.onRefresh();
this.setData({ backRefresh: false });
},
onReachBottom() {
console.log('[订单列表] 触底加载更多', {
listLoading: this.data.listLoading,
curTab: this.data.curTab,
currentPage: this.page.num
});
if (this.data.listLoading === 0) {
this.getOrderList(this.data.curTab);
}
},
onPageScroll(e) {
this.pullDownRefresh && this.pullDownRefresh.onPageScroll(e);
},
onPullDownRefresh_(e) {
console.log('[订单列表] 下拉刷新开始', {
curTab: this.data.curTab,
timestamp: new Date().toISOString()
});
// 安全检查 e.detail 是否存在
const callback = e && e.detail && e.detail.callback;
this.setData({ pullDownRefreshing: true });
this.refreshList(this.data.curTab)
.then(() => {
console.log('[订单列表] 下拉刷新成功');
this.setData({ pullDownRefreshing: false });
// 确保 callback 存在且是函数
if (callback && typeof callback === 'function') {
callback();
}
})
.catch((err) => {
console.error('[订单列表] 下拉刷新失败', err);
this.setData({ pullDownRefreshing: false });
// 即使出错也要调用 callback 来结束刷新状态
if (callback && typeof callback === 'function') {
callback();
}
Promise.reject(err);
});
},
init(status) {
console.log('[订单列表] 初始化开始', {
inputStatus: status,
currentTab: this.data.curTab
});
status = status !== undefined ? status : this.data.curTab;
this.setData({
status,
curTab: status, // 设置当前tab确保UI切换到对应的标签页
});
console.log('[订单列表] 初始化完成,开始刷新列表', { finalStatus: status });
this.refreshList(status);
},
getOrderList(statusCode = -1, reset = false) {
console.log('[订单列表] 开始获取订单数据', {
statusCode,
reset,
currentPage: this.page.num,
pageSize: this.page.size,
timestamp: new Date().toISOString()
});
this.setData({ listLoading: 1 });
// 使用修复后的API调用方式
const status = statusCode === -1 ? '' : statusCode.toString();
console.log('🔍 [订单列表] API调用参数', {
originalStatusCode: statusCode,
convertedStatus: status,
pageNum: this.page.num,
pageSize: this.page.size
});
return fetchOrders(status, this.page.num, this.page.size)
.then((res) => {
console.log('📋 [订单列表] API响应成功 - 完整数据结构', {
responseData: res,
listLength: res?.orders?.length || 0
});
// 打印完整的原始订单数据
console.log('🔍 [订单列表] 原始订单数据详情', {
totalOrders: res?.orders?.length || 0,
rawOrdersData: res?.orders,
responseStructure: {
hasOrders: !!res?.orders,
hasData: !!res?.data,
hasList: !!res?.list,
responseKeys: res ? Object.keys(res) : []
}
});
// 逐个打印每个订单的详细信息
if (res?.orders && Array.isArray(res.orders)) {
res.orders.forEach((order, index) => {
console.log(`📦 [订单${index + 1}] 原始订单数据:`, {
orderIndex: index,
orderId: order.orderId || order.id,
orderNo: order.orderNo || order.order_no,
orderStatus: order.orderStatus || order.status,
paymentAmount: order.paymentAmount || order.pay_amount,
orderItemVOs: order.orderItemVOs,
items: order.items,
order_items: order.order_items,
rawOrderData: order,
orderKeys: Object.keys(order)
});
// 打印订单商品详情
const orderItems = order.orderItemVOs || order.order_items || order.items || [];
if (orderItems.length > 0) {
console.log(`🛍️ [订单${index + 1}] 商品列表详情:`, {
itemCount: orderItems.length,
items: orderItems.map((item, itemIndex) => ({
itemIndex,
id: item.id,
goodsName: item.goodsName,
product_name: item.product_name,
productName: item.productName,
title: item.title,
price: item.price,
actualPrice: item.actualPrice,
unit_price: item.unit_price,
quantity: item.quantity,
buyQuantity: item.buyQuantity,
num: item.num,
specifications: item.specifications,
specs: item.specs,
specification: item.specification,
product_image: item.product_image,
goodsPictureUrl: item.goodsPictureUrl,
productImage: item.productImage,
thumb: item.thumb,
rawItemData: item,
itemKeys: Object.keys(item)
}))
});
} else {
console.log(`⚠️ [订单${index + 1}] 无商品数据或商品列表为空`);
}
});
}
this.page.num++;
let orderList = [];
// 适配新的API响应格式
if (res && res.orders) {
orderList = (res.orders || []).map((order) => {
// 处理商品列表数据
const goodsList = (order.orderItemVOs || order.order_items || order.items || []).map((item) => {
// 尝试从多个可能的来源获取图片
const finalThumb = item.product_image ||
item.goodsPictureUrl ||
item.productImage ||
item.thumb ||
item.image ||
item.goodsPictureURL ||
item.picture ||
item.pic ||
item.img ||
(item.product && item.product.main_image) ||
(item.product && item.product.images && item.product.images[0]) ||
(item.sku && item.sku.image);
// 调试spec_info数据
console.log(`🔍 [商品规格] 商品${item.goodsName || item.product_name}的规格信息:`, {
spec_info: item.spec_info,
specInfo: item.specInfo,
specText: item.specText,
specifications: item.specifications,
specs: item.specs,
specification: item.specification
});
const goodsItem = {
id: item.id || item.product_id,
title: item.goodsName || item.product_name || item.productName || item.title,
thumb: finalThumb,
price: ((item.price || item.actualPrice || item.unit_price || 0) / 100).toFixed(2),
originPrice: ((item.original_price || item.originPrice || 0) / 100).toFixed(2),
num: item.quantity || item.buyQuantity || item.num || 1,
// 优先使用服务层处理好的specText然后是其他规格信息
specs: item.specText ||
(Array.isArray(item.specifications)
? item.specifications.map(spec => `${spec.specTitle}:${spec.specValue}`).join(' ')
: (item.specs || item.specification || '')),
// 保留原始的spec_info数据供调试使用
spec_info: item.spec_info,
specInfo: item.specInfo,
skuId: item.skuId || item.sku_id,
productId: item.spuId || item.productId || item.product_id,
hideKey: {
thumb: false,
title: false,
desc: false,
price: false,
num: false,
originPrice: false,
specs: false
}
};
console.log(`✅ [商品规格] 最终商品数据:`, {
title: goodsItem.title,
specs: goodsItem.specs,
spec_info: goodsItem.spec_info,
specInfo: goodsItem.specInfo
});
return goodsItem;
});
const orderItem = {
id: order.orderId || order.id,
orderNo: order.orderNo || order.order_no,
parentOrderNo: order.parentOrderNo,
storeId: order.storeId || order.store_id,
storeName: order.storeName || '默认店铺',
status: order.orderStatus || order.status,
statusDesc: order.statusName || this.getOrderStatusName(order.orderStatus || order.status),
amount: order.paymentAmount || order.pay_amount || order.payAmount,
totalAmount: order.totalAmount || order.total_amount,
logisticsNo: order.logisticsNo || order.express_no,
createTime: order.createdAt || order.created_at,
goodsList: goodsList,
buttons: order.buttons || this.getOrderButtons(order.orderStatus || order.status),
groupInfoVo: order.groupInfoVo,
freightFee: order.freightFee || order.shipping_fee || 0,
receiverName: order.receiverName || order.receiver_name,
receiverAddress: order.receiverAddress || order.receiver_address,
// 合并相关属性
canMerge: (order.orderStatus || order.status) === 0, // 只有待支付订单可以合并
selected: false,
};
return orderItem;
});
}
return new Promise((resolve) => {
if (reset) {
this.setData({ orderList: [] }, () => resolve());
} else resolve();
}).then(() => {
const newList = reset ? orderList : this.data.orderList.concat(orderList);
console.log('✅ [订单列表] 数据处理完成', {
reset,
newOrderCount: orderList.length,
totalOrderCount: newList.length,
listLoading: orderList.length > 0 ? 0 : 2
});
// 打印处理后的订单数据详情
console.log('🎯 [订单列表] 处理后的订单数据详情', {
processedOrderCount: orderList.length,
processedOrders: orderList.map((order, index) => ({
index,
id: order.id,
orderNo: order.orderNo,
status: order.status,
statusDesc: order.statusDesc,
amount: order.amount,
totalAmount: order.totalAmount,
goodsCount: order.goodsList?.length || 0,
goodsList: order.goodsList?.map((goods, goodsIndex) => ({
goodsIndex,
id: goods.id,
title: goods.title,
price: goods.price,
num: goods.num,
specs: goods.specs,
thumb: goods.thumb,
skuId: goods.skuId,
productId: goods.productId
})),
receiverName: order.receiverName,
receiverAddress: order.receiverAddress,
createTime: order.createTime,
canMerge: order.canMerge,
buttons: order.buttons
}))
});
// 打印最终的订单列表状态
console.log('📊 [订单列表] 最终状态汇总', {
totalOrdersInList: newList.length,
ordersByStatus: newList.reduce((acc, order) => {
const status = order.status;
acc[status] = (acc[status] || 0) + 1;
return acc;
}, {}),
ordersWithGoods: newList.filter(order => order.goodsList && order.goodsList.length > 0).length,
ordersWithoutGoods: newList.filter(order => !order.goodsList || order.goodsList.length === 0).length
});
// 设置正确的加载状态
let loadingStatus = 0; // 默认为正常状态
if (reset && newList.length === 0) {
// 首次加载且无数据,显示空状态
loadingStatus = 2;
console.log('🔍 [订单列表] 首次加载无数据,设置空状态', {
reset,
orderListLength: orderList.length,
newListLength: newList.length,
loadingStatus
});
} else if (!reset && newList.length === this.data.orderList.length) {
// 加载更多但无新数据,显示"没有更多了"
loadingStatus = 2;
console.log('🔍 [订单列表] 加载更多无新数据', {
reset,
orderListLength: orderList.length,
newListLength: newList.length,
currentOrderListLength: this.data.orderList.length,
loadingStatus
});
} else {
console.log('🔍 [订单列表] 正常数据状态', {
reset,
orderListLength: orderList.length,
newListLength: newList.length,
loadingStatus
});
}
this.setData({
orderList: newList,
listLoading: loadingStatus,
});
console.log('[订单列表] UI更新完成', {
finalOrderListLength: newList.length,
listLoading: loadingStatus,
listIsEmpty: !newList.length,
shouldShowEmpty: !newList.length && (loadingStatus === 0 || loadingStatus === 2)
});
});
})
.catch((err) => {
console.error('[订单列表] 获取订单列表失败', {
error: err,
statusCode,
timestamp: new Date().toISOString()
});
this.setData({ listLoading: 3 });
return Promise.reject(err);
});
},
// 获取订单状态名称
getOrderStatusName(status) {
const statusMap = {
1: '未付款',
2: '待发货', // 统一为待发货
3: '待发货', // 统一为待发货
4: '已发货',
5: '待收货',
6: '已完成',
7: '已取消',
8: '退货中',
9: '已退款'
};
return statusMap[status] || '未知状态';
},
// 获取订单操作按钮
getOrderButtons(status) {
switch (status) {
case 0:
return [{ name: '去支付', type: 2 }, { name: '取消订单', type: 1 }];
case 1:
return [{ name: '查看详情', type: 'detail' }];
case 2:
return [{ name: '确认收货', type: 4 }, { name: '查看物流', type: 'logistics' }];
case 3:
return [{ name: '查看详情', type: 'detail' }, { name: '再次购买', type: 9 }];
case 4:
return [{ name: '查看详情', type: 'detail' }, { name: '再次购买', type: 9 }];
case 9:
return [{ name: '查看退款', type: 10 }, { name: '再次购买', type: 9 }];
default:
return [{ name: '查看详情', type: 'detail' }];
}
},
onReTryLoad() {
this.getOrderList(this.data.curTab);
},
onTabChange(e) {
const { value } = e.detail;
console.log('[订单列表] 标签切换', {
fromTab: this.data.curTab,
toTab: value,
timestamp: new Date().toISOString()
});
this.setData({
status: value,
});
this.updateEmptyStateConfig(value);
this.refreshList(value);
},
// 根据订单状态更新空状态配置
updateEmptyStateConfig(status) {
let config = {
title: '暂无订单',
description: '快去挑选心仪的商品吧~',
buttonText: '去购物',
showButton: true,
icon: 'shop'
};
switch (status) {
case -1: // 全部
config = {
title: '暂无订单',
description: '快去挑选心仪的商品吧~',
buttonText: '去购物',
showButton: true,
icon: 'shop'
};
break;
case 1: // 未付款
config = {
title: '暂无待付款订单',
description: '您当前没有需要付款的订单',
buttonText: '去购物',
showButton: true,
icon: 'wallet'
};
break;
case 2: // 已付款
config = {
title: '暂无已付款订单',
description: '您当前没有已付款的订单',
buttonText: '去购物',
showButton: true,
icon: 'check-circle'
};
break;
case 3: // 待发货
config = {
title: '暂无待发货订单',
description: '您当前没有等待发货的订单',
buttonText: '去购物',
showButton: true,
icon: 'package'
};
break;
case 4: // 已发货
config = {
title: '暂无已发货订单',
description: '您当前没有已发货的订单',
buttonText: '去购物',
showButton: true,
icon: 'delivery'
};
break;
case 5: // 待收货
config = {
title: '暂无待收货订单',
description: '您当前没有等待收货的订单',
buttonText: '去购物',
showButton: true,
icon: 'location'
};
break;
case 6: // 已完成
config = {
title: '暂无已完成订单',
description: '您还没有完成的订单',
buttonText: '去购物',
showButton: true,
icon: 'check-circle-filled'
};
break;
case 9: // 已退款
config = {
title: '暂无退款订单',
description: '您当前没有退款记录',
buttonText: '去购物',
showButton: true,
icon: 'money-circle'
};
break;
}
this.setData({
emptyStateConfig: config
});
},
// 处理空状态按钮点击
onEmptyButtonTap() {
// 跳转到首页
wx.switchTab({
url: '/pages/home/home'
});
},
getOrdersCount() {
return fetchOrdersCount().then((res) => {
const tabsCount = res.data || [];
const { tabs } = this.data;
tabs.forEach((tab) => {
const tabCount = tabsCount.find((c) => c.tabType === tab.key);
if (tabCount) {
tab.info = tabCount.orderNum;
}
});
this.setData({ tabs });
});
},
refreshList(status = -1) {
console.log('[订单列表] 刷新列表开始', {
status,
timestamp: new Date().toISOString()
});
this.page = {
size: this.page.size,
num: 1,
};
this.setData({
curTab: status,
orderList: [],
listLoading: 1 // 设置为加载中状态
});
return Promise.all([this.getOrderList(status, true), this.getOrdersCount()]);
},
onRefresh() {
console.log('[订单列表] 手动刷新', {
curTab: this.data.curTab
});
this.refreshList(this.data.curTab);
},
onOrderCardTap(e) {
const { order } = e.currentTarget.dataset;
console.log('[订单列表] 订单卡片点击', {
orderNo: order?.orderNo,
mergeMode: this.data.mergeMode,
timestamp: new Date().toISOString()
});
// 合并模式下不跳转详情页
if (this.data.mergeMode) {
console.log('[订单列表] 合并模式下,不跳转详情页');
return;
}
console.log('[订单列表] 跳转到订单详情页', {
orderNo: order.orderNo
});
wx.navigateTo({
url: `/pages/order/order-detail/index?orderNo=${order.orderNo}`,
});
},
// 进入合并模式
enterMergeMode() {
this.setData({
mergeMode: true,
selectedOrders: []
});
},
// 退出合并模式
exitMergeMode() {
// 清除所有选择状态
const orderList = this.data.orderList.map(order => ({
...order,
selected: false
}));
this.setData({
mergeMode: false,
selectedOrders: [],
orderList
});
},
// 订单选择/取消选择
onOrderSelect(e) {
const { orderIndex } = e.currentTarget.dataset;
const { value } = e.detail;
const orderList = [...this.data.orderList];
const order = orderList[orderIndex];
order.selected = value;
// 更新选中的订单列表
let selectedOrders = [...this.data.selectedOrders];
if (value) {
selectedOrders.push(order.id);
} else {
selectedOrders = selectedOrders.filter(id => id !== order.id);
}
this.setData({
orderList,
selectedOrders
});
},
// 确认合并订单
confirmMergeOrders() {
const { selectedOrders } = this.data;
if (selectedOrders.length < 2) {
wx.showToast({
title: '请至少选择2个订单',
icon: 'none'
});
return;
}
// 验证选中的订单是否可以合并
const selectedOrderList = this.data.orderList.filter(order =>
selectedOrders.includes(order.id)
);
// 检查是否都是同一个收货地址
const firstAddress = selectedOrderList[0].receiverAddress;
const hasDifferentAddress = selectedOrderList.some(order =>
order.receiverAddress !== firstAddress
);
if (hasDifferentAddress) {
wx.showToast({
title: '只能合并相同收货地址的订单',
icon: 'none'
});
return;
}
wx.showModal({
title: '确认合并订单',
content: `确定要合并这${selectedOrders.length}个订单吗?合并后将生成一个新订单。`,
success: (res) => {
if (res.confirm) {
this.mergeOrders(selectedOrders);
}
}
});
},
// 执行订单合并
mergeOrders(orderIds) {
wx.showLoading({
title: '合并中...'
});
// 调用合并订单API
wx.request({
url: `${config.apiBase}/orders/merge`,
method: 'POST',
header: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${wx.getStorageSync('token')}`
},
data: {
orderIds: orderIds
},
success: (res) => {
wx.hideLoading();
if (res.statusCode === 200 && res.data.code === 0) {
wx.showToast({
title: '合并成功',
icon: 'success'
});
// 退出合并模式并刷新列表
this.exitMergeMode();
this.refreshList(this.data.curTab);
} else {
wx.showToast({
title: res.data.message || '合并失败',
icon: 'none'
});
}
},
fail: (err) => {
wx.hideLoading();
console.error('合并订单失败:', err);
wx.showToast({
title: '网络错误,请重试',
icon: 'none'
});
}
});
},
// 分享功能
onShareAppMessage() {
const { curTab } = this.data;
const tabText = this.data.tabs.find(t => t.key === curTab)?.text || '全部';
return {
title: `我的订单 - ${tabText}订单`,
path: `/pages/order/order-list/index?status=${curTab}`
};
},
// 分享到朋友圈
onShareTimeline() {
return {
title: '我的订单 - 查看我的购物记录'
};
}
});

View File

@@ -0,0 +1,16 @@
{
"navigationBarTitleText": "我的订单",
"usingComponents": {
"t-tabs": "tdesign-miniprogram/tabs/tabs",
"t-tab-panel": "tdesign-miniprogram/tab-panel/tab-panel",
"t-empty": "tdesign-miniprogram/empty/empty",
"t-toast": "tdesign-miniprogram/toast/toast",
"t-dialog": "tdesign-miniprogram/dialog/dialog",
"t-pull-down-refresh": "tdesign-miniprogram/pull-down-refresh/pull-down-refresh",
"load-more": "/components/load-more/index",
"order-button-bar": "../components/order-button-bar/index",
"price": "/components/price/index",
"order-card": "../components/order-card/index",
"specs-goods-card": "../components/specs-goods-card/index"
}
}

View File

@@ -0,0 +1,154 @@
<view class="page-container">
<view class="tab-bar">
<view class="tab-bar__placeholder" />
<t-tabs
t-class="tab-bar__inner"
t-class-active="tab-bar__active"
t-class-track="t-tabs-track"
bind:change="onTabChange"
value="{{status}}"
style="position: fixed; top: 0; left: 0; z-index: 100"
>
<t-tab-panel
wx:for="{{tabs}}"
wx:for-index="index"
wx:for-item="item"
wx:key="index"
label="{{item.text}}"
value="{{item.key}}"
/>
</t-tabs>
</view>
<!-- 合并订单工具栏 -->
<view class="merge-toolbar" wx:if="{{status === 0}}">
<view class="merge-actions">
<t-button
wx:if="{{!mergeMode}}"
size="small"
variant="outline"
bind:tap="enterMergeMode"
>
合并订单
</t-button>
<view wx:else class="merge-mode-actions">
<text class="selected-count">已选择 {{selectedOrders.length}} 个订单</text>
<t-button
size="small"
variant="outline"
bind:tap="exitMergeMode"
>
取消
</t-button>
<t-button
size="small"
theme="primary"
bind:tap="confirmMergeOrders"
disabled="{{selectedOrders.length < 2}}"
>
确认合并
</t-button>
</view>
</view>
</view>
<t-pull-down-refresh
id="pull-down-refresh"
normal-bar-height="{{200}}"
max-bar-height="{{272}}"
refreshTimeout="{{3000}}"
background="#f5f5f5"
use-loading-slot
loading-size="60rpx"
bindrefresh="onPullDownRefresh_"
t-class-indicator="t-class-indicator"
>
<order-card
wx:for="{{orderList}}"
wx:key="id"
wx:for-item="order"
wx:for-index="oIndex"
order="{{order}}"
defaultShowNum="{{3}}"
data-order="{{order}}"
bindcardtap="onOrderCardTap"
useLogoSlot
class="{{mergeMode ? 'merge-mode-card' : ''}}"
>
<view slot="top-left" class="order-number">
<!-- 合并模式下的选择框 -->
<view wx:if="{{mergeMode && order.canMerge}}" class="order-checkbox">
<t-checkbox
value="{{order.selected}}"
bind:change="onOrderSelect"
data-order-id="{{order.id}}"
data-order-index="{{oIndex}}"
/>
</view>
<text decode>订单号&nbsp;</text>
{{order.orderNo}}
<!-- 不可合并订单的提示 -->
<text wx:if="{{mergeMode && !order.canMerge}}" class="cannot-merge-tip">(不可合并)</text>
</view>
<specs-goods-card
wx:for="{{order.goodsList}}"
wx:key="id"
wx:for-item="goods"
wx:for-index="gIndex"
data="{{goods}}"
no-top-line="{{gIndex === 0}}"
/>
<view slot="more">
<view class="price-total">
<text>总价</text>
<price fill price="{{order.totalAmount + ''}}" />
<text>,运费</text>
<price fill price="{{order.freightFee + ''}}" />
<text decode>&nbsp;</text>
<text class="bold-price" decode="{{true}}">实付&nbsp;</text>
<price fill class="real-pay" price="{{order.amount + ''}}" decimalSmaller />
</view>
<!-- 订单按钮栏 -->
<order-button-bar order="{{order}}" bindrefresh="onRefresh" data-order="{{order}}" />
</view>
</order-card>
<!-- 列表加载中/已全部加载 -->
<load-more
wx:if="{{!pullDownRefreshing}}"
list-is-empty="{{!orderList.length}}"
status="{{listLoading}}"
bindretry="onReTryLoad"
>
<!-- 空态 -->
<view slot="empty" class="empty-wrapper">
<view class="empty-state">
<!-- 空状态图标 -->
<view class="empty-icon">
<t-icon name="{{emptyStateConfig.icon}}" size="120rpx" color="#E6E6E6" />
</view>
<!-- 空状态标题 -->
<view class="empty-title">{{emptyStateConfig.title}}</view>
<!-- 空状态描述 -->
<view class="empty-description">{{emptyStateConfig.description}}</view>
<!-- 操作按钮 -->
<view class="empty-actions" wx:if="{{emptyStateConfig.showButton}}">
<t-button
theme="primary"
size="medium"
bind:tap="onEmptyButtonTap"
t-class="empty-button"
>
{{emptyStateConfig.buttonText}}
</t-button>
</view>
</view>
</view>
</load-more>
</t-pull-down-refresh>
</view>
<t-toast id="t-toast" />
<t-dialog id="t-dialog" />

View File

@@ -0,0 +1,222 @@
:host {
background-color: #f5f5f5;
}
.page-container .tab-bar__placeholder,
.page-container .tab-bar__inner {
height: 88rpx;
line-height: 88rpx;
background: #fff;
}
.page-container .tab-bar__inner {
font-size: 26rpx;
color: #333333;
position: fixed;
width: 100vw;
top: 0;
left: 0;
}
.page-container .tab-bar__inner.order-nav .order-nav-item .bottom-line {
bottom: 12rpx;
}
.tab-bar__inner .t-tabs-is-active {
color: #fa4126 !important;
}
.tab-bar__inner .t-tabs-track {
background: #fa4126 !important;
}
.page-container .tab-bar__active {
font-size: 28rpx;
}
.page-container .specs-popup .bottom-btn {
color: #fa4126;
color: var(--color-primary, #fa4126);
}
.page-container .specs-popup .bottom-btn::after {
border-color: #fa4126;
border-color: var(--color-primary, #fa4126);
}
.dialog .dialog__button-confirm {
color: #fa4126;
color: var(--color-primary, #fa4126);
}
.list-loading {
height: 100rpx;
}
.empty-wrapper {
height: calc(100vh - 88rpx);
display: flex;
align-items: center;
justify-content: center;
}
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 80rpx 40rpx;
text-align: center;
}
.empty-icon {
margin-bottom: 40rpx;
opacity: 0.6;
}
.empty-title {
font-size: 32rpx;
font-weight: 500;
color: #333333;
margin-bottom: 16rpx;
line-height: 1.4;
}
.empty-description {
font-size: 28rpx;
color: #999999;
margin-bottom: 60rpx;
line-height: 1.5;
max-width: 400rpx;
}
.empty-actions {
width: 100%;
display: flex;
justify-content: center;
}
.empty-button {
min-width: 200rpx !important;
border-radius: 50rpx !important;
font-size: 28rpx !important;
}
.btn-bar {
margin-top: 20rpx;
}
.load-more {
margin: 0 24rpx;
}
wr-order-goods-card:not(:first-child) .wr-goods-card {
margin-top: 40rpx;
}
.price-total {
font-size: 24rpx;
line-height: 32rpx;
color: #999999;
padding-top: 10rpx;
width: 100%;
display: flex;
align-items: baseline;
justify-content: flex-end;
}
.price-total .bold-price {
color: #333333;
font-size: 28rpx;
line-height: 40rpx;
color: #333333;
}
.price-total .real-pay {
font-size: 36rpx;
line-height: 48rpx;
color: #fa4126;
font-weight: bold;
}
.t-tabs.t-tabs--top .t-tabs-scroll {
border: none !important;
}
.t-empty-text {
font-size: 28rpx;
color: #999;
}
.page-container .order-number {
color: #666666;
font-size: 28rpx;
}
.t-class-indicator {
color: #b9b9b9 !important;
}
.tab-bar .tab-bar__active {
color: #333333 !important;
}
/* 合并订单相关样式 */
.merge-toolbar {
background: #fff;
padding: 20rpx 24rpx;
border-bottom: 1rpx solid #f0f0f0;
position: sticky;
top: 88rpx;
z-index: 99;
}
.merge-actions {
display: flex;
align-items: center;
justify-content: flex-end;
}
.merge-mode-actions {
display: flex;
align-items: center;
gap: 20rpx;
width: 100%;
justify-content: space-between;
}
.selected-count {
font-size: 28rpx;
color: #666;
}
.order-checkbox {
display: inline-block;
margin-right: 16rpx;
vertical-align: middle;
}
.order-number {
display: flex;
align-items: center;
flex-wrap: wrap;
}
.cannot-merge-tip {
font-size: 24rpx;
color: #999;
margin-left: 16rpx;
}
.merge-mode-card {
position: relative;
}
.merge-mode-card::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
border: 2rpx solid transparent;
border-radius: 16rpx;
pointer-events: none;
transition: border-color 0.3s ease;
}
.merge-mode-card.selected::before {
border-color: #fa4126;
}
.tab-bar .t-tabs-track {
background: #333333 !important;
}
.t-button {
--td-button-default-color: #000;
--td-button-primary-text-color: #fa4126;
}