first commit
This commit is contained in:
@@ -0,0 +1,176 @@
|
||||
<?php
|
||||
/**
|
||||
* The file was created by Assimon.
|
||||
*
|
||||
* @author assimon<ashang@utf8.hk>
|
||||
* @copyright assimon<ashang@utf8.hk>
|
||||
* @link http://utf8.hk/
|
||||
*/
|
||||
|
||||
namespace App\Admin\Charts;
|
||||
|
||||
|
||||
use App\Models\Order;
|
||||
use Dcat\Admin\Widgets\Metrics\RadialBar;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class DashBoard extends RadialBar
|
||||
{
|
||||
|
||||
/**
|
||||
* 初始化卡片内容
|
||||
*/
|
||||
protected function init()
|
||||
{
|
||||
parent::init();
|
||||
|
||||
$this->title(admin_trans('dujiaoka.sales_data'));
|
||||
$this->height(400);
|
||||
$this->chartHeight(300);
|
||||
$this->chartLabels(admin_trans('dujiaoka.order_success_rate'));
|
||||
$this->dropdown([
|
||||
'today' => admin_trans('dujiaoka.last_today'),
|
||||
'seven' => admin_trans('dujiaoka.last_seven_days'),
|
||||
'month' => admin_trans('dujiaoka.last_month'),
|
||||
'year' => admin_trans('dujiaoka.last_year'),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理请求
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return mixed|void
|
||||
*/
|
||||
public function handle(Request $request)
|
||||
{
|
||||
$endTime = Carbon::now();
|
||||
switch ($request->get('option')) {
|
||||
case 'seven':
|
||||
$startTime = Carbon::now()->subDays(7);
|
||||
break;
|
||||
case 'month':
|
||||
$startTime = Carbon::now()->subDays(30);
|
||||
break;
|
||||
case 'year':
|
||||
$startTime = Carbon::now()->subDays(365);
|
||||
break;
|
||||
case 'today':
|
||||
default:
|
||||
$startTime = Carbon::today();
|
||||
}
|
||||
// 分组查询
|
||||
$orderGroup = Order::query()
|
||||
->where('created_at', '>=', $startTime)
|
||||
->where('created_at', '<=', $endTime)
|
||||
->select('status', DB::raw('count(id) as num'))
|
||||
->groupBy('status')
|
||||
->pluck('num', 'status')
|
||||
->toArray();
|
||||
$pending = $orderGroup[Order::STATUS_PENDING] ?? 0;
|
||||
$processing = $orderGroup[Order::STATUS_PROCESSING] ?? 0;
|
||||
$completed = $orderGroup[Order::STATUS_COMPLETED] ?? 0;
|
||||
$failure = $orderGroup[Order::STATUS_FAILURE] ?? 0;
|
||||
$abnormal = $orderGroup[Order::STATUS_ABNORMAL] ?? 0;
|
||||
$orderCount = array_sum($orderGroup);
|
||||
if ($orderCount == 0) {
|
||||
$successRate = 0;
|
||||
} else {
|
||||
$rate = bcdiv($completed, $orderCount, 2);
|
||||
$successRate = bcmul($rate, 100);
|
||||
}
|
||||
// 订单数
|
||||
$this->withOrderCount($orderCount);
|
||||
// 卡片底部
|
||||
$this->withFooter($pending, $processing, $completed, $failure, $abnormal);
|
||||
// 图表数据
|
||||
$this->withChart($successRate);
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单总数
|
||||
*
|
||||
* @param $count
|
||||
* @return DashBoard
|
||||
*
|
||||
* @author assimon<ashang@utf8.hk>
|
||||
* @copyright assimon<ashang@utf8.hk>
|
||||
* @link http://utf8.hk/
|
||||
*/
|
||||
public function withOrderCount($count)
|
||||
{
|
||||
$title = admin_trans('dujiaoka.order_count_number');
|
||||
return $this->content(
|
||||
<<<HTML
|
||||
<div class="d-flex flex-column flex-wrap text-center">
|
||||
<h1 class="font-lg-2 mt-2 mb-0">{$count}</h1>
|
||||
<small>{$title}</small>
|
||||
</div>
|
||||
HTML
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 成交率.
|
||||
*
|
||||
* @param int $data
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function withChart(int $data)
|
||||
{
|
||||
return $this->chart([
|
||||
'series' => [$data],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $pending
|
||||
* @param $processing
|
||||
* @param $completed
|
||||
* @param $failure
|
||||
* @param $abnormal
|
||||
* @return DashBoard
|
||||
*
|
||||
* @author assimon<ashang@utf8.hk>
|
||||
* @copyright assimon<ashang@utf8.hk>
|
||||
* @link http://utf8.hk/
|
||||
*/
|
||||
public function withFooter($pending, $processing, $completed, $failure, $abnormal)
|
||||
{
|
||||
$statusPendingTitle = admin_trans('dujiaoka.status_pending_number');
|
||||
$statusProcessingNumber = admin_trans('dujiaoka.status_processing_number');
|
||||
$statusCompletedNumber = admin_trans('dujiaoka.status_completed_number');
|
||||
$statusFailureNumber = admin_trans('dujiaoka.status_failure_number');
|
||||
$statusAbnormalNumber = admin_trans('dujiaoka.status_abnormal_number');
|
||||
return $this->footer(
|
||||
<<<HTML
|
||||
<div class="d-flex justify-content-between p-1" style="padding-top: 0!important;">
|
||||
<div class="text-center">
|
||||
<p>{$statusPendingTitle}</p>
|
||||
<span class="font-lg-1">{$pending}</span>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
<p>{$statusProcessingNumber}</p>
|
||||
<span class="font-lg-1">{$processing}</span>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
<p>{$statusCompletedNumber}</p>
|
||||
<span class="font-lg-1">{$completed}</span>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
<p>{$statusFailureNumber}</p>
|
||||
<span class="font-lg-1">{$failure}</span>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
<p>{$statusAbnormalNumber}</p>
|
||||
<span class="font-lg-1">{$abnormal}</span>
|
||||
</div>
|
||||
</div>
|
||||
HTML
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
/**
|
||||
* The file was created by Assimon.
|
||||
*
|
||||
* @author assimon<ashang@utf8.hk>
|
||||
* @copyright assimon<ashang@utf8.hk>
|
||||
* @link http://utf8.hk/
|
||||
*/
|
||||
|
||||
namespace App\Admin\Charts;
|
||||
|
||||
|
||||
use App\Models\Order;
|
||||
use Dcat\Admin\Admin;
|
||||
use Dcat\Admin\Widgets\Metrics\Donut;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Carbon;
|
||||
|
||||
class PayoutRateCard extends Donut
|
||||
{
|
||||
|
||||
protected $labels;
|
||||
|
||||
/**
|
||||
* 初始化卡片内容
|
||||
*/
|
||||
protected function init()
|
||||
{
|
||||
parent::init();
|
||||
|
||||
$this->labels = [admin_trans('dujiaoka.payment_successful_number'), admin_trans('dujiaoka.unpaid_number')];
|
||||
$color = Admin::color();
|
||||
$colors = [$color->primary(), $color->alpha('blue2', 0.5)];
|
||||
|
||||
$this->title(admin_trans('dujiaoka.payment_chart'));
|
||||
$this->chartLabels($this->labels);
|
||||
// 设置图表颜色
|
||||
$this->chartColors($colors);
|
||||
$this->dropdown([
|
||||
'seven' => admin_trans('dujiaoka.last_seven_days'),
|
||||
'today' => admin_trans('dujiaoka.last_today'),
|
||||
'month' => admin_trans('dujiaoka.last_month'),
|
||||
'year' => admin_trans('dujiaoka.last_year'),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理请求
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return mixed|void
|
||||
*/
|
||||
public function handle(Request $request)
|
||||
{
|
||||
$endTime = Carbon::now();
|
||||
switch ($request->get('option')) {
|
||||
case 'seven':
|
||||
$startTime = Carbon::now()->subDays(7);
|
||||
break;
|
||||
case 'month':
|
||||
$startTime = Carbon::now()->subDays(30);
|
||||
break;
|
||||
case 'year':
|
||||
$startTime = Carbon::now()->subDays(365);
|
||||
break;
|
||||
case 'today':
|
||||
$startTime = Carbon::today();
|
||||
break;
|
||||
default:
|
||||
$startTime = Carbon::now()->subDays(7);
|
||||
}
|
||||
// 成功的数量
|
||||
$success = Order::query()
|
||||
->where('created_at', '>=', $startTime)
|
||||
->where('created_at', '<=', $endTime)
|
||||
->where('status', '>', Order::STATUS_WAIT_PAY)
|
||||
->count();
|
||||
// 待支付的数量
|
||||
$unpaid = Order::query()
|
||||
->where('created_at', '>=', $startTime)
|
||||
->where('created_at', '<=', $endTime)
|
||||
->where('status', '<=', Order::STATUS_WAIT_PAY)
|
||||
->count();
|
||||
$this->withContent($success, $unpaid);
|
||||
// 图表数据
|
||||
$this->withChart([$success, $unpaid]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置图表数据.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function withChart(array $data)
|
||||
{
|
||||
return $this->chart([
|
||||
'series' => $data
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置卡片头部内容.
|
||||
*
|
||||
* @param mixed $success
|
||||
* @param mixed $unpaid
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
protected function withContent($success, $unpaid)
|
||||
{
|
||||
$blue = Admin::color()->alpha('blue2', 0.5);
|
||||
|
||||
$style = 'margin-bottom: 8px';
|
||||
$labelWidth = 120;
|
||||
|
||||
return $this->content(
|
||||
<<<HTML
|
||||
<div class="d-flex pl-1 pr-1 pt-1" style="{$style}">
|
||||
<div style="width: {$labelWidth}px">
|
||||
<i class="fa fa-circle text-primary"></i> {$this->labels[0]}
|
||||
</div>
|
||||
<div>{$success}</div>
|
||||
</div>
|
||||
<div class="d-flex pl-1 pr-1" style="{$style}">
|
||||
<div style="width: {$labelWidth}px">
|
||||
<i class="fa fa-circle" style="color: $blue"></i> {$this->labels[1]}
|
||||
</div>
|
||||
<div>{$unpaid}</div>
|
||||
</div>
|
||||
HTML
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
<?php
|
||||
/**
|
||||
* The file was created by Assimon.
|
||||
*
|
||||
* @author assimon<ashang@utf8.hk>
|
||||
* @copyright assimon<ashang@utf8.hk>
|
||||
* @link http://utf8.hk/
|
||||
*/
|
||||
|
||||
namespace App\Admin\Charts;
|
||||
|
||||
|
||||
use App\Models\Order;
|
||||
use Dcat\Admin\Admin;
|
||||
use Dcat\Admin\Widgets\Metrics\Bar;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class SalesCard extends Bar
|
||||
{
|
||||
|
||||
/**
|
||||
* 初始化卡片内容
|
||||
*/
|
||||
protected function init()
|
||||
{
|
||||
parent::init();
|
||||
|
||||
$color = Admin::color();
|
||||
|
||||
$dark35 = $color->dark35();
|
||||
|
||||
// 卡片内容宽度
|
||||
$this->contentWidth(5, 7);
|
||||
// 标题
|
||||
$this->title(admin_trans('dujiaoka.sales_chart'));
|
||||
// 设置下拉选项
|
||||
$this->dropdown([
|
||||
'seven' => admin_trans('dujiaoka.last_seven_days'),
|
||||
'today' => admin_trans('dujiaoka.last_today'),
|
||||
'month' => admin_trans('dujiaoka.last_month'),
|
||||
]);
|
||||
// 设置图表颜色
|
||||
$this->chartColors([
|
||||
$dark35,
|
||||
$color->primary(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理请求
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return mixed|void
|
||||
*/
|
||||
public function handle(Request $request)
|
||||
{
|
||||
$endTime = Carbon::now();
|
||||
switch ($request->get('option')) {
|
||||
case 'seven':
|
||||
$startTime = Carbon::now()->subDays(7);
|
||||
break;
|
||||
case 'month':
|
||||
$startTime = Carbon::now()->subDays(30);
|
||||
break;
|
||||
case 'today':
|
||||
$startTime = Carbon::today();
|
||||
break;
|
||||
default:
|
||||
$startTime = Carbon::now()->subDays(7);
|
||||
}
|
||||
// 分组查询
|
||||
$orderGroup = Order::query()
|
||||
->where('created_at', '>=', $startTime)
|
||||
->where('created_at', '<=', $endTime)
|
||||
->where('status', '>', Order::STATUS_PENDING)
|
||||
->select(DB::raw('DATE(created_at) as date'), DB::raw('sum(actual_price) as actual_price'))
|
||||
->groupBy('date')
|
||||
->pluck('actual_price')
|
||||
->toArray();
|
||||
$totalPrice = array_sum($orderGroup);
|
||||
$this->withContent($totalPrice, '', '', $startTime, $endTime);
|
||||
$this->withChart([
|
||||
[
|
||||
'name' => admin_trans('dujiaoka.sales_chart'),
|
||||
'data' => $orderGroup,
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置图表数据.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function withChart(array $data)
|
||||
{
|
||||
return $this->chart([
|
||||
'series' => $data,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置卡片内容.
|
||||
*
|
||||
* @param string $title
|
||||
* @param string $value
|
||||
* @param string $style
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function withContent($title, $value, $style = 'success', $startTime, $endTime)
|
||||
{
|
||||
$minHeight = '183px';
|
||||
$uri = admin_route('order.index', [
|
||||
'created_at[start]' => $startTime->format('Y-m-d H:i:s'),
|
||||
'created_at[end]' => $endTime->format('Y-m-d H:i:s')
|
||||
]);
|
||||
return $this->content(
|
||||
<<<HTML
|
||||
<div class="d-flex p-1 flex-column justify-content-between" style="padding-top: 0;width: 100%;height: 100%;min-height: {$minHeight}">
|
||||
<div class="text-left">
|
||||
<h1 class="font-lg-2 mt-2 mb-0">{$title}¥</h1>
|
||||
<h5 class="font-medium-2" style="margin-top: 10px;">
|
||||
<span class="text-{$style}">{$value} </span>
|
||||
</h5>
|
||||
</div>
|
||||
|
||||
<a href="{$uri}" class="btn btn-primary shadow waves-effect waves-light">View Details <i class="feather icon-chevrons-right"></i></a>
|
||||
</div>
|
||||
HTML
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
/**
|
||||
* The file was created by Assimon.
|
||||
*
|
||||
* @author assimon<ashang@utf8.hk>
|
||||
* @copyright assimon<ashang@utf8.hk>
|
||||
* @link http://utf8.hk/
|
||||
*/
|
||||
|
||||
namespace App\Admin\Charts;
|
||||
|
||||
|
||||
use App\Models\Order;
|
||||
use Dcat\Admin\Widgets\Metrics\Line;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class SuccessOrderCard extends Line
|
||||
{
|
||||
|
||||
/**
|
||||
* 初始化卡片内容
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function init()
|
||||
{
|
||||
parent::init();
|
||||
|
||||
$this->title(admin_trans('dujiaoka.status_completed_number'));
|
||||
$this->dropdown([
|
||||
'seven' => admin_trans('dujiaoka.last_seven_days'),
|
||||
'today' => admin_trans('dujiaoka.last_today'),
|
||||
'month' => admin_trans('dujiaoka.last_month'),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理请求
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return mixed|void
|
||||
*/
|
||||
public function handle(Request $request)
|
||||
{
|
||||
$endTime = Carbon::now();
|
||||
switch ($request->get('option')) {
|
||||
case 'seven':
|
||||
$startTime = Carbon::now()->subDays(7);
|
||||
break;
|
||||
case 'month':
|
||||
$startTime = Carbon::now()->subDays(30);
|
||||
break;
|
||||
case 'today':
|
||||
$startTime = Carbon::today();
|
||||
break;
|
||||
default:
|
||||
$startTime = Carbon::now()->subDays(7);
|
||||
}
|
||||
// 分组查询
|
||||
$orderGroup = Order::query()
|
||||
->where('created_at', '>=', $startTime)
|
||||
->where('created_at', '<=', $endTime)
|
||||
->where('status', Order::STATUS_COMPLETED)
|
||||
->select(DB::raw('DATE(created_at) as date'), DB::raw('count(id) as num'))
|
||||
->groupBy('date')
|
||||
->pluck('num')
|
||||
->toArray();
|
||||
$successCount = array_sum($orderGroup);
|
||||
// 卡片内容
|
||||
$this->withContent($successCount);
|
||||
// 图表数据
|
||||
$this->withChart($orderGroup);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置图表数据.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function withChart(array $data)
|
||||
{
|
||||
return $this->chart([
|
||||
'series' => [
|
||||
[
|
||||
'name' => $this->title,
|
||||
'data' => $data,
|
||||
],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置卡片内容.
|
||||
*
|
||||
* @param string $content
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function withContent($content)
|
||||
{
|
||||
return $this->content(
|
||||
<<<HTML
|
||||
<div class="d-flex justify-content-between align-items-center mt-1" style="margin-bottom: 2px">
|
||||
<h2 class="ml-1 font-lg-1">{$content}</h2>
|
||||
<span class="mb-0 mr-1 text-80">{$this->title}</span>
|
||||
</div>
|
||||
HTML
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user