where('goods_id',$data['goods_id'])->sum('stock_num'); } /** * 计算显示销量 (初始销量 + 实际销量) */ public function getGoodsSalesAttr($value, $data) { return $data['sales_initial'] + $data['sales_actual']; } /** * 计算月销量 */ public function getMonthSalesAttr($value, $data) { $time = time()-(30*24*60*60); return OrderGoods::where('goods_id',$data['goods_id']) ->where('create_time','>',$time) ->sum('total_num'); } /** * 关联商品分类表 */ public function category() { return $this->belongsTo('app\\common\\model\\food\\Category','category_id'); } /** * 关联商品规格表 */ public function spec() { return $this->hasMany('app\\common\\model\\food\\GoodsSpec','goods_id')->order(['goods_spec_id' => 'asc']); } /** * 关联商品规格关系表 */ public function specRel() { return $this->belongsToMany('app\\common\\model\\food\\SpecValue', 'app\\common\\model\\food\\GoodsSpecRel','spec_value_id','goods_id'); } /** * 关联商品图片表 */ public function image() { return $this->hasMany('app\\common\\model\\food\\GoodsImage','goods_id')->order(['id' => 'asc']); } /** * 显示状态 */ public function getGoodsStatusAttr($value) { $status = [10 => '上架', 20 => '下架']; return ['text' => $status[$value], 'value' => $value]; } /** * 是否推荐 */ public function getIsRecommendAttr($value) { $status = ['否', '是']; return ['text' => $status[$value], 'value' => $value]; } /** * 获取商品列表 */ public function getList($shop_id = 0,$status = 0, $category_id = 0, string $search = '', $sortType = 'all', $sortPrice = false) { // 筛选条件 $filter = []; $shop_id > 0 && $filter['shop_id'] = $shop_id; $status > 0 && $filter['goods_status'] = $status; $category_id > 0 && $filter['category_id'] = $category_id; !empty($search) && $filter['goods_name'] = ['like', '%' . trim($search) . '%']; // 排序规则 $sort = []; if ($sortType === 'all') { $sort = ['goods_sort', 'goods_id' => 'desc']; } elseif ($sortType === 'sales') { $sort = ['goods_sales' => 'desc']; } elseif ($sortType === 'price') { $sort = $sortPrice ? ['goods_max_price' => 'desc'] : ['goods_min_price']; } // 商品表名称 $tableName = $this->getTable(); // 多规格商品 最高价与最低价 $GoodsSpec = new GoodsSpec; $minPriceSql = $GoodsSpec->field(['MIN(goods_price)']) ->where('goods_id', 'EXP', "= `$tableName`.`goods_id`")->buildSql(); $maxPriceSql = $GoodsSpec->field(['MAX(goods_price)']) ->where('goods_id', 'EXP', "= `$tableName`.`goods_id`")->buildSql(); // 执行查询 $list = $this->field(['*', '(sales_initial + sales_actual) as goods_sales', "$minPriceSql AS goods_min_price", "$maxPriceSql AS goods_max_price" ])->with(['category', 'image.file', 'spec', 'spec.image']) ->where('is_delete', '=', 0) ->where($filter) ->order($sort) ->paginate(['list_rows'=>15,'query' => request()->param()]); return $list; } /** * 获取商品详情 */ public static function detail($id) { return self::with(['category', 'image.file', 'spec', 'spec.image', 'spec_rel.spec'])->find($id); } /** * 清除商品记录 */ public function remove($goods_id) { $filter['goods_id'] = $goods_id; // 开启事务 Db::startTrans(); try { $this->where($filter)->delete(); GoodsImage::where($filter)->delete(); GoodsSpec::where($filter)->delete(); GoodsSpecRel::where($filter)->delete(); Db::commit(); return true; } catch (\Exception $e) { Db::rollback(); } return false; } /** * 设置商品上下架 */ public function status() { $this->goods_status['value'] == 10 ? $this->goods_status = 20 :$this->goods_status = 10; return $this->save() !== false; } /** * 获取商品总数 */ public static function getCount($shop_id=0) { // 筛选条件 $filter = []; $shop_id > 0 && $filter['shop_id'] = $shop_id; return self::where($filter)->count(); } /** * 更新商品库存销量 * */ public function updateStockSales($goodsList,$stock = false,$inc= true) { // 整理批量更新商品销量 $goodsSave = []; // 批量更新商品规格:sku销量、库存 $goodsSpecSave = []; foreach ($goodsList as $goods) { if($inc){ //判断商品是否存在 if($model = (new Goods)->get($goods['goods_id'])){ //增加销量 $model->sales_actual = ['inc', $goods['total_num']]; $model->save(); $model = (new GoodsSpec)->get($goods['goods_spec_id']); $model->goods_sales = ['inc', $goods['total_num']]; // 判断是否减库存 if ($stock) { if($model->stock_num > $goods['total_num']){ $model->stock_num = ['dec', $goods['total_num']]; }else{ $model->stock_num = 0; } } $model->save(); } }else{ //退销量 if($goods['refund_num'] > 0){ if($model = (new Goods)->get($goods['goods_id'])){ if($model->sales_actual > $goods['refund_num']){ $model->sales_actual = ['dec', $goods['refund_num']]; }else{ $model->sales_actual = 0; } $model->save(); $model = (new GoodsSpec)->get($goods['goods_spec_id']); if($model->goods_sales > $goods['refund_num']){ $model->goods_sales = ['dec', $goods['refund_num']]; }else{ $model->goods_sales = 0; } // 判断是否减库存 if ($stock) { $model->stock_num = ['inc', $goods['refund_num']]; } $model->save(); } } } } return true; } /** * 获取商品列表 - DIY组件 */ public static function getAll($shop_id = 0,$sortType = 'all',$limit=null) { // 筛选条件 $filter = []; $filter['goods_status'] = 10; $shop_id > 0 && $filter['shop_id'] = $shop_id; if($sortType == 'recommend'){ $filter['is_recommend'] = 1;//推荐商品 } // 排序规则 $sort = []; if ($sortType === 'all') { $sort = ['sales_actual', 'goods_id' => 'desc']; } elseif ($sortType === 'sales') { $sort = ['goods_sales' => 'desc']; } elseif ($sortType === 'new') { $sort = ['goods_id' => 'desc']; } // 执行查询 return self::with(['category', 'image.file', 'spec', 'spec.image']) ->field(['*','(sales_initial + sales_actual) as goods_sales']) ->where('is_delete', '=', 0) ->where($filter) ->order($sort) ->limit($limit) ->select(); } /** * 猜您喜欢 */ public function getBestList($shop_id = 0,$limit=10) { // 筛选条件 $filter = []; $filter['goods_status'] = 10; $filter['is_delete'] = 0; $shop_id > 0 && $filter['shop_id'] = $shop_id; return $this->with(['spec', 'category', 'image.file']) ->where($filter) ->order(['sales_initial' => 'desc', 'goods_sort' => 'asc']) ->limit($limit) ->select(); } /** * 商品多规格信息 */ public function getGoodsSku(string $goods_sku_id = '') { $goodsSkuData = array_column($this['spec']->toArray(), null, 'spec_sku_id'); if (!isset($goodsSkuData[$goods_sku_id])) { return false; } $goods_sku = $goodsSkuData[$goods_sku_id]; // 多规格文字内容 $goods_sku['goods_attr'] = ''; if ($this['spec_type'] == 20) { $attrs = explode('_', $goods_sku['spec_sku_id']); $spec_rel = array_column($this['spec_rel']->toArray(), null, 'spec_value_id'); foreach ($attrs as $specValueId) { if(!empty($goods_sku['goods_attr'])){ $goods_sku['goods_attr'] .= '/'; } /*$goods_sku['goods_attr'] .= $spec_rel[$specValueId]['spec']['spec_name'] . ':' . $spec_rel[$specValueId]['spec_value'];*/ $goods_sku['goods_attr'] .= $spec_rel[$specValueId]['spec_value']; } } return $goods_sku; } /** * 获取规格信息 */ public function getManySpecData($spec_rel, $spec) { // spec_attr $specAttrData = []; foreach ($spec_rel as $item) { if (!isset($specAttrData[$item['spec_id']])) { $specAttrData[$item['spec_id']] = [ 'group_id' => $item['spec']['spec_id'], 'group_name' => $item['spec']['spec_name'], 'spec_items' => [], ]; } $specAttrData[$item['spec_id']]['spec_items'][] = [ 'item_id' => $item['spec_value_id'], 'spec_value' => $item['spec_value'], ]; } // spec_list $specListData = []; foreach ($spec as $item) { $image = (isset($item['image']) && !empty($item['image'])) ? $item['image'] : ['file_id' => 0, 'url' => '']; $spec_name = ''; $spec_id_list = explode('_',$item['spec_sku_id']); for($n=0;$n $item['goods_spec_id'], 'spec_sku_id' => $item['spec_sku_id'], 'spec_name' => $spec_name, 'rows' => [], 'form' => [ 'image_id' => $image['file_id'], 'image_url' => $image['url'], 'goods_no' => $item['goods_no'], 'goods_price' => $item['goods_price'], 'line_price' => $item['line_price'], 'stock_num' => $item['stock_num'] ], ]; } return ['spec_attr' => array_values($specAttrData), 'spec_list' => $specListData]; } }