Bläddra i källkod

购物车以及商品搜索

panghu 8 månader sedan
förälder
incheckning
533ee1b36a

+ 65 - 0
app/Http/Controllers/Api/GoodsController.php

@@ -6,7 +6,9 @@ namespace App\Http\Controllers\Api;
 use App\Http\Controllers\ApiController;
 use App\Models\Goods;
 use App\Models\GoodsCategory;
+use App\Models\GoodsSearch;
 use App\Servers\CommonServer;
+use App\Servers\GoodsServer;
 use App\Servers\GoodsSpecServer;
 
 /**
@@ -88,4 +90,67 @@ class GoodsController extends ApiController
         return $this->apiResponseSuccess('成功',$sku);
     }
 
+
+    /**
+     * 搜索商家商品
+     */
+    function getSearchGoodsList()
+    {
+        $m_id = $this->getMemberId();//用户id
+        $commonServer = CommonServer::creatServer();
+        $search = $commonServer->filtrationStr('search');//搜索
+        $shop_id = $commonServer->filtrationStr('shop_id');//商品id
+
+        if (empty($shop_id)) return $this->apiResponseError('请选择商家');
+        if (empty($search)) return $this->apiResponseSuccess('请输入搜索内容');
+        //记录搜索
+        GoodsServer::creatServer()->setSearch($m_id,$shop_id, $search);
+
+        //查询该关键词下的商品
+        $list = Goods::where('is_del',0)
+            ->where('status',1)
+            ->where('shop_id',$shop_id)
+            ->where('goods_name','like',"%$search%")
+            ->select(['id as goods_id','category_id','goods_name','goods_desc','goods_image','price','spec_type','line_price','sales','is_infinite','stock'])
+            ->orderBy('sort','desc')
+            ->paginate(10);
+        return $this->apiResponseSuccess('获取成功', [
+            'items' => $list->items(),
+            'total' => $list->total(),
+            'limit' => 10,
+        ]);
+    }
+
+    /**
+     * 获取搜索内容
+     */
+    function getSearchList()
+    {
+        $m_id = $this->getMemberId();//用户id
+        $commonServer = CommonServer::creatServer();
+        $shop_id = $commonServer->filtrationStr('shop_id');//商品id
+
+        if (empty($shop_id)) return $this->apiResponseError('请选择商家');
+        $data = GoodsServer::creatServer()->getSearch($m_id,$shop_id);
+        return $this->apiResponseSuccess('获取数据成功', $data);
+    }
+
+
+    /**
+     * 清除搜索记录
+     */
+    function delSearch()
+    {
+        $m_id = $this->getMemberId();//用户id
+        $commonServer = CommonServer::creatServer();
+        $shop_id = $commonServer->filtrationStr('shop_id');//商品id
+
+        if (empty($shop_id)) return $this->apiResponseError('请选择商家');
+
+        $res = GoodsSearch::where('m_id', $m_id)->where('shop_id',$shop_id)->delete();
+        if (!$res){
+            return $this->apiResponseError('清除失败');
+        }
+        return $this->apiResponseSuccess('清除成功');
+    }
 }

+ 79 - 0
app/Http/Controllers/Api/ShoppingController.php

