首页统计改为产品总数
This commit is contained in:
parent
76b37ed867
commit
920689fbee
|
|
@ -11,7 +11,8 @@ class HomeController extends Controller
|
|||
public function index()
|
||||
{
|
||||
$data = [
|
||||
'views' => DashboardRepo::getCustomerViewData(),
|
||||
'products' => DashboardRepo::getProductData(),
|
||||
// 'views' => DashboardRepo::getCustomerViewData(),
|
||||
'orders' => DashboardRepo::getOrderData(),
|
||||
'customers' => DashboardRepo::getCustomerData(),
|
||||
'order_totals' => DashboardRepo::getTotalData(),
|
||||
|
|
|
|||
|
|
@ -11,9 +11,9 @@
|
|||
|
||||
namespace Beike\Admin\Repositories;
|
||||
|
||||
use Beike\Models\Product;
|
||||
use Beike\Repositories\CustomerRepo;
|
||||
use Beike\Repositories\OrderRepo;
|
||||
use Beike\Repositories\ProductRepo;
|
||||
|
||||
class DashboardRepo
|
||||
{
|
||||
|
|
@ -21,12 +21,22 @@ class DashboardRepo
|
|||
* 获取商品总数
|
||||
*
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function getProductData(): array
|
||||
{
|
||||
$today = ProductRepo::getBuilder(['created_start' => today()->subDay(), 'created_end' => today()])->count();
|
||||
$yesterday = ProductRepo::getBuilder(['created_start' => today()->subDays(2), 'created_end' => today()->subDay()])->count();
|
||||
$difference = $today - $yesterday;
|
||||
if ($difference && $yesterday) {
|
||||
$percentage = round(($difference / $yesterday) * 100);
|
||||
} else {
|
||||
$percentage = 0;
|
||||
}
|
||||
|
||||
return [
|
||||
'total' => quantity_format(Product::query()->count()),
|
||||
'percentage' => 0,
|
||||
'total' => $today,
|
||||
'percentage' => $percentage,
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ class ProductRepo
|
|||
*/
|
||||
public static function getProductsByCategory($categoryId, $filterData)
|
||||
{
|
||||
$builder = self::getBuilder(array_merge(['category_id' => $categoryId, 'active' => 1], $filterData));
|
||||
$builder = self::getBuilder(array_merge(['category_id' => $categoryId, 'active' => 1], $filterData));
|
||||
|
||||
return $builder->with('inCurrentWishlist')
|
||||
->paginate($filterData['per_page'] ?? perPage())
|
||||
|
|
@ -81,10 +81,11 @@ class ProductRepo
|
|||
/**
|
||||
* 获取商品筛选对象
|
||||
*
|
||||
* @param array $data
|
||||
* @param array $filters
|
||||
* @return Builder
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function getBuilder(array $data = []): Builder
|
||||
public static function getBuilder(array $filters = []): Builder
|
||||
{
|
||||
$builder = Product::query()->with('description', 'skus', 'masterSku', 'attributes');
|
||||
|
||||
|
|
@ -98,17 +99,17 @@ class ProductRepo
|
|||
});
|
||||
$builder->select(['products.*', 'pd.name', 'pd.content', 'pd.meta_title', 'pd.meta_description', 'pd.meta_keywords', 'pd.name', 'product_skus.price']);
|
||||
|
||||
if (isset($data['category_id'])) {
|
||||
$builder->whereHas('categories', function ($query) use ($data) {
|
||||
if (is_array($data['category_id'])) {
|
||||
$query->whereIn('category_id', $data['category_id']);
|
||||
if (isset($filters['category_id'])) {
|
||||
$builder->whereHas('categories', function ($query) use ($filters) {
|
||||
if (is_array($filters['category_id'])) {
|
||||
$query->whereIn('category_id', $filters['category_id']);
|
||||
} else {
|
||||
$query->where('category_id', $data['category_id']);
|
||||
$query->where('category_id', $filters['category_id']);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$productIds = $data['product_ids'] ?? [];
|
||||
$productIds = $filters['product_ids'] ?? [];
|
||||
if ($productIds) {
|
||||
$builder->whereIn('products.id', $productIds);
|
||||
$productIds = implode(',', $productIds);
|
||||
|
|
@ -116,8 +117,8 @@ class ProductRepo
|
|||
}
|
||||
|
||||
// attr 格式:attr=10:10,13|11:34,23|3:4
|
||||
if (isset($data['attr']) && $data['attr']) {
|
||||
$attributes = self::parseFilterParamsAttr($data['attr']);
|
||||
if (isset($filters['attr']) && $filters['attr']) {
|
||||
$attributes = self::parseFilterParamsAttr($filters['attr']);
|
||||
foreach ($attributes as $attribute) {
|
||||
$builder->whereHas('attributes', function ($query) use ($attribute) {
|
||||
$query->where('attribute_id', $attribute['attr'])
|
||||
|
|
@ -126,21 +127,21 @@ class ProductRepo
|
|||
}
|
||||
}
|
||||
|
||||
if (isset($data['sku']) || isset($data['model'])) {
|
||||
$builder->whereHas('skus', function ($query) use ($data) {
|
||||
if (isset($data['sku'])) {
|
||||
$query->where('sku', 'like', "%{$data['sku']}%");
|
||||
if (isset($filters['sku']) || isset($filters['model'])) {
|
||||
$builder->whereHas('skus', function ($query) use ($filters) {
|
||||
if (isset($filters['sku'])) {
|
||||
$query->where('sku', 'like', "%{$filters['sku']}%");
|
||||
}
|
||||
if (isset($data['model'])) {
|
||||
$query->where('model', 'like', "%{$data['model']}%");
|
||||
if (isset($filters['model'])) {
|
||||
$query->where('model', 'like', "%{$filters['model']}%");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (isset($data['price']) && $data['price']) {
|
||||
$builder->whereHas('skus', function ($query) use ($data) {
|
||||
if (isset($filters['price']) && $filters['price']) {
|
||||
$builder->whereHas('skus', function ($query) use ($filters) {
|
||||
// price 格式:price=30-100
|
||||
$prices = explode('-', $data['price']);
|
||||
$prices = explode('-', $filters['price']);
|
||||
if (! $prices[1]) {
|
||||
$query->where('price', '>', $prices[0] ?: 0)->where('is_default', 1);
|
||||
} else {
|
||||
|
|
@ -149,11 +150,11 @@ class ProductRepo
|
|||
});
|
||||
}
|
||||
|
||||
if (isset($data['name'])) {
|
||||
$builder->where('pd.name', 'like', "%{$data['name']}%");
|
||||
if (isset($filters['name'])) {
|
||||
$builder->where('pd.name', 'like', "%{$filters['name']}%");
|
||||
}
|
||||
|
||||
$keyword = trim($data['keyword'] ?? '');
|
||||
$keyword = trim($filters['keyword'] ?? '');
|
||||
if ($keyword) {
|
||||
$keywords = explode(' ', $keyword);
|
||||
$keywords = array_unique($keywords);
|
||||
|
|
@ -175,17 +176,25 @@ class ProductRepo
|
|||
});
|
||||
}
|
||||
|
||||
if (isset($data['active'])) {
|
||||
$builder->where('active', (int) $data['active']);
|
||||
if (isset($filters['created_start'])) {
|
||||
$builder->where('products.created_at', '>', $filters['created_start']);
|
||||
}
|
||||
|
||||
if (isset($filters['created_end'])) {
|
||||
$builder->where('products.created_at', '>', $filters['created_end']);
|
||||
}
|
||||
|
||||
if (isset($filters['active'])) {
|
||||
$builder->where('active', (int) $filters['active']);
|
||||
}
|
||||
|
||||
// 回收站
|
||||
if (isset($data['trashed']) && $data['trashed']) {
|
||||
if (isset($filters['trashed']) && $filters['trashed']) {
|
||||
$builder->onlyTrashed();
|
||||
}
|
||||
|
||||
$sort = $data['sort'] ?? 'products.position';
|
||||
$order = $data['order'] ?? 'desc';
|
||||
$sort = $filters['sort'] ?? 'products.position';
|
||||
$order = $filters['order'] ?? 'desc';
|
||||
$builder->orderBy($sort, $order);
|
||||
|
||||
return $builder;
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ class TotalService
|
|||
$maps = [];
|
||||
foreach (self::TOTAL_CODES as $code) {
|
||||
$serviceName = Str::studly($code) . 'Service';
|
||||
$maps[$code] = "\Beike\\Shop\\Services\\TotalServices\\{$serviceName}";
|
||||
$maps[$code] = "\Beike\\Shop\\Services\\TotalServices\\{$serviceName}";
|
||||
}
|
||||
|
||||
return hook_filter('service.total.maps', $maps);
|
||||
|
|
|
|||
|
|
@ -13,18 +13,17 @@
|
|||
<div class="col-xl-3 col-6">
|
||||
<div class="card mb-4">
|
||||
<div class="card-header d-flex justify-content-between">
|
||||
<span>{{ __('admin/dashboard.customer_view') }}</span>
|
||||
<span>{{ __('admin/dashboard.product_total') }}</span>
|
||||
<span class="mt-n1 ms-2 badge bg-success-soft">{{ __('admin/dashboard.yesterday') }}</span>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{{-- <h6 class="text-uppercase text-black-50 mb-3">{{ __('admin/dashboard.customer_view') }}</h6> --}}
|
||||
<div class="d-flex align-items-center justify-content-between">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="fs-2 lh-1 fw-bold">{{ $views['total'] }}</div>
|
||||
<div class="fs-2 lh-1 fw-bold">{{ $products['total'] }}</div>
|
||||
</div>
|
||||
{{-- <div><i class="fs-4 bi bi-cart"></i></div> --}}
|
||||
</div>
|
||||
<div class="mt-3 d-flex align-items-center lh-1"><span class="text-success">{{ $views['percentage'] }}%</span> <span class="vr mx-2"></span> <span class="text-muted">{{ __('admin/dashboard.day_before') }}</span></div>
|
||||
<div class="mt-3 d-flex align-items-center lh-1"><span class="text-success">{{ $products['percentage'] }}%</span>
|
||||
<span class="vr mx-2"></span> <span class="text-muted">{{ __('admin/dashboard.day_before') }}</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -35,14 +34,13 @@
|
|||
<span class="mt-n1 ms-2 badge bg-success-soft">{{ __('admin/dashboard.yesterday') }}</span>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{{-- <h6 class="text-uppercase text-black-50 mb-3">{{ __('admin/dashboard.order_total') }}</h6> --}}
|
||||
<div class="d-flex align-items-center justify-content-between">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="fs-2 lh-1 fw-bold">{{ $orders['total'] }}</div>
|
||||
</div>
|
||||
{{-- <div><i class="fs-4 bi bi-journal-text"></i></div> --}}
|
||||
</div>
|
||||
<div class="mt-3 d-flex align-items-center lh-1"><span class="text-success">{{ $orders['percentage'] }}%</span> <span class="vr mx-2"></span> <span class="text-muted">{{ __('admin/dashboard.day_before') }}</span></div>
|
||||
<div class="mt-3 d-flex align-items-center lh-1"><span class="text-success">{{ $orders['percentage'] }}%</span>
|
||||
<span class="vr mx-2"></span> <span class="text-muted">{{ __('admin/dashboard.day_before') }}</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -53,14 +51,13 @@
|
|||
<span class="mt-n1 ms-2 badge bg-success-soft">{{ __('admin/dashboard.yesterday') }}</span>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{{-- <h6 class="text-uppercase text-black-50 mb-3">{{ __('admin/dashboard.customer_new') }}</h6> --}}
|
||||
<div class="d-flex align-items-center justify-content-between">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="fs-2 lh-1 fw-bold">{{ $customers['total'] }}</div>
|
||||
</div>
|
||||
{{-- <div><i class="fs-4 bi bi-person"></i></div> --}}
|
||||
</div>
|
||||
<div class="mt-3 d-flex align-items-center lh-1"><span class="text-danger">{{ $customers['percentage'] }}%</span> <span class="vr mx-2"></span> <span class="text-muted">{{ __('admin/dashboard.day_before') }}</span></div>
|
||||
<div class="mt-3 d-flex align-items-center lh-1"><span class="text-danger">{{ $customers['percentage'] }}%</span>
|
||||
<span class="vr mx-2"></span> <span class="text-muted">{{ __('admin/dashboard.day_before') }}</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -71,15 +68,14 @@
|
|||
<span class="mt-n1 ms-2 badge bg-success-soft">{{ __('admin/dashboard.yesterday') }}</span>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{{-- <h6 class="text-uppercase text-black-50 mb-3">{{ __('admin/dashboard.order_amount') }}</h6> --}}
|
||||
<div class="d-flex align-items-center justify-content-between">
|
||||
<div class="d-flex align-items-center">
|
||||
<img src="https://beikeshop.com/install/install-enter.jpg?version={{ config('beike.version') }}&build_date={{ config('beike.build') }}" class="d-none">
|
||||
<div class="fs-2 lh-1 fw-bold">{{ $order_totals['total'] }}</div>
|
||||
</div>
|
||||
{{-- <div><i class="fs-4 bi bi-person"></i></div> --}}
|
||||
</div>
|
||||
<div class="mt-3 d-flex align-items-center lh-1"><span class="text-danger">{{ $order_totals['percentage'] }}%</span> <span class="vr mx-2"></span> <span class="text-muted">{{ __('admin/dashboard.day_before') }}</span></div>
|
||||
<div class="mt-3 d-flex align-items-center lh-1"><span class="text-danger">{{ $order_totals['percentage'] }}%</span>
|
||||
<span class="vr mx-2"></span> <span class="text-muted">{{ __('admin/dashboard.day_before') }}</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -10,5 +10,5 @@
|
|||
*/
|
||||
|
||||
return [
|
||||
'price_filter' => 'Price Filter',
|
||||
'price_filter' => 'Price Filter',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
*/
|
||||
|
||||
return [
|
||||
'product_total' => '产品总数',
|
||||
'customer_view' => '用户访问量',
|
||||
'order_total' => '订单量',
|
||||
'customer_new' => '新增用户',
|
||||
|
|
|
|||
|
|
@ -10,5 +10,5 @@
|
|||
*/
|
||||
|
||||
return [
|
||||
'price_filter' => '价格筛选',
|
||||
'price_filter' => '价格筛选',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -10,14 +10,14 @@
|
|||
*/
|
||||
|
||||
return [
|
||||
'products_index' => '商品列表',
|
||||
'products_create' => '创建商品',
|
||||
'products_show' => '商品详情',
|
||||
'products_update' => '更新商品',
|
||||
'products_delete' => '删除商品',
|
||||
'products_trashed' => '回收站',
|
||||
'products_restore' => '恢复回收站',
|
||||
'clear_restore' => '清空回收站',
|
||||
'products_index' => '商品列表',
|
||||
'products_create' => '创建商品',
|
||||
'products_show' => '商品详情',
|
||||
'products_update' => '更新商品',
|
||||
'products_delete' => '删除商品',
|
||||
'products_trashed' => '回收站',
|
||||
'products_restore' => '恢复回收站',
|
||||
'clear_restore' => '清空回收站',
|
||||
'products_filter_index' => '查看高级筛选',
|
||||
'products_filter_update' => '修改高级筛选',
|
||||
|
||||
|
|
|
|||
|
|
@ -10,5 +10,5 @@
|
|||
*/
|
||||
|
||||
return [
|
||||
'price_filter' => '價格篩選',
|
||||
'price_filter' => '價格篩選',
|
||||
];
|
||||
|
|
|
|||
Loading…
Reference in New Issue