0) { $employee_ids = implode(',', $employee_filter); $sql .= " AND c.cs_belong IN ($employee_ids)"; } } else { $sql .= " AND c.cs_belong = $employee_filter"; } } $sql .= " GROUP BY oi.product_id ORDER BY total_revenue DESC LIMIT $limit"; $result = $conn->query($sql); return $result; } /** * 获取产品销售趋势 * * @param mysqli $conn 数据库连接 * @param string $start_date 开始日期 * @param string $end_date 结束日期 * @param int $product_id 产品ID,为0时获取所有产品的总体趋势 * @param string $period 时间粒度 (day/week/month) * @param mixed $employee_filter 业务员过滤条件 * @return mysqli_result 产品销售趋势数据结果集 */ function getProductSalesTrend($conn, $start_date, $end_date, $product_id = 0, $period = 'month', $employee_filter = null) { $groupFormat = '%Y-%m-%d'; if ($period == 'week') { $groupFormat = '%x-W%v'; // ISO year and week number } else if ($period == 'month') { $groupFormat = '%Y-%m'; } $sql = "SELECT DATE_FORMAT(o.order_date, '$groupFormat') as time_period, SUM(oi.quantity) as total_quantity, SUM(oi.total_price) as total_revenue, COUNT(DISTINCT o.id) as order_count FROM order_items oi JOIN orders o ON oi.order_id = o.id"; if ($employee_filter !== null) { $sql .= " JOIN customer c ON o.customer_id = c.id"; } $sql .= " WHERE o.order_date BETWEEN '$start_date' AND '$end_date'"; if ($product_id > 0) { $sql .= " AND oi.product_id = $product_id"; } // 添加业务员过滤 if ($employee_filter !== null) { if (is_array($employee_filter)) { if (count($employee_filter) > 0) { $employee_ids = implode(',', $employee_filter); $sql .= " AND c.cs_belong IN ($employee_ids)"; } } else { $sql .= " AND c.cs_belong = $employee_filter"; } } $sql .= " GROUP BY time_period ORDER BY MIN(o.order_date)"; $result = $conn->query($sql); return $result; } /** * 获取产品类别销售分布 * * @param mysqli $conn 数据库连接 * @param string $start_date 开始日期 * @param string $end_date 结束日期 * @param mixed $employee_filter 业务员过滤条件 * @return mysqli_result 产品类别销售分布数据结果集 */ function getProductCategorySales($conn, $start_date, $end_date, $employee_filter = null) { $sql = "SELECT pc.name as category_name, SUM(oi.quantity) as total_quantity, SUM(oi.total_price) as total_revenue, COUNT(DISTINCT o.id) as order_count FROM order_items oi JOIN products p ON oi.product_id = p.id JOIN product_categories pc ON p.category_id = pc.id JOIN orders o ON oi.order_id = o.id"; if ($employee_filter !== null) { $sql .= " JOIN customer c ON o.customer_id = c.id"; } $sql .= " WHERE o.order_date BETWEEN '$start_date' AND '$end_date'"; // 添加业务员过滤 if ($employee_filter !== null) { if (is_array($employee_filter)) { if (count($employee_filter) > 0) { $employee_ids = implode(',', $employee_filter); $sql .= " AND c.cs_belong IN ($employee_ids)"; } } else { $sql .= " AND c.cs_belong = $employee_filter"; } } $sql .= " GROUP BY p.category_id ORDER BY total_revenue DESC"; $result = $conn->query($sql); return $result; } /** * 获取产品与地区关联分析 * * @param mysqli $conn 数据库连接 * @param string $start_date 开始日期 * @param string $end_date 结束日期 * @param mixed $employee_filter 业务员过滤条件 * @param int $limit 限制返回的产品-地区组合数量 * @return mysqli_result 产品与地区关联分析数据结果集 */ function getProductRegionAnalysis($conn, $start_date, $end_date, $employee_filter = null, $limit = 10) { $sql = "SELECT p.ProductName, c.countryName, SUM(oi.quantity) as total_quantity, SUM(oi.total_price) as total_revenue FROM order_items oi JOIN products p ON oi.product_id = p.id JOIN orders o ON oi.order_id = o.id JOIN customer cu ON o.customer_id = cu.id JOIN country c ON cu.cs_country = c.id"; $sql .= " WHERE o.order_date BETWEEN '$start_date' AND '$end_date'"; // 添加业务员过滤 if ($employee_filter !== null) { if (is_array($employee_filter)) { if (count($employee_filter) > 0) { $employee_ids = implode(',', $employee_filter); $sql .= " AND cu.cs_belong IN ($employee_ids)"; } } else { $sql .= " AND cu.cs_belong = $employee_filter"; } } $sql .= " GROUP BY oi.product_id, cu.cs_country ORDER BY total_revenue DESC LIMIT $limit"; $result = $conn->query($sql); return $result; } /** * 获取产品销售概览数据 * * @param mysqli $conn 数据库连接 * @param string $start_date 开始日期 * @param string $end_date 结束日期 * @param int $category_filter 产品分类过滤 * @param mixed $employee_filter 业务员过滤条件 * @return array 产品销售概览数据 */ function getProductSalesOverview($conn, $start_date, $end_date, $category_filter = 0, $employee_filter = null) { $where_clause = "WHERE o.order_date BETWEEN '$start_date' AND '$end_date'"; if ($category_filter > 0) { $where_clause .= " AND p.category_id = $category_filter"; } $sql = "SELECT COUNT(DISTINCT oi.product_id) as total_products, SUM(oi.quantity) as total_quantity, SUM(oi.total_price) as total_revenue, AVG(oi.unit_price) as avg_unit_price, COUNT(DISTINCT o.id) as total_orders, SUM(oi.total_price) / COUNT(DISTINCT o.id) as avg_order_value, COUNT(DISTINCT o.customer_id) as total_customers FROM order_items oi JOIN orders o ON oi.order_id = o.id JOIN products p ON oi.product_id = p.id"; if ($employee_filter !== null) { $sql .= " JOIN customer c ON o.customer_id = c.id"; } $sql .= " $where_clause"; // 添加业务员过滤 if ($employee_filter !== null) { if (is_array($employee_filter)) { if (count($employee_filter) > 0) { $employee_ids = implode(',', $employee_filter); $sql .= " AND c.cs_belong IN ($employee_ids)"; } } else { $sql .= " AND c.cs_belong = $employee_filter"; } } $result = $conn->query($sql); return $result->fetch_assoc(); } /** * 获取产品价格趋势分析 * * @param mysqli $conn 数据库连接 * @param string $start_date 开始日期 * @param string $end_date 结束日期 * @param int $product_id 产品ID * @param string $period 时间粒度 * @param mixed $employee_filter 业务员过滤条件 * @return mysqli_result 产品价格趋势数据 */ function getProductPriceTrendAnalysis($conn, $start_date, $end_date, $product_id = 0, $period = 'month', $employee_filter = null) { $groupFormat = getPeriodFormat($period); $sql = "SELECT DATE_FORMAT(o.order_date, '$groupFormat') as time_period, AVG(oi.unit_price) as avg_price, MIN(oi.unit_price) as min_price, MAX(oi.unit_price) as max_price FROM order_items oi JOIN orders o ON oi.order_id = o.id"; if ($employee_filter !== null) { $sql .= " JOIN customer c ON o.customer_id = c.id"; } $sql .= " WHERE o.order_date BETWEEN '$start_date' AND '$end_date'"; if ($product_id > 0) { $sql .= " AND oi.product_id = $product_id"; } // 添加业务员过滤 if ($employee_filter !== null) { if (is_array($employee_filter)) { if (count($employee_filter) > 0) { $employee_ids = implode(',', $employee_filter); $sql .= " AND c.cs_belong IN ($employee_ids)"; } } else { $sql .= " AND c.cs_belong = $employee_filter"; } } $sql .= " GROUP BY time_period ORDER BY MIN(o.order_date)"; $result = $conn->query($sql); return $result; } /** * 获取产品季节性分析 * * @param mysqli $conn 数据库连接 * @param string $start_date 开始日期 * @param string $end_date 结束日期 * @param int $product_id 产品ID * @param mixed $employee_filter 业务员过滤条件 * @return mysqli_result 产品季节性分析数据 */ function getProductSeasonalityAnalysis($conn, $start_date, $end_date, $product_id = 0, $employee_filter = null) { $sql = "SELECT MONTH(o.order_date) as month, SUM(oi.quantity) as total_quantity, SUM(oi.total_price) as total_revenue, COUNT(DISTINCT o.id) as order_count FROM order_items oi JOIN orders o ON oi.order_id = o.id"; if ($employee_filter !== null) { $sql .= " JOIN customer c ON o.customer_id = c.id"; } $sql .= " WHERE o.order_date BETWEEN '$start_date' AND '$end_date'"; if ($product_id > 0) { $sql .= " AND oi.product_id = $product_id"; } // 添加业务员过滤 if ($employee_filter !== null) { if (is_array($employee_filter)) { if (count($employee_filter) > 0) { $employee_ids = implode(',', $employee_filter); $sql .= " AND c.cs_belong IN ($employee_ids)"; } } else { $sql .= " AND c.cs_belong = $employee_filter"; } } $sql .= " GROUP BY MONTH(o.order_date) ORDER BY MONTH(o.order_date)"; $result = $conn->query($sql); return $result; } /** * 获取产品客户细分分析 * * @param mysqli $conn 数据库连接 * @param string $start_date 开始日期 * @param string $end_date 结束日期 * @param int $product_id 产品ID * @param mixed $employee_filter 业务员过滤条件 * @return mysqli_result 产品客户细分分析数据 */ function getProductCustomerSegmentAnalysis($conn, $start_date, $end_date, $product_id = 0, $employee_filter = null) { $sql = "SELECT ct.businessType as segment_name, 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_unit_price FROM order_items oi JOIN orders o ON oi.order_id = o.id JOIN customer c ON o.customer_id = c.id JOIN clienttype ct ON c.cs_type = ct.id"; $sql .= " WHERE o.order_date BETWEEN '$start_date' AND '$end_date'"; if ($product_id > 0) { $sql .= " AND oi.product_id = $product_id"; } // 添加业务员过滤 if ($employee_filter !== null) { if (is_array($employee_filter)) { if (count($employee_filter) > 0) { $employee_ids = implode(',', $employee_filter); $sql .= " AND c.cs_belong IN ($employee_ids)"; } } else { $sql .= " AND c.cs_belong = $employee_filter"; } } $sql .= " GROUP BY ct.id"; $result = $conn->query($sql); return $result; } /** * 获取产品分类列表 * * @param mysqli $conn 数据库连接 * @return mysqli_result 产品分类数据结果集 */ function getProductCategories($conn) { $sql = "SELECT id, parent_id, name, description, sort_order FROM product_categories WHERE status = 1 ORDER BY sort_order ASC, id ASC"; $stmt = $conn->prepare($sql); $stmt->execute(); return $stmt->get_result(); } /** * 渲染热门产品表格 * * @param mysqli_result $top_products 热门产品数据 * @return void */ function renderTopProductsTable($top_products) { ?>

热门产品

fetch_assoc()): ?>
产品名称 销售数量 销售收入
¥

产品销售趋势

产品类别销售分布

产品类别销售数量分布

产品类别销售收入分布

产品地区关联分析

fetch_assoc()): ?>
产品名称 国家/地区 销售数量 销售收入
¥

