main
panliang 2024-04-23 18:12:09 +08:00
commit a2f0d0a277
3 changed files with 257 additions and 72 deletions

View File

@ -4,7 +4,9 @@ namespace App\Admin\Controllers;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Models\Employee; use App\Models\Employee;
use App\Models\Keyword;
use App\Models\Ledger; use App\Models\Ledger;
use App\Models\LedgerItem;
use App\Models\Store; use App\Models\Store;
use App\Models\TaskPerformance; use App\Models\TaskPerformance;
use Illuminate\Http\Request; use Illuminate\Http\Request;
@ -41,10 +43,10 @@ class CockpitController extends Controller
], ],
); );
$data = collect();
$last = $request->input('last'); $last = $request->input('last');
$data = collect();
if (in_array($last, ['7days', '30days'])) { if (in_array($last, ['7days', '30days'])) {
// 按天 // 按天
$days = match ($last) { $days = match ($last) {
@ -104,7 +106,7 @@ class CockpitController extends Controller
$ledger = $ledgers->get($month); $ledger = $ledgers->get($month);
$data->push([ $data->push([
'date' => $month, 'month' => $month,
'sales' => trim_zeros($ledger->sales ?? 0), 'sales' => trim_zeros($ledger->sales ?? 0),
]); ]);
@ -120,7 +122,119 @@ class CockpitController extends Controller
*/ */
public function lotterySalesTrend(Request $request): array public function lotterySalesTrend(Request $request): array
{ {
return []; $request->validate(
rules: [
'last' => ['bail', 'required', Rule::in(['7days', '30days', '180days', '365days'])],
],
);
$last = $request->input('last');
$data = collect();
/** @var \Illuminate\Database\Eloquent\Collection */
$lotteryTypes = Keyword::where('parent_key', 'lottery_type')->get();
if (in_array($last, ['7days', '30days'])) {
// 按天
$days = match ($last) {
'7days' => 7,
'30days' => 30,
};
// 今天
$today = Carbon::today();
// 开始时间
$startAt = $today->copy()->subDays($days);
// 结束时间
$endAt = $today->copy()->subDay();
/** @var \Illuminate\Support\Collection */
$lotteryTypeLedgers = LedgerItem::select([
'date',
'ledger_item_type_id',
DB::raw('SUM(sales) as sales'),
])
->whereBetween('date', [$startAt->toDateString(), $endAt->toDateString()])
->groupBy(['date', 'ledger_item_type_id'])
->get()
->groupBy('date');
while ($startAt->lte($endAt)) {
$date = $startAt->toDateString();
$lotteryTypeLedgerItems = $lotteryTypeLedgers->get($date, collect())->keyBy('ledger_item_type_id');
$data->push([
'date' => $date,
'data' => $lotteryTypes->map(function ($lotteryType) use ($lotteryTypeLedgerItems) {
$lotteryTypeLedgerItem = $lotteryTypeLedgerItems->get($lotteryType->key);
return [
'id' => $lotteryType->key,
'name' => $lotteryType->name,
'sales' => trim_zeros($lotteryTypeLedgerItem->sales ?? 0),
];
}),
]);
$startAt->addDay();
}
}
elseif (in_array($last, ['180days', '365days'])) {
// 按月
$months = match ($last) {
'180days' => 6, // 6个月
'365days' => 12, // 12个月
};
// 今天
$today = Carbon::today();
// 开始时间
$startAt = $today->copy()->startOfMonth()->subMonths($months);
// 结束时间
$endAt = $today->copy()->startOfMonth()->subMonth()->endOfMonth();
/** @var \Illuminate\Support\Collection */
$lotteryTypeLedgers = LedgerItem::select([
DB::raw("DATE_FORMAT(`date`, '%Y-%m') as month"),
'ledger_item_type_id',
DB::raw('SUM(sales) as sales'),
])
->whereBetween('date', [$startAt->toDateString(), $endAt->toDateString()])
->groupBy(['month', 'ledger_item_type_id'])
->get()
->keyBy('month');
for ($i=0; $i < $months; $i++) {
$month = $startAt->format('Y-m');
$lotteryTypeLedgerItems = $lotteryTypeLedgers->get($month, collect())->keyBy('ledger_item_type_id');
$data->push([
'month' => $month,
'data' => $lotteryTypes->map(function ($lotteryType) use ($lotteryTypeLedgerItems) {
$lotteryTypeLedgerItem = $lotteryTypeLedgerItems->get($lotteryType->key);
return [
'id' => $lotteryType->key,
'name' => $lotteryType->name,
'sales' => trim_zeros($lotteryTypeLedgerItem->sales ?? 0),
];
}),
]);
$startAt->addMonth();
}
}
return [
'lottery_types' => $lotteryTypes->map(function ($lotteryType) {
return [
'id' => $lotteryType->id,
'name' => $lotteryType->name,
];
}),
'data' => $data->all(),
];
} }
/** /**
@ -128,7 +242,56 @@ class CockpitController extends Controller
*/ */
public function storeSalesRanking(Request $request): array public function storeSalesRanking(Request $request): array
{ {
return []; $request->validate(
rules: [
'last' => ['bail', 'required', Rule::in(['7days', '30days', '180days', '365days'])],
],
);
$last = $request->input('last');
$storeSales = Ledger::select(['store_id', DB::raw('SUM(sales) as sales')])
->when($last, function ($query, $last) {
$today = Carbon::today();
if (in_array($last, ['7days', '30days'])) {
$days = match ($last) {
'7days' => 7,
'30days' => 30,
};
$query->whereBetween('date', [
$today->copy()->subDays($days)->toDateString(),
$today->copy()->subDay()->toDateString(),
]);
} elseif (in_array($last, ['180days', '365days'])) {
$months = match ($last) {
'180days' => 6, // 6个月
'365days' => 12, // 12个月
};
$query->whereBetween('date', [
$today->copy()->startOfMonth()->subMonths($months)->toDateString(),
$today->copy()->startOfMonth()->subMonth()->endOfMonth()->toDateString(),
]);
}
})
->groupBy('store_id');
$stores = Store::leftJoinSub($storeSales, 'store_sales', fn ($join) => $join->on('stores.id', '=', 'store_sales.store_id'))
->orderBy('store_sales.sales', 'DESC')
->limit(30)
->get();
return $stores->map(function (Store $store) {
return [
'store' => [
'id' => $store->id,
'title' => $store->title,
],
'sales' => trim_zeros($store->sales ?: 0),
];
})->all();
} }
/** /**

View File

@ -183,7 +183,7 @@ class LedgerController extends Controller
throw tap($e, fn ($e) => report($e)); throw tap($e, fn ($e) => report($e));
} }
return $this->prepareLedger($ledger); return response()->noContent();
} }
public function show(string $date, Request $request) public function show(string $date, Request $request)
@ -197,25 +197,39 @@ class LedgerController extends Controller
->where('date', $date) ->where('date', $date)
->first(); ->first();
return [ $items = [];
'data' => $ledger ? $this->prepareLedger($ledger) : null,
]; if ($user->store->isLotteryStore()) {
} /** @var \Illuminate\Database\Eloquent\Collection */
$lotteryTypes = Keyword::filter(['parent_key' => 'lottery_type'])
->oldest('sort')
->get();
$ledgerItems = collect();
if ($ledger) {
$ledgerItems = $ledger->items->keyBy('ledger_item_type_id');
}
$items = $lotteryTypes->map(function ($lotteryType) use ($ledgerItems) {
$ledgerItem = $ledgerItems->get($lotteryType->key);
return [
'id' => $lotteryType->key,
'name' => $lotteryType->name,
'sales' => $ledgerItem?->sales,
'expenditure' => $ledgerItem?->expenditure,
];
})->all();
}
protected function prepareLedger(Ledger $ledger)
{
return [ return [
'date' => $ledger->date, 'date' => $date,
'items' => $ledger->items->map(fn ($item) => [ 'items' => $items,
'id' => $item->ledger_item_type_id, 'new_customers' => $ledger?->new_customers,
'sales' => $item->sales, 'sales' => $ledger?->sales,
'expenditure' => $item->expenditure, 'expenditure' => $ledger?->expenditure,
]), 'handover_amount' => $ledger?->handover_amount,
'new_customers' => $ledger->new_customers, 'photos' => $ledger?->photos ?: [],
'sales' => $ledger->sales, 'allow_rereport' => is_null($ledger) ? true : $ledger->allowReReport(),
'expenditure' => $ledger->expenditure,
'handover_amount' => $ledger->handover_amount,
'photos' => $ledger->photos,
]; ];
} }
} }

