generated from liutk/owl-admin-base
门店统计
parent
aede82735a
commit
18e8b386f2
|
|
@ -0,0 +1,86 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Admin\Controllers\Finance;
|
||||||
|
|
||||||
|
use App\Admin\Controllers\AdminController;
|
||||||
|
use App\Admin\Filters\LedgerFilter;
|
||||||
|
use App\Admin\Filters\LedgerItemFilter;
|
||||||
|
use App\Admin\Filters\StoreFilter;
|
||||||
|
use App\Models\Ledger;
|
||||||
|
use App\Models\Store;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
|
class StoreStatisticController extends AdminController
|
||||||
|
{
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
if ($this->actionOfGetData()) {
|
||||||
|
return $this->response()->success([
|
||||||
|
'items' => $this->getStoreStatistics(request()),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->response()->success(
|
||||||
|
$this->baseList(
|
||||||
|
$this->baseCRUD()
|
||||||
|
->headerToolbar([
|
||||||
|
amis('filter-toggler')->align('right'),
|
||||||
|
])
|
||||||
|
->footerToolbar([])
|
||||||
|
->bulkActions([])
|
||||||
|
->filter($this->baseFilter()->body([
|
||||||
|
amis()->GroupControl()->mode('horizontal')->body([
|
||||||
|
amis()->DateRangeControl('date_range', '日期')
|
||||||
|
->valueFormat('YYYY-MM-DD')
|
||||||
|
->columnRatio(6),
|
||||||
|
amis()->InputCityControl('region', '区域')
|
||||||
|
->allowDistrict(false)
|
||||||
|
->extractValue(false),
|
||||||
|
]),
|
||||||
|
]))
|
||||||
|
->columns([
|
||||||
|
amis()->TableColumn('ranking', '排序'),
|
||||||
|
amis()->TableColumn('title', '门店'),
|
||||||
|
amis()->TableColumn('sales', '收入')->sortable(),
|
||||||
|
amis()->TableColumn('expenditure', '支出')->sortable(),
|
||||||
|
])
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getStoreStatistics(Request $request): array
|
||||||
|
{
|
||||||
|
$stores = Store::filter($request->only(['region']), StoreFilter::class)
|
||||||
|
->get(['id', 'title']);
|
||||||
|
|
||||||
|
/** @var \Illuminate\Database\Eloquent\Collection */
|
||||||
|
$statistics = Ledger::select([
|
||||||
|
'store_id',
|
||||||
|
DB::raw('SUM(sales) as sales'),
|
||||||
|
DB::raw('SUM(expenditure) as expenditure'),
|
||||||
|
])
|
||||||
|
->filter($request->input(), LedgerItemFilter::class)
|
||||||
|
->groupBy('store_id')
|
||||||
|
->get()
|
||||||
|
->keyBy('store_id');
|
||||||
|
|
||||||
|
// 排序规则
|
||||||
|
$sortBy = [
|
||||||
|
[$request->input('orderBy') ?: 'sales', $request->input('orderDir') ?: 'desc'],
|
||||||
|
];
|
||||||
|
|
||||||
|
return $stores->map(function ($store) use ($statistics) {
|
||||||
|
$statistic = $statistics->get($store->id);
|
||||||
|
return [
|
||||||
|
'title' => $store->title,
|
||||||
|
'sales' => trim_zeros($statistic->sales ?? '0'),
|
||||||
|
'expenditure' => trim_zeros($statistic->expenditure ?? '0'),
|
||||||
|
];
|
||||||
|
})
|
||||||
|
->sortBy($sortBy)
|
||||||
|
->values()
|
||||||
|
->map(fn ($statistic, $key) => array_merge($statistic, ['ranking' => $key + 1]))
|
||||||
|
->all();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,21 +3,41 @@
|
||||||
namespace App\Admin\Filters;
|
namespace App\Admin\Filters;
|
||||||
|
|
||||||
use EloquentFilter\ModelFilter;
|
use EloquentFilter\ModelFilter;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
|
|
||||||
class LedgerFilter extends ModelFilter
|
class LedgerFilter extends ModelFilter
|
||||||
{
|
{
|
||||||
public function store($id)
|
public function store($id)
|
||||||
{
|
{
|
||||||
$this->query->where('store_id', $id);
|
$this->where('store_id', $id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function dateRange($dateRange)
|
public function dateRange($dateRange)
|
||||||
{
|
{
|
||||||
$this->query->whereBetween('date', explode(',', $dateRange));
|
$this->whereBetween('date', explode(',', $dateRange));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function status($status)
|
public function status($status)
|
||||||
{
|
{
|
||||||
$this->query->whereIn('ledger_status', explode(',', $status));
|
$this->whereIn('ledger_status', explode(',', $status));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function region($region)
|
||||||
|
{
|
||||||
|
if (! is_array($region)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$provinceCode = Arr::get($region, 'provinceCode');
|
||||||
|
$cityCode = Arr::get($region, 'cityCode');
|
||||||
|
|
||||||
|
if (empty($provinceCode) && empty($cityCode)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->related('store', function($query) use ($provinceCode, $cityCode) {
|
||||||
|
$query->when($provinceCode, fn ($query) => $query->where('region->provinceCode', $provinceCode))
|
||||||
|
->when($cityCode, fn ($query) => $query->where('region->cityCode', $cityCode));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
use App\Admin\Controllers\BaseKeywordController;
|
use App\Admin\Controllers\BaseKeywordController;
|
||||||
use App\Admin\Controllers\Finance\LedgerController;
|
use App\Admin\Controllers\Finance\LedgerController;
|
||||||
use App\Admin\Controllers\Finance\SalesStatisticController;
|
use App\Admin\Controllers\Finance\SalesStatisticController;
|
||||||
|
use App\Admin\Controllers\Finance\StoreStatisticController;
|
||||||
use App\Admin\Controllers\Hr\EmployeeController;
|
use App\Admin\Controllers\Hr\EmployeeController;
|
||||||
use App\Admin\Controllers\Hr\RestController;
|
use App\Admin\Controllers\Hr\RestController;
|
||||||
use App\Admin\Controllers\Hr\SignController;
|
use App\Admin\Controllers\Hr\SignController;
|
||||||
|
|
@ -88,6 +89,8 @@ Route::group([
|
||||||
$router->post('ledgers/{ledger}/approval', [LedgerController::class, 'approval'])->name('ledgers.approval');
|
$router->post('ledgers/{ledger}/approval', [LedgerController::class, 'approval'])->name('ledgers.approval');
|
||||||
// 销售统计
|
// 销售统计
|
||||||
$router->get('sales-statistics', [SalesStatisticController::class, 'index'])->name('sales_statistics.index');
|
$router->get('sales-statistics', [SalesStatisticController::class, 'index'])->name('sales_statistics.index');
|
||||||
|
// 门店统计
|
||||||
|
$router->get('store-statistics', [StoreStatisticController::class, 'index'])->name('store_statistics.index');
|
||||||
});
|
});
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -151,6 +151,15 @@ class AdminPermissionSeeder extends Seeder
|
||||||
'index' => '销售统计',
|
'index' => '销售统计',
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
'store_statistics' => [
|
||||||
|
'name' => '门店统计',
|
||||||
|
'icon' => 'material-symbols:store-rounded',
|
||||||
|
'uri' => '/finance/store-statistics',
|
||||||
|
'resource' => false,
|
||||||
|
'children' => [
|
||||||
|
'index' => '门店统计',
|
||||||
|
],
|
||||||
|
],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue