Quellcode durchsuchen

预售更新问题

shish vor 1 Monat
Ursprung
Commit
f7894afdde
1 geänderte Dateien mit 55 neuen und 5 gelöschten Zeilen
  1. 55 5
      console/controllers/ProductController.php

+ 55 - 5
console/controllers/ProductController.php

@@ -1,5 +1,13 @@
 <?php
 
+/**
+ * 商品控制器 (控制台脚本)
+ * 
+ * 用途:用于定时任务、命令行脚本处理商品数据,如复制花材、预售到期自动取消等。
+ * 谁用:系统定时任务 (Cron Job) 自动调用。
+ * 解决什么问题:解决商品后台定时数据维护问题,如预售到期自动取消与部分日期到期更新。
+ */
+
 namespace console\controllers;
 
 use biz\item\classes\PtItemClass;
@@ -290,7 +298,16 @@ class ProductController extends Controller
         }
     }
 
-    //预售到期自动取消
+    /**
+     * 预售到期自动取消与更新脚本
+     * 
+     * 职责:每天凌晨执行,扫描所有预售商品,若预售日期已到则进行清除或更新。
+     * 入参/返回:无(定时脚本,无入参,无返回值)
+     * 副作用:会修改商品表(product)的 presell 和 presellDate 字段,并修改 Redis 缓存。
+     * 关键边界:
+     * 1. 如果设置的全部预售日期都到了,则彻底清除预售状态(presell = 0,presellDate = ''),并删除 Redis 缓存。
+     * 2. 如果只到了其中部分日期,则只清除已到期的日期,保留未到期的日期,预售继续(presell = 1,更新 presellDate),并更新 Redis 缓存为剩余最早日期。
+     */
     public function actionCancelPresell()
     {
         try{
@@ -323,10 +340,43 @@ class ProductController extends Controller
                         $redis->del($key);
                         continue;
                     }
-                    $item->presell = 0;
-                    $item->presellDate = '';
-                    $item->save();
-                    $redis->del($key);
+
+                    // 解析商品当前的预售日期列表,干什么:获取所有设置的预售日期时间戳,为什么:需要逐一比对是否到期
+                    $presellDateStr = trim($item->presellDate ?? '');
+                    if (empty($presellDateStr)) {
+                        // 预售日期为空,干什么:直接清除预售状态,为什么:没有日期的预售是无效数据,必须清除并删缓存
+                        $item->presell = 0;
+                        $item->presellDate = '';
+                        $item->save();
+                        $redis->del($key);
+                        continue;
+                    }
+
+                    $presellDates = explode(',', $presellDateStr);
+                    $presellDates = array_unique(array_filter(array_map('intval', $presellDates)));
+
+                    // 过滤掉所有已经到期(小于当前时间)的预售日期,干什么:筛选出未来还未到期的预售日期,为什么:只保留未到期的预售日期
+                    $remainingDates = [];
+                    foreach ($presellDates as $date) {
+                        if ($date >= $now) {
+                            $remainingDates[] = $date;
+                        }
+                    }
+
+                    // 根据剩余日期情况,决定是完全清除预售还是只清除部分日期
+                    if (empty($remainingDates)) {
+                        // 全部预售日期都到了,干什么:清除预售状态,删除 Redis 缓存,为什么:所有预售日期都已过期,商品不再是预售商品
+                        $item->presell = 0;
+                        $item->presellDate = '';
+                        $item->save();
+                        $redis->del($key);
+                    } else {
+                        // 只到了其中部分日期,干什么:清除已到期的日期,预售继续,并更新 Redis 缓存为剩余的最早日期,为什么:部分日期未到,预售仍需继续
+                        sort($remainingDates);
+                        $item->presellDate = implode(',', $remainingDates);
+                        $item->save();
+                        $redis->set($key, $remainingDates[0]);
+                    }
                 }
             } while ($cursor !== '0');