349 lines
8.9 KiB
PHP
349 lines
8.9 KiB
PHP
<?php
|
|
|
|
namespace app\admin\controller;
|
|
|
|
use app\admin\addresmart\Address;
|
|
use app\admin\model\Abnormal;
|
|
use app\admin\model\Aftersale;
|
|
use app\admin\model\AuthGroupAccess;
|
|
use app\admin\model\order\Invoice;
|
|
use app\admin\model\OrderAbnormal;
|
|
use app\admin\model\OrderDispatch;
|
|
use app\admin\model\Worker;
|
|
use app\admin\model\WorkerItem;
|
|
use app\common\controller\Backend;
|
|
use app\common\Logic\OrderLogic;
|
|
use fast\Tree;
|
|
use think\Db;
|
|
use think\Exception;
|
|
use think\exception\DbException;
|
|
use think\exception\PDOException;
|
|
use think\exception\ValidateException;
|
|
use think\Hook;
|
|
use think\Model;
|
|
use function Symfony\Component\Clock\now;
|
|
|
|
/**
|
|
* 订单列管理
|
|
*
|
|
* @icon fa fa-circle-o
|
|
*/
|
|
class Orderplan extends Backend
|
|
{
|
|
|
|
/**
|
|
* Order模型对象
|
|
* @var \app\admin\model\Order
|
|
*/
|
|
protected $model = null;
|
|
protected $sources = null;
|
|
protected $items = null;
|
|
|
|
public function _initialize()
|
|
{
|
|
parent::_initialize();
|
|
$this->model = new \app\admin\model\Order;
|
|
|
|
}
|
|
|
|
|
|
public function dashboard()
|
|
{
|
|
|
|
return $this->fetch('orderplan/index');
|
|
|
|
}
|
|
|
|
public function data()
|
|
{
|
|
$top = $this->getTopTotal();
|
|
$lines = $this->getLine();
|
|
$pie = $this->getPie();
|
|
$order = $this->getOrder();
|
|
$this->success(data: [
|
|
'top' => $top,
|
|
'lines' => $lines,
|
|
'pie' => $pie,
|
|
'order' => $order,
|
|
]);
|
|
}
|
|
|
|
private function getTopTotal()
|
|
{
|
|
$build = new \app\admin\model\Order();
|
|
|
|
$build->field([
|
|
'sum(total) total',
|
|
'count(id) count',
|
|
'sum(performance) performance'
|
|
])->limit(1);
|
|
|
|
$res = $this->buildDate($build)->select();
|
|
|
|
$res = $res[0] ?? false;
|
|
$worker = Worker::where('status', 1)->count();
|
|
if ($res) {
|
|
return [
|
|
'total' => $res->total,
|
|
'count' => $res->count,
|
|
'performance' => $res->performance,
|
|
'worker' => $worker,
|
|
];
|
|
}
|
|
|
|
return [
|
|
'total' => 0,
|
|
'count' => 0,
|
|
'performance' => 0,
|
|
'worker' => 0,
|
|
];
|
|
}
|
|
|
|
private function getLine()
|
|
{
|
|
$build = new \app\admin\model\Order();
|
|
$start = now()->modify('-14 days')->format('Y-m-d');
|
|
$end_at = now()->format('Y-m-d');
|
|
$build->field([
|
|
'DATE(create_time) day',
|
|
'sum(total) total',
|
|
'count(id) count',
|
|
'sum(performance) performance'
|
|
])->group(' DATE(create_time)');
|
|
|
|
$res = $this->buildDate($build)->select();
|
|
$data = [];
|
|
foreach ($res as $re) {
|
|
$re = $re->getData();
|
|
$data [] = $re;
|
|
}
|
|
return $this->prepareEchartsBarData($data, $start, $end_at);
|
|
}
|
|
|
|
private function getPie()
|
|
{
|
|
$build = new OrderAbnormal();
|
|
$res = $this->buildDate($build)
|
|
->field([
|
|
'abnormal_title name',
|
|
'count(id) value',
|
|
])
|
|
->group('abnormal_title')
|
|
->select();
|
|
$data = [];
|
|
foreach ($res as $re) {
|
|
$re = $re->getData();
|
|
$data [] = $re;
|
|
}
|
|
$out ['cancel'] = $data;
|
|
|
|
|
|
|
|
$build = new \app\admin\model\Order();
|
|
$res = $this->buildDate($build)
|
|
->field([
|
|
'item_title name',
|
|
'count(id) value',
|
|
])
|
|
->group('item_title')
|
|
->select();
|
|
$data = [];
|
|
foreach ($res as $re) {
|
|
$re = $re->getData();
|
|
$name = explode('/',$re['name']);
|
|
$re['name'] = str_replace(' ', '' ,array_pop($name));
|
|
$data [] = $re;
|
|
}
|
|
$out ['item'] = $data;
|
|
|
|
$build = new \app\admin\model\Order();
|
|
$res = $this->buildDate($build)
|
|
->field([
|
|
'SUBSTRING(area_id, 1, 2) AS name',
|
|
'count(id) value',
|
|
])
|
|
->group('name')
|
|
->select();
|
|
$data = [];
|
|
foreach ($res as $re) {
|
|
$re = $re->getData();
|
|
$re['name'] = $this->getProvinceByCode($re['name']);
|
|
$data [] = $re;
|
|
}
|
|
$out ['area'] = $data;
|
|
|
|
$build = new \app\admin\model\Order();
|
|
$res = $this->buildDate($build)
|
|
->field([
|
|
'source_shop AS name',
|
|
'count(id) value',
|
|
])
|
|
->group('name')
|
|
->select();
|
|
$data = [];
|
|
foreach ($res as $re) {
|
|
$re = $re->getData();
|
|
$data [] = $re;
|
|
}
|
|
$out ['source'] = $data;
|
|
|
|
|
|
return $out;
|
|
}
|
|
|
|
|
|
private function buildDate($build,$table_name = null)
|
|
{
|
|
$start = now()->modify('-14 days')->format('Y-m-d');
|
|
$end_at = now()->format('Y-m-d');
|
|
|
|
if ($table_name){
|
|
$build->where($table_name.'.create_time', 'between', [$start, $end_at]);
|
|
}else{
|
|
$build->where('create_time', 'between', [$start, $end_at]);
|
|
|
|
}
|
|
return $build;
|
|
}
|
|
|
|
|
|
|
|
private function getOrder()
|
|
{
|
|
$build = new OrderAbnormal();
|
|
$res = $build
|
|
->where('status',0)
|
|
->count('id');
|
|
$out ['abnormal'] = $res;
|
|
|
|
$build = new \app\admin\model\Order();
|
|
$res = $build
|
|
->where('status',\app\admin\model\Order::STATUS_CHECKING)
|
|
->count('id');
|
|
$out ['check'] = $res;
|
|
|
|
|
|
$build = new \app\admin\model\Order();
|
|
$res = $build
|
|
->where('status',\app\admin\model\Order::STATUS_AUDITING)
|
|
->count('id');
|
|
$out ['auditing'] = $res;
|
|
|
|
|
|
$build = new \app\admin\model\Order();
|
|
$res = $build
|
|
->alias('a')
|
|
->join('order_review b','a.id = b.order_id','left')
|
|
->where('a.status','in',[\app\admin\model\Order::STATUS_FINISHED,\app\admin\model\Order::STATUS_CANCEL])
|
|
->whereNull('b.id')
|
|
->count('a.id');
|
|
|
|
$out ['review'] = $res;
|
|
|
|
|
|
$build = new Aftersale();
|
|
$res = $build
|
|
->where('status',1)
|
|
->count('id');
|
|
$out ['after_sale'] = $res;
|
|
|
|
$build = new Invoice();
|
|
$res = $build
|
|
->where('status',0)
|
|
->count('id');
|
|
$out ['invoice'] = $res;
|
|
|
|
return $out;
|
|
}
|
|
|
|
|
|
private function prepareEchartsBarData(array $data, string $startDate, string $endDate): array
|
|
{
|
|
// 将原始数据用日期作为键索引
|
|
$indexed = [];
|
|
foreach ($data as $item) {
|
|
$indexed[$item['day']] = $item;
|
|
}
|
|
|
|
$start = strtotime($startDate);
|
|
$end = strtotime($endDate);
|
|
|
|
$xAxis = [];
|
|
$series_total = [];
|
|
$series_count = [];
|
|
$series_performance = [];
|
|
$rate = [];
|
|
|
|
for ($date = $start; $date <= $end; $date += 86400) {
|
|
$day = date('Y-m-d', $date);
|
|
$xAxis[] = $day;
|
|
|
|
$total = isset($indexed[$day]) ? (float)$indexed[$day]['total'] : 0;
|
|
$count = isset($indexed[$day]) ? (int)$indexed[$day]['count'] : 0;
|
|
$performance = isset($indexed[$day]) ? (float)$indexed[$day]['performance'] : 0;
|
|
|
|
$series_total[] = $total;
|
|
$series_count[] = $count;
|
|
$series_performance[] = $performance;
|
|
$rate[] = $total ? number_format($performance / $total * 100, 2) : '0';
|
|
}
|
|
|
|
return [
|
|
'xAxis' => $xAxis,
|
|
'series' => [
|
|
'total' => $series_total,
|
|
'count' => $series_count,
|
|
'performance' => $series_performance,
|
|
'rate' => $rate,
|
|
],
|
|
];
|
|
}
|
|
|
|
|
|
function getProvinceByCode($code) {
|
|
// 省级行政区域编码对应数组
|
|
$provinces = [
|
|
11 => '北京',
|
|
12 => '天津',
|
|
13 => '河北',
|
|
14 => '山西',
|
|
15 => '内蒙古',
|
|
21 => '辽宁',
|
|
22 => '吉林',
|
|
23 => '黑龙江',
|
|
31 => '上海',
|
|
32 => '江苏',
|
|
33 => '浙江',
|
|
34 => '安徽',
|
|
35 => '福建',
|
|
36 => '江西',
|
|
37 => '山东',
|
|
41 => '河南',
|
|
42 => '湖北',
|
|
43 => '湖南',
|
|
44 => '广东',
|
|
45 => '广西',
|
|
46 => '海南',
|
|
50 => '重庆',
|
|
51 => '四川',
|
|
52 => '贵州',
|
|
53 => '云南',
|
|
54 => '西藏',
|
|
61 => '陕西',
|
|
62 => '甘肃',
|
|
63 => '青海',
|
|
64 => '宁夏',
|
|
65 => '新疆',
|
|
71 => '台湾',
|
|
81 => '香港',
|
|
82 => '澳门'
|
|
];
|
|
|
|
// 如果提供的代码存在于数组中,返回对应的省名称,否则返回未知
|
|
return isset($provinces[$code]) ? $provinces[$code] : '未知';
|
|
}
|
|
|
|
|
|
|
|
}
|