$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'];
?>
本期间共有 名新客户进行了购买。以下是他们购买的产品明细:
产品名称 |
产品分类 |
订单数 |
购买客户数 |
销售数量 |
销售金额 |
平均单价 |
|
|
|
|
|
|
|