|
|
|
@ -16,98 +16,99 @@ use Illuminate\Support\Facades\Cache;
|
|
|
|
|
|
|
|
|
|
class ProductController extends Controller
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 商品列表
|
|
|
|
|
* 显示商品列表
|
|
|
|
|
*
|
|
|
|
|
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
|
|
|
|
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View 返回商品列表视图
|
|
|
|
|
*/
|
|
|
|
|
public function index()
|
|
|
|
|
{
|
|
|
|
|
// 随机查出一些商品展示
|
|
|
|
|
// 随机查出一些商品展示,取前 9 个商品
|
|
|
|
|
$products = Product::query()->inRandomOrder()->take(9)->get(['uuid', 'name'])->split(3);
|
|
|
|
|
// 获取所有商品的拼音
|
|
|
|
|
$pinyins = ProductPinYin::query()->orderBy('pinyin')->pluck('pinyin');
|
|
|
|
|
|
|
|
|
|
// 返回商品列表视图,并传递商品和拼音数据
|
|
|
|
|
return view('products.index', compact('products', 'pinyins'));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* ajax 通过商品首字母查询商品
|
|
|
|
|
* @param $pinyin
|
|
|
|
|
* @return mixed
|
|
|
|
|
* 通过商品首字母查询商品(AJAX请求)
|
|
|
|
|
*
|
|
|
|
|
* @param string $pinyin 商品首字母
|
|
|
|
|
* @return mixed 返回符合条件的商品集合
|
|
|
|
|
*/
|
|
|
|
|
public function getProductsByPinyin($pinyin)
|
|
|
|
|
{
|
|
|
|
|
// 查询首字母为指定字母的商品,并返回
|
|
|
|
|
$products = Product::query()->where('first_pinyin', $pinyin)->get(['id', 'name'])->split(3);
|
|
|
|
|
|
|
|
|
|
return $products;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 商品搜索
|
|
|
|
|
* 商品搜索功能
|
|
|
|
|
*
|
|
|
|
|
* @param Request $request
|
|
|
|
|
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
|
|
|
|
* @param Request $request 请求对象
|
|
|
|
|
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View 返回搜索结果视图
|
|
|
|
|
*/
|
|
|
|
|
public function search(Request $request)
|
|
|
|
|
{
|
|
|
|
|
$keyword = $request->input('keyword', '');
|
|
|
|
|
$page = abs((int)$request->get('page', 1));
|
|
|
|
|
$limit = (int)$request->get('limit', 20);
|
|
|
|
|
$offset = (int) ($page - 1) * $limit;
|
|
|
|
|
|
|
|
|
|
// 全文索引
|
|
|
|
|
$keyword = $request->input('keyword', ''); // 获取搜索关键词
|
|
|
|
|
$page = abs((int)$request->get('page', 1)); // 获取当前页码
|
|
|
|
|
$limit = (int)$request->get('limit', 20); // 获取每页显示的商品数量
|
|
|
|
|
$offset = (int) ($page - 1) * $limit; // 计算偏移量
|
|
|
|
|
|
|
|
|
|
// 尝试使用全文索引搜索商品
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
|
|
$parameters = [
|
|
|
|
|
'multi_match' => [
|
|
|
|
|
'query' => $keyword,
|
|
|
|
|
'fields' => ['title', 'body'],
|
|
|
|
|
]
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 获取搜索结果数量
|
|
|
|
|
$count = Product::searchCount($parameters);
|
|
|
|
|
$searchCount = $count['count'] ?? 0;
|
|
|
|
|
$searchResult = Product::search($parameters, $limit, $offset);
|
|
|
|
|
$filterIds = Collection::make($searchResult['hits']['hits'] ?? [])->pluck('_source.id');
|
|
|
|
|
$models = Product::query()->findMany($filterIds);
|
|
|
|
|
|
|
|
|
|
$searchCount = $count['count'] ?? 0; // 搜索结果总数
|
|
|
|
|
$searchResult = Product::search($parameters, $limit, $offset); // 获取搜索结果
|
|
|
|
|
$filterIds = Collection::make($searchResult['hits']['hits'] ?? [])->pluck('_source.id'); // 提取商品ID
|
|
|
|
|
$models = Product::query()->findMany($filterIds); // 根据ID查询商品
|
|
|
|
|
|
|
|
|
|
// 创建分页对象
|
|
|
|
|
$products = new LengthAwarePaginator($models, $searchCount, $limit, $page);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} catch (\Exception $e) {
|
|
|
|
|
|
|
|
|
|
// 如果全文索引搜索失败,使用模糊搜索
|
|
|
|
|
$products = Product::query()->withCount('users')->where('name', 'like', "%{$keyword}%")->paginate($limit);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 返回搜索结果视图
|
|
|
|
|
return view('products.search', compact('products'));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 单个商品显示
|
|
|
|
|
* 显示单个商品的详细信息
|
|
|
|
|
*
|
|
|
|
|
* @param $uuid
|
|
|
|
|
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
|
|
|
|
* @param string $uuid 商品的UUID
|
|
|
|
|
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View 返回商品详情视图
|
|
|
|
|
*/
|
|
|
|
|
public function show($uuid)
|
|
|
|
|
{
|
|
|
|
|
/**
|
|
|
|
|
* @var $user User|null
|
|
|
|
|
*/
|
|
|
|
|
// 查询商品
|
|
|
|
|
$product = Product::query()->where('uuid', $uuid)->firstOrFail();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (! $product->today_has_view) {
|
|
|
|
|
// 记录今日是否已查看
|
|
|
|
|
if (!$product->today_has_view) {
|
|
|
|
|
$product->today_has_view = true;
|
|
|
|
|
$product->save();
|
|
|
|
|
}
|
|
|
|
|
// 直接使用缓存
|
|
|
|
|
|
|
|
|
|
// 增加商品浏览次数
|
|
|
|
|
$today = Carbon::today()->toDateString();
|
|
|
|
|
Cache::increment($product->getViewCountKey($today));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 商品浏览次数 + 1
|
|
|
|
|
// 当前登录用户
|
|
|
|
|
$user = auth()->user();
|
|
|
|
|
|
|
|
|
|
// 同类商品推荐
|
|
|
|
@ -116,28 +117,30 @@ class ProductController extends Controller
|
|
|
|
|
->take(5)
|
|
|
|
|
->get();
|
|
|
|
|
|
|
|
|
|
// 加载出详情,收藏的人数, 评论
|
|
|
|
|
// 加载商品的详细信息、收藏用户和评论
|
|
|
|
|
$product->load([
|
|
|
|
|
'detail',
|
|
|
|
|
'users',
|
|
|
|
|
'comments' => function ($query) {
|
|
|
|
|
$query->latest();
|
|
|
|
|
$query->latest(); // 按最新评论排序
|
|
|
|
|
},
|
|
|
|
|
'comments.user'
|
|
|
|
|
]);
|
|
|
|
|
// 检查当前用户是否已收藏该商品
|
|
|
|
|
$product->userIsLike = $product->users()->where('id', auth()->id())->exists();
|
|
|
|
|
|
|
|
|
|
// 如果登录返回所有地址列表,如果没有,则返回一个空集合
|
|
|
|
|
// 如果用户已登录,增加积分
|
|
|
|
|
if ($user) {
|
|
|
|
|
|
|
|
|
|
// 浏览商品增加积分
|
|
|
|
|
(new ScoreLogServe)->visitedProductAddScore($user, $product);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 返回商品详情视图
|
|
|
|
|
return view('products.show', compact('product', 'recommendProducts'));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 获取当前认证用户的守卫
|
|
|
|
|
*
|
|
|
|
|
* @return \Illuminate\Contracts\Auth\StatefulGuard
|
|
|
|
|
*/
|
|
|
|
|
protected function guard()
|
|
|
|
|