You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
aquaculture/app/Http/Controllers/ProductController.php

151 lines
4.9 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?php
namespace App\Http\Controllers;
use App\Models\Node;
use App\Models\Product;
use App\Models\ProductPinYin;
use App\Models\User;
use App\Services\ScoreLogServe;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cache;
class ProductController extends Controller
{
/**
* 显示商品列表
*
* @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 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 返回搜索结果视图
*/
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; // 计算偏移量
// 尝试使用全文索引搜索商品
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'); // 提取商品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 string $uuid 商品的UUID
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View 返回商品详情视图
*/
public function show($uuid)
{
// 查询商品
$product = Product::query()->where('uuid', $uuid)->firstOrFail();
// 记录今日是否已查看
if (!$product->today_has_view) {
$product->today_has_view = true;
$product->save();
}
// 增加商品浏览次数
$today = Carbon::today()->toDateString();
Cache::increment($product->getViewCountKey($today));
// 当前登录用户
$user = auth()->user();
// 同类商品推荐
$recommendProducts = Product::query()
->where('category_id', $product->category_id)
->take(5)
->get();
// 加载商品的详细信息、收藏用户和评论
$product->load([
'detail',
'users',
'comments' => function ($query) {
$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()
{
return auth()->guard();
}
}