Browse Source

fix:获取子分类的商品

super-yimizi 1 month ago
parent
commit
8be75ff211

+ 51 - 1
application/api/controller/Goods.php

@@ -11,16 +11,18 @@ use app\common\model\AttributeValue;
 // use app\common\model\Coupon;
 // use app\common\model\CouponCondition;
 // use app\common\model\UserCoupon;
+use app\common\Service\Goods\GoodService;
 use fast\Http;
 use think\Log;
 use think\Db;
 use app\common\Service\SkuSpec as SkuSpecService;
+use app\common\Service\Goods\CategoryService;
 /**
  * 商品接口
  */
 class Goods extends Base
 {
-    protected $noNeedLogin = [ 'detail', 'lists', 'getWxCode'];
+    protected $noNeedLogin = [ 'detail', 'lists', 'getWxCode','getCategoryGoods'];
     //详情
     public function detail()
     {
@@ -194,6 +196,54 @@ class Goods extends Base
         $this->success('', $list);
     }
 
+    //  根据分类顶级ID 查询子集 和对应的商品
+
+    public function getCategoryGoods()
+    {
+        $param = $this->request->param();
+        $categoryId = $param['category_id'] ?? 0;
+        // 验证器 
+        $validate = new \app\api\validate\Goods();
+        if (!$validate->scene('getCategoryGoods')->check($param)) {
+            $this->error($validate->getError());
+        }
+        // 查询子集分类信息
+        $categoryChildIds = CategoryService::getCategoryChildrenIds($categoryId);
+        // 查询所有直接子分类
+        $children = [];
+        foreach (CategoryService::getCategoryByIds($categoryChildIds) as $cat) {
+            if (isset($cat['pid']) && $cat['pid'] == $categoryId) {
+                $children[] = $cat;
+            }
+        }
+        // 获取所有直接子分类ID
+        $childrenIds = array_column($children, 'id');
+        // 一次性查出所有相关分类下的所有商品(不分页)
+        $allGoods = GoodService::getCategoryGoods($childrenIds); // 不分页查全部
+        // 按分类分组,每组只保留4个
+        $goodsByCategory = [];
+        foreach ($allGoods as $goods) {
+            if (empty($goods['category_ids'])) continue;
+            $goodsCatIds = explode(',', $goods['category_ids']);
+            foreach ($goodsCatIds as $catId) {
+                $catId = intval($catId);
+                if (in_array($catId, $childrenIds)) {
+                    if (!isset($goodsByCategory[$catId])) $goodsByCategory[$catId] = [];
+                    if (count($goodsByCategory[$catId]) < 4) {
+                        $goodsByCategory[$catId][] = $goods;
+                    }
+                }
+            }
+        }
+        // 组装返回
+        $arrReturn = [];
+        foreach ($children as $item) {
+            $item['goods'] = $goodsByCategory[$item['id']] ?? [];
+            $arrReturn[] = $item;
+        }
+        $this->success('', $arrReturn);
+    }
+
     //获取小程序码
     public function getWxCode()
     {

+ 1 - 0
application/api/validate/Goods.php

@@ -40,5 +40,6 @@ class Goods extends Validate
      */
     protected $scene = [
         'lists' => ['orderby', 'orderway', 'pageSize', 'page', 'keywords', 'category_id', 'brand_id'],
+        'getCategoryGoods' => ['category_id','page', 'pageSize'],
     ];
 } 

+ 51 - 0
application/common/Service/Goods/CategoryService.php

@@ -0,0 +1,51 @@
+<?php
+
+namespace app\common\Service\Goods;
+
+use app\common\model\Category;
+
+class CategoryService
+{
+    /**
+     * 获取栏目所有子级的ID
+     * @param mixed $ids      栏目ID或集合ID
+     * @param bool  $withself 是否包含自身
+     * @return array
+     */
+    public static function getCategoryChildrenIds($ids, $withself = true)
+    {
+        // $cacheName = 'shop-childrens-' . $ids . '-' . $withself;
+        // $result = Cache::get($cacheName);
+        // if ($result === false) {
+            $categoryList = Category::where('status', 'normal')
+                ->order('weigh desc,id desc')
+                ->select();
+
+            $result = [];
+            $tree = \fast\Tree::instance();
+            $tree->init(collection($categoryList)->toArray(), 'pid');
+            $CategoryIds = is_array($ids) ? $ids : explode(',', $ids);
+            foreach ($CategoryIds as $index => $CategoryId) {
+                $result = array_merge($result, $tree->getChildrenIds($CategoryId, $withself));
+            }
+        //     Cache::set($cacheName, $result);
+        // }
+        return $result;
+    }
+
+    /**
+     * 根据分类ID获取分类信息
+     * @param array $arrCategoryIds 分类ID集合
+     * @return array
+     */
+    public static function getCategoryByIds($arrCategoryIds = []){
+        $categoryList = Category::where('id', 'IN', $arrCategoryIds)
+        ->where('status', 'normal')
+        ->order('weigh desc,id desc')
+        ->field('id,name,image,weigh,pid')
+        ->select();
+        $arrCategory = collection($categoryList)->toArray();
+        return $arrCategory;
+    }
+    
+}

+ 38 - 0
application/common/Service/Goods/GoodService.php

@@ -0,0 +1,38 @@
+<?php
+
+namespace app\common\Service\Goods;
+use app\common\model\Goods;
+use app\common\Enum\GoodsEnum;
+class GoodService
+{
+    /**
+     * 根据分类ID获取商品列表
+     * @param int $categoryId 分类ID
+     * @param int $page 页码
+     * @param int $pageSize 每页条数
+     * @return \think\Paginator
+     */
+    public static function getCategoryGoods($arrCategoryId = [], $page = 0, $pageSize = 10){
+        
+
+        $query = Goods::where(function ($query) use ($arrCategoryId) {
+            // 所有子分类使用 find_in_set or 匹配,亲测速度并不慢
+            foreach ($arrCategoryId as $key => $category_id) {
+                $query->whereOrRaw("find_in_set($category_id, category_ids)");
+            }
+        })->where('status',GoodsEnum::STATUS_ON_SALE)->order('weigh desc,id desc');
+        $arrfield = ['id','title','image','category_ids','price','sales','views','description','lineation_price','is_hot','createtime'];
+        // 判断是否分页
+        if($page > 0){
+            $nStart = $page * $pageSize;
+         $goodsList = $query->field($arrfield)
+            ->limit($nStart, $pageSize)
+            ->select();
+        }else{
+            $goodsList = $query->field($arrfield)
+            ->select();
+        }
+        $arrGoods = collection($goodsList)->toArray();
+        return $arrGoods;
+    }
+}

+ 1 - 152
application/common/model/Category.php

@@ -22,7 +22,6 @@ class Category extends Model
     protected $updateTime = 'updatetime';
     // 追加属性
     protected $append = [
-        'url',
         'flag_text',
     ];
 
@@ -51,40 +50,6 @@ class Category extends Model
         return is_array($value) ? implode(',', $value) : $value;
     }
 
