feat: Enhance product support in Cart and OrderItem models
- Added new fields 'billing_cycle' and 'product_pricing_id' to Cart and OrderItem models. - Updated product retrieval logic to support both new and legacy systems. - Introduced relationships for Product and ProductPricings in Cart and OrderItem models. - Created migration to add new fields to the carts and order_item tables. - Updated frontend service index to handle new pricing structure and billing cycles. - Improved UI components for better user experience in product selection and pricing display. - Refactored action buttons in various views for consistency and improved styling.
This commit is contained in:
@@ -11,6 +11,7 @@ use App\Models\Hosting;
|
||||
use App\Models\Group;
|
||||
use App\Models\Type;
|
||||
use App\Models\VPS;
|
||||
use App\Models\ProductCategories;
|
||||
use App\Repositories\Addon\AddonRepositoryInterface;
|
||||
use App\Repositories\Domain\DomainRepositoryInterface;
|
||||
use App\Repositories\Group\GroupRepositoryInterface;
|
||||
@@ -18,7 +19,6 @@ use App\Repositories\Hosting\HostingRepositoryInterface;
|
||||
use App\Repositories\Type\TypeRepositoryInterface;
|
||||
use App\Repositories\VPS\VPSRepositoryInterface;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
|
||||
class ShopController extends Controller
|
||||
{
|
||||
@@ -34,24 +34,22 @@ class ShopController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the shop index page with optimized queries
|
||||
* Display the shop index page
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$title = "Dịch vụ của chúng tôi";
|
||||
|
||||
// Cache types with groups for better performance
|
||||
$type = Cache::remember('shop_types_with_groups', 3600, function () {
|
||||
return Type::with(['group' => function ($query) {
|
||||
$query->where('status', 1); // Only active groups
|
||||
}])
|
||||
|
||||
// Get types with groups
|
||||
$type = Type::with(['group' => function ($query) {
|
||||
$query->where('status', 1); // Only active groups
|
||||
}])
|
||||
->whereNotIn('id', [1, 2])
|
||||
->where('status', 1) // Only active types
|
||||
->latest('id')
|
||||
->get();
|
||||
});
|
||||
|
||||
// Handle product filtering with optimized queries
|
||||
// Handle product filtering
|
||||
if ($request->type && $request->group) {
|
||||
$product = $this->getProductsByTypeAndGroup($request->type, $request->group);
|
||||
$group = $this->getGroupsByType($request->type);
|
||||
@@ -84,76 +82,67 @@ class ShopController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* Display products by group slug with pagination and optimization
|
||||
* Display products by category slug (ProductCategories)
|
||||
*/
|
||||
public function show(Request $request, string $slug)
|
||||
{
|
||||
// Cache group data for better performance
|
||||
$page = (int) $request->get('page', 1);
|
||||
$cacheKey = "group_products_{$slug}_page_{$page}";
|
||||
|
||||
$data = Cache::remember($cacheKey, 1800, function () use ($slug, $page) {
|
||||
// Find group with optimized query
|
||||
$group = Group::with(['type'])
|
||||
->where('slug', $slug)
|
||||
->where('status', 1) // Only active groups
|
||||
->first();
|
||||
// Find category by slug
|
||||
$category = ProductCategories::with(['parent', 'children'])
|
||||
->where('slug', $slug)
|
||||
->where('is_active', 1)
|
||||
->first();
|
||||
|
||||
if (!$group) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Get products with pagination based on group type
|
||||
$products = $this->getPaginatedProducts($group, $page);
|
||||
|
||||
return [
|
||||
'group' => $group,
|
||||
'products' => $products,
|
||||
];
|
||||
});
|
||||
|
||||
if (!$data) {
|
||||
abort(404, 'Nhóm sản phẩm không tồn tại');
|
||||
if (!$category) {
|
||||
abort(404, 'Danh mục sản phẩm không tồn tại');
|
||||
}
|
||||
|
||||
// Get products with pagination and pricing
|
||||
$products = $category->products()
|
||||
->with([
|
||||
'pricings' => function ($query) {
|
||||
$query->where('is_active', 1)->orderBy('price');
|
||||
},
|
||||
'osVersions.osGroup',
|
||||
'controlPanels'
|
||||
])
|
||||
->where('is_active', 1)
|
||||
->orderBy('created_at', 'desc')
|
||||
->paginate(12);
|
||||
|
||||
return view('frontend.service.index', [
|
||||
'group' => $data['group'],
|
||||
'products' => $data['products'],
|
||||
'breadcrumbs' => $this->crums->add(__('Dashboard'))->add('Sản phẩm thuộc ' . $data['group']->name),
|
||||
'category' => $category,
|
||||
'products' => $products,
|
||||
'breadcrumbs' => $this->crums->add(__('Dashboard'))->add('Sản phẩm thuộc ' . $category->name),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get products by type and group with optimization
|
||||
* Get products by type and group
|
||||
*/
|
||||
private function getProductsByTypeAndGroup(int $typeId, int $groupId)
|
||||
{
|
||||
return Cache::remember("products_type_{$typeId}_group_{$groupId}", 1800, function () use ($typeId, $groupId) {
|
||||
return match ($typeId) {
|
||||
3 => Hosting::where('group_id', $groupId)
|
||||
->where('status', 1)
|
||||
->with(['group', 'type'])
|
||||
->get(),
|
||||
4 => VPS::where('group_id', $groupId)
|
||||
->where('status', 1)
|
||||
->with(['group', 'type', 'operatingSystems.osGroup'])
|
||||
->get(),
|
||||
default => collect()
|
||||
};
|
||||
});
|
||||
return match ($typeId) {
|
||||
3 => Hosting::where('group_id', $groupId)
|
||||
->where('status', 1)
|
||||
->with(['group', 'type'])
|
||||
->get(),
|
||||
4 => VPS::where('group_id', $groupId)
|
||||
->where('status', 1)
|
||||
->with(['group', 'type', 'operatingSystems.osGroup'])
|
||||
->get(),
|
||||
default => collect()
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get groups by type with optimization
|
||||
* Get groups by type
|
||||
*/
|
||||
private function getGroupsByType(int $typeId)
|
||||
{
|
||||
return Cache::remember("groups_type_{$typeId}", 3600, function () use ($typeId) {
|
||||
return Group::with('type')
|
||||
->where('type_id', $typeId)
|
||||
->where('status', 1)
|
||||
->get();
|
||||
});
|
||||
return Group::with('type')
|
||||
->where('type_id', $typeId)
|
||||
->where('status', 1)
|
||||
->get();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -171,34 +160,4 @@ class ShopController extends Controller
|
||||
default => null
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get paginated products based on group type
|
||||
*/
|
||||
private function getPaginatedProducts(Group $group, int $page = 1, int $perPage = 12)
|
||||
{
|
||||
$query = null;
|
||||
|
||||
// Determine which model to query based on group type
|
||||
switch ($group->type_id) {
|
||||
case 3: // Hosting
|
||||
$query = Hosting::where('group_id', $group->id)
|
||||
->where('status', 1)
|
||||
->with(['group', 'type'])
|
||||
->orderBy('created_at', 'desc');
|
||||
break;
|
||||
|
||||
case 4: // VPS
|
||||
$query = VPS::where('group_id', $group->id)
|
||||
->where('status', 1)
|
||||
->with(['group', 'type'])
|
||||
->orderBy('created_at', 'desc');
|
||||
break;
|
||||
|
||||
default:
|
||||
return collect()->paginate($perPage);
|
||||
}
|
||||
|
||||
return $query->paginate($perPage, ['*'], 'page', $page);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user