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(); $order_count = $this->getOrderCount(); $order_rank = $this->orderRank(); $item_rank = $this->itemRank(); $this->success(data: [ 'top' => $top, 'lines' => $lines, 'pie' => $pie, 'order' => $order, 'order_count' => $order_count, 'order_rank' => $order_rank, 'item_rank' => $item_rank, ]); } 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 getOrderCount() { $start = now()->format('Y-m-d 00:00:00'); $end_at = now()->format('Y-m-d 23:59:59'); $build = new \app\admin\model\Order(); $build->whereBetween('create_time', [$start, $end_at]); $data = $build->field([ 'sum(total) total', 'count(id) count', 'count(if(status=-10,1,null)) cancel' ])->select(); $today = [ 'total' => $data[0]->total ?? 0, 'count' => $data[0]->count ?? 0, 'cancel' => $data[0]->cancel ?? 0, ]; $build = new Worker(); $build->whereBetween('create_time', [$start, $end_at]); $data = $build->field([ 'count(id) count', ])->select(); // dd($data); $today['worker'] = $data[0]->count ?? 0; $build = new Aftersale(); $build->whereBetween('create_time', [$start, $end_at]); $data = $build->field([ 'count(id) count', ])->select(); $today['after_sale'] = $data[0]->count ?? 0; // 本月 $start = now()->format('Y-m-01 00:00:00'); $end_at = (new Carbon())->endOfMonth()->format('Y-m-d H:m:s'); // dd($start,$end_at); $build = new \app\admin\model\Order(); $build->whereBetween('create_time', [$start, $end_at]); $data = $build->field([ 'sum(total) total', 'count(id) count', 'count(if(status=-10,1,null)) cancel' ])->select(); // dd($data,\app\admin\model\Order::getLastSql()); $month = [ 'month_total' => $data[0]->total ?? 0, 'month_count' => $data[0]->count ?? 0, 'month_cancel' => $data[0]->cancel ?? 0, ]; $build = new Worker(); $build->whereBetween('create_time', [$start, $end_at]); $data = $build->field([ 'count(id) count', ])->select(); $month['month_worker'] = $data[0]->count ?? 0; $build = new Aftersale(); $build->whereBetween('create_time', [$start, $end_at]); $data = $build->field([ 'count(id) count', ])->select(); $month['month_after_sale'] = $data[0]->count ?? 0; return [ ...$today, ...$month ]; } private function orderRank() { $start = now()->format('Y-m-d 00:00:00'); $end_at = now()->format('Y-m-d 23:59:59'); $build = new \app\admin\model\Order(); $build->whereBetween('create_time', [$start, $end_at]); $data = $build->field([ 'admin_id', 'count(id) count', ])->group('admin_id') ->with('user') ->order('count', 'desc') ->limit(5) ->select(); $rank = []; foreach ($data as $da) { $rank [] = [ 'name' => $da->user->nickname ?? '', 'count' => $da->count ?? '', ]; } $build = new OrderDispatch(); $build->whereBetween('create_time', [$start, $end_at]); $data = $build->field([ 'worker_name', 'count(id) count', ])->group('worker_name') ->order('count', 'desc') ->limit(5) ->select(); $worker = []; foreach ($data as $da) { $worker [] = [ 'name' => $da->worker_name, 'count' => $da->count ?? '', ]; } return [ 'dispatch' => $rank, 'doing' => $worker, ]; } private function itemRank() { $start = now()->format('Y-m-d 00:00:00'); $end_at = now()->format('Y-m-d 23:59:59'); $build = new \app\admin\model\Order(); $build->whereBetween('create_time', [$start, $end_at]); $total = $build->count('id'); $build = new \app\admin\model\Order(); $build->whereBetween('create_time', [$start, $end_at]); $data = $build->field([ 'item_id', 'count(id) count', ])->group('item_id') ->with('user') ->order('count', 'desc') ->limit(6) ->select(); $rank = []; foreach ($data as $da) { $rank [] = [ 'name' => $da->item->title ?? '', 'count' => $da->count ?? 0, 'rate' => $this->mydiv($da->count ?? 0,$total) ]; } $build = new \app\admin\model\Order(); $res = $build->whereBetween('create_time', [$start, $end_at]) ->field([ 'SUBSTRING(area_id, 1, 2) AS name', 'count(id) count', ]) ->group('name') ->order('count','desc') ->limit(6) ->select(); $area = []; foreach ($res as $re) { $re = $re->getData(); $re['name'] = $this->getProvinceByCode($re['name']); $re['rate'] = $this->mydiv($da->count ?? 0,$total); $area [] = $re; } return [ 'item' => $rank, 'area' => $area, ]; } 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] : '未知'; } private function mydiv($a , $b){ if ($b == 0) { return '0'; }else{ return (int)($a / $b * 100); } } }