|
|
@@ -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');
|
|
|
|