$date_range, 'custom_start' => $custom_start, 'custom_end' => $custom_end, 'period' => $period, 'start_date' => $start_date, 'end_date' => $end_date, 'start_date_sql' => $start_date_sql, 'end_date_sql' => $end_date_sql ]; } /** * 生成图表颜色数组 * * @param int $count 需要的颜色数量 * @param bool $transparent 是否透明 * @return array 背景色和边框色数组 */ function generateChartColors($count = 10, $transparent = true) { $colors = [ ['rgba(255, 99, 132, ' . ($transparent ? '0.7' : '1') . ')', 'rgba(255, 99, 132, 1)'], ['rgba(54, 162, 235, ' . ($transparent ? '0.7' : '1') . ')', 'rgba(54, 162, 235, 1)'], ['rgba(255, 206, 86, ' . ($transparent ? '0.7' : '1') . ')', 'rgba(255, 206, 86, 1)'], ['rgba(75, 192, 192, ' . ($transparent ? '0.7' : '1') . ')', 'rgba(75, 192, 192, 1)'], ['rgba(153, 102, 255, ' . ($transparent ? '0.7' : '1') . ')', 'rgba(153, 102, 255, 1)'], ['rgba(255, 159, 64, ' . ($transparent ? '0.7' : '1') . ')', 'rgba(255, 159, 64, 1)'], ['rgba(199, 199, 199, ' . ($transparent ? '0.7' : '1') . ')', 'rgba(199, 199, 199, 1)'], ['rgba(83, 102, 255, ' . ($transparent ? '0.7' : '1') . ')', 'rgba(83, 102, 255, 1)'], ['rgba(40, 159, 64, ' . ($transparent ? '0.7' : '1') . ')', 'rgba(40, 159, 64, 1)'], ['rgba(210, 199, 199, ' . ($transparent ? '0.7' : '1') . ')', 'rgba(210, 199, 199, 1)'] ]; $result = []; // 确保有足够的颜色 while (count($result) < $count) { foreach ($colors as $color) { $result[] = $color; if (count($result) >= $count) { break; } } } return array_slice($result, 0, $count); } /** * 格式化数值,处理空值和小数位数 * * @param mixed $value 要格式化的值 * @param int $decimals 小数位数 * @return string 格式化后的数值 */ function formatNumber($value, $decimals = 2) { if ($value === null || $value === '') { return '0'; } return number_format((float)$value, $decimals); } /** * 获取时间粒度对应的MySQL DATE_FORMAT格式 * * @param string $period 时间粒度 (day/week/month) * @return string MySQL DATE_FORMAT格式字符串 */ function getPeriodFormat($period) { switch ($period) { case 'week': return '%x-W%v'; // ISO year and week number case 'month': return '%Y-%m'; case 'day': default: return '%Y-%m-%d'; } } /** * 获取新增客户详细信息 * * @param mysqli $conn 数据库连接 * @param string $start_date 开始日期 * @param string $end_date 结束日期 * @return array 新增客户详细数据 */ function getNewCustomersDetails($conn, $start_date, $end_date) { $sql = "SELECT c.id, c.cs_company as company_name, c.cs_code as customer_code, co.countryName as country, ct.businessType as customer_type, e.em_user as employee_name, c.cs_addtime as add_date FROM customer c LEFT JOIN country co ON c.cs_country = co.id LEFT JOIN clienttype ct ON c.cs_type = ct.id LEFT JOIN employee e ON c.cs_belong = e.id WHERE c.cs_addtime BETWEEN ? AND ? ORDER BY c.cs_addtime DESC LIMIT 30"; $stmt = $conn->prepare($sql); $stmt->bind_param("ss", $start_date, $end_date); $stmt->execute(); $result = $stmt->get_result(); $customers = []; while ($row = $result->fetch_assoc()) { $customers[] = $row; } return $customers; } /** * 获取各业务员新增客户统计 * * @param mysqli $conn 数据库连接 * @param string $start_date 开始日期 * @param string $end_date 结束日期 * @return array 业务员新增客户统计数据 */ function getNewCustomersByEmployee($conn, $start_date, $end_date) { $sql = "SELECT e.id as employee_id, e.em_user as employee_name, COUNT(c.id) as customer_count FROM employee e LEFT JOIN customer c ON e.id = c.cs_belong AND c.cs_addtime BETWEEN ? AND ? WHERE e.em_role IS NOT NULL GROUP BY e.id ORDER BY customer_count DESC"; $stmt = $conn->prepare($sql); $stmt->bind_param("ss", $start_date, $end_date); $stmt->execute(); $result = $stmt->get_result(); $data = []; while ($row = $result->fetch_assoc()) { $data[] = $row; } return $data; } /** * 渲染新增客户图表 * * @param array $customers 新增客户数据 * @return void */ function renderNewCustomersChart($customers) { if (empty($customers)) { echo '
该时间段内没有新增客户数据
'; return; } ?>
客户名称 客户编码 国家/地区 客户类型 负责业务员 添加日期
该时间段内没有业务员新增客户数据'; return; } // 准备图表数据 $employee_names = []; $customer_counts = []; foreach ($employee_data as $row) { $employee_names[] = $row['employee_name']; $customer_counts[] = $row['customer_count']; } // 生成图表背景色 $colors = generateChartColors(count($employee_data)); $backgroundColors = []; $borderColors = []; foreach ($colors as $color) { $backgroundColors[] = $color[0]; $borderColors[] = $color[1]; } ?>
业务员 新增客户数量
prepare($new_customer_sql); $stmt->bind_param("sss", $start_date, $end_date, $start_date); $stmt->execute(); $new_customers_result = $stmt->get_result(); $new_customer_ids = []; while ($row = $new_customers_result->fetch_assoc()) { $new_customer_ids[] = $row['customer_id']; } // 如果没有新客户,返回空数组 if (empty($new_customer_ids)) { return []; } // 构建查询条件中的客户ID列表 $customer_ids_str = implode(',', $new_customer_ids); // 查询这些新客户购买的产品 $category_filter = ""; if ($category_id > 0) { $category_filter = "AND p.category_id = " . intval($category_id); } $product_sql = " SELECT p.id, p.ProductName as product_name, pc.name as category_name, COUNT(DISTINCT o.id) as order_count, COUNT(DISTINCT o.customer_id) as customer_count, SUM(oi.quantity) as total_quantity, SUM(oi.total_price) as total_revenue, AVG(oi.unit_price) as avg_price FROM orders o JOIN order_items oi ON o.id = oi.order_id JOIN products p ON oi.product_id = p.id LEFT JOIN product_categories pc ON p.category_id = pc.id WHERE o.customer_id IN ({$customer_ids_str}) AND o.order_date BETWEEN ? AND ? AND o.order_status != 0 {$category_filter} GROUP BY p.id ORDER BY total_revenue DESC "; $stmt = $conn->prepare($product_sql); $stmt->bind_param("ss", $start_date, $end_date); $stmt->execute(); $result = $stmt->get_result(); $products = []; while ($row = $result->fetch_assoc()) { $products[] = $row; } return [ 'new_customer_count' => count($new_customer_ids), 'products' => $products ]; } /** * 渲染新客户产品购买明细 * * @param array $product_data 产品购买数据 * @return void */ function renderNewCustomerProductPurchases($product_data) { if (empty($product_data) || empty($product_data['products'])) { echo '
该时间段内没有新客户购买产品数据
'; return; } $products = $product_data['products']; $new_customer_count = $product_data['new_customer_count']; ?>

本期间共有 名新客户进行了购买。以下是他们购买的产品明细:

产品名称 产品分类 订单数 购买客户数 销售数量 销售金额 平均单价