fetch('index'); } 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 = json_decode(request()->get('filter','[]'),true); 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'; } } $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 ]; } 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; } }