Explorar o código

商品定时上架

gorden hai 11 meses
pai
achega
f6b16657f2

+ 57 - 6
app/admin/service/goods/GoodsService.php

@@ -10,6 +10,7 @@ use app\model\GoodsSku;
 use app\model\SysSerial;
 use support\Db;
 use support\exception\BusinessException;
+use support\Redis;
 use support\Request;
 use support\Response;
 
@@ -20,6 +21,7 @@ class GoodsService
         $page = $request->get('page');
         $pageSize = $request->get('pageSize');
         $goodsName = $request->get('goods_name', '');
+        $categoryId = $request->get('join_goods_category_id', null);
 
         $rows = Goods::with([
             'category' => function ($query) {
@@ -34,9 +36,11 @@ class GoodsService
                     $q->where('goods_name', 'like', '%' . $goodsName . '%')
                         ->OrWhere('goods_title', 'like', '%' . $goodsName . '%');
                 });
+            })->when($categoryId != null, function ($query) use ($categoryId) {
+                $query->where('join_goods_category_id', $categoryId);
             })
             ->where('goods_classify', $classify)
-            ->orderBy('goods_sort', 'DESC')
+            ->orderBy('goods_addtimes', 'DESC')
             ->forPage($page, $pageSize)
             ->get()
             ->toArray();
@@ -45,6 +49,8 @@ class GoodsService
                 $q->where('goods_name', 'like', '%' . $goodsName . '%')
                     ->OrWhere('goods_title', 'like', '%' . $goodsName . '%');
             });