总销售产品数

种类

总销售数量

总销售收入

¥

平均单价

¥
元/件

订单数量

平均订单金额

¥
元/订单
fetch_assoc()) { $time_periods[] = $row['time_period']; $avg_prices[] = round($row['avg_price'], 2); $min_prices[] = round($row['min_price'], 2); $max_prices[] = round($row['max_price'], 2); } ?>

产品价格趋势分析

fetch_assoc()) { $months[] = date('n月', mktime(0, 0, 0, $row['month'], 1)); $quantities[] = (int)$row['total_quantity']; $revenues[] = round($row['total_revenue'], 2); $order_counts[] = (int)$row['order_count']; } ?>

产品季节性分析

fetch_assoc()) { $segments[] = $row['segment_name']; $customer_counts[] = (int)$row['customer_count']; $revenues[] = round($row['total_revenue'], 2); $avg_prices[] = round($row['avg_unit_price'], 2); } ?>

产品客户细分分析

0) { $employee_ids = implode(',', $employee_filter); $sql .= " AND c.cs_belong IN ($employee_ids)"; } } else { $sql .= " AND c.cs_belong = $employee_filter"; } } $sql .= " GROUP BY oi.product_id HAVING current_revenue > 0 ORDER BY current_revenue DESC LIMIT 10"; $current_data = $conn->query($sql); // 计算上一个时间段 $date1 = new DateTime($start_date); $date2 = new DateTime($end_date); $interval = $date1->diff($date2); $days_diff = $interval->days; $prev_end = $date1->format('Y-m-d'); $prev_start = $date1->modify("-{$days_diff} days")->format('Y-m-d'); // 获取上一期间的数据 $sql = "SELECT p.ProductName, SUM(oi.total_price) as prev_revenue, SUM(oi.quantity) as prev_quantity, COUNT(DISTINCT o.id) as prev_orders FROM order_items oi JOIN products p ON oi.product_id = p.id JOIN orders o ON oi.order_id = o.id WHERE o.order_date BETWEEN '$prev_start' AND '$prev_end' GROUP BY oi.product_id"; $prev_result = $conn->query($sql); $prev_data = []; while ($row = $prev_result->fetch_assoc()) { $prev_data[$row['ProductName']] = $row; } $growth_data = []; while ($current = $current_data->fetch_assoc()) { $product_name = $current['ProductName']; $prev = isset($prev_data[$product_name]) ? $prev_data[$product_name] : [ 'prev_revenue' => 0, 'prev_quantity' => 0, 'prev_orders' => 0 ]; $growth_data[] = [ 'product_name' => $product_name, 'current_revenue' => $current['current_revenue'], 'current_quantity' => $current['current_quantity'], 'current_orders' => $current['current_orders'], 'prev_revenue' => $prev['prev_revenue'], 'prev_quantity' => $prev['prev_quantity'], 'prev_orders' => $prev['prev_orders'], 'revenue_growth' => calculateGrowthRate($current['current_revenue'], $prev['prev_revenue']), 'quantity_growth' => calculateGrowthRate($current['current_quantity'], $prev['prev_quantity']), 'orders_growth' => calculateGrowthRate($current['current_orders'], $prev['prev_orders']) ]; } return $growth_data; } /** * 计算增长率 */ function calculateGrowthRate($current, $previous) { if ($previous == 0) { return $current > 0 ? 100 : 0; } return round((($current - $previous) / $previous) * 100, 2); } /** * 渲染产品增长率分析 */ function renderProductGrowthAnalysis($growth_data) { ?>

