allocatr/application/admin/controller/Orderplan.php
2025-05-07 23:34:30 +08:00

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] : '未知';
}
}