@@ -0,0 +1,79 @@
+<?php
+
+namespace App\Http\Controllers\Api;
+
+
+
+use App\Http\Controllers\ApiController;
+use App\Servers\CommonServer;
+use App\Servers\ShoppingCartServer;
+
+/**
+ * 购物车服务
+ */
+class ShoppingController extends ApiController
+{
+    /**
+     * 获取购物车列表
+     */
+    function getShoppingList()
+    {
+        $commonServer = CommonServer::creatServer();
+        $m_id = $this->getMemberId();//用户id
+        $shop_id = $commonServer->filtrationStr('shop_id');//商家id
+
+        if (empty($shop_id)) return $this->apiResponseError('请选择商家');
+        $data = ShoppingCartServer::creatServer()->getShoppingList($m_id,$shop_id);
+
+        return $this->apiResponseSuccess('成功',$data);
+    }
+
+    /**
+     * 更新购物车数量
+     */
+    function saveShoppingNumber()
+    {
+
+        $commonServer = CommonServer::creatServer();
+        $m_id = $this->getMemberId();//用户id
+        $goods_id = $commonServer->filtrationStr('goods_id');//商品id
+        $shop_id = $commonServer->filtrationStr('shop_id');//商家id
+        $category_id = $commonServer->filtrationStr('category_id');//分类id
+        $goods_spec_id = $commonServer->filtrationStr('goods_spec_id',0);//商品规格id
+        $number = $commonServer->filtrationStr('number',0);//数量
+
+        if (empty($goods_id)) return $this->apiResponseError('请选择商品');
+
+
+        if (empty($shop_id)) return $this->apiResponseError('请选择商家');
+        if (empty($category_id)) return $this->apiResponseError('类目错误');
+        $result = ShoppingCartServer::creatServer()->saveShopping($m_id,$shop_id,$category_id,$goods_id,$goods_spec_id,$number);
+
+        if ($result['code'] == 0) {
+            return $this->apiResponseError($result['msg']);
+        }
+
+        return $this->apiResponseSuccess($result['msg'],[],$result['code']);
+    }
+
+    /**
+     * 删除购物车
+     */
+    function delShopping()
+    {
+        $commonServer = CommonServer::creatServer();
+        $m_id = $this->getMemberId();//用户id
+        $shop_id = $commonServer->filtrationStr('shop_id');//商家id
+        if (empty($shop_id)) return $this->apiResponseError('请选择商家');
+
+        $result = ShoppingCartServer::creatServer()->delShopping($m_id,$shop_id);
+
+        if ($result['code'] == 0) {
+            return $this->apiResponseError($result['msg']);
+        }
+
+        return $this->apiResponseSuccess($result['msg']);
+
+    }
+
+}

+ 44 - 0
app/Models/GoodsSearch.php

@@ -0,0 +1,44 @@
+<?php
+
+namespace App\Models;
+
+use DateTimeInterface;
+use Illuminate\Database\Eloquent\Model;
+
+/**
+ * 会员搜索表
+ */
+class GoodsSearch extends Model
+{
+    /**
+     * The table associated with the model.
+     *
+     * @var string
+     */
+    protected $table = 'goods_search';
+
+    /**
+     * The primary key associated with the table.
+     *
+     * @var string
+     */
+    protected $primaryKey = 'id';
+
+    /**
+     * Indicates if the model should be timestamped.
+     *
+     * @var bool
+     */
+    public $timestamps = true;
+
+
+    /**
+     * 不能被批量赋值的属性
+     *
+     * @var array
+     */
+    protected $guarded = ['id', 'updated_at', 'created_at'];
+
+
+
+}

+ 44 - 0
app/Models/SearchStr.php

@@ -0,0 +1,44 @@
+<?php
+
+namespace App\Models;
+
+use DateTimeInterface;
+use Illuminate\Database\Eloquent\Model;
+
+/**
+ * 搜索关键词表
+ */
+class SearchStr extends Model
+{
+    /**
+     * The table associated with the model.
+     *
+     * @var string
+     */
+    protected $table = 'search_str';
+
+    /**
+     * The primary key associated with the table.
+     *
+     * @var string
+     */
+    protected $primaryKey = 'id';
+
+    /**
+     * Indicates if the model should be timestamped.
+     *
+     * @var bool
+     */
+    public $timestamps = true;
+
+
+    /**
+     * 不能被批量赋值的属性
+     *
+     * @var array
+     */
+    protected $guarded = ['id', 'updated_at', 'created_at'];
+
+
+
+}

+ 43 - 0
app/Models/Shopping.php

@@ -0,0 +1,43 @@
+<?php
+
+namespace App\Models;
+
+use DateTimeInterface;
+use Illuminate\Database\Eloquent\Model;
+
+/**
+ * 购物车表
+ */
+class Shopping extends Model
+{
+    /**
+     * The table associated with the model.
+     *
+     * @var string
+     */
+    protected $table = 'shopping';
+
+    /**
+     * The primary key associated with the table.
+     *
+     * @var string
+     */
+    protected $primaryKey = 'id';
+
+    /**
+     * Indicates if the model should be timestamped.
+     *
+     * @var bool
+     */
+    public $timestamps = true;
+
+
+    /**
+     * 不能被批量赋值的属性
+     *
+     * @var array
+     */
+    protected $guarded = ['id', 'updated_at', 'created_at'];
+
+
+}

+ 81 - 0
app/Servers/GoodsServer.php

