18 changed files with 15750 additions and 4 deletions
-
0app/Admin/Actions/Exporter/SalesMan.php
-
147app/Admin/Actions/Metrics/Distance.php
-
119app/Admin/Actions/Metrics/Shipping.php
-
126app/Admin/Actions/Tools/DataReportDate.php
-
55app/Admin/Actions/Tools/DataReportOption.php
-
59app/Admin/Actions/Tools/DataReportOrder.php
-
60app/Admin/Actions/Tools/DataReportTime.php
-
1app/Admin/Common/LinkUrl.php
-
34app/Admin/Common/Order.php
-
224app/Admin/Controllers/v3/DataReport.php
-
113app/Admin/Extensions/Chart/Bar/OrderBar.php
-
1app/Admin/routes.php
-
3public/css/data_report.css
-
14765public/js/moment-with-locales.js
-
22resources/views/admin/tools/data_report_date.blade.php
-
11resources/views/admin/tools/data_report_option.blade.php
-
7resources/views/admin/tools/data_report_order.blade.php
-
7resources/views/admin/tools/data_report_time.blade.php
@ -0,0 +1,147 @@ |
|||||
|
<?php |
||||
|
|
||||
|
|
||||
|
namespace App\Admin\Actions\Metrics; |
||||
|
|
||||
|
|
||||
|
use Dcat\Admin\Admin; |
||||
|
use Dcat\Admin\Widgets\Metrics\Round; |
||||
|
|
||||
|
class Distance extends Round |
||||
|
{ |
||||
|
protected $distance; |
||||
|
protected $number; |
||||
|
public function __construct($distance, $number) |
||||
|
{ |
||||
|
$this->distance = $distance; |
||||
|
$this->number = $number; |
||||
|
parent::__construct($title=null, $icon=null); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 初始化卡片内容 |
||||
|
*/ |
||||
|
protected function init() |
||||
|
{ |
||||
|
parent::init(); |
||||
|
$this->height = 160; |
||||
|
$this->style('padding-top:0'); |
||||
|
$this->chartLabels(['1km以内', '1-3km', '3-5km','5km以上']); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 渲染模板 |
||||
|
* |
||||
|
* @return string |
||||
|
*/ |
||||
|
public function render() |
||||
|
{ |
||||
|
$this->fill(); |
||||
|
Admin::script($this->script()); |
||||
|
return parent::render(); |
||||
|
} |
||||
|
|
||||
|
public function script() |
||||
|
{ |
||||
|
return <<<JS |
||||
|
$('#shipping').parent().parent().parent().parent().prev().addClass('pt-0'); |
||||
|
JS; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 写入数据. |
||||
|
* |
||||
|
* @return void |
||||
|
*/ |
||||
|
public function fill() |
||||
|
{ |
||||
|
$this->withContent($this->distance[0], $this->distance[1],$this->distance[2],$this->distance[3]); |
||||
|
// 图表数据
|
||||
|
$this->withChart([ |
||||
|
$this->distance[0]>0?sprintf("%.2f",($this->distance[0]/$this->number)*100):0, |
||||
|
$this->distance[0]>0?sprintf("%.2f",($this->distance[1]/$this->number)*100):0, |
||||
|
$this->distance[0]>0?sprintf("%.2f",($this->distance[2]/$this->number)*100):0, |
||||
|
$this->distance[0]>0?sprintf("%.2f",($this->distance[3]/$this->number)*100):0, |
||||
|
]); |
||||
|
|
||||
|
// 总数
|
||||
|
$this->chartTotal('订单数', $this->number); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 设置图表数据. |
||||
|
* |
||||
|
* @param array $data |
||||
|
* |
||||
|
* @return $this |
||||
|
*/ |
||||
|
public function withChart(array $data) |
||||
|
{ |
||||
|
return $this->chart([ |
||||
|
'series' => $data, |
||||
|
]); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 卡片内容. |
||||
|
* |
||||
|
* @param int $finished |
||||
|
* @param int $pending |
||||
|
* @param int $rejected |
||||
|
* |
||||
|
* @return $this |
||||
|
*/ |
||||
|
public function withContent($d1, $d2, $d3,$d4) |
||||
|
{ |
||||
|
return $this->content( |
||||
|
<<<HTML |
||||
|
<div class="col-12 d-flex flex-column flex-wrap text-center" id="shipping" style="max-width: 220px;"> |
||||
|
<div class="chart-info d-flex justify-content-between mb-1 mt-2"> |
||||
|
<div class="series-info d-flex align-items-center"> |
||||
|
<i class="fa fa-circle-o text-bold-700 text-primary"></i> |
||||
|
<span class="text-bold-600 ml-50">1km以内</span> |
||||
|
</div> |
||||
|
<div class="product-result"> |
||||
|
<span>{$d1}</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="chart-info d-flex justify-content-between mb-1"> |
||||
|
<div class="series-info d-flex align-items-center"> |
||||
|
<i class="fa fa-circle-o text-bold-700 text-warning"></i> |
||||
|
<span class="text-bold-600 ml-50">1-3km</span> |
||||
|
</div> |
||||
|
<div class="product-result"> |
||||
|
<span>{$d2}</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="chart-info d-flex justify-content-between mb-1"> |
||||
|
<div class="series-info d-flex align-items-center"> |
||||
|
<i class="fa fa-circle-o text-bold-700 text-danger"></i> |
||||
|
<span class="text-bold-600 ml-50">3-5km</span> |
||||
|
</div> |
||||
|
<div class="product-result"> |
||||
|
<span>{$d3}</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="chart-info d-flex justify-content-between mb-1"> |
||||
|
<div class="series-info d-flex align-items-center"> |
||||
|
<i class="fa fa-circle-o text-bold-700 text-danger"></i> |
||||
|
<span class="text-bold-600 ml-50">5km以上</span> |
||||
|
</div> |
||||
|
<div class="product-result"> |
||||
|
<span>{$d4}</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
HTML |
||||
|
); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,119 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Admin\Actions\Metrics; |
||||
|
|
||||
|
use Dcat\Admin\Admin; |
||||
|
use Dcat\Admin\Widgets\Metrics\Donut; |
||||
|
|
||||
|
class Shipping extends Donut |
||||
|
{ |
||||
|
protected $labels = ['站内配送', '用户自提', '配送占比', '自提占比']; |
||||
|
protected $shipping; |
||||
|
|
||||
|
public function __construct($shipping) |
||||
|
{ |
||||
|
|
||||
|
$this->shipping = $shipping; |
||||
|
parent::__construct($title = null, $icon = null); |
||||
|
} |
||||
|
|
||||
|
public function init() |
||||
|
{ |
||||
|
parent::init(); // TODO: Change the autogenerated stub
|
||||
|
$color = Admin::color(); |
||||
|
$colors = [$color->primary(), $color->alpha('blue2', 0.5)]; |
||||
|
//$this->title('<small>配送数据</small>');
|
||||
|
$this->height = 150; |
||||
|
$this->chartLabels($this->labels); |
||||
|
// 设置图表颜色
|
||||
|
$this->chartColors($colors); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 渲染模板 |
||||
|
* |
||||
|
* @return string |
||||
|
*/ |
||||
|
public function render() |
||||
|
{ |
||||
|
$this->fill(); |
||||
|
return parent::render(); // TODO: Change the autogenerated stub
|
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 写入数据. |
||||
|
* |
||||
|
* @return void |
||||
|
*/ |
||||
|
public function fill() |
||||
|
{ |
||||
|
$total = array_sum($this->shipping); |
||||
|
$s3 = $this->shipping[0]>0?sprintf("%.1f", ($this->shipping[0] / $total) * 100) . '%':'0%'; |
||||
|
$s4 = $this->shipping[0]>0?sprintf("%.1f", ($this->shipping[1] / $total) * 100) . '%':'0%'; |
||||
|
// 图表数据
|
||||
|
|
||||
|
$this->withChart($this->shipping); |
||||
|
|
||||
|
$this->withContent($this->shipping[0], $this->shipping[1], $s3, $s4); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 设置图表数据. |
||||
|
* |
||||
|
* @param array $data |
||||
|
* |
||||
|
* @return $this |
||||
|
*/ |
||||
|
public function withChart(array $data) |
||||
|
{ |
||||
|
return $this->chart([ |
||||
|
'series' => $data |
||||
|
]); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 设置卡片头部内容. |
||||
|
* |
||||
|
* @param mixed $desktop |
||||
|
* @param mixed $mobile |
||||
|
* |
||||
|
* @return $this |
||||
|
*/ |
||||
|
protected function withContent($s1, $s2, $s3, $s4) |
||||
|
{ |
||||
|
$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>{$s1}</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>{$s2}</div> |
||||
|
</div> |
||||
|
|
||||
|
<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[2]} |
||||
|
</div> |
||||
|
<div>{$s3}</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[3]} |
||||
|
</div> |
||||
|
<div>{$s4}</div> |
||||
|
</div> |
||||
|
HTML |
||||
|
); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,126 @@ |
|||||
|
<?php |
||||
|
|
||||
|
|
||||
|
namespace App\Admin\Actions\Tools; |
||||
|
|
||||
|
|
||||
|
use App\Admin\Common\LinkUrl; |
||||
|
use Dcat\Admin\Admin; |
||||
|
use Dcat\Admin\Grid\Tools\AbstractTool; |
||||
|
|
||||
|
class DataReportDate extends AbstractTool |
||||
|
{ |
||||
|
|
||||
|
protected $route; |
||||
|
|
||||
|
public function __construct($route) |
||||
|
{ |
||||
|
$this->route = $route; |
||||
|
parent::__construct(); |
||||
|
} |
||||
|
|
||||
|
protected function script() |
||||
|
{ |
||||
|
$url = $path = request()->url(); |
||||
|
$fullUrl = request()->fullUrl(); |
||||
|
$date = request()->input('created_at'); |
||||
|
$start = $date?$date['start']:''; |
||||
|
$end = $date?$date['end']:''; |
||||
|
if(!(request()->server('QUERY_STRING'))){ |
||||
|
$fullUrl = $url .= "?type=today&option=1"; |
||||
|
} |
||||
|
return <<<JS |
||||
|
var app= new Vue({ |
||||
|
el:"#date_time", |
||||
|
data:{ |
||||
|
start: "$start", |
||||
|
end: "$end", |
||||
|
url:"$url", |
||||
|
full_url:"$fullUrl", |
||||
|
path:"$path", |
||||
|
pickerOptions: { |
||||
|
disabledDate(time) { |
||||
|
return time.getTime() > Date.now(); |
||||
|
}, |
||||
|
shortcuts: [{ |
||||
|
text: '今天', |
||||
|
onClick(picker) { |
||||
|
picker.\$emit('pick', new Date()); |
||||
|
} |
||||
|
}, { |
||||
|
text: '昨天', |
||||
|
onClick(picker) { |
||||
|
const date = new Date(); |
||||
|
date.setTime(date.getTime() - 3600 * 1000 * 24); |
||||
|
picker.\$emit('pick', date); |
||||
|
} |
||||
|
}, { |
||||
|
text: '一周前', |
||||
|
onClick(picker) { |
||||
|
const date = new Date(); |
||||
|
date.setTime(date.getTime() - 3600 * 1000 * 24 * 7); |
||||
|
picker.\$emit('pick', date); |
||||
|
} |
||||
|
}] |
||||
|
}, |
||||
|
}, |
||||
|
methods:{ |
||||
|
doSearch(){ |
||||
|
var market_id = sessionStorage.getItem('market_id'); |
||||
|
|
||||
|
if (market_id==0&&!this.start&&!this.end){ |
||||
|
this.\$message({message:'请选择查询市场或时间',type:"error"}) |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
var url = this.url; |
||||
|
if (this.start){ |
||||
|
url = url+"?type=date&option=0&created_at[start]="+this.start; |
||||
|
} |
||||
|
if (this.end){ |
||||
|
if (!this.start){ |
||||
|
this.\$message({message:'请选择起始时间',type:"error"}) |
||||
|
return false; |
||||
|
} |
||||
|
url = url+"&created_at[end]="+this.end; |
||||
|
}else { |
||||
|
if (this.start){ |
||||
|
this.\$message({message:'请选择截止时间',type:"error"}) |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (this.start&&this.end&&(this.start>this.end)){ |
||||
|
this.\$message({message:'截止时间不能小于起始时间',type:"error"}) |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
if (market_id>0&&!this.start&&!this.end){ |
||||
|
url = this.full_url+"&market_id="+market_id; |
||||
|
}else { |
||||
|
url = url+"&market_id="+market_id; |
||||
|
} |
||||
|
|
||||
|
window.location.href=url; |
||||
|
}, |
||||
|
reset(){ |
||||
|
window.location.href=this.path; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
}); |
||||
|
|
||||
|
JS; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public function render() |
||||
|
{ |
||||
|
Admin::js(LinkUrl::VUE_JS); |
||||
|
Admin::js(LinkUrl::ELEMENT_UI_JS); |
||||
|
Admin::css(LinkUrl::ELEMENT_UI_CSS); |
||||
|
Admin::css('css/data_report.css'); |
||||
|
Admin::script($this->script()); |
||||
|
return view('admin.tools.data_report_date'); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,55 @@ |
|||||
|
<?php |
||||
|
|
||||
|
|
||||
|
namespace App\Admin\Actions\Tools; |
||||
|
|
||||
|
|
||||
|
use App\Admin\Common\LinkUrl; |
||||
|
use Dcat\Admin\Admin; |
||||
|
use Dcat\Admin\Grid\Tools\AbstractTool; |
||||
|
|
||||
|
class DataReportOption extends AbstractTool |
||||
|
{ |
||||
|
|
||||
|
protected $route; |
||||
|
protected $option; |
||||
|
public function __construct($route,$option) |
||||
|
{ |
||||
|
$this->route = $route; |
||||
|
$this->option = $option; |
||||
|
parent::__construct(); |
||||
|
} |
||||
|
|
||||
|
protected function script() |
||||
|
{ |
||||
|
$option = json_encode($this->option); |
||||
|
$market_id = request()->get('market_id',0); |
||||
|
return <<<JS |
||||
|
var options = JSON.stringify($option) |
||||
|
var app= new Vue({ |
||||
|
el:"#option", |
||||
|
data:{ |
||||
|
options: JSON.parse(options), |
||||
|
value: $market_id, |
||||
|
}, |
||||
|
methods:{ |
||||
|
doSomething(url){ |
||||
|
sessionStorage.setItem('market_id',this.value) |
||||
|
} |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
JS; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public function render() |
||||
|
{ |
||||
|
Admin::js(LinkUrl::VUE_JS); |
||||
|
Admin::js(LinkUrl::ELEMENT_UI_JS); |
||||
|
Admin::css(LinkUrl::ELEMENT_UI_CSS); |
||||
|
Admin::css('css/data_report.css'); |
||||
|
Admin::script($this->script()); |
||||
|
return view('admin.tools.data_report_option'); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,59 @@ |
|||||
|
<?php |
||||
|
|
||||
|
|
||||
|
namespace App\Admin\Actions\Tools; |
||||
|
|
||||
|
|
||||
|
use Dcat\Admin\Admin; |
||||
|
use Dcat\Admin\Grid\Tools\AbstractTool; |
||||
|
|
||||
|
class DataReportOrder extends AbstractTool |
||||
|
{ |
||||
|
protected $url; |
||||
|
protected $option; |
||||
|
protected $route; |
||||
|
protected $dateTime; |
||||
|
protected $marketId; |
||||
|
public function __construct($route,$marketId,$dateTime) |
||||
|
{ |
||||
|
$this->route = $route; |
||||
|
$this->dateTime = $dateTime; |
||||
|
$this->marketId = $marketId; |
||||
|
parent::__construct(); |
||||
|
} |
||||
|
|
||||
|
protected function script() |
||||
|
{ |
||||
|
return <<<JS |
||||
|
$("#{$this->option}").change(function () { |
||||
|
var url = "{$this->url}" |
||||
|
Dcat.reload(url) |
||||
|
}); |
||||
|
JS; |
||||
|
} |
||||
|
|
||||
|
public function render() |
||||
|
{ |
||||
|
$options = [ |
||||
|
'amount' => '金额', |
||||
|
'num' => '单数', |
||||
|
|
||||
|
|
||||
|
]; |
||||
|
|
||||
|
$data = [ |
||||
|
'amount' => '1', |
||||
|
'num' => '2', |
||||
|
|
||||
|
]; |
||||
|
$option = request()->get('option'); |
||||
|
$this->dateTime['start'] = date('Y-m-d',$this->dateTime['start']); |
||||
|
$this->dateTime['end'] = date('Y-m-d',$this->dateTime['end']); |
||||
|
foreach ($data as $key=>$value){ |
||||
|
$this->url = "{$this->route}?order_type={$key}&option={$option}&name={$options[$key]}&market_id={$this->marketId}&created_at[start]={$this->dateTime['start']}&created_at[end]={$this->dateTime['end']}"; |
||||
|
$this->option = $key; |
||||
|
Admin::script($this->script()); |
||||
|
} |
||||
|
return view('admin.tools.data_report_order', compact('options')); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,60 @@ |
|||||
|
<?php |
||||
|
|
||||
|
|
||||
|
namespace App\Admin\Actions\Tools; |
||||
|
|
||||
|
|
||||
|
use Dcat\Admin\Admin; |
||||
|
use Dcat\Admin\Grid\Tools\AbstractTool; |
||||
|
|
||||
|
class DataReportTime extends AbstractTool |
||||
|
{ |
||||
|
protected $url; |
||||
|
protected $option; |
||||
|
protected $route; |
||||
|
public function __construct($route) |
||||
|
{ |
||||
|
$this->route = $route; |
||||
|
parent::__construct(); |
||||
|
} |
||||
|
|
||||
|
protected function script() |
||||
|
{ |
||||
|
return <<<JS |
||||
|
$("#{$this->option}").change(function () { |
||||
|
var url = "{$this->url}" |
||||
|
Dcat.reload(url) |
||||
|
}); |
||||
|
JS; |
||||
|
} |
||||
|
|
||||
|
public function render() |
||||
|
{ |
||||
|
$options = [ |
||||
|
'today' => '今日', |
||||
|
'yesterday' => '昨日', |
||||
|
'week' => '本周', |
||||
|
'last_week' => '上周', |
||||
|
'month' => '本月', |
||||
|
'last_month' => '上月', |
||||
|
|
||||
|
]; |
||||
|
|
||||
|
$data = [ |
||||
|
'today' => '1', |
||||
|
'yesterday' => '-1', |
||||
|
'week' => 'w', |
||||
|
'last_week' => 'lw', |
||||
|
'month' => '30', |
||||
|
'last_month' => '-30', |
||||
|
|
||||
|
]; |
||||
|
|
||||
|
foreach ($data as $key=>$value){ |
||||
|
$this->url = "{$this->route}?type={$key}&option={$value}&&name={$options[$key]}"; |
||||
|
$this->option = $key; |
||||
|
Admin::script($this->script()); |
||||
|
} |
||||
|
return view('admin.tools.data_report_time', compact('options')); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,224 @@ |
|||||
|
<?php |
||||
|
|
||||
|
|
||||
|
namespace App\Admin\Controllers\v3; |
||||
|
|
||||
|
use App\Admin\Actions\Metrics\Distance; |
||||
|
use App\Admin\Actions\Metrics\Shipping; |
||||
|
use App\Admin\Actions\Tools\DataReportDate; |
||||
|
use App\Admin\Actions\Tools\DataReportOption; |
||||
|
use App\Admin\Common\Order; |
||||
|
use App\Admin\Extensions\Chart\Bar\OrderBar; |
||||
|
use App\Admin\Extensions\Chart\PolarArea\Market; |
||||
|
use App\Models\ImsCjdcMarket; |
||||
|
use App\Models\v3\User; |
||||
|
use Dcat\Admin\Layout\Column; |
||||
|
use Dcat\Admin\Layout\Content; |
||||
|
use Dcat\Admin\Layout\Row; |
||||
|
use Dcat\Admin\Widgets\Card; |
||||
|
use Illuminate\Support\Facades\DB; |
||||
|
|
||||
|
class DataReport |
||||
|
{ |
||||
|
/** |
||||
|
* 数据报表 |
||||
|
* @param Content $content |
||||
|
* @return Content |
||||
|
*/ |
||||
|
protected $_amount; |
||||
|
protected $_number; |
||||
|
protected $_count_user; |
||||
|
protected $_shipping; |
||||
|
protected $_distance; |
||||
|
protected $_order_count_user; |
||||
|
public function __construct() |
||||
|
{ |
||||
|
$option = request()->get('option',1); |
||||
|
$marketId = request()->get('market_id',''); |
||||
|
$this->_amount = Order::getOrderData([ |
||||
|
'user_type'=>'market_service',//谁取数据 user_type 用户类型
|
||||
|
'data_type'=>'amount',//取什么数据 data_type 数据类型
|
||||
|
'market_id'=>$marketId,//取哪个市场数据
|
||||
|
'condition'=>1,//取数据维度 condition
|
||||
|
'user_ids'=>null |
||||
|
],$option); |
||||
|
$this->_number = Order::getOrderData([ |
||||
|
'user_type'=>'market_service',//谁取数据 user_type 用户类型
|
||||
|
'data_type'=>'number',//取什么数据 data_type 数据类型
|
||||
|
'market_id'=>$marketId,//取哪个市场数据
|
||||
|
'condition'=>1,//取数据维度 condition
|
||||
|
'user_ids'=>null |
||||
|
],$option); |
||||
|
$this->_count_user = Order::getOrderData([ |
||||
|
'user_type'=>'market_service',//谁取数据 user_type 用户类型
|
||||
|
'data_type'=>'count_user',//取什么数据 data_type 数据类型
|
||||
|
'market_id'=>$marketId,//取哪个市场数据
|
||||
|
'condition'=>1,//取数据维度 condition
|
||||
|
'user_ids'=>null |
||||
|
],$option); |
||||
|
$this->_shipping = Order::getOrderData([ |
||||
|
'user_type'=>'market_service',//谁取数据 user_type 用户类型
|
||||
|
'data_type'=>'shipping',//取什么数据 data_type 数据类型
|
||||
|
'market_id'=>$marketId,//取哪个市场数据
|
||||
|
'condition'=>1,//取数据维度 condition
|
||||
|
'user_ids'=>null |
||||
|
],$option); |
||||
|
$this->_distance = Order::getOrderData([ |
||||
|
'user_type'=>'market_service',//谁取数据 user_type 用户类型
|
||||
|
'data_type'=>'distance',//取什么数据 data_type 数据类型
|
||||
|
'market_id'=>$marketId,//取哪个市场数据
|
||||
|
'condition'=>1,//取数据维度 condition
|
||||
|
'user_ids'=>null |
||||
|
],$option); |
||||
|
$this->_order_count_user = Order::getOrderData([ |
||||
|
'user_type'=>'market_service',//谁取数据 user_type 用户类型
|
||||
|
'data_type'=>'order_count_user',//取什么数据 data_type 数据类型
|
||||
|
'market_id'=>$marketId,//取哪个市场数据
|
||||
|
'condition'=>1,//取数据维度 condition
|
||||
|
'user_ids'=>null |
||||
|
],$option); |
||||
|
} |
||||
|
|
||||
|
public function index(Content $content) |
||||
|
{ |
||||
|
return $content |
||||
|
->header('订单数据') |
||||
|
->body(function (Row $row){ |
||||
|
$row->column(4,function (Column $column){ |
||||
|
$column->row(new \App\Admin\Actions\Tools\DataReportTime('data_report')); |
||||
|
}); |
||||
|
$row->column(2,function (Column $column){ |
||||
|
$markets = ImsCjdcMarket::getMarket(); |
||||
|
$data = [['value'=>0,'label'=>'全部市场']]; |
||||
|
foreach ($markets as $key=>$val){ |
||||
|
$item = []; |
||||
|
$item['value'] = $key; |
||||
|
$item['label'] = $val; |
||||
|
$data[] = $item; |
||||
|
} |
||||
|
$column->row(new DataReportOption('data_report',$data)); |
||||
|
}); |
||||
|
|
||||
|
$row->column(6,function (Column $column){ |
||||
|
$column->row(new DataReportDate('data_report')); |
||||
|
}); |
||||
|
|
||||
|
})->body('<hr />') |
||||
|
->body(function (Row $row){ |
||||
|
$row->column(2,function (Column $column){ |
||||
|
$title = "订单数"; |
||||
|
$value = $this->_number; |
||||
|
$card = Card::make("<span style='color: #ffffff'>{$title}</span>","<span style='color: #ffffff'>{$value}</span>"); |
||||
|
$card->style('background-color:#4e9876'); |
||||
|
$column->row($card); |
||||
|
}); |
||||
|
|
||||
|
$row->column(2,function (Column $column){ |
||||
|
$title = "订单总额(元)"; |
||||
|
$value = $this->_amount; |
||||
|
$card = Card::make("<span style='color: #ffffff'>{$title}</span>","<span style='color: #ffffff'>{$value}</span>"); |
||||
|
$card->style('background-color:#4e9876'); |
||||
|
$column->row($card); |
||||
|
}); |
||||
|
|
||||
|
$row->column(2,function (Column $column) { |
||||
|
$title = "下单人数"; |
||||
|
$value =$this->_count_user; |
||||
|
$card = Card::make("<span style='color: #ffffff'>{$title}</span>","<span style='color: #ffffff'>{$value}</span>"); |
||||
|
$card->style('background-color:#4e9876'); |
||||
|
$column->row($card); |
||||
|
}); |
||||
|
$row->column(2,function (Column $column){ |
||||
|
$title = "人均单价(元)"; |
||||
|
if ($this->_amount){ |
||||
|
$value = sprintf("%.2f",$this->_amount/$this->_count_user); |
||||
|
}else{ |
||||
|
$value=0; |
||||
|
} |
||||
|
|
||||
|
$card = Card::make("<span style='color: #ffffff'>{$title}</span>","<span style='color: #ffffff'>{$value}</span>"); |
||||
|
$card->style('background-color:#4e9876'); |
||||
|
$column->row($card); |
||||
|
}); |
||||
|
$row->column(2,function (Column $column){ |
||||
|
$title = "线上用户总数"; |
||||
|
$value = User::where('nick_name','!=','')->count(); |
||||
|
$card = Card::make("<span style='color: #ffffff'>{$title}</span>","<span style='color: #ffffff'>{$value}</span>"); |
||||
|
$card->style('background-color:#4e9876'); |
||||
|
$column->row($card); |
||||
|
}); |
||||
|
$row->column(2,function (Column $column){ |
||||
|
$title = "下过单的用户数"; |
||||
|
$value = $this->_order_count_user; |
||||
|
$card = Card::make("<span style='color: #ffffff'>{$title}</span>","<span style='color: #ffffff'>{$value}</span>"); |
||||
|
$card->style('background-color:#4e9876'); |
||||
|
$column->row($card); |
||||
|
}); |
||||
|
}) |
||||
|
->body(function (Row $row){ |
||||
|
$row->column(8,function (Column $column){ |
||||
|
$card = new Card(); |
||||
|
$card->title('订单图表'); |
||||
|
//默认查询最近20天的数据
|
||||
|
$dateTime = request()->get('created_at')??null; |
||||
|
if ($dateTime){ |
||||
|
$dateTime['start'] = strtotime($dateTime['start']); |
||||
|
$dateTime['end'] = strtotime($dateTime['end']); |
||||
|
}else{ |
||||
|
$dateTime =['start'=>time()-(20*86400),'end'=>time()]; |
||||
|
} |
||||
|
$marketId = request()->get('market_id')??0; |
||||
|
$card->tool(new \App\Admin\Actions\Tools\DataReportOrder('data_report',$marketId,$dateTime)); |
||||
|
$card->content(OrderBar::make($this->orderData(['type'=>1,'market_id'=>$marketId,'date_time'=>$dateTime]))); |
||||
|
$column->row($card); |
||||
|
}); |
||||
|
$row->column(4,function (Column $column){ |
||||
|
$column->row(new Shipping($this->_shipping)); |
||||
|
$column->row(new Distance($this->_distance,$this->_number)); |
||||
|
$card3 = Card::make('送达时间(暂无)'); |
||||
|
$card3->style("height:155px"); |
||||
|
$column->row($card3); |
||||
|
}); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 订单数据 |
||||
|
* @param array $params |
||||
|
* @return array[]|string[] |
||||
|
*/ |
||||
|
public function orderData($params=[]) |
||||
|
{ |
||||
|
$where['type'] = $params['type']; |
||||
|
if ($params['market_id']>0){ |
||||
|
$where['market_id'] = $params['market_id']; |
||||
|
} |
||||
|
$data = DB::table('lanzu_order_main') |
||||
|
->select('money') |
||||
|
->selectRaw("FROM_UNIXTIME(created_at,'%Y-%m-%d') as add_time") |
||||
|
->whereIn('state', [3, 4, 5, 10,11]) |
||||
|
->where($where) |
||||
|
->whereBetween('created_at',$params['date_time']) |
||||
|
->get(); |
||||
|
$time = $num = $amount = []; |
||||
|
if ($data){ |
||||
|
$data = $data->groupBy('add_time')->toArray(); |
||||
|
foreach ($data as $key=>$val){ |
||||
|
$time[] = $key; |
||||
|
$num[] = intval(count($val)); |
||||
|
$amount[] = sprintf("%.2f",array_sum(array_column($val,'money'))); |
||||
|
} |
||||
|
return ['time'=>$time,'num'=>$num,'amount'=>$amount]; |
||||
|
} |
||||
|
return ['time'=>'','num'=>'','amount'=>'']; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
public function getOrderData() |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
||||
@ -0,0 +1,113 @@ |
|||||
|
<?php |
||||
|
namespace App\Admin\Extensions\Chart\Bar; |
||||
|
|
||||
|
use Dcat\Admin\Admin; |
||||
|
use Dcat\Admin\Widgets\ApexCharts\Chart; |
||||
|
use Dcat\Admin\Widgets\Metrics\Bar; |
||||
|
|
||||
|
class OrderBar extends Chart |
||||
|
{ |
||||
|
protected $_data; |
||||
|
public function __construct($data=[]) |
||||
|
{ |
||||
|
parent::__construct($containerSelector=null, $options=[]); |
||||
|
$this->_data = $data; |
||||
|
$this->setUpOptions(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 初始化图表配置 |
||||
|
*/ |
||||
|
protected function setUpOptions() |
||||
|
{ |
||||
|
$color = Admin::color(); |
||||
|
$colors = [$color->primary(), $color->primaryDarker()]; |
||||
|
|
||||
|
$this->options([ |
||||
|
'colors' => $colors, |
||||
|
'chart' => [ |
||||
|
'type' => 'bar', |
||||
|
'height' => 430, |
||||
|
], |
||||
|
'plotOptions' => [ |
||||
|
'bar' => [ |
||||
|
'horizontal' => false, |
||||
|
'dataLabels' => [ |
||||
|
'position' => 'top', |
||||
|
], |
||||
|
] |
||||
|
], |
||||
|
'dataLabels' => [ |
||||
|
'enabled' => true, |
||||
|
'offsetX' => -6, |
||||
|
'style' => [ |
||||
|
'fontSize' => '12px', |
||||
|
'colors' => ['#fff'] |
||||
|
] |
||||
|
], |
||||
|
'stroke' => [ |
||||
|
'show' => true, |
||||
|
'width' => 1, |
||||
|
'colors' => ['#fff'] |
||||
|
], |
||||
|
'xaxis' => [ |
||||
|
'categories' => [], |
||||
|
], |
||||
|
]); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 处理图表数据 |
||||
|
*/ |
||||
|
protected function buildData() |
||||
|
{ |
||||
|
$orderType = request()->input('order_type')??'amount'; |
||||
|
// 执行你的数据查询逻辑
|
||||
|
$data = [ |
||||
|
[ |
||||
|
'name'=>$orderType=='num'?'订单数':'订单金额', |
||||
|
'data' =>$orderType=='num'? $this->_data['num']:$this->_data['amount'] |
||||
|
], |
||||
|
]; |
||||
|
$categories = $this->_data['time']; |
||||
|
$this->withData($data); |
||||
|
$this->withCategories($categories); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 设置图表数据 |
||||
|
* |
||||
|
* @param array $data |
||||
|
* |
||||
|
* @return $this |
||||
|
*/ |
||||
|
public function withData(array $data) |
||||
|
{ |
||||
|
return $this->option('series', $data); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 设置图表类别. |
||||
|
* |
||||
|
* @param array $data |
||||
|
* |
||||
|
* @return $this |
||||
|
*/ |
||||
|
public function withCategories(array $data) |
||||
|
{ |
||||
|
return $this->option('xaxis.categories', $data); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 渲染图表 |
||||
|
* |
||||
|
* @return string |
||||
|
*/ |
||||
|
public function render() |
||||
|
{ |
||||
|
$this->buildData(); |
||||
|
|
||||
|
return parent::render(); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,3 @@ |
|||||
|
.el-input__inner { |
||||
|
height: 37px; |
||||
|
} |
||||
14765
public/js/moment-with-locales.js
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,22 @@ |
|||||
|
<div id="date_time"> |
||||
|
<div class="block"> |
||||
|
<el-date-picker |
||||
|
class="v1" |
||||
|
v-model="start" |
||||
|
type="date" |
||||
|
value-format="yyyy-MM-dd" |
||||
|
placeholder="选择日期"> |
||||
|
</el-date-picker> |
||||
|
- |
||||
|
<el-date-picker |
||||
|
v-model="end" |
||||
|
type="date" |
||||
|
value-format="yyyy-MM-dd" |
||||
|
placeholder="选择日期"> |
||||
|
</el-date-picker> |
||||
|
<button type="button" class="btn btn-primary" @click="doSearch()">查询</button> |
||||
|
|
||||
|
<button type="button" class="btn btn-primary" @click="reset()">重置</button> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
@ -0,0 +1,11 @@ |
|||||
|
<div id="option"> |
||||
|
<el-select v-model="value" filterable placeholder="选择市场"> |
||||
|
<el-option |
||||
|
v-for="item in options" |
||||
|
:change="doSomething()" |
||||
|
:key="item.value" |
||||
|
:label="item.label" |
||||
|
:value="item.value"> |
||||
|
</el-option> |
||||
|
</el-select> |
||||
|
</div> |
||||
@ -0,0 +1,7 @@ |
|||||
|
<div class="btn-group btn-group-toggle" data-toggle="buttons"> |
||||
|
@foreach($options as $option => $label) |
||||
|
<label class="btn btn-outline-primary {{request()->get('order_type','amount')==$option? 'active':''}}"> |
||||
|
<input type="radio" name="options" id="{{$option}}"> {{$label}} |
||||
|
</label> |
||||
|
@endforeach |
||||
|
</div> |
||||
@ -0,0 +1,7 @@ |
|||||
|
<div class="btn-group btn-group-toggle" data-toggle="buttons"> |
||||
|
@foreach($options as $option => $label) |
||||
|
<label class="btn btn-outline-primary {{request()->get('type','yesterday')==$option? 'active':''}}"> |
||||
|
<input type="radio" name="options" id="{{$option}}"> {{$label}} |
||||
|
</label> |
||||
|
@endforeach |
||||
|
</div> |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue