diff --git a/application/admin/controller/statistics/Item.php b/application/admin/controller/statistics/Item.php index 103475d..437cb35 100644 --- a/application/admin/controller/statistics/Item.php +++ b/application/admin/controller/statistics/Item.php @@ -13,6 +13,7 @@ use think\Collection; use think\Exception; use think\exception\DbException; use think\Loader; +use think\Model; use think\response\Json; use function Symfony\Component\Clock\now; @@ -25,7 +26,6 @@ class Item extends Backend { - protected $relationSearch = true; public function _initialize() @@ -38,14 +38,15 @@ class Item extends Backend return $this->fetch('index'); } - public function list(){ - + public function list() + { $build = new Order(); $start = now()->modify('-14 days')->format('Y-m-d'); $end_at = now()->format('Y-m-d 23:29:59'); - $filter ['daterange'] = request()->get('daterange'); + $filter = json_decode(request()->get('filter','[]'),true); + if (!empty($filter['daterange'])) { $arr = explode(' - ', $filter['daterange']); if (trim($arr[0])) { @@ -55,18 +56,134 @@ class Item extends Backend $end_at = trim($arr[1]) . ' 23:29:59'; } } - $build->field([ - 'item_title', - 'sum(total) total', - 'count(id) count', - 'sum(performance) performance' - ])->group('item_title'); + $offset = request()->get('offset',0); + $limit = request()->get('limit',15); + $build->whereBetween('create_time', [$start, $end_at]) + ->field([ + 'item_title name', // 类型 + 'sum(total) total', // 营业额 + 'count(id) count_num', // 单量 + 'count(if(status=60,1,null)) finish_num', // 单量 + 'sum(performance) performance', // 收益 + 'sum(cost) cost', // 收益 + 'sum(material_cost) material_cost', // 收益 + 'sum(refund_amount) refund_amount', // 公司退款 + 'sum(worker_refund_amount) worker_refund_amount', // 工人退款 + ])->group('item_title') + ->order('count_num', 'desc'); +// dd($total); + $res = $build->paginate(); + $total = $res->total(); + $ress = $res->items(); + $data = []; +// dd($res); + foreach ($ress as $re) { + $re = $re->toArray(); +// dd($re); + $cost_total = $re['cost'] + $re['material_cost']; + $name = explode('/', $re['name']); + $re['name'] = str_replace(' ', '', array_pop($name)); + $re['performance_rate'] = $this->mydiv($re['performance'],$re['total']); + $re['trans_rate'] = $this->mydiv($re['finish_num'],$re['count_num']); + $re['cash_value'] = $this->mydiv($re['performance'],$re['count_num']); + $re['total_avg'] = $this->mydiv($re['total'],$re['count_num'],2,false); + $re['performance_avg'] = $this->mydiv($re['performance'],$re['finish_num'],2,false); + + $re['cost_total'] = $cost_total; +// $re['id'] = $re['item_id']; + $data [] = $re; + } + + return [ + 'rows' => $data, + 'total' => $total + ]; - return []; } - public function chartData(){ - return []; + public function chartData() + { + $build = new Order(); + + $start = now()->modify('-14 days')->format('Y-m-d'); + $end_at = now()->format('Y-m-d 23:29:59'); + + $filter ['daterange'] = request()->post('daterange'); + + if (!empty($filter['daterange'])) { + $arr = explode(' - ', $filter['daterange']); + if (trim($arr[0])) { + $start = trim($arr[0]); + } + if (trim($arr[1])) { + $end_at = trim($arr[1]) . ' 23:29:59'; + } + } + + $res = $build->whereBetween('create_time', [$start, $end_at]) + ->where('status', Order::STATUS_FINISHED) + ->field([ + 'item_title name', // 类型 + 'sum(total) total', // 营业额 + 'count(id) count', // 单量 + 'sum(performance) performance', // 收益 + 'sum(refund_amount) refund_amount', // 公司退款 + 'sum(worker_refund_amount) worker_refund_amount', // 工人退款 + ])->group('item_title') + ->order('count', 'desc')->select(); + $data = []; + foreach ($res as $re) { + $re = $re->getData(); + $name = explode('/', $re['name']); + $re['name'] = str_replace(' ', '', array_pop($name)); + $data [] = $re; + } + + $xAxis = []; + $totalPerformance = []; + $conversionRate = []; // 假设转化率 = performance / total(或自定义逻辑) + $profitRate = []; // 假设利润率 = (performance - worker_refund_amount) / performance + $refundRate = []; // 假设退款率 = refund_amount / total + $monetizedValue = []; // 假设变现值 = performance - refund_amount + + foreach ($data as $item) { + $name = $item['name']; + $total = (float)$item['total']; + $performance = (float)$item['performance']; + $refund = (float)($item['refund_amount'] + $item['worker_refund_amount']); + $workerRefund = (float)$item['worker_refund_amount']; + $count = max((int)$item['count'], 1); // 避免除以0 + + $xAxis[] = $name; + $totalPerformance[] = $total; + $conversionRate[] = $total > 0 ? round($performance / $total * 100, 2) : 0; + $profitRate[] = $total > 0 ? round(($total - $workerRefund) / $total * 100, 2) : 0; + $refundRate[] = $total > 0 ? round($refund / $total * 100, 2) : 0; + $monetizedValue[] = $total / $count; + } + $result = [ + 'xAxis' => $xAxis, + 'series' => [ + ['name' => '总业绩(¥)', 'type' => 'bar', 'yAxisIndex' => 0, 'data' => $totalPerformance], + ['name' => '转化率(%)', 'type' => 'bar', 'yAxisIndex' => 1, 'data' => $conversionRate], + ['name' => '利润率(%)', 'type' => 'bar', 'yAxisIndex' => 1, 'data' => $profitRate], + ['name' => '退款率(%)', 'type' => 'bar', 'yAxisIndex' => 1, 'data' => $refundRate], + ['name' => '变现值(¥)', 'type' => 'line', 'yAxisIndex' => 0, 'data' => $monetizedValue], + ] + ]; + + return $result; + } + + private function mydiv($a, $b, int $scale = 4, $is_percent = true): int|string + { + $val = $b > 0 ? bcdiv($a, $b, $scale) : 0; + + if ($is_percent) { + + return bcmul($val, 100, 2); + } + return $val; } } diff --git a/application/admin/view/statistics/item/index.html b/application/admin/view/statistics/item/index.html index b74f52d..749ac6e 100644 --- a/application/admin/view/statistics/item/index.html +++ b/application/admin/view/statistics/item/index.html @@ -24,19 +24,9 @@