|
@@ -1165,4 +1165,151 @@ function renderCustomerSourceChart($source_data) {
|
|
|
});
|
|
|
</script>
|
|
|
<?php
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 获取客户转化漏斗数据
|
|
|
+ *
|
|
|
+ * @param mysqli $conn 数据库连接
|
|
|
+ * @param string $start_date 开始日期
|
|
|
+ * @param string $end_date 结束日期
|
|
|
+ * @return array 客户转化漏斗数据
|
|
|
+ */
|
|
|
+function getCustomerConversionFunnel($conn, $start_date, $end_date) {
|
|
|
+ // 获取总客户数(潜在客户)
|
|
|
+ $total_sql = "SELECT COUNT(id) as total FROM customer";
|
|
|
+ $total_result = $conn->query($total_sql);
|
|
|
+ $total_row = $total_result->fetch_assoc();
|
|
|
+ $total_customers = $total_row['total'];
|
|
|
+
|
|
|
+ // 获取明确需求的客户数
|
|
|
+ $needs_sql = "SELECT COUNT(id) as needs_count FROM customer WHERE cs_deal = 2";
|
|
|
+ $needs_result = $conn->query($needs_sql);
|
|
|
+ $needs_row = $needs_result->fetch_assoc();
|
|
|
+ $needs_customers = $needs_row['needs_count'];
|
|
|
+
|
|
|
+ // 获取已成交客户数
|
|
|
+ $deal_sql = "SELECT COUNT(id) as deal_count FROM customer WHERE cs_deal = 3";
|
|
|
+ $deal_result = $conn->query($deal_sql);
|
|
|
+ $deal_row = $deal_result->fetch_assoc();
|
|
|
+ $deal_customers = $deal_row['deal_count'];
|
|
|
+
|
|
|
+ // 获取有订单的客户数
|
|
|
+ $order_sql = "SELECT COUNT(DISTINCT customer_id) as order_count FROM orders WHERE order_date BETWEEN ? AND ?";
|
|
|
+ $order_stmt = $conn->prepare($order_sql);
|
|
|
+ $order_stmt->bind_param("ss", $start_date, $end_date);
|
|
|
+ $order_stmt->execute();
|
|
|
+ $order_result = $order_stmt->get_result();
|
|
|
+ $order_row = $order_result->fetch_assoc();
|
|
|
+ $order_customers = $order_row['order_count'];
|
|
|
+
|
|
|
+ // 获取复购客户数(多次下单)
|
|
|
+ $repeat_sql = "SELECT COUNT(customer_id) as repeat_count FROM (
|
|
|
+ SELECT customer_id, COUNT(id) as order_count
|
|
|
+ FROM orders
|
|
|
+ WHERE order_date BETWEEN ? AND ?
|
|
|
+ GROUP BY customer_id
|
|
|
+ HAVING order_count > 1
|
|
|
+ ) as repeat_customers";
|
|
|
+ $repeat_stmt = $conn->prepare($repeat_sql);
|
|
|
+ $repeat_stmt->bind_param("ss", $start_date, $end_date);
|
|
|
+ $repeat_stmt->execute();
|
|
|
+ $repeat_result = $repeat_stmt->get_result();
|
|
|
+ $repeat_row = $repeat_result->fetch_assoc();
|
|
|
+ $repeat_customers = $repeat_row['repeat_count'];
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'stages' => ['潜在客户', '明确需求', '已成交', '有效订单', '复购客户'],
|
|
|
+ 'counts' => [$total_customers, $needs_customers, $deal_customers, $order_customers, $repeat_customers]
|
|
|
+ ];
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 渲染客户转化漏斗图表
|
|
|
+ *
|
|
|
+ * @param array $funnel_data 客户转化漏斗数据
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+function renderCustomerFunnelChart($funnel_data) {
|
|
|
+ ?>
|
|
|
+ <div class="chart-container">
|
|
|
+ <div class="chart-header">
|
|
|
+ <h2 class="chart-title">客户转化漏斗</h2>
|
|
|
+ </div>
|
|
|
+ <canvas id="customerFunnelChart" style="max-height: 400px;"></canvas>
|
|
|
+
|
|
|
+ <div class="customer-stats-summary">
|
|
|
+ <div class="stats-row">
|
|
|
+ <?php
|
|
|
+ foreach ($funnel_data['stages'] as $index => $stage):
|
|
|
+ $current_count = $funnel_data['counts'][$index];
|
|
|
+ $prev_count = $index > 0 ? $funnel_data['counts'][$index-1] : $current_count;
|
|
|
+ $conversion_rate = $prev_count > 0 ? ($current_count / $prev_count) * 100 : 0;
|
|
|
+ ?>
|
|
|
+ <div class="stat-item">
|
|
|
+ <span class="stat-label"><?php echo $stage; ?>:</span>
|
|
|
+ <span class="stat-value"><?php echo number_format($current_count); ?></span>
|
|
|
+ <?php if ($index > 0): ?>
|
|
|
+ <span class="stat-conversion">
|
|
|
+ 转化率: <?php echo number_format($conversion_rate, 1); ?>%
|
|
|
+ </span>
|
|
|
+ <?php endif; ?>
|
|
|
+ </div>
|
|
|
+ <?php endforeach; ?>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <script>
|
|
|
+ // 客户转化漏斗图
|
|
|
+ var funnelCtx = document.getElementById('customerFunnelChart').getContext('2d');
|
|
|
+ var funnelChart = new Chart(funnelCtx, {
|
|
|
+ type: 'bar',
|
|
|
+ data: {
|
|
|
+ labels: <?php echo json_encode($funnel_data['stages']); ?>,
|
|
|
+ datasets: [{
|
|
|
+ label: '客户数量',
|
|
|
+ data: <?php echo json_encode($funnel_data['counts']); ?>,
|
|
|
+ backgroundColor: [
|
|
|
+ 'rgba(54, 162, 235, 0.7)',
|
|
|
+ 'rgba(75, 192, 192, 0.7)',
|
|
|
+ 'rgba(255, 206, 86, 0.7)',
|
|
|
+ 'rgba(255, 99, 132, 0.7)',
|
|
|
+ 'rgba(153, 102, 255, 0.7)'
|
|
|
+ ],
|
|
|
+ borderWidth: 1
|
|
|
+ }]
|
|
|
+ },
|
|
|
+ options: {
|
|
|
+ indexAxis: 'y',
|
|
|
+ responsive: true,
|
|
|
+ scales: {
|
|
|
+ x: {
|
|
|
+ beginAtZero: true,
|
|
|
+ title: {
|
|
|
+ display: true,
|
|
|
+ text: '客户数量'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ plugins: {
|
|
|
+ tooltip: {
|
|
|
+ callbacks: {
|
|
|
+ afterLabel: function(context) {
|
|
|
+ var index = context.dataIndex;
|
|
|
+ if (index > 0) {
|
|
|
+ var currentValue = context.parsed.x;
|
|
|
+ var previousValue = context.dataset.data[index-1];
|
|
|
+ var conversionRate = previousValue > 0 ? (currentValue / previousValue * 100).toFixed(1) : 0;
|
|
|
+ return '转化率: ' + conversionRate + '%';
|
|
|
+ }
|
|
|
+ return '';
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ </script>
|
|
|
+ <?php
|
|
|
}
|