['in', ((isset($type) && $type == 'all') ? ['up', 'hidden'] : ['up'])], // type = all 查询全部 ]; // 排序字段 if (isset($order)) { $order = self::getGoodsListOrder($order); } else { // $order = 'weigh desc'; $order = 'weigh asc'; } if (isset($keywords) && $keywords !== '') { $where['title|subtitle'] = ['like', "%$keywords%"]; } if (isset($goods_ids) && $goods_ids !== '') { $order = 'field(id, ' . $goods_ids . ')'; // 如果传了 goods_ids 就按照里面的 id 进行排序 $goodsIdsArray = explode(',', $goods_ids); $where['id'] = ['in', $goodsIdsArray]; // 装修/首页指定 id 时允许 hidden(如招商礼盒),仍不展示 down $where['status'] = ['in', ['up', 'hidden']]; } $category_ids = []; if (isset($category_id) && $category_id != 0) { // 查询分类所有子分类,包括自己 $category_ids = Category::getCategoryIds($category_id); } $goods = self::where($where)->where(function ($query) use ($category_ids) { // 所有子分类使用 find_in_set or 匹配,亲测速度并不慢 foreach ($category_ids as $key => $category_id) { $query->whereOrRaw("find_in_set($category_id, category_ids)"); } }); // 过滤有活动的商品 if (isset($no_activity) && $no_activity) { $goods = $goods->whereNotExists(function ($query) use ($where) { $activityTableName = (new Activity())->getQuery()->getTable(); $goodsTableName = (new self())->getQuery()->getTable(); $query->table($activityTableName) ->where("find_in_set(" . $goodsTableName . ".id, goods_ids)") ->where('deletetime', 'null'); // 必须手动加上 deletetime = null }); } $goods = $goods->field('*,(sales + show_sales) as total_sales')->orderRaw($order)->order('id desc'); if ($is_page) { $goods = $goods->paginate($per_page ?? 10); $goodsData = $goods->items(); } else { $goods = $goodsData = $goods->select(); } $data = []; if ($goodsData) { $collection = collection($goodsData); $data = $collection->hidden(self::$list_hidden); // 处理活动 // load_relation($data, 'skuPrice'); // 只针对数组 $data->load('skuPrice'); // 延迟预加载 // if (!isset($no_activity) || !$no_activity) { // 没有 传入 no_activity 或者 no_activity = false // 默认查询活动, no_activity 的时候这里也要执行一下,这里计算了销量规格等信息 $source = !empty($params['platform']) ? $params['platform'] : ''; foreach ($data as $key => $g) { $data[$key] = self::operActivity($g, $g['sku_price'], $source); } // } } if ($is_page) { $goods->data = $data; } else { $goods = $data; // 目前只缓存不分页的请求, // 缓存暂时注释,如果需要,可以打开,请注意后台更新商品记得清除缓存 // cache($cacheKey, json_encode($goods), (600 + mt_rand(0, 300))); } return $goods; } public static function getGoodsListByIds($goodsIds) { $goodsIdsArray = explode(',', $goodsIds); $where = [ 'status' => 'up', 'deletetime' => null, 'id' => ['in', $goodsIdsArray] ]; $goods = self::where($where)->paginate(10); if ($goods->items()) { $collection = collection($goods->items()); $data = $collection->hidden(self::$list_hidden); // 处理活动 // load_relation($data, 'skuPrice'); // 只针对数组 $data->load('skuPrice'); // 延迟预加载 foreach ($data as $key => $g) { // $skuPrice = []; // foreach ($g['sku_price'] as $v) { // if ($v['status'] === 'up') { // $skuPrice[] = $v; // } // } $data[$key] = self::operActivity($g, $g['sku_price']); } $goods->data = $data; } return $goods; } public static function getFavoriteGoodsList($type = 'normal', $status = 'up') { $where = [ 'type' => $type, 'status' => $status, 'deletetime' => null, ]; $goods = self::where($where)->paginate(10); if ($goods->items()) { $collection = collection($goods->items()); $data = $collection->hidden(self::$list_hidden); $goods->data = $data; } return $goods; } // 预约抢购商品列表 public static function getRobBuyGoodsList($params) { extract($params); $type = $type ?? 'all'; if ((new self)->hasRedis()) { // 如果有redis,读取 redis $activityList = (new self)->getActivityList(['robbuy'], $type); } else { $where = [ 'type' => 'robbuy' ]; if ($type == 'ing') { $where['starttime'] = ['<', time()]; $where['endtime'] = ['>', time()]; } else if ($type == 'nostart') { $where['starttime'] = ['>', time()]; } else if ($type == 'ended') { $where['endtime'] = ['<', time()]; } $activityList = Activity::where($where)->select(); } // 获取所有商品 id $goodsIds = ''; foreach ($activityList as $key => $activity) { $goodsIds .= ',' . $activity['goods_ids']; } if ($goodsIds) { $goodsIds = trim($goodsIds, ','); } $goodsList = self::getGoodsListByIds($goodsIds); return $goodsList; } // 获取秒杀商品列表 public static function getSeckillGoodsList($params) { extract($params); $type = $type ?? 'all'; if ((new self)->hasRedis()) { // 如果有redis,读取 redis $activityList = (new self)->getActivityList(['seckill'], $type); } else { $where = [ 'type' => 'seckill' ]; if ($type == 'ing') { $where['starttime'] = ['<', time()]; $where['endtime'] = ['>', time()]; } else if ($type == 'nostart') { $where['starttime'] = ['>', time()]; } else if ($type == 'ended') { $where['endtime'] = ['<', time()]; } $activityList = Activity::where($where)->select(); } // 获取所有商品 id $goodsIds = ''; foreach ($activityList as $key => $activity) { $goodsIds .= ',' . $activity['goods_ids']; } if ($goodsIds) { $goodsIds = trim($goodsIds, ','); } $goodsList = self::getGoodsListByIds($goodsIds); return $goodsList; } // 获取促销商品列表 public static function getPromoteGoodsList($params) { extract($params); $type = $type ?? 'all'; if ((new self)->hasRedis()) { // 如果有redis,读取 redis $activityList = (new self)->getActivityList(['promote'], $type); } else { $where = [ 'type' => 'seckill' ]; if ($type == 'ing') { $where['starttime'] = ['<', time()]; $where['endtime'] = ['>', time()]; } else if ($type == 'nostart') { $where['starttime'] = ['>', time()]; } else if ($type == 'ended') { $where['endtime'] = ['<', time()]; } $activityList = Activity::where($where)->select(); } // 获取所有商品 id $goodsIds = ''; foreach ($activityList as $key => $activity) { if (!empty($params['platform']) && strpos($activity['show'], handleSource($params['platform'])) !== false) { $goodsIds .= ',' . $activity['goods_ids']; } } if ($goodsIds) { $goodsIds = trim($goodsIds, ','); } $goodsList = self::getGoodsListByIds($goodsIds); return $goodsList; } // 获取限时秒杀商品列表 public static function getTimerGoodsList($params) { extract($params); $type = $type ?? 'all'; if ((new self)->hasRedis()) { // 如果有redis,读取 redis $activityList = (new self)->getActivityList(['timer'], $type); } else { $where = [ 'type' => 'timer' ]; if ($type == 'ing') { $where['starttime'] = ['<', time()]; $where['endtime'] = ['>', time()]; } else if ($type == 'nostart') { $where['starttime'] = ['>', time()]; } else if ($type == 'ended') { $where['endtime'] = ['<', time()]; } $activityList = Activity::where($where)->select(); } // 获取所有商品 id $goodsIds = ''; foreach ($activityList as $key => $activity) { $goodsIds .= ',' . $activity['goods_ids']; } if ($goodsIds) { $goodsIds = trim($goodsIds, ','); } $goodsList = self::getGoodsListByIds($goodsIds); return $goodsList; } // 获取拼团商品列表 public static function getGrouponGoodsList($params) { extract($params); $type = 'ing'; if ((new self)->hasRedis()) { // 如果有redis,读取 redis $activityList = (new self)->getActivityList(['groupon'], $type); } else { $where = [ 'type' => 'groupon' ]; if ($type == 'ing') { $where['starttime'] = ['<', time()]; $where['endtime'] = ['>', time()]; } $activityList = Activity::where($where)->select(); } // 获取所有商品 id $goodsIds = ''; foreach ($activityList as $key => $activity) { if (!empty($params['platform']) && strpos($activity['show'], handleSource($params['platform'])) !== false) { $goodsIds .= ',' . $activity['goods_ids']; } } if ($goodsIds) { $goodsIds = trim($goodsIds, ','); } $goodsList = self::getGoodsListByIds($goodsIds); return $goodsList; } public static function getGoodsDetail($id, $source = '') { $user = User::info(); $detail = (new self)->where('id', $id)->with(['favorite' => function ($query) use ($user) { $user_id = empty($user) ? 0 : $user->id; return $query->where(['user_id' => $user_id]); }])->find(); if (!$detail || $detail->status === 'down') { new Exception('商品不存在或已下架'); } $append = ['service', 'coupons']; // 多规格商品才加载规格属性 if (!empty($detail->is_sku)) { $append[] = 'sku'; } $detail = $detail->append($append); // 处理活动规格 $detail = self::operActivity($detail, $detail->sku_price, $source); return $detail; } /** * 获取自提点 */ public static function getGoodsStore($params) { $user = User::info(); $id = $params['id'] ?? 0; $keyword = $params['keyword'] ?? ''; $latitude = $params['latitude'] ?? 0; $longitude = $params['longitude'] ?? 0; $per_page = $params['per_page'] ?? 10; $detail = (new self)->where('id', $id)->find(); if (!$detail) { new Exception('商品不存在'); } if (strpos($detail['dispatch_type'], 'selfetch') === false) { new Exception('商品不支持自提'); } // 商品支持自提,查询自提模板 $dispatch = Dispatch::where('type', 'selfetch')->where('id', 'in', $detail['dispatch_ids'])->find(); if (!$dispatch) { new Exception('自提模板不存在'); } $dispatchSelfetch = DispatchSelfetch::where('id', 'in', $dispatch['type_ids'])->order('id', 'asc')->find(); if (!$dispatchSelfetch) { new Exception('自提模板不存在'); } // 查询自提点 $selfetch = Store::show()->where('selfetch', 1); if ($dispatchSelfetch['store_ids']) { // 部分门店 $selfetch = $selfetch->where('id', 'in', $dispatchSelfetch['store_ids']); } if ($latitude && $longitude) { $selfetch = $selfetch->field('*, ' . getDistanceBuilder($latitude, $longitude))->order('distance', 'asc'); } if ($keyword) { $selfetch = $selfetch->where('name', 'like', '%' . $keyword . '%'); } $selfetch = $selfetch->paginate($per_page); return $selfetch; } /** * 获取商品购买人 * * @param integer $goods_id * @param integer $activity_id * @return array */ protected static function getGoodsBuyers($goods_id = 0, $activity_id = 0) { $where = [ 'goods_id' => $goods_id ]; if ($activity_id) { // 是否查询指定活动的购买人 $where['activity_id'] = $activity_id; } // 查询活动正在购买的人Goods $orderItems = OrderItem::with(['user' => function ($query) { return $query->field('id,nickname,avatar'); }])->whereExists(function ($query) { $order_table_name = (new Order())->getQuery()->getTable(); $table_name = (new OrderItem())->getQuery()->getTable(); $query->table($order_table_name)->where($table_name . '.order_id=' . $order_table_name . '.id')->where('status', '>', 0); })->field('user_id')->where($where)->group('user_id')->limit(3)->select(); $user = []; foreach ($orderItems as $item) { if ($item['user']) { $user[] = $item['user']; } } return $user; } public function getCouponsAttr($value, $data) { $user = User::info(); $goods_id = $data['id']; // 只查可以领取的 $where = [ 'gettimestart' => ['elt', time()], 'gettimeend' => ['egt', time()] ]; $coupons = Coupons::where(function ($query) use ($goods_id) { $query->where('find_in_set(' . $goods_id . ',goods_ids)') ->whereOr('goods_ids', 0); }); if ($user) { // 关联用户状态 $coupons = $coupons->with(['userCoupons' => function ($query) use ($user) { $query->where('user_id', $user->id); }]); } $coupons = $coupons->where($where)->select(); // 判断优惠券,当前用户领取状态 foreach ($coupons as &$coupon) { if ($user && $coupon->limit <= count($coupon->user_coupons)) { $coupon->status_code = 'cannot_get'; $coupon->status_name = '已领取'; } else { $coupon->status_code = 'can_get'; $coupon->status_name = '可以领取'; } } return $coupons; } protected function getSkuAttr($value, $data) { $sku = GoodsSku::all([ 'goods_id' => $data['id'], 'pid' => 0, ]); foreach ($sku as $s => &$k) { $sku[$s]['content'] = GoodsSku::all([ 'goods_id' => $data['id'], 'pid' => $k['id'] ]); } return $sku; } private static function getSkuPrice($value, $data) { return GoodsSkuPrice::all([ 'goods_id' => $data['id'], 'status' => 'up', 'deletetime' => null ]); } public function getParamsAttr($value, $data) { return $value ? json_decode($value, true) : []; } public function getServiceAttr($value, $data) { $value = $data['service_ids']; $serviceData = []; if (!empty($value)) { $serviceArray = explode(',', $value); $serviceData = []; foreach ($serviceArray as $v) { $serviceData[] = \addons\shopro\model\GoodsService::where(['id' => $v, 'status' => 'normal'])->find(); } } return $serviceData; } public function getImageAttr($value, $data) { if (!empty($value)) return cdnurl($value, true); } public function getImagesAttr($value, $data) { $imagesArray = []; if (!empty($value)) { $imagesArray = explode(',', $value); foreach ($imagesArray as &$v) { $v = cdnurl($v, true); } return $imagesArray; } return $imagesArray; } public function getContentAttr($value, $data) { $content = $data['content']; $content = str_replace("hasOne(\addons\shopro\model\UserFavorite::class, 'goods_id', 'id'); } public function scoreGoodsSkuPrice() { return $this->hasMany(\addons\shopro\model\scoreGoodsSkuPrice::class, 'goods_id', 'id') ->where('status', 'up')->order('id', 'asc'); } public function skuPrice() { return $this->hasMany(\addons\shopro\model\GoodsSkuPrice::class, 'goods_id', 'id') ->order('id', 'asc'); } //商品列表排序 private static function getGoodsListOrder($orderStr) { $order = 'weigh desc'; $orderList = json_decode(htmlspecialchars_decode($orderStr), true); extract($orderList); if (isset($defaultOrder) && $defaultOrder === 1) { $order = 'weigh desc'; } if (isset($priceOrder) && $priceOrder === 1) { $order = "convert(`price`, DECIMAL(10, 2)) asc"; } elseif (isset($priceOrder) && $priceOrder === 2) { $order = "convert(`price`, DECIMAL(10, 2)) desc"; } if (isset($salesOrder) && $salesOrder === 1) { $order = 'total_sales desc'; } if (isset($newProdcutOrder) && $newProdcutOrder === 1) { $order = 'id desc'; } return $order; } }