// +---------------------------------------------------------------------- namespace App\Services\Api; use App\Models\GoodsCategoryModel; use App\Models\GoodsCollectModel; use App\Models\GoodsModel; use App\Models\GoodsSkuModel; use App\Models\MemberModel; use App\Services\BaseService; use App\Services\ConfigService; use App\Services\RedisService; /** * 商品管理-服务类 * @author laravel开发员 * @since 2020/11/11 * @package App\Services\Api */ class GoodsService extends BaseService { // 静态对象 protected static $instance = null; /** * 构造函数 * @author laravel开发员 * @since 2020/11/11 */ public function __construct() { $this->model = new GoodsModel(); } /** * 静态入口 */ public static function make() { if (!self::$instance) { self::$instance = new static(); } return self::$instance; } /** * 列表数据 * @param $params * @param int $pageSize * @return array */ public function getDataList($params, $pageSize = 15) { $cacheKey = "caches:goods:list_{$pageSize}_" . ($params ? md5(json_encode($params)) : 0); $datas = RedisService::get($cacheKey); if (empty($datas)) { $query = $this->getQuery($params) ->orderBy('a.create_time', 'desc') ->orderBy('a.id', 'desc'); $field = ["a.*"]; $list = $query->select($field) ->paginate($pageSize > 0 ? $pageSize : 9999999); $list = $list ? $list->toArray() : []; if ($list) { $datas = [ 'pageSize' => $pageSize, 'total' => isset($list['total']) ? $list['total'] : 0, 'list' => isset($list['data']) ? $list['data'] : [] ]; RedisService::set($cacheKey, $datas, rand(3, 5)); } } return $datas; } /** * 查询条件 * @param $params * @return mixed */ public function getQuery($params) { $where = ['a.type'=>1,'a.is_recommend'=>1,'a.status' => 1, 'a.mark' => 1]; $status = isset($params['status']) ? $params['status'] : 1; $isRecommend = isset($params['is_recommend']) ? $params['is_recommend'] : 0; $type = isset($params['type']) && $params['type']? $params['type'] : 1; if ($status > 0) { $where['a.status'] = $status; } else { unset($where['a.status']); } if ($isRecommend == 1) { $where['a.is_recommend'] = $isRecommend; } else { unset($where['a.is_recommend']); } if ($type>0){ $where['a.type'] = $type; } else { unset($where['a.type']); } $model = $this->model->with(['store','category']) ->from('goods as a') ->where($where) ->where(function ($query) use ($params) { // 分类 $categoryId = isset($params['category_id'])? intval($params['category_id']) : 0; if($categoryId>0){ $query->where('a.category_id', $categoryId); } // 套餐类型 $mealType = isset($params['meal_type'])? intval($params['meal_type']) : 0; if($mealType>0){ $query->where('a.meal_type', $mealType); } // 企业 $storeId = isset($params['store_id'])? intval($params['store_id']) : 0; if($storeId>0){ $query->where('a.store_id', $storeId); } $keyword = isset($params['keyword']) ? trim($params['keyword']) : ''; if ($keyword) { $query->where(function ($query) use ($keyword) { $query->where('a.goods_name', 'like', "%{$keyword}%") ->orWhere('a.tags','like',"%{$keyword}%"); }); } }); return $model; } /** * 分类 * @return array|mixed */ public function getCategoryList() { $cacheKey = "caches:goods:categoryList"; $datas = RedisService::get($cacheKey); if($datas){ return $datas; } $datas = GoodsCategoryModel::where(['pid'=>0,'status'=>1,'mark'=>1]) ->select(['id','name','icon','pid','sort']) ->orderBy('sort','desc') ->orderBy('id','asc') ->get(); $datas = $datas? $datas->toArray() : []; if($datas){ RedisService::set($cacheKey, $datas, rand(300,600)); } return $datas; } /** * 详情信息 * @param $id * @return mixed */ public function getInfo($id,$userId=0) { $cacheKey = "caches:goods:info_{$id}_{$userId}"; $info = RedisService::get($cacheKey); if ($info) { return $info; } $info = $this->model->with(['store','category','skus'])->where(['id' => $id])->first(); $info = $info ? $info->toArray() : []; if ($info) { RedisService::set($cacheKey, $info, rand(10, 20)); } return $info; } /** * 收藏 * @param $userId * @param $goodsId * @return array|false */ public function collect($userId, $goodsId) { $info = $this->model->where(['id' => $goodsId,'status'=>1,'mark'=>1])->first(); $info = $info ? $info->toArray() : []; if(empty($info)){ $this->error = '商品已下架'; return false; } if($id = GoodsCollectModel::where(['user_id'=>$userId,'goods_id'=>$goodsId,'mark'=>1])->value('id')){ GoodsCollectModel::where(['id'=>$id])->update(['mark'=>0,'update_time'=>time()]); $this->error = '取消收藏'; RedisService::clear("caches:goods:info_{$id}_{$userId}"); return ['id'=>$id,'is_collect'=>0]; }else{ if(!$id = GoodsCollectModel::insertGetId(['user_id'=>$userId,'goods_id'=>$goodsId,'status'=>1,'mark'=>1,'create_time'=>time(),'update_time'=>time()])){ $this->error = '收藏失败'; return false; } $this->error = '收藏成功'; RedisService::clear("caches:goods:info_{$id}_{$userId}"); return ['id'=>$id,'is_collect'=>1]; } } /** * 按类型获取商品 * @param $position * @param int $buyType * @return array|mixed */ public function getListByType($type, $buyType=1, $userId=0) { $cacheKey = "caches:goods:{$type}_{$userId}_{$buyType}"; $datas = RedisService::get($cacheKey); if($datas){ return $datas; } $datas = $this->model->where('id','=', $buyType) ->where(['type'=> $type,'status'=> 1,'mark'=>1]) ->select(['id','thumb','type','meal_type','goods_name','price','bd_score','description']) ->get(); $datas = $datas? $datas->toArray() : []; if($datas){ RedisService::set($cacheKey, $datas, rand(5, 10)); } return $datas; } /** * @param $ids * @param $goods * @param $userId * @param $orderNo 订单号 * @return array|false */ public function getOrderGoods($ids, $goods, $userId, $orderNo='', $discountPoint=0) { if(empty($ids) || empty($goods)){ $this->error = '请选择商品'; return false; } // 用户信息 if(empty($orderNo)){ $userInfo = MemberModel::where(['id' => $userId, 'mark' => 1]) ->select(['id','openid', 'status']) ->first(); $status = isset($userInfo['status']) ? $userInfo['status'] : 0; $openid = isset($userInfo['openid']) ? $userInfo['openid'] : 0; $discountPoint = isset($userInfo['discount_point']) ? $userInfo['discount_point'] : 0; // 折扣 if (empty($userInfo) || $status != 1) { $this->error = 1045; return false; } if (empty($openid)) { $this->error = 1042; return false; } } $list = $this->model->whereIn('id', $ids) ->where(['status'=>1,'mark'=>1]) ->select(['id as goods_id','goods_name','category_id','store_id','meal_type','delivery_fee','profit_rate','sku_type','price','bd_score','cost_price','ls_score_rate','stock','unit','weight','thumb','sku_type']) ->get() ->keyBy('goods_id'); $list = $list? $list->toArray() : []; if($list){ // 净利润比例 $profitRate = ConfigService::make()->getConfigByCode('goods_profit_rate', 20); $profitRate = $profitRate>0 && $profitRate<100?$profitRate:20; $skus = GoodsSkuModel::whereIn('goods_id', $ids)->select(['id','sku_name','price','cost_price','stock'])->get()->keyBy('id'); $skus = $skus?$skus->toArray() : []; $result = ['discount_point'=>$discountPoint,'profit_rate'=>$profitRate,'meal_type'=>0,'profit_total'=>0,'net_profit'=>0,'cost_total'=>0,'store_id'=>0,'discount_total'=>0.00,'delivery_fee'=>0.00,'goods_total'=>0,'order_total'=>0,'bd_score_total'=>0,'count'=>0,'goods'=>[]]; foreach ($goods as $params){ $goodsId = isset($params['id'])?$params['id']:0; $skuId = isset($params['sku_id'])?$params['sku_id']:0; $num = isset($params['num'])?$params['num']:0; $item = isset($list[$goodsId])?$list[$goodsId] : []; if(empty($item)){ continue; } $item['order_no'] = $orderNo; $id = isset($item['goods_id'])?$item['goods_id']:0; $goodsName = isset($item['goods_name'])?$item['goods_name']:''; $storeId = isset($item['store_id'])?$item['store_id']:0; $mealType = isset($item['meal_type'])?$item['meal_type']:0; $deliveryFee = isset($item['delivery_fee'])?$item['delivery_fee']:0; $bdScore = isset($item['bd_score'])?$item['bd_score']:0; $stock = isset($item['stock'])?$item['stock']:0; $skuType = isset($item['sku_type'])?$item['sku_type']: 1; $skuData = isset($skus[$skuId])? $skus[$skuId]:[]; $skuPrice = isset($skuData['price'])?$skuData['price']:0; $costPrice = isset($skuData['cost_price'])?$skuData['cost_price']:0; $skuStock = isset($skuData['stock'])?$skuData['stock']:0; $skuName = isset($skuData['sku_name'])?$skuData['sku_name']:''; $price = $skuType==2 ? $skuPrice : $item['price']; $goodsProfitRate = isset($item['profit_rate']) && $item['profit_rate']>0?$item['profit_rate']: 0; $profitRate = $goodsProfitRate>0 && $goodsProfitRate<100?$goodsProfitRate: $profitRate; $costPrice = $skuType==2 ? $costPrice : $item['cost_price']; unset($item['skus']); if(isset($item['type_name'])){ unset($item['type_name']); } if($result['store_id'] && $storeId != $result['store_id']){ $this->error = '一次只能购买同一个商家的商品,请核对后重试~'; return false; } if($stock<=0 || $num>$stock){ $this->error = $skuId? "商品[{$goodsName}]规格[{$skuName}]库存不足~" : "商品[{$goodsName}]库存不足~"; return false; } if($skuType==2 && ($skuStock<=0 || $num>$skuStock)){ $this->error = "商品[{$goodsName}]规格[{$skuName}]库存不足~"; return false; } if($num>0 && $goodsId == $id && $price>0){ $result['store_id'] = $storeId; $result['meal_type'] = $mealType; $result['delivery_fee'] = max($deliveryFee,$result['delivery_fee']); $item['user_id'] = $userId; $item['sku_id'] = $skuId; if(empty($orderNo)){ $item['sku'] = $skuData; } $item['price'] = $price; $item['bd_score'] = $bdScore; $item['total'] = $price; $costTotal = round(max(0,($costPrice) * $num),2); $profitTotal = round(max(0,($price-$costPrice) * $num),2); $netProfit = round($profitTotal * $profitRate/100, 2); $item['cost_price'] = $costTotal; $item['profit_total'] = $profitTotal; // 毛利 $item['net_profit'] = $netProfit; // 净利润 $item['num'] = $num; $total = round($price * $num,2); $item['total'] = $total; $item['thumb'] = $orderNo?get_image_path($item['thumb']):$item['thumb']; $result['goods'][] = $item; $result['goods_total'] += $total; $result['order_total'] += $total; $result['bd_score_total'] += $bdScore; $result['profit_total'] += $profitTotal; $result['cost_total'] += $costTotal; $result['net_profit'] += $netProfit; $result['count']++; } } // 会员折扣 $orderTotal = $result['order_total']; if($discountPoint>0 && $discountPoint<1){ $result['order_total'] = moneyFormat((1-$discountPoint) * $result['order_total'],2); $result['discount_total'] = moneyFormat($orderTotal - $result['order_total'],2); } $result['pay_total'] = floatval(moneyFormat($result['order_total'] + $result['delivery_fee'],2)); return $result; } return false; } }