Browse Source

热词、商品搜索

master
weigang 5 years ago
parent
commit
8643064f2c
  1. 5
      app/Constants/v3/SsdbKeys.php
  2. 8
      app/Controller/v3/GoodsRecommendController.php
  3. 54
      app/Controller/v3/SearchController.php
  4. 85
      app/Model/v3/Goods.php
  5. 37
      app/Model/v3/Store.php
  6. 42
      app/Request/v3/SearchGoodsRequest.php
  7. 15
      app/Service/v3/Implementations/GoodsService.php
  8. 90
      app/Service/v3/Implementations/SearchService.php
  9. 4
      app/Service/v3/Implementations/ShopCartService.php
  10. 3
      app/Service/v3/Interfaces/GoodsServiceInterface.php
  11. 13
      app/Service/v3/Interfaces/SearchServiceInterface.php
  12. 2
      app/Service/v3/Interfaces/ShopCartServiceInterface.php
  13. 10784
      composer.lock
  14. 1
      config/autoload/dependencies.php
  15. 3
      config/routes.php

5
app/Constants/v3/SsdbKeys.php

@ -14,4 +14,9 @@ class SsdbKeys extends AbstractConstants
* @Message("短信验证码")
*/
const VERIFY_CODE = 'verify_code_';
/**
* @Message("商品月销")
*/
const GOODS_MONTH_SALES = 'goods_m_sales_';
}

8
app/Controller/v3/GoodsRecommendController.php

@ -33,7 +33,7 @@ class GoodsRecommendController extends BaseController
'spec' => [
['key' => '净含量', 'value' => '500g']
],
'tag' => ['限时', '折扣'],
'tags' => ['限时', '折扣'],
'original_price' => 50.5,
'price' => 25.25,
'inventory' => 10,
@ -56,7 +56,7 @@ class GoodsRecommendController extends BaseController
'spec' => [
['key' => '净含量', 'value' => '500g']
],
'tag' => ['限时', '折扣'],
'tags' => ['限时', '折扣'],
'original_price' => 50.5,
'price' => 25.25,
'inventory' => 10,
@ -78,7 +78,7 @@ class GoodsRecommendController extends BaseController
'spec' => [
['key' => '净含量', 'value' => '500g']
],
'tag' => ['限时', '折扣'],
'tags' => ['限时', '折扣'],
'original_price' => 50.5,
'price' => 25.25,
'inventory' => 10,
@ -100,7 +100,7 @@ class GoodsRecommendController extends BaseController
'spec' => [
['key' => '净含量', 'value' => '500g']
],
'tag' => ['限时', '折扣'],
'tags' => ['限时', '折扣'],
'original_price' => 50.5,
'price' => 25.25,
'inventory' => 10,

54
app/Controller/v3/SearchController.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()
{
}
}

85
app/Model/v3/Goods.php

@ -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');
}
}

37
app/Model/v3/Store.php

@ -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 = [];
}

42
app/Request/v3/SearchGoodsRequest.php

@ -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();
}
}

15
app/Service/v3/Implementations/GoodsService.php

@ -53,4 +53,19 @@ class GoodsService implements GoodsServiceInterface
];
return $spec;
}
public function do()
{
// TODO: Implement do() method.
}
public function check($goodsId)
{
// TODO: Implement check() method.
}
public function undo()
{
// TODO: Implement undo() method.
}
}

90
app/Service/v3/Implementations/SearchService.php

@ -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.
}
}

4
app/Service/v3/Implementations/ShopCartService.php

@ -55,9 +55,9 @@ class ShopCartService implements ShopCartServiceInterface
return $res;
}
public function check()
public function check($goodsId)
{
// TODO: Implement check() method.
return mt_rand(0,6);
}
public function undo()

3
app/Service/v3/Interfaces/GoodsServiceInterface.php

@ -4,5 +4,8 @@ namespace App\Service\v3\Interfaces;
interface GoodsServiceInterface
{
public function do();
public function check($goodsId);
public function undo();
public function detail();
}

13
app/Service/v3/Interfaces/SearchServiceInterface.php

@ -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();
}

2
app/Service/v3/Interfaces/ShopCartServiceInterface.php

@ -6,7 +6,7 @@ interface ShopCartServiceInterface
{
public function detail();
public function check();
public function check($goodsId);
public function undo();
}

10784
composer.lock
File diff suppressed because it is too large
View File

1
config/autoload/dependencies.php

@ -48,4 +48,5 @@ return [
\App\Service\v3\Interfaces\ShopCartServiceInterface::class => \App\Service\v3\Implementations\ShopCartService::class,
\App\Service\v3\Interfaces\WxLoginServiceInterface::class => \App\Service\v3\Implementations\WxLoginService::class,
\App\Service\v3\Interfaces\UserInfoServiceInterface::class => \App\Service\v3\Implementations\UserInfoService::class,
\App\Service\v3\Interfaces\SearchServiceInterface::class => \App\Service\v3\Implementations\SearchService::class,
];

3
config/routes.php

@ -88,6 +88,9 @@ Router::addGroup('/v3/', function () {
Router::post('shopCart/detail', 'App\Controller\v3\ShopCartController@detail');
Router::post('login/wxLogin', 'App\Controller\v3\LoginController@wxLogin');
Router::post('location/getMarketListByLocation', 'App\Controller\v3\LocationController@getMarketListByLocation');
Router::post('search/hotKeywords', 'App\Controller\v3\SearchController@hotKeywords');
Router::post('search/goods', 'App\Controller\v3\SearchController@goods');
Router::post('search/stores', 'App\Controller\v3\SearchController@stores');
},['middleware' => [\App\Middleware\Auth\ApiMiddleware::class]]);
// 需要登录的路由

Loading…
Cancel
Save