产品增长率分析

与上一时期相比
产品名称 当期收入 收入增长率 当期销量 销量增长率 当期订单数 订单增长率
¥ = 0 ? '+' : '') . $row['revenue_growth']; ?>% = 0 ? '+' : '') . $row['quantity_growth']; ?>% = 0 ? '+' : '') . $row['orders_growth']; ?>%
o1.order_date WHERE o1.order_date BETWEEN '$start_date' AND '$end_date' GROUP BY o1.customer_id, o1.order_date ) next_order ON o.customer_id = next_order.customer_id AND o.order_date = next_order.order_date WHERE o.order_date BETWEEN '$start_date' AND '$end_date'"; // 添加业务员过滤 if ($employee_filter !== null) { if (is_array($employee_filter)) { if (count($employee_filter) > 0) { $employee_ids = implode(',', $employee_filter); $sql .= " AND c.cs_belong IN ($employee_ids)"; } } else { $sql .= " AND c.cs_belong = $employee_filter"; } } $sql .= " GROUP BY p.id HAVING order_count > 1 ORDER BY purchase_frequency DESC LIMIT 10"; $result = $conn->query($sql); return $result; } /** * 渲染产品购买频率分析 */ function renderProductPurchaseFrequency($frequency_data) { ?>

产品购买频率分析

