diff --git a/backend/app/services/order/OrderCenterServices.php b/backend/app/services/order/OrderCenterServices.php index 252e47367..211c5c083 100644 --- a/backend/app/services/order/OrderCenterServices.php +++ b/backend/app/services/order/OrderCenterServices.php @@ -20,6 +20,7 @@ use crmeb\trade\order\type\OrderCenterSyncInterface; use crmeb\trade\mode\TradeModeRegistry; use crmeb\trade\product\ProductTypeRegistry; use crmeb\utils\SnowflakeIdGenerator; +use crmeb\exceptions\ApiException; use app\dao\driver\pay\PayChannelDao; use app\dao\user\UserBillDao; use think\facade\Log; @@ -2247,9 +2248,9 @@ class OrderCenterServices extends BaseService implements OrderCenterSyncInterfac { $searchWhere = []; - // 通用:是否删除筛选,默认不查已删除 + // 通用:是否后台删除筛选,默认不查已删除;用户删除(is_del)不影响后台可见性 $isDeleted = $where['is_deleted'] ?? false; - $searchWhere[] = ['is_del', '=', $isDeleted ? 1 : 0]; + $searchWhere[] = ['is_system_del', '=', $isDeleted ? 1 : 0]; // 订单大类筛选 if (!empty($where['order_category'])) { @@ -2303,7 +2304,7 @@ class OrderCenterServices extends BaseService implements OrderCenterSyncInterfac total_num, title, image, subtitle, shipping_type, extra_info, remark, detail_route, - add_time, pay_time, delivery_time, take_time, refund_time, cancel_time, is_del'; + add_time, pay_time, delivery_time, take_time, refund_time, cancel_time, is_del, is_system_del'; // 售后状态筛选:需要先按其他条件筛选出候选订单号,再按售后状态过滤,保证分页准确 $afterSaleOrderNos = []; @@ -2506,7 +2507,7 @@ class OrderCenterServices extends BaseService implements OrderCenterSyncInterfac $ttl = empty($where['date_range']) ? 300 : 60; return app()->cache->remember($cacheKey, function () use ($where) { - $baseWhere = [['is_del', '=', 0]]; + $baseWhere = [['is_system_del', '=', 0]]; // 按订单大类筛选 if (!empty($where['order_category'])) { $baseWhere[] = ['order_category', '=', $where['order_category']]; @@ -2610,13 +2611,24 @@ class OrderCenterServices extends BaseService implements OrderCenterSyncInterfac } /** - * 软删除订单 + * 软删除订单(管理端) + * 写 is_system_del 仅隐藏后台列表,不影响用户端;仅允许后台删除用户端已删除的订单 * @param int $id 订单中台记录ID * @return bool 返回是否删除成功 + * @throws ApiException 订单不存在或用户未删除时抛出 */ public function delete(int $id): bool { - return $this->dao->update(['id' => $id], ['is_del' => 1]) !== false; + $orderInfo = $this->dao->get(['id' => $id]); + if (!$orderInfo) { + throw new ApiException('订单不存在'); + } + if (!(int)($orderInfo['is_del'] ?? 0)) { + throw new ApiException('订单未被用户删除,不能删除'); + } + $res = $this->dao->update(['id' => $id], ['is_system_del' => 1]) !== false; + app()->cache->delete('order_center:stat:*'); + return $res; } /** diff --git a/backend/public/install/crmeb_table.sql b/backend/public/install/crmeb_table.sql index 865d04497..65535d8a5 100755 --- a/backend/public/install/crmeb_table.sql +++ b/backend/public/install/crmeb_table.sql @@ -786,7 +786,8 @@ CREATE TABLE IF NOT EXISTS `eb_order_center` ( `take_time` int NOT NULL DEFAULT '0' COMMENT '收货/完成时间', `refund_time` int NOT NULL DEFAULT '0' COMMENT '退款时间', `cancel_time` int NOT NULL DEFAULT '0' COMMENT '取消时间', - `is_del` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否删除(软删除)', + `is_del` tinyint(1) NOT NULL DEFAULT '0' COMMENT '用户删除标记(用户端隐藏)', + `is_system_del` tinyint(1) NOT NULL DEFAULT '0' COMMENT '后台删除标记(后台列表隐藏)', PRIMARY KEY (`id`), UNIQUE KEY `uk_order_no` (`order_no`), UNIQUE KEY `uk_source_order` (`source_type`,`source_id`), diff --git a/backend/public/install/update.sql b/backend/public/install/update.sql new file mode 100644 index 000000000..d6d2e2ef4 --- /dev/null +++ b/backend/public/install/update.sql @@ -0,0 +1,13 @@ +-- ============================================================ +-- CRMEB 数据库增量更新脚本 +-- 用途:已安装环境升级到当前版本时执行;全新安装直接导入 +-- crmeb_table.sql,无需本文件。 +-- 注意:MySQL 8 不支持 ADD COLUMN IF NOT EXISTS,请勿重复执行。 +-- ============================================================ + +-- 2026-10-09 订单中台删除标记拆分:is_del=用户删除(用户端隐藏), +-- is_system_del=后台删除(后台列表隐藏);后台列表与统计改按 +-- is_system_del 过滤,用户删除的订单后台仍可见,后台删除以用户已删为前提。 +ALTER TABLE `eb_order_center` + ADD COLUMN `is_system_del` tinyint(1) NOT NULL DEFAULT '0' COMMENT '后台删除标记(后台列表隐藏)' AFTER `is_del`, + MODIFY COLUMN `is_del` tinyint(1) NOT NULL DEFAULT '0' COMMENT '用户删除标记(用户端隐藏)';