@@ -0,0 +1,81 @@
+<?php
+
+namespace App\Servers;
+
+use App\Models\GoodsSearch;
+use App\Models\SearchStr;
+use Illuminate\Support\Facades\DB;
+
+/**
+ * 商品服务
+ */
+class GoodsServer
+{
+    static private $server = '';
+
+    private function __construct()
+    {
+
+    }
+
+    /**
+     * 创建对象
+     * @return GoodsServer
+     */
+    static function creatServer()
+    {
+        if (empty(self::$server)) {
+            self::$server = new  GoodsServer();
+        }
+        return self::$server;
+    }
+
+    /**
+     * 记录搜索信息
+     * @param $m_id
+     * @param $shop_id
+     * @param $search
+     * @return bool
+     */
+    function setSearch($m_id,$shop_id, $search)
+    {
+        $search = strip_tags($search);
+        $search = trim($search);
+        if (empty($search)) return false;
+        $search_id = SearchStr::where('search_str', $search)->where('shop_id',$shop_id)->value('id');
+        if (empty($search_id)) {
+            $search_info = SearchStr::create(['search_str' => $search, 'num' => 1, 'shop_id' => $shop_id]);
+            GoodsSearch::create(['m_id' => $m_id, 'search_id' => $search_info->{'id'}, 'num' => 1, 'shop_id' => $shop_id]);
+        } else {
+            SearchStr::where('id', $search_id)->increment('num');
+            $id = GoodsSearch::where('m_id', $m_id)->where('search_id', $search_id)->value('id');
+            if (empty($id)) {
+                GoodsSearch::create(['m_id' => $m_id, 'search_id' => $search_id, 'num' => 1, 'shop_id' => $shop_id]);
+            } else {
+                GoodsSearch::where('id', $id)->increment('num');
+            }
+        }
+        return true;
+    }
+
+    /**
+     * 获取搜索关键信息
+     * @param $m_id
+     * @param $shop_id
+     * @return array
+     */
+    function getSearch($m_id,$shop_id)
+    {
+//        $hot_search = SearchStr::orderBy('type', 'desc')->orderBy('num', 'desc')->limit(10)->pluck('search_str');//热门搜索
+        $hot_search = [];
+        $my_search = GoodsSearch::from('goods_search as g')
+            ->leftJoin('search_str as s', 's.id', '=', 'g.search_id')
+            ->where('g.m_id', $m_id)
+            ->where('g.shop_id', $shop_id)
+            ->orderBy('g.id','desc')
+            ->limit(30)
+            ->pluck('s.search_str');
+
+        return ['hot_search' => $hot_search, 'my_search' => $my_search];
+    }
+}

+ 248 - 0
app/Servers/ShoppingCartServer.php