View File

@ -2,10 +2,10 @@
namespace App\Traits; namespace App\Traits;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Slowlyo\OwlAdmin\Admin; use Slowlyo\OwlAdmin\Admin;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Storage;
trait UploadTrait trait UploadTrait
{ {
@ -25,17 +25,17 @@ trait UploadTrait
public function uploadRich() public function uploadRich()
{ {
$fromWangEditor = false; $fromWangEditor = false;
$file = request()->file('file'); $file = request()->file('file');
if (! $file) { if (!$file) {
$fromWangEditor = true; $fromWangEditor = true;
$file = request()->file('wangeditor-uploaded-image'); $file = request()->file('wangeditor-uploaded-image');
if (! $file) { if (!$file) {
$file = request()->file('wangeditor-uploaded-video'); $file = request()->file('wangeditor-uploaded-video');
} }
} }
if (! $file) { if (!$file) {
return $this->response()->additional(['errno' => 1])->fail(__('admin.upload_file_error')); return $this->response()->additional(['errno' => 1])->fail(__('admin.upload_file_error'));
} }
@ -57,7 +57,7 @@ trait UploadTrait
{ {
$file = request()->file('file'); $file = request()->file('file');
if (! $file) { if (!$file) {
return $this->response()->fail(__('admin.upload_file_error')); return $this->response()->fail(__('admin.upload_file_error'));
} }
@ -69,63 +69,71 @@ trait UploadTrait
return $this->response()->success(['value' => $path]); return $this->response()->success(['value' => $path]);
} }
public function saveImage($field, $path) public function saveImage($field = 'image', $path)
{ {
return $this->saveFile($field, $path); return $this->saveFile($field, $path);
} }
/** /**
* 表单提交时,转存实际目录,并保留上传时文件名称;文件保存全路径 * 表单提交时,转存实际目录,并保留上传时文件名称;文件保存全路径
*/ */
public function saveFile($field, $path) public function saveFile($field = 'file', $path)
{ {
$file = request()->file($field); $file = request()->file($field);
if (! $file) { if (!$file) {
$file = request()->get($field); $file = request()->get($field);
} }
$fileArr = []; $fileArr = [];
//判断是否多个文件; //判断是否多个文件;
if (is_string($file) || isset($file['id'])) { if(is_string($file) || isset($file['id'])){
$files = [$file]; $files = [$file];
} else { }else{
$files = $file; $files = $file;
} }
if ($files) { if($files){
foreach ($files as $file) { foreach($files as $file){
if (is_array($file) && isset($file['state'])) { if(is_array($file) && isset($file['state'])){
switch ($file['state']) { switch($file['state']){
case 'init': case 'init':
if (strpos($file['value'], 'temporary') !== false) { if(strpos($file['value'], 'temporary') !== false){
$filePath = $path.'/'.$file['name']; $filePath = $path.'/'.$file['name'];
Storage::disk(Admin::config('admin.upload.disk'))->move($file['value'], $filePath); $res = Storage::disk(Admin::config('admin.upload.disk'))->move($file['value'], $filePath);
$fileArr[] = Storage::disk(Admin::config('admin.upload.disk'))->url($filePath); if($res){
} else { $fileArr[] = Storage::disk(Admin::config('admin.upload.disk'))->url($filePath);
}else{
return response()->fail(__('admin.upload_file_error'));
}
}else{
$fileArr[] = $file['value']; $fileArr[] = $file['value'];
} }
break; break;
case 'uploaded': case 'uploaded':
if (isset($file['name'])) { if(isset($file['name'])){
$filePath = $path.'/'.$file['name']; $filePath = $path.'/'.$file['name'];
if (Str::startsWith($file['value'], ['http://', 'https://'])) { if(Str::startsWith($file['value'], ['http://', 'https://'])){
$fileUrl = parse_url($file['value']); $fileUrl = parse_url($file['value']);
$fileValue = ltrim($fileUrl['path'], '/'); $fileValue = ltrim($fileUrl['path'], '/storage');
} else { }else{
$fileValue = $file['value']; $fileValue = $file['value'];
} }
Storage::disk(Admin::config('admin.upload.disk'))->move($file['value'], $filePath); $res = Storage::disk(Admin::config('admin.upload.disk'))->move($fileValue, $filePath);
$fileArr[] = Storage::disk(Admin::config('admin.upload.disk'))->url($filePath);
if($res){
$fileArr[] = Storage::disk(Admin::config('admin.upload.disk'))->url($filePath);
}else{
return $this->response()->fail(__('admin.upload_file_error'));
}
} }
break; break;
} }
} else { }else{
$fileArr[] = $file; $fileArr[] = $file;
} }
} }
} }
return $fileArr; return $fileArr;
} }
@ -139,8 +147,8 @@ trait UploadTrait
$uploadId = md5(time().$fileName); $uploadId = md5(time().$fileName);
//创建临时文件夹 //创建临时文件夹
if (Storage::disk(Admin::config('admin.upload.disk'))->exists(Admin::config('admin.upload.tem_directory.'.$type).'/'.$uploadId) === false) { if ( Storage::disk(Admin::config('admin.upload.disk'))->exists(Admin::config('admin.upload.tem_directory.' . $type).'/'.$uploadId) === false ) {
if (Storage::disk(Admin::config('admin.upload.disk'))->makeDirectory(Admin::config('admin.upload.tem_directory.'.$type).'/'.$uploadId) === false) { if ( Storage::disk(Admin::config('admin.upload.disk'))->makeDirectory(Admin::config('admin.upload.tem_directory.' . $type).'/'.$uploadId) === false ) {
return false; return false;
} }
} }
@ -159,19 +167,18 @@ trait UploadTrait
$uploadId = request()->get('uploadId'); $uploadId = request()->get('uploadId');
$partNumber = request()->get('partNumber'); $partNumber = request()->get('partNumber');
$partSize = request()->get('partSize'); $partSize = request()->get('partSize');
// dd($file);
$fileName = $file->getClientOriginalName(); $fileName = $file->getClientOriginalName();
$fileName = str_replace(' ', '', $fileName);//去掉空格
//判断该分片是否已存在, //判断该分片是否已存在,
$dirPath = Admin::config('admin.upload.tem_directory.'.$type).'/'.$uploadId; $dirPath = Admin::config('admin.upload.tem_directory.' . $type).'/'.$uploadId;
if (Storage::disk(Admin::config('admin.upload.disk'))->exists($dirPath.'/'.$fileName.'_'.$partNumber)) { if(Storage::disk(Admin::config('admin.upload.disk'))->exists($dirPath . '/'.$fileName.'_'.$partNumber)){
return $this->response()->fail(__('admin.upload_file_error')); return $this->response()->fail(__('admin.upload_file_error'));
} else { }else{
//验证分片大小-todo //验证分片大小-todo
$path = $file->storeAs($dirPath, $fileName.'_'.$partNumber, Admin::config('admin.upload.disk')); $path = $file->storeAs($dirPath, $fileName.'_'.$partNumber, Admin::config('admin.upload.disk'));
$realPath = Storage::disk(Admin::config('admin.upload.disk'))->url($path); $realPath = Storage::disk(Admin::config('admin.upload.disk'))->url($path);
$eTag = md5_file($realPath); $eTag = md5_file($realPath);
return $this->response()->success(['eTag' => $eTag]); return $this->response()->success(['eTag' => $eTag]);
} }
} }
@ -184,31 +191,32 @@ trait UploadTrait
$type = 'file'; $type = 'file';
//合并文件 //合并文件
$fileName = request()->get('filename', ''); $fileName = request()->get('filename', '');
$fileName = str_replace(' ', '', $fileName);
$uploadId = request()->get('uploadId', ''); $uploadId = request()->get('uploadId', '');
$partList = request()->get('partList', []); $partList = request()->get('partList', []);
$basePath = Admin::config('admin.upload.tem_directory.'.$type).'/'.$uploadId; $basePath = Admin::config('admin.upload.tem_directory.' . $type).'/'.$uploadId;
$realPath = 'chunk/'.$fileName; $realPath = 'chunk/'.$fileName;
//获取分片列表中序号,查看分片是否都完成上传 //获取分片列表中序号,查看分片是否都完成上传
$partNumberList = Arr::pluck($partList, 'partNumber'); $partNumberList = Arr::pluck($partList, 'partNumber');
if (max($partNumberList) === count($partNumberList)) { if(max($partNumberList) === count($partNumberList)){
//判断是否已存在同名文件,进行删除 //判断是否已存在同名文件,进行重命名
if (Storage::disk(Admin::config('admin.upload.disk'))->exists($realPath)) { if(Storage::disk(Admin::config('admin.upload.disk'))->exists($realPath)){
$realPath = 'chunk/(1)'.$fileName; $realPath = 'chunk/(1)'.$fileName;
} }
for ($i = 1; $i <= count($partNumberList); $i++) { for($i = 1; $i<= count($partNumberList); $i++){
$_file = Storage::disk(Admin::config('admin.upload.disk'))->get($basePath.'/'.$fileName.'_'.$i); $_file = Storage::disk(Admin::config('admin.upload.disk'))->get($basePath.'/'.$fileName.'_'.$i);
Storage::disk(Admin::config('admin.upload.disk'))->append($realPath, $_file, null); $res = Storage::disk(Admin::config('admin.upload.disk'))->append($realPath, $_file, null);
} }
//删除分片文件夹 //删除分片文件夹
Storage::disk(Admin::config('admin.upload.disk'))->deleteDirectory($basePath); Storage::disk(Admin::config('admin.upload.disk'))->deleteDirectory($basePath);
$value = Storage::disk(Admin::config('admin.upload.disk'))->url($realPath); $value = Storage::disk(Admin::config('admin.upload.disk'))->url($realPath);
return $this->response()->success(['value' => $value]); return $this->response()->success(['value'=>$value]);
} else { }else{
return $this->response()->fail(__('admin.upload_file_error')); return $this->response()->fail(__('admin.upload_file_error'));
} }
} }