-    public function getUrlAttr($value, $data)
-    {
-        return $this->buildUrl($value, $data);
-    }
-
-    public function getFullurlAttr($value, $data)
-    {
-        return $this->buildUrl($value, $data, true);
-    }
-
-    private function buildUrl($value, $data, $domain = false)
-    {
-        $diyname = isset($data['diyname']) && $data['diyname'] ? $data['diyname'] : $data['id'];
-        $cateid = $data['id'] ?? 0;
-        $catename = isset($data['diyname']) && $data['diyname'] ? $data['diyname'] : 'all';
-        $time = $data['createtime'] ?? time();
-
-        $vars = [
-            ':id'       => $data['id'],
-            ':diyname'  => $diyname,
-            ':category' => $cateid,
-            ':catename' => $catename,
-            ':cateid'   => $cateid,
-            ':year'     => date("Y", $time),
-            ':month'    => date("m", $time),
-            ':day'      => date("d", $time)
-        ];
-        if (isset($data['type']) && isset($data['outlink']) && $data['type'] == 'link') {
-            return $this->getAttr('outlink');
-        }
-        $suffix = static::$config['moduleurlsuffix']['category'] ?? static::$config['urlsuffix'];
-        return addon_url('shop/category/index', $vars, $suffix, $domain);
-    }
-
     public function getImageAttr($value, $data)
     {
         $value = $value ? $value : self::$config['default_category_img'];
@@ -96,62 +61,13 @@ class Category extends Model
         return ['hot' => __('Hot'), 'index' => __('Index'), 'recommend' => __('Recommend')];
     }
 