@@ -0,0 +1,248 @@
+<?php
+
+
+namespace App\Servers;
+
+
+
+
+use App\Models\Goods;
+use App\Models\GoodsSku;
+use App\Models\GoodsSpec;
+use App\Models\Shopping;
+
+/**
+ * 购物车服务
+ */
+class ShoppingCartServer
+{
+
+    static private $server = null;
+
+
+    private $errorMsg = '';
+
+    private function __construct()
+    {
+
+    }
+
+    /**
+     * 创建对象
+     * @return ShoppingCartServer
+     */
+    static function creatServer()
+    {
+        if (empty(self::$server)) self::$server = new ShoppingCartServer();
+        return self::$server;
+    }
+
+
+    /**
+     * 获取购物车列表
+     * @param $m_id
+     * @param $shop_id
+     * @return array
+     */
+    function getShoppingList($m_id,$shop_id)
+    {
+        //获取购物车商品数据
+        $where = [['p.m_id',$m_id], ['p.shop_id',$shop_id], ['p.type',1], ['g.is_del',0], ['g.status',1]];
+        $shopping =  Shopping::from('shopping as p')
+            ->leftJoin('goods as g','g.id','=','p.goods_id')
+            ->where($where)
+            ->select(['p.id as shopping_id','p.number','p.goods_spec_id','g.id as goods_id','g.shop_id','g.goods_name','g.goods_image','g.price','g.spec_type','g.category_id','g.pack_price','g.is_infinite','g.stock'])
+            ->orderBy('p.id','asc')
+            ->get();
+
+        $total_num = 0;//总商品数
+        $total_goods_money = '0.00';//总商品费用
+        $total_pack_price = 0;//打包费
+        $goods_list = [];//商品列表
+        $goodsNumber = [];//记录商品一共点了多少,判断是否限购超库存
+
+        foreach ($shopping as $value){
+            $goods_id = $value->{'goods_id'};//商品id
+            $goods_price = $value->{'price'};//商品金额
+            $spec_type = $value->{'spec_type'};//商品类型
+            $goods_spec_id = $value->{'goods_spec_id'};//商品规格id
+            $status_str = '';
+            $goods_attr = "";//规则值
+            $goods_number = $value['number'];//商品数量
+            $goods_spec = [];
+            //记录商品一共点了多少,判断是否限购超库存
+            if (isset($goodsNumber[$goods_id])){
+                $goodsNumber[$goods_id] = bcadd($goodsNumber[$goods_id],$goods_number);
+            }else{
+                $goodsNumber[$goods_id] = $goods_number;
+            }
+
+            if ($goods_spec_id && $spec_type == 2){//存在规格
+                $specIds = array_filter(explode('_', $goods_spec_id));
+                $goods_spec = GoodsSpec::where('goods_id',$goods_id)
+                    ->whereIn('id',$specIds)
+                    ->where('is_del',0)
+                    ->select(['spec_name','spec_price'])
+                    ->get();
+                foreach ($goods_spec as $spec_value){
+                    $goods_attr .= $spec_value['spec_name'] . ',';
+                    $goods_price = bcadd($spec_value['spec_price'],$goods_price,2);
+                }
+            }
+            //商品不是无限库存,判断库存是否足够
+            if ($value->{'is_infinite'} != 1){
+                if ($value->{'stock'} < $goodsNumber[$goods_id]){
+                    $status_str = '库存不足';
+                    $this->errorMsg = $value['goods_name'].'库存不足';
+                }
+            }
+            //计算价格
+            $goods_money = bcmul($goods_price,$goods_number,2);
+
+
+            $goods_list[] = [
+                'shop_id' => $value['shop_id'],
+                'category_id' => $value['category_id'],
+                'goods_id' => $goods_id,
+                'goods_spec_id' => $goods_spec_id,
+                'goods_money' => rtrim(rtrim($goods_money, '0'),'.'),
+                'goods_number' => $goods_number,
+                'goods_name' => $value['goods_name'],
+                'goods_image' => $value['goods_image'],
+                'spec_type' => $value['spec_type'],
+                'price' => $goods_price,
+                'pack_price' => $value['pack_price'],
+                'goods_attr' => $goods_attr,
+                'is_infinite' => $value['is_infinite'],
+                'status_str' => $status_str,
+            ];
+            //计算打包费
+            $total_pack_price = bcadd($total_pack_price,bcmul($goods_number,$value['pack_price'],2),2);
+            //计算总数量
+            $total_num += $goods_number;
+            //计算总商品费用
+            $total_goods_money = bcadd($total_goods_money,$goods_money,2);
+        }
+        //订单总价-商品总价+总包装费
+        $total_price = bcadd($total_goods_money,$total_pack_price,2);
+
+        $data['total_price'] = rtrim(rtrim($total_price, '0'),'.');
+        $data['total_num'] = (int)$total_num;
+        $data['total_goods_money'] = rtrim(rtrim($total_goods_money, '0'),'.');
+        $data['pack_price'] = $total_pack_price;
+        $data['err_msg'] = $this->errorMsg;
+        $data['goods_list'] = $goods_list;
+
+        $this->errorMsg = '';
+
+        return $data;
+    }
+
+    /**
+     * 添加购物车
+     * @param $m_id
+     * @param $shop_id
+     * @param $category_id
+     * @param $goods_id
+     * @param $goods_spec_id
+     * @param $number
+     * @return array
+     */
+    function saveShopping($m_id,$shop_id,$category_id,$goods_id,$goods_spec_id,$number)
+    {
+        if (empty($goods_spec_id)){
+            $goods_spec_id = '';
+        }
+        //获取商品
+        $goods = Goods::where('is_del',0)
+            ->where('id',$goods_id)
+            ->where('shop_id',$shop_id)
+            ->where('category_id',$category_id)
+            ->select(['id as goods_id','is_infinite','stock','status','spec_type'])
+            ->first();
+        if (empty($goods)) return ['code' => 0, 'msg' => '当前商品不存在'];
+        if ($goods->{'status'} != 1) return ['code' => 0, 'msg' => '当前商品已下架'];
+        //如果商品是多规格但是没选规格
+        if ($goods->{'spec_type'} == 2 && empty($goods_spec_id)){
+            return ['code' => 0, 'msg' => '请选择商品规格'];
+        }elseif ($goods->{'spec_type'} == 2 && $goods_spec_id){
+            //如果商品是多规格,查询规格商品是否选择全
+            $skuIds = GoodsSku::where('goods_id',$goods->{'goods_id'})->where('is_del',0)->pluck('id')->toArray();
+            $spec = array_filter(explode('_', $goods_spec_id));
+            foreach ($skuIds as $skuId){
+                $specIds = GoodsSpec::where('goods_id',$goods->{'goods_id'})->where('is_del',0)->where('sku_id',$skuId)->pluck('id')->toArray();
+
+                if (!array_intersect($spec,$specIds)){
+                    return ['code' => 0, 'msg' => '请完整选择规格'];
+                }
+            }
+        }
+
+        //获取购物车是否存在此商品
+        $where = [['m_id',$m_id], ['shop_id',$shop_id], ['category_id',$category_id], ['goods_id',$goods_id]];
+        //获取此商品数量
+        $shopping_number = Shopping::where($where)->sum('number');
+        $total_number = bcadd($shopping_number,$number);
+        if ($goods_spec_id) $where[] = ['goods_spec_id',$goods_spec_id];
+        //查询
+        $shopping_info = Shopping::where($where)->select(['id', 'goods_id', 'number'])->first();
+
+        //商品不是无限库存,判断库存是否足够
+        if ($goods->{'is_infinite'} != 1){
+            if ($goods->{'stock'} < $total_number){
+                return ['code' => 0, 'msg' => '商品库存余'.$goods->{'stock'}.'份'];
+            }
+        }
+        if (empty($shopping_info)) {
+            if ($number <= 0){
+                return ['code' => 0, 'msg' => '请选择数量'];
+            }
+
+            //入库
+            $shopping = Shopping::create([
+                'm_id' => $m_id,
+                'type' => 1,
+                'shop_id' => $shop_id,
+                'category_id' => $category_id,
+                'goods_id' => $goods_id,
+                'goods_spec_id' => $goods_spec_id,
+                'number' => $number,
+            ]);
+
+        }else{
+            if ($number <= 0){//数量为0直接删除
+                $shopping = Shopping::where('id',$shopping_info->{'id'})->delete();
+            }else{
+                $shopping = Shopping::where('id',$shopping_info->{'id'})->update(['number' => $number]);
+            }
+        }
+
+        if (empty($shopping)){
+            return ['code' => 0, 'msg' => '添加失败'];
+        }
+
+        return ['code' => 1, 'msg' => '添加成功'];
+    }
+
+
+    /**
+     * 删除购物车
+     * @param $m_id
+     * @param $shop_id
+     * @return array
+     */
+    function delShopping($m_id,$shop_id)
+    {
+        //删除数据
+        $where = [['m_id',$m_id], ['shop_id',$shop_id]];
+
+        $res =  Shopping::where($where)->delete();
+
+        if (empty($res)){
+            return ['code' => 0, 'msg' => '删除失败'];
+        }
+
+        return ['code' => 1, 'msg' => '删除成功'];
+    }
+
+}

