diff --git a/backend/app/api/controller/v1/order/CenterOrderController.php b/backend/app/api/controller/v1/order/CenterOrderController.php
index 7a8bf2582..de137046d 100644
--- a/backend/app/api/controller/v1/order/CenterOrderController.php
+++ b/backend/app/api/controller/v1/order/CenterOrderController.php
@@ -64,10 +64,15 @@ class CenterOrderController
'status_code' => $this->mapSemanticStatus($semanticStatus),
'product_type' => request()->param('product_type', ''),
];
- // 待收货/待使用:均为 STATUS_PROCESSING,需按产品类型细分
- // 待收货=实物业态(normal),待使用=非实物业态(virtual/cardkey/hotel/ticket 等)
+ // 待发货/待收货/待使用:均为 STATUS_PROCESSING,需按产品类型与发货状态细分
+ // 待发货=实物业态(normal)未发货;待收货=实物业态已发货未收货;待使用=非实物业态(virtual/cardkey/hotel/ticket 等)
if ($semanticStatus === 'pending_delivery') {
$where['product_type'] = 'normal';
+ $where['delivery_time'] = 0;
+ } elseif ($semanticStatus === 'pending_receipt') {
+ $where['product_type'] = 'normal';
+ $where['delivery_time_ne'] = 0;
+ $where['take_time'] = 0;
} elseif ($semanticStatus === 'pending_use') {
$where['product_type_ne'] = 'normal';
}
@@ -79,8 +84,8 @@ class CenterOrderController
/**
* 语义化状态映射到实际 status_code
* 前端传入语义化状态标识,后端映射到中台 status_code,支持逗号分隔多状态(如售后=refunding,refunded)
- * 待收货(pending_delivery)/待使用(pending_use) 均映射到 STATUS_PROCESSING,
- * 由 list 方法追加 product_type 条件细分,此处不承担产品类型过滤
+ * 待发货(pending_delivery)/待收货(pending_receipt)/待使用(pending_use) 均映射到 STATUS_PROCESSING,
+ * 发货状态与产品类型过滤由 list 方法处理,此处不承担
* @param string $status 语义化状态标识
* @return string 返回 status_code,空表示不筛选(全部)
*/
@@ -89,7 +94,7 @@ class CenterOrderController
$map = [
'pending_payment' => OrderCenter::STATUS_PENDING_PAYMENT,
'pending_receipt' => OrderCenter::STATUS_PROCESSING,
- // 待收货/待使用:均为进行中状态,产品类型过滤交由 list 方法处理
+ // 待发货/待收货/待使用:均为进行中状态,产品类型与发货状态过滤交由 list 方法处理
'pending_delivery' => OrderCenter::STATUS_PROCESSING,
'pending_use' => OrderCenter::STATUS_PROCESSING,
// 待评价:按已完成状态筛选(与前端原 getStatusMap 逻辑一致)
diff --git a/backend/app/services/order/OrderCenterServices.php b/backend/app/services/order/OrderCenterServices.php
index 326ea7540..b507cdcea 100644
--- a/backend/app/services/order/OrderCenterServices.php
+++ b/backend/app/services/order/OrderCenterServices.php
@@ -180,6 +180,8 @@ class OrderCenterServices extends BaseService implements OrderCenterSyncInterfac
public function createRecord(array $data): bool
{
$extraInfo = $data['extra_info'] ?? [];
+ // 新订单进入统计(全部/待支付计数),清除统计缓存
+ $this->clearStatCache();
$insert = [
'order_no' => $data['order_no'], //
diff --git a/backend/app/services/order/OrderCenterUserServices.php b/backend/app/services/order/OrderCenterUserServices.php
index 4b28efb23..0fd32aa4e 100644
--- a/backend/app/services/order/OrderCenterUserServices.php
+++ b/backend/app/services/order/OrderCenterUserServices.php
@@ -73,6 +73,16 @@ class OrderCenterUserServices extends OrderCenterServices
if (!empty($where['product_type_ne'])) {
$searchWhere[] = ['product_type', '<>', $where['product_type_ne']];
}
+ // 发货状态筛选(delivery_time int 默认 0,0=未发货):待发货=未发货,待收货=已发货未收货
+ if (isset($where['delivery_time'])) {
+ $searchWhere[] = ['delivery_time', '=', (int)$where['delivery_time']];
+ }
+ if (array_key_exists('delivery_time_ne', $where)) {
+ $searchWhere[] = ['delivery_time', '<>', (int)$where['delivery_time_ne']];
+ }
+ if (isset($where['take_time'])) {
+ $searchWhere[] = ['take_time', '=', (int)$where['take_time']];
+ }
$list = $this->dao->selectList(
$searchWhere,
@@ -309,8 +319,10 @@ class OrderCenterUserServices extends OrderCenterServices
*/
public function getUserStatistics(int $uid): array
{
- // 缓存 key 带 v2 版本,统计结构变更后强制失效旧缓存
- $cacheKey = 'order_center:user_stat:v2:' . $uid;
+ // 缓存 key 带结构版本 v3 + 失效版本号:订单状态流转经 syncStatus/updateRecord 递增
+ // order_center:stat:ver 强制换 key 刷新(结构变更升级 v3),旧 key 靠自身 TTL 自然过期
+ $ver = (int) app()->cache->get('order_center:stat:ver');
+ $cacheKey = 'order_center:user_stat:v3:' . $uid . ':' . $ver;
return app()->cache->remember($cacheKey, function () use ($uid) {
$baseWhere = [
@@ -339,7 +351,8 @@ class OrderCenterUserServices extends OrderCenterServices
];
}
- // STATUS_PROCESSING 按产品类型拆分:normal=待收货(实物),其他=待使用(虚拟/卡密/酒店/门票等)
+ // STATUS_PROCESSING 按产品类型拆分:非实物业态=待使用(虚拟/卡密/酒店/门票等)
+ // 实物(normal)进行中再按发货状态细分为待发货/待收货,与订单列表 tab 及角标口径一致
$processingByType = $this->dao->getDb()
->where($baseWhere)
->where('status_code', OrderCenter::STATUS_PROCESSING)
@@ -347,8 +360,6 @@ class OrderCenterUserServices extends OrderCenterServices
->group('product_type')
->select()
->toArray();
- $deliveryCount = 0;
- $deliveryAmount = '0.00';
$useCount = 0;
$useAmount = '0.00';
foreach ($processingByType as $row) {
@@ -360,23 +371,41 @@ class OrderCenterUserServices extends OrderCenterServices
} catch (\Throwable $e) {
$isDelivery = false;
}
- if ($isDelivery) {
- $deliveryCount += (int) ($row['count'] ?? 0);
- $deliveryAmount = bcadd($deliveryAmount, (string) ($row['amount'] ?? '0.00'), 2);
- } else {
+ if (!$isDelivery) {
$useCount += (int) ($row['count'] ?? 0);
$useAmount = bcadd($useAmount, (string) ($row['amount'] ?? '0.00'), 2);
}
}
+ // 实物进行中按发货状态拆分:待发货=未发货(delivery_time=0),待收货=已发货未收货
+ $pendingShip = $this->dao->getDb()
+ ->where($baseWhere)
+ ->where('status_code', OrderCenter::STATUS_PROCESSING)
+ ->where('product_type', 'normal')
+ ->where('delivery_time', 0)
+ ->field('COUNT(*) as count, SUM(pay_price) as amount')
+ ->find();
+ $pendingReceipt = $this->dao->getDb()
+ ->where($baseWhere)
+ ->where('status_code', OrderCenter::STATUS_PROCESSING)
+ ->where('product_type', 'normal')
+ ->where('delivery_time', '<>', 0)
+ ->where('take_time', 0)
+ ->field('COUNT(*) as count, SUM(pay_price) as amount')
+ ->find();
+
$grouped = [
'pending_payment' => [
'count' => $statusCounts[OrderCenter::STATUS_PENDING_PAYMENT]['count'] ?? 0,
'amount' => $statusCounts[OrderCenter::STATUS_PENDING_PAYMENT]['amount'] ?? '0.00',
],
'pending_delivery' => [
- 'count' => $deliveryCount,
- 'amount' => $deliveryAmount,
+ 'count' => (int) ($pendingShip['count'] ?? 0),
+ 'amount' => (string) ($pendingShip['amount'] ?? '0.00'),
+ ],
+ 'pending_receipt' => [
+ 'count' => (int) ($pendingReceipt['count'] ?? 0),
+ 'amount' => (string) ($pendingReceipt['amount'] ?? '0.00'),
],
'pending_use' => [
'count' => $useCount,
diff --git a/frontend/uni-app/src/dynamic-pages/engines/OrderListEngine.vue b/frontend/uni-app/src/dynamic-pages/engines/OrderListEngine.vue
index 1675c1eda..3c71bb88b 100644
--- a/frontend/uni-app/src/dynamic-pages/engines/OrderListEngine.vue
+++ b/frontend/uni-app/src/dynamic-pages/engines/OrderListEngine.vue
@@ -26,12 +26,12 @@
{{ orderData.grouped && orderData.grouped.pending_payment && orderData.grouped.pending_payment.count || 0 }}
- {{ $t(`待收货`) }}
+ {{ $t(`待发货`) }}
{{ orderData.grouped && orderData.grouped.pending_delivery && orderData.grouped.pending_delivery.count || 0 }}
-
- {{ $t(`待使用`) }}
- {{ orderData.grouped && orderData.grouped.pending_use && orderData.grouped.pending_use.count || 0 }}
+
+ {{ $t(`待收货`) }}
+ {{ orderData.grouped && orderData.grouped.pending_receipt && orderData.grouped.pending_receipt.count || 0 }}
{{ $t(`待评价`) }}
diff --git a/frontend/uni-app/src/pages/goods/order_list/index.vue b/frontend/uni-app/src/pages/goods/order_list/index.vue
index 3c042c5e8..1d995ef28 100644
--- a/frontend/uni-app/src/pages/goods/order_list/index.vue
+++ b/frontend/uni-app/src/pages/goods/order_list/index.vue
@@ -9,18 +9,18 @@ import OrderListEngine from '@/dynamic-pages/engines/OrderListEngine.vue';
// 旧版数字 status → 新版语义化 status 映射表
// 旧:0待付款 / 1待发货 / 2待收货 / 3待评价 / 9全部
-// 新:pending_payment 待支付 / pending_delivery 待收货(实物) / pending_use 待使用(非实物) / pending_comment 待评价 / after_sale 退款售后 / all 全部
-// 旧数字 1/2 均为实物语义(待发货/待收货),统一映射到 pending_delivery
+// 新:pending_payment 待支付 / pending_delivery 待发货(实物未发货) / pending_receipt 待收货(已发货未收货)
+// / pending_use 待使用(非实物) / pending_comment 待评价 / after_sale 退款售后 / all 全部
const STATUS_MAP = {
'0': 'pending_payment',
'1': 'pending_delivery',
- '2': 'pending_delivery',
+ '2': 'pending_receipt',
'3': 'pending_comment',
'9': 'all',
};
// 新版语义化状态白名单,命中则直接透传
-const SEMANTIC_STATUS = ['all', 'pending_payment', 'pending_delivery', 'pending_use', 'pending_comment', 'after_sale'];
+const SEMANTIC_STATUS = ['all', 'pending_payment', 'pending_delivery', 'pending_receipt', 'pending_use', 'pending_comment', 'after_sale'];
const statusFilter = ref('all');
const engine = ref(null);