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