+        })->when($categoryId != null, function ($query) use ($categoryId) {
+            $query->where('join_goods_category_id', $categoryId);
         })->where('goods_classify', $classify)->count();
 
         foreach ($rows as &$row) {
@@ -113,7 +119,6 @@ class GoodsService
                     $skuNameValue = [];
                     $i = 1;
                     foreach ($skuSpecsJson as $k => $item) {
-//                        dump($item);
                         $skuSpecs = $skuSpecs . $item . ',';
                         $skuNameKey = 'skuName' . $i;
                         $skuValueKey = 'skuValue' . $i;
@@ -173,7 +178,7 @@ class GoodsService
     {
         Db::beginTransaction();
         try {
-            $params['goods_id'] = "GD" . sprintf('%016d', SysSerial::getSerial()) . random_string(8);
+            $params['goods_id'] = "GD" . sprintf('%016d', SysSerial::getSerial()) . random_string(6, 'up');
             // 主表
             self::mainInsert($params);
             // 商品详情表
@@ -184,7 +189,12 @@ class GoodsService
             self::goodsRunningInsert($params);
             // sku表
             self::goodsSkuSet($params, 'insert');
-
+            // 待上架状态,上架时间大于当前时间
+            if ($params['goods_status'] == 'PENDING' && strtotime($params['goods_on_addtimes']) > time()) {
+                $redis = Redis::connection('listing');
+                $key = date('YmdHi', strtotime($params['goods_on_addtimes']));
+                $redis->sAdd(Goods::LISTING_KEY_PREFIX . $key, $params['goods_id']);
+            }
             Db::commit();
         } catch (\PDOException $e) {
             Db::rollBack();
@@ -252,6 +262,7 @@ class GoodsService
             GoodsDetail::whereIn('join_detail_goods_id', $ids)->delete();
             GoodsLabel::whereIn('join_label_goods_id', $ids)->delete();
             GoodsRunning::whereIn('join_running_goods_id', $ids)->delete();
+            GoodsSku::whereIn('join_sku_goods_id', $ids)->delete();
 
             Db::commit();
             return json_success("商品删除成功");
@@ -276,6 +287,12 @@ class GoodsService
         if (!empty($params['goods_cover'])) {
             $params['goods_cover'] = str_replace(getenv('STORAGE_DOMAIN'), '', $params['goods_cover']);
         }
+        // 如果产品是待处理状态
+        if ($params['goods_status'] == 'PENDING') {
+            if (strtotime($params['goods_on_addtimes']) <= time()) {
+                $params['goods_status'] = 'ON';
+            }
+        }
         try {
             $model = new Goods();
             $model->goods_id = $params['goods_id'];
@@ -293,7 +310,7 @@ class GoodsService
             $model->goods_title = $params['goods_title'] ?? '';
             $model->goods_cover = $params['goods_cover'] ?? '';
             $model->goods_on_addtimes = $params['goods_on_addtimes'] ? strtotime($params['goods_on_addtimes']) : null;
-            $model->goods_sort = $params['goods_sort'];
+            $model->goods_sort = $params['goods_sort'] ?? null;
             $model->goods_groupby = $params['goods_groupby'] ?? '';
             $model->goods_remark = $params['goods_remark'] ?? '';
             $model->goods_extend_json = $params['goods_extend_json'] ?? '{}';
@@ -436,7 +453,22 @@ class GoodsService
             $data['goods_on_addtimes'] = strtotime($data['goods_on_addtimes']);
             $data['goods_sku_json'] = !empty($params['goods_sku_json_label']) ? json_encode($params['goods_sku_json_label']) : json_encode(['规格' => []]);
 
-            self::doUpdate($data['goods_id'], $data, new Goods());
+            $row = Goods::find($data['goods_id']);
+            // 上架时间有变动
+            if ($data['goods_status'] == 'PENDING' && $row->goods_on_addtimes != $data['goods_on_addtimes']) {
+                $redis = Redis::connection('listing');
+                // 删掉原来的
+                $oldKey = Goods::LISTING_KEY_PREFIX . date('YmdHi', $row->goods_on_addtimes);
+                $redis->srem($oldKey, $data['goods_id']);
+
+                // 加入新的
+                $newKey = Goods::LISTING_KEY_PREFIX . date('YmdHi', $data['goods_on_addtimes']);
+                $redis->sadd($newKey, $data['goods_id']);
+            }
+            foreach ($data as $key => $val) {
+                $row->{$key} = $val;
+            }
+            $row->save();
         } catch (BusinessException $e) {
             throw new BusinessException($e->getMessage());
         } catch (\Exception $e) {
@@ -635,4 +667,23 @@ class GoodsService
         }
         $row->save();
     }
+
+    /**
+     * @Desc 上架定时
+     * @Author Gorden
+     * @Date 2024/4/11 15:13
+     *
+     * @return void
+     */
+    public static function checkListing()
+    {
+        $key = Goods::LISTING_KEY_PREFIX . date('YmdHi');
+        $redis = Redis::connection('listing');
+        if ($redis->exists($key)) {
+            $goodsIds = $redis->sMembers($key);
+            if (Goods::whereIn('goods_id', $goodsIds)->update(['goods_status' => 'ON'])) {
+                $redis->del($key);
+            }
+        }
+    }
 }

+ 2 - 0
app/model/Goods.php

@@ -20,6 +20,8 @@ class Goods extends Model
 
     const UPDATED_AT = null;
 
+    const LISTING_KEY_PREFIX = "GOODS:LISTING:";
+
     public function serializeDate(DateTimeInterface $date)
     {
         return $date->format('Y-m-d H:i:s');

+ 2 - 1
composer.json

@@ -36,7 +36,8 @@
     "topthink/think-validate": "^2.0",
     "symfony/translation": "^5.4",
     "tinywan/jwt": "^1.9.1",
-    "tinywan/storage": "^1.0"
+    "tinywan/storage": "^1.0",
+    "workerman/crontab": "^1.0"
   },
   "suggest": {
     "ext-event": "For better performance. "

+ 4 - 2
config/process.php

@@ -28,7 +28,6 @@ return [
                 base_path() . '/support',
                 base_path() . '/resource',
                 base_path() . '/route',
-                base_path() . '/.env',
             ], glob(base_path() . '/plugin/*/app'), glob(base_path() . '/plugin/*/config'), glob(base_path() . '/plugin/*/api')),
             // Files with these suffixes will be monitored
             'monitorExtensions' => [
@@ -39,5 +38,8 @@ return [
                 'enable_memory_monitor' => DIRECTORY_SEPARATOR === '/',
             ]
         ]
-    ]
+    ],
+    'task'  => [
+        'handler'  => process\Task::class
+    ],
 ];

+ 6 - 0
config/redis.php

@@ -19,4 +19,10 @@ return [
         'port' => getenv('REDIS_PORT', 6379),
         'database' => 0,
     ],
+    'listing' => [  // 商品上架
+        'host' => getenv('REDIS_HOST', '127.0.0.1'),
+        'password' => getenv('REDIS_PASSWORD'),
+        'port' => getenv('REDIS_PORT', 6379),
+        'database' => 1,
+    ],
 ];

+ 17 - 0
process/Task.php

@@ -0,0 +1,17 @@
+<?php
+namespace process;
+
+use app\admin\service\goods\GoodsService;
+use Workerman\Crontab\Crontab;
+
+class Task
+{
+    public function onWorkerStart()
+    {        // 每分钟执行一次
+        new Crontab('0 */1 * * * *', function(){
+            GoodsService::checkListing();
+            echo date('Y-m-d H:i:s')."\n";
+        });
+
+    }
+}

+ 2 - 1
support/helpers.php

@@ -568,7 +568,8 @@ function random_string($length, $type = 'all')
             $result = $string;
             break;
         case 'up':
-            $result = $stringUp;
+            $result = $stringUp . $number;
+            break;
         case 'number':
             $result = $number;
             break;