fetch_assoc()): ?>
产品名称 订单总数 购买客户数 平均购买频率 平均购买间隔(天)
次/客户
0) { $employee_ids = implode(',', $employee_filter); $sql .= "cs_belong IN ($employee_ids))"; } else { $sql .= "1=1)"; } } else { $sql .= "cs_belong = $employee_filter)"; } } $sql .= " GROUP BY customer_id )"; if ($category_filter > 0) { $sql .= " AND p.category_id = $category_filter"; } // 添加业务员过滤 if ($employee_filter !== null) { if (is_array($employee_filter)) { if (count($employee_filter) > 0) { $employee_ids = implode(',', $employee_filter); $sql .= " AND c.cs_belong IN ($employee_ids)"; } } else { $sql .= " AND c.cs_belong = $employee_filter"; } } $sql .= " GROUP BY p.id ORDER BY customer_count DESC, total_revenue DESC"; $result = $conn->query($sql); // 查询新客户总数 $sql_count = "SELECT COUNT(DISTINCT o.customer_id) as total_new_customers FROM orders o JOIN customer c ON o.customer_id = c.id WHERE o.order_date BETWEEN '$start_date' AND '$end_date' AND o.id IN ( SELECT MIN(id) FROM orders WHERE order_date BETWEEN '$start_date' AND '$end_date'"; if ($employee_filter !== null) { $sql_count .= " AND customer_id IN ( SELECT id FROM customer WHERE "; if (is_array($employee_filter)) { if (count($employee_filter) > 0) { $employee_ids = implode(',', $employee_filter); $sql_count .= "cs_belong IN ($employee_ids))"; } else { $sql_count .= "1=1)"; } } else { $sql_count .= "cs_belong = $employee_filter)"; } } $sql_count .= " GROUP BY customer_id )"; if ($employee_filter !== null) { if (is_array($employee_filter)) { if (count($employee_filter) > 0) { $employee_ids = implode(',', $employee_filter); $sql_count .= " AND c.cs_belong IN ($employee_ids)"; } } else { $sql_count .= " AND c.cs_belong = $employee_filter"; } } $result_count = $conn->query($sql_count); $count_row = $result_count->fetch_assoc(); $new_customer_count = $count_row ? $count_row['total_new_customers'] : 0; // 格式化返回数据 $products = []; if ($result) { while ($row = $result->fetch_assoc()) { $products[] = [ 'product_name' => $row['ProductName'], 'product_id' => $row['product_id'], 'category_name' => $row['category_name'], 'customer_count' => $row['customer_count'], 'order_count' => $row['order_count'], 'total_quantity' => $row['total_quantity'], 'total_revenue' => $row['total_revenue'], 'avg_price' => $row['avg_unit_price'] ]; } } return [ 'products' => $products, 'new_customer_count' => $new_customer_count ]; }