+ 4 - 1
routes/api/goods.php

@@ -4,10 +4,13 @@ use Illuminate\Support\Facades\Route;
 
 
 
-Route::group(['domain' => env('APP_USER_API'), 'prefix' => 'goods'],function (){
+Route::group(['domain' => env('APP_HOST_API'), 'prefix' => 'goods'],function (){
     Route::match(['get','post'],'category', 'GoodsController@getShopCategoryList')->name('goods.category');//获取商家分类
     Route::match(['get','post'],'goods', 'GoodsController@getShopGoodsList')->name('goods.goods');//获取商家分类商品
     Route::match(['get','post'],'goodsSpec', 'GoodsController@getGoodsSpec')->name('goods.goodsSpec');//获取商品sku
 
+    Route::match(['get','post'],'search', 'GoodsController@getSearchGoodsList')->name('goods.search');//搜索商品
+    Route::match(['get','post'],'search_list', 'GoodsController@getSearchList')->name('goods.search_list');//获取搜索记录
+    Route::match(['get','post'],'del_search', 'GoodsController@delSearch')->name('goods.del_search');//删除搜索记录
 
 });

+ 12 - 0
routes/api/shopping.php

@@ -0,0 +1,12 @@
+<?php
+
+use Illuminate\Support\Facades\Route;
+
+
+
+Route::group(['domain' => env('APP_HOST_API'), 'prefix' => 'shopping'],function (){
+    Route::match(['get','post'],'list', 'ShoppingController@getShoppingList')->name('shopping.list');//获取购物车
+    Route::match(['get','post'],'save', 'ShoppingController@saveShoppingNumber')->name('shopping.save');//添加/更新购物车
+    Route::match(['get','post'],'del', 'ShoppingController@delShopping')->name('shopping.del');//删除购物车
+
+});