15 changed files with 11139 additions and 7 deletions
-
5app/Constants/v3/SsdbKeys.php
-
8app/Controller/v3/GoodsRecommendController.php
-
54app/Controller/v3/SearchController.php
-
85app/Model/v3/Goods.php
-
37app/Model/v3/Store.php
-
42app/Request/v3/SearchGoodsRequest.php
-
15app/Service/v3/Implementations/GoodsService.php
-
90app/Service/v3/Implementations/SearchService.php
-
4app/Service/v3/Implementations/ShopCartService.php
-
3app/Service/v3/Interfaces/GoodsServiceInterface.php
-
13app/Service/v3/Interfaces/SearchServiceInterface.php
-
2app/Service/v3/Interfaces/ShopCartServiceInterface.php
-
10784composer.lock
-
1config/autoload/dependencies.php
-
3config/routes.php
@ -0,0 +1,54 @@ |
|||
<?php |
|||
|
|||
namespace App\Controller\v3; |
|||
|
|||
use App\Controller\BaseController; |
|||
use App\Request\v3\SearchGoodsRequest; |
|||
use App\Service\v3\Interfaces\SearchServiceInterface; |
|||
use Hyperf\Di\Annotation\Inject; |
|||
use Psr\Http\Message\ResponseInterface; |
|||
|
|||
class SearchController extends BaseController |
|||
{ |
|||
/** |
|||
* @Inject |
|||
* @var SearchServiceInterface |
|||
*/ |
|||
protected $searchService; |
|||
|
|||
/** |
|||
* 获取搜索热词 |
|||
* 1、参数type区分是商品还是商户 |
|||
* 2、不同type处理不同的service获取热词 |
|||
*/ |
|||
public function hotKeywords() |
|||
{ |
|||
|
|||
$type = $this->request->input('type', 'goods'); |
|||
$keywords = $this->searchService->getHotKeywords($type); |
|||
|
|||
return $this->success(['keywords' => $keywords]); |
|||
} |
|||
|
|||
/** |
|||
* 商品搜索 |
|||
* 1、筛选条件:商品分类、商品关键词 |
|||
* 2、排序:综合排序、销量最多、价格高/低 |
|||
* 3、返回数据格式,大购物车统计+商品数据含有id、封面图、名称、原价、现价、库存、月销、tag、规格、购物车相关、商户id、商户avatar、商户名 |
|||
* @param SearchGoodsRequest $request |
|||
* @return ResponseInterface |
|||
*/ |
|||
public function goods(SearchGoodsRequest $request) |
|||
{ |
|||
|
|||
$params = $request->validated(); |
|||
$data = $this->searchService->doForGoods($params); |
|||
|
|||
return $this->success(['goods' => $data]); |
|||
} |
|||
|
|||
public function stores() |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,85 @@ |
|||
<?php |
|||
|
|||
declare (strict_types=1); |
|||
namespace App\Model\v3; |
|||
|
|||
use App\Constants\v3\SsdbKeys; |
|||
use App\Model\Model; |
|||
use App\Service\v3\Interfaces\ShopCartServiceInterface; |
|||
use App\TaskWorker\SSDBTask; |
|||
use Hyperf\Database\Model\SoftDeletes; |
|||
use Hyperf\Utils\ApplicationContext; |
|||
use Hyperf\Di\Annotation\Inject; |
|||
|
|||
/** |
|||
*/ |
|||
class Goods extends Model |
|||
{ |
|||
use SoftDeletes; |
|||
|
|||
/** |
|||
* @Inject |
|||
* @var ShopCartServiceInterface |
|||
*/ |
|||
protected $shopCartService; |
|||
|
|||
/** |
|||
* The table associated with the model. |
|||
* |
|||
* @var string |
|||
*/ |
|||
protected $table = 'lanzu_goods'; |
|||
/** |
|||
* The attributes that are mass assignable. |
|||
* |
|||
* @var array |
|||
*/ |
|||
protected $fillable = []; |
|||
/** |
|||
* The attributes that should be cast to native types. |
|||
* |
|||
* @var array |
|||
*/ |
|||
protected $casts = [ |
|||
'details_imgs' => 'array', |
|||
'spec' => 'array', |
|||
'tags' => 'array', |
|||
]; |
|||
|
|||
protected $appends = [ |
|||
'month_sales', |
|||
'cart_num', |
|||
]; |
|||
|
|||
public function scopeOrderByDefault($query, $sort) |
|||
{ |
|||
return $query->orderBy('id', $sort); |
|||
} |
|||
|
|||
public function scopeOrderBySales($query, $sort) |
|||
{ |
|||
return $query->orderBy('sales', $sort); |
|||
} |
|||
|
|||
public function scopeOrderByPrice($query, $sort) |
|||
{ |
|||
return $query->orderBy('price', $sort); |
|||
} |
|||
|
|||
public function getMonthSalesAttribute() |
|||
{ |
|||
$ssdb = ApplicationContext::getContainer()->get(SSDBTask::class); |
|||
return (integer)$ssdb->exec('get', SsdbKeys::GOODS_MONTH_SALES.date('YM').'_'.$this->id); |
|||
} |
|||
|
|||
public function getCartNumAttribute() |
|||
{ |
|||
return (integer)$this->shopCartService->check($this->id); |
|||
} |
|||
|
|||
public function store() |
|||
{ |
|||
return $this->belongsTo(Store::class, 'store_id', 'id'); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,37 @@ |
|||
<?php |
|||
|
|||
declare (strict_types=1); |
|||
namespace App\Model\v3; |
|||
|
|||
use App\Model\Model; |
|||
use Hyperf\Database\Model\SoftDeletes; |
|||
|
|||
/** |
|||
*/ |
|||
class Store extends Model |
|||
{ |
|||
use SoftDeletes; |
|||
|
|||
/** |
|||
* The table associated with the model. |
|||
* |
|||
* @var string |
|||
*/ |
|||
protected $table = 'lanzu_store'; |
|||
/** |
|||
* The attributes that are mass assignable. |
|||
* |
|||
* @var array |
|||
*/ |
|||
protected $fillable = []; |
|||
/** |
|||
* The attributes that should be cast to native types. |
|||
* |
|||
* @var array |
|||
*/ |
|||
protected $casts = []; |
|||
|
|||
protected $appends = []; |
|||
|
|||
|
|||
} |
|||
@ -0,0 +1,42 @@ |
|||
<?php |
|||
|
|||
declare(strict_types=1); |
|||
|
|||
namespace App\Request\v3; |
|||
|
|||
use App\Request\BaseFormRequest; |
|||
|
|||
class SearchGoodsRequest extends BaseFormRequest |
|||
{ |
|||
|
|||
/** |
|||
* Get the validation rules that apply to the request. |
|||
*/ |
|||
public function rules(): array |
|||
{ |
|||
return [ |
|||
'market_id' => 'required|nonempty|integer', |
|||
'type_id' => 'nonempty|integer', |
|||
'keyword' => 'nonempty', |
|||
'order_by' => 'nonempty|in:default,sales,price', |
|||
'sort' => 'nonempty|in:asc,desc', |
|||
'page' => 'nonempty|integer', |
|||
'pagesize' => 'nonempty|integer', |
|||
]; |
|||
} |
|||
|
|||
/** |
|||
* @return array |
|||
*/ |
|||
public function messages(): array |
|||
{ |
|||
return [ |
|||
'*.*' => ':attribute无效', |
|||
]; |
|||
} |
|||
|
|||
public function attributes(): array |
|||
{ |
|||
return parent::attributes(); |
|||
} |
|||
} |
|||
@ -0,0 +1,90 @@ |
|||
<?php |
|||
|
|||
|
|||
namespace App\Service\v3\Implementations; |
|||
|
|||
|
|||
use App\Model\v3\Goods; |
|||
|
|||
class SearchService implements \App\Service\v3\Interfaces\SearchServiceInterface |
|||
{ |
|||
|
|||
public function doForGoods($params) |
|||
{ |
|||
|
|||
$builder = Goods::query() |
|||
->with(['store' => function($query) { |
|||
return $query->select(['id', 'logo', 'name']); |
|||
}]) |
|||
->where(['market_id' => $params['market_id']]) |
|||
->where('inventory', '>', 0); |
|||
|
|||
if (isset($params['type_id']) && $params['type_id']) { |
|||
$builder->where(['goods_type_id' => $params['type_id']]); |
|||
} |
|||
|
|||
if (isset($params['keyword']) && $params['keyword']) { |
|||
$builder->where('name', 'like', '%'.$params['keyword'].'%'); |
|||
} |
|||
|
|||
if (isset($params['order_by']) && $params['order_by']) { |
|||
$sort = $params['sort'] ?? 'desc'; |
|||
switch ($params['order_by']) { |
|||
case 'sales': |
|||
$builder->orderBySales($sort); |
|||
break; |
|||
case 'price': |
|||
$builder->orderByPrice($sort); |
|||
break; |
|||
default: |
|||
$builder->orderByDefault($sort); |
|||
break; |
|||
} |
|||
} |
|||
|
|||
$builder->select(['id', 'store_id', 'cover_img', 'name', 'spec', 'tags', 'original_price', 'price', 'inventory', 'sales as total_sales']); |
|||
$goods = $builder->forPage($params['page'], $params['pagesize'])->get()->toArray(); |
|||
|
|||
$data = []; |
|||
foreach ($goods as $key => &$item) { |
|||
$store = (object)$item['store']; |
|||
unset($item['store']); |
|||
$data[] = [ |
|||
'goods' => $item, |
|||
'store' => $store |
|||
]; |
|||
} |
|||
|
|||
return $data; |
|||
} |
|||
|
|||
public function doForStores() |
|||
{ |
|||
// TODO: Implement doForStores() method.
|
|||
} |
|||
|
|||
public function getHotKeywords($type) |
|||
{ |
|||
$keywords = [ |
|||
'goods' => ['酱油','油','生蚝'], |
|||
'store' => ['黄姐','王姐','黄姐蔬菜摊'], |
|||
]; |
|||
|
|||
return $keywords[$type]; |
|||
} |
|||
|
|||
public function do() |
|||
{ |
|||
// TODO: Implement do() method.
|
|||
} |
|||
|
|||
public function check() |
|||
{ |
|||
// TODO: Implement check() method.
|
|||
} |
|||
|
|||
public function undo() |
|||
{ |
|||
// TODO: Implement undo() method.
|
|||
} |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
<?php |
|||
|
|||
namespace App\Service\v3\Interfaces; |
|||
|
|||
interface SearchServiceInterface |
|||
{ |
|||
public function doForGoods($params); |
|||
public function doForStores(); |
|||
public function getHotKeywords($type); |
|||
public function do(); |
|||
public function check(); |
|||
public function undo(); |
|||
} |
|||
10784
composer.lock
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
Write
Preview
Loading…
Cancel
Save
Reference in new issue