prepare($sql);
$stmt->bind_param("ssi", $start_date, $end_date, $limit);
$stmt->execute();
return $stmt->get_result();
}
/**
* 获取产品销售趋势
*
* @param mysqli $conn 数据库连接
* @param string $start_date 开始日期
* @param string $end_date 结束日期
* @param int $product_id 产品ID,为0时获取所有产品的总体趋势
* @param string $period 时间粒度 (day/week/month)
* @return mysqli_result 产品销售趋势数据结果集
*/
function getProductSalesTrend($conn, $start_date, $end_date, $product_id = 0, $period = 'month') {
$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 ($product_id > 0) {
$sql .= " WHERE o.order_date BETWEEN ? AND ? AND oi.product_id = ?";
} else {
$sql .= " WHERE o.order_date BETWEEN ? AND ?";
}
$sql .= " GROUP BY time_period
ORDER BY MIN(o.order_date)";
$stmt = $conn->prepare($sql);
if ($product_id > 0) {
$stmt->bind_param("ssi", $start_date, $end_date, $product_id);
} else {
$stmt->bind_param("ss", $start_date, $end_date);
}
$stmt->execute();
return $stmt->get_result();
}
/**
* 获取产品类别销售分布
*
* @param mysqli $conn 数据库连接
* @param string $start_date 开始日期
* @param string $end_date 结束日期
* @return mysqli_result 产品类别销售分布数据结果集
*/
function getProductCategorySales($conn, $start_date, $end_date) {
$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
WHERE o.order_date BETWEEN ? AND ?
GROUP BY p.category_id
ORDER BY total_revenue DESC";
$stmt = $conn->prepare($sql);
$stmt->bind_param("ss", $start_date, $end_date);
$stmt->execute();
return $stmt->get_result();
}
/**
* 获取产品与地区关联分析
*
* @param mysqli $conn 数据库连接
* @param string $start_date 开始日期
* @param string $end_date 结束日期
* @param int $limit 限制返回的产品-地区组合数量
* @return mysqli_result 产品与地区关联分析数据结果集
*/
function getProductRegionAnalysis($conn, $start_date, $end_date, $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
WHERE o.order_date BETWEEN ? AND ?
GROUP BY oi.product_id, cu.cs_country
ORDER BY total_revenue DESC
LIMIT ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param("ssi", $start_date, $end_date, $limit);
$stmt->execute();
return $stmt->get_result();
}
/**
* 获取产品销售概览数据
*/
function getProductSalesOverview($conn, $start_date, $end_date, $category_filter = 0) {
$where_clause = "WHERE o.order_date BETWEEN ? AND ?";
$params = [$start_date, $end_date];
if ($category_filter > 0) {
$where_clause .= " AND p.category_id = ?";
$params[] = $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
$where_clause";
$stmt = $conn->prepare($sql);
$stmt->bind_param(str_repeat('s', count($params)), ...$params);
$stmt->execute();
return $stmt->get_result()->fetch_assoc();
}
/**
* 获取产品价格趋势分析
*/
function getProductPriceTrendAnalysis($conn, $start_date, $end_date, $product_id = 0, $period = 'month') {
$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 ($product_id > 0) {
$sql .= " WHERE o.order_date BETWEEN ? AND ? AND oi.product_id = ?";
} else {
$sql .= " WHERE o.order_date BETWEEN ? AND ?";
}
$sql .= " GROUP BY time_period ORDER BY MIN(o.order_date)";
$stmt = $conn->prepare($sql);
if ($product_id > 0) {
$stmt->bind_param("ssi", $start_date, $end_date, $product_id);
} else {
$stmt->bind_param("ss", $start_date, $end_date);
}
$stmt->execute();
return $stmt->get_result();
}
/**
* 获取产品季节性分析
*/
function getProductSeasonalityAnalysis($conn, $start_date, $end_date, $product_id = 0) {
$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 ($product_id > 0) {
$sql .= " WHERE oi.product_id = ? AND o.order_date BETWEEN ? AND ?";
} else {
$sql .= " WHERE o.order_date BETWEEN ? AND ?";
}
$sql .= " GROUP BY MONTH(o.order_date)
ORDER BY MONTH(o.order_date)";
$stmt = $conn->prepare($sql);
if ($product_id > 0) {
$stmt->bind_param("iss", $product_id, $start_date, $end_date);
} else {
$stmt->bind_param("ss", $start_date, $end_date);
}
$stmt->execute();
return $stmt->get_result();
}
/**
* 获取产品客户细分分析
*/
function getProductCustomerSegmentAnalysis($conn, $start_date, $end_date, $product_id = 0) {
$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";
if ($product_id > 0) {
$sql .= " WHERE oi.product_id = ? AND o.order_date BETWEEN ? AND ?";
} else {
$sql .= " WHERE o.order_date BETWEEN ? AND ?";
}
$sql .= " GROUP BY ct.id";
$stmt = $conn->prepare($sql);
if ($product_id > 0) {
$stmt->bind_param("iss", $product_id, $start_date, $end_date);
} else {
$stmt->bind_param("ss", $start_date, $end_date);
}
$stmt->execute();
return $stmt->get_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
ORDER BY current_revenue DESC
LIMIT 10";
$stmt = $conn->prepare($sql);
$stmt->bind_param("ss", $start_date, $end_date);
$stmt->execute();
$current_data = $stmt->get_result();
// 计算上一个时间段
$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 ? AND ?
GROUP BY oi.product_id";
$stmt = $conn->prepare($sql);
$stmt->bind_param("ss", $prev_start, $prev_end);
$stmt->execute();
$prev_result = $stmt->get_result();
$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 ? AND ?
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 ? AND ?
GROUP BY p.id
HAVING order_count > 1
ORDER BY purchase_frequency DESC
LIMIT 10";
$stmt = $conn->prepare($sql);
$stmt->bind_param("ssss", $start_date, $end_date, $start_date, $end_date);
$stmt->execute();
return $stmt->get_result();
}
/**
* 渲染产品购买频率分析
*/
function renderProductPurchaseFrequency($frequency_data) {
?>
产品名称 |
订单总数 |
购买客户数 |
平均购买频率 |
平均购买间隔(天) |
fetch_assoc()): ?>
|
|
|
次/客户 |
|