-    public function getOutlinkAttr($value, $data)
-    {
-        $indexUrl = $view_replace_str = config('view_replace_str.__PUBLIC__');
-        $indexUrl = rtrim($indexUrl, '/');
-        return str_replace('__INDEX__', $indexUrl, $value ?: '');
-    }
-
     public function getFlagTextAttr($value, $data)
     {
         $value = $value ?: ($data['flag'] ?? '');
         $valueArr = explode(',', $value);
         $list = $this->getFlagList();
         return implode(',', array_intersect_key($list, array_flip($valueArr)));
-    }
-
-    /**
-     * 判断是否拥有子列表
-     * @param $value
-     * @param $data
-     * @return bool|mixed
-     */
-    public function getHasChildAttr($value, $data)
-    {
-        static $checked = [];
-        if (isset($checked[$data['id']])) {
-            return $checked[$data['id']];
-        }
-        if (is_null(self::$parentIds)) {
-            self::$parentIds = self::where('pid', '>', 0)->cache(true, null, 'shop')->where('status', 'normal')->column('pid');
-        }
-        if (self::$parentIds && in_array($data['id'], self::$parentIds)) {
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * 判断导航是否拥有子列表
-     * @param $value
-     * @param $data
-     * @return bool|mixed
-     */
-    public function getHasNavChildAttr($value, $data)
-    {
-        static $checked = [];
-        if (isset($checked[$data['id']])) {
-            return $checked[$data['id']];
-        }
-        if (is_null(self::$navParentIds)) {
-            self::$navParentIds = self::where('pid', '>', 0)->cache(true, null, 'shop')->where('status', 'normal')->where('isnav', 1)->column('pid');
-        }
-        if (self::$navParentIds && in_array($data['id'], self::$navParentIds)) {
-            return true;
-        }
-        return false;
-    }
+    } 
 
     public static function getIndexCategoryList()
     {
@@ -165,73 +81,6 @@ class Category extends Model
         $categoryList = collection($categoryList)->toArray();
         return $categoryList;
     }
-
-
-    /**
-     * 获取面包屑导航
-     * @param array $category
-     * @param array $goods
-     * @param array $page
-     * @return array
-     */
-    public static function getBreadcrumb($category, $goods = [], $page = [])
-    {
-        $list = [];
-        $list[] = ['name' => __('Home'), 'url' => addon_url('shop/index/index', [], false)];
-        if ($category) {
-            if ($category['pid']) {
-                $categoryList = self::where('status', 'normal')
-                    ->order('weigh desc,id desc')
-                    ->field('id,name,pid,diyname')
-                    ->cache(true, null, 'shop')
-                    ->select();
-                //获取栏目的所有上级栏目
-                $parents = \fast\Tree::instance()->init(collection($categoryList)->toArray(), 'pid')->getParents($category['id']);
-                foreach ($parents as $k => $v) {
-                    $list[] = ['name' => $v['name'], 'url' => $v['url']];
-                }
-            }
-            $list[] = ['name' => $category['name'], 'url' => $category['url']];
-        }
-        if ($goods) {
-            //$list[] = ['name' => $goods['title'], 'url' => $goods['url']];
-        }
-        if ($page && $category['url'] != $page['url']) {
-            $list[] = ['name' => $page['title'], 'url' => $page['url']];
-        }
-        return $list;
-    }
-
-    /**
-     * 获取导航分类列表HTML
-     * @param       $category
-     * @param array $tag
-     * @return mixed|string
-     */
-    public static function getNav($category, $tag = [])
-    {
-        $config = get_addon_config('shop');
-        $condition = empty($tag['condition']) ? '' : $tag['condition'];
-        $maxLevel = !isset($tag['maxlevel']) ? 0 : $tag['maxlevel'];
-
-        list($cacheKey, $cacheExpire) = Service::getCacheKeyExpire('nav', $tag);
-
-        $cacheName = 'shop-nav-' . md5(serialize($tag));
-        $result = Cache::tag('shop')->get($cacheName);
-        if ($result === false) {
-            $categoryList = Category::where($condition)
-                ->where('status', 'normal')
-                ->order('weigh desc,id desc')
-                ->cache($cacheKey, $cacheExpire, 'shop')
-                ->select();
-            $tree = \fast\Tree::instance();
-            $tree->init(collection($categoryList)->toArray(), 'pid');
-            $result = self::getTreeUl($tree, 0, $category ? $category['id'] : '', '', 1, $maxLevel);
-            Cache::tag('shop')->set($cacheName, $result);
-        }
-        return $result;
-    }
-
     /**
      * 获取栏目所有子级的ID
      * @param mixed $ids      栏目ID或集合ID