Merge branch 'dev'
This commit is contained in:
commit
da7db72158
|
|
@ -620,7 +620,7 @@ class Statistics extends Base
|
|||
$productInfos = [];
|
||||
if (!empty($goodslistIds)) {
|
||||
$productInfos = GoodsList::where('id', 'in', $goodslistIds)
|
||||
->field('id, title, imgurl, price, money, sc_money, real_pro')
|
||||
->field('id, title, imgurl, price, money, sc_money, real_pro, shang_id')
|
||||
->select()
|
||||
->toArray();
|
||||
}
|
||||
|
|
@ -992,7 +992,7 @@ class Statistics extends Base
|
|||
$headers = [
|
||||
'ID', '盒子名称', '盒子类型', '状态', '单价', '抽奖次数',
|
||||
'收入(微信+钻石)', '出货价值', '已兑换达达卷', '已申请发货',
|
||||
'利润', '利润率(%)'
|
||||
'单盒子利润', '单盒子利润比(%)', '利润', '利润率(%)'
|
||||
];
|
||||
|
||||
foreach ($headers as $col => $header) {
|
||||
|
|
@ -1010,7 +1010,7 @@ class Statistics extends Base
|
|||
'startColor' => ['rgb' => 'E0E0E0'],
|
||||
],
|
||||
];
|
||||
$sheet->getStyle('A1:L1')->applyFromArray($headerStyle);
|
||||
$sheet->getStyle('A1:N1')->applyFromArray($headerStyle);
|
||||
|
||||
// 填充数据
|
||||
$row = 2;
|
||||
|
|
@ -1027,6 +1027,14 @@ class Statistics extends Base
|
|||
default: $statusText = '自动下架'; break;
|
||||
}
|
||||
|
||||
// 计算单盒子利润和单盒子利润比
|
||||
$boxIncome = $item['price'] * $statsData['cj_count'];
|
||||
$singleBoxProfit = $boxIncome - $statsData['sc_money'];
|
||||
$singleBoxProfitRate = 0;
|
||||
if ($boxIncome > 0) {
|
||||
$singleBoxProfitRate = ($singleBoxProfit / $boxIncome) * 100;
|
||||
}
|
||||
|
||||
// 填充一行数据
|
||||
$sheet->setCellValue('A' . $row, $item['id']);
|
||||
$sheet->setCellValue('B' . $row, $item['title']);
|
||||
|
|
@ -1038,12 +1046,14 @@ class Statistics extends Base
|
|||
$sheet->setCellValue('H' . $row, $statsData['sc_money']);
|
||||
$sheet->setCellValue('I' . $row, $statsData['re_money']);
|
||||
$sheet->setCellValue('J' . $row, $statsData['fh_money']);
|
||||
$sheet->setCellValue('K' . $row, $statsData['profit']);
|
||||
$sheet->setCellValue('L' . $row, $statsData['profit_rate']);
|
||||
$sheet->setCellValue('K' . $row, $singleBoxProfit);
|
||||
$sheet->setCellValue('L' . $row, round($singleBoxProfitRate, 2));
|
||||
$sheet->setCellValue('M' . $row, $statsData['profit']);
|
||||
$sheet->setCellValue('N' . $row, $statsData['profit_rate']);
|
||||
|
||||
// 设置负利润的行为红色背景
|
||||
if ($statsData['profit'] < 0) {
|
||||
$sheet->getStyle('A' . $row . ':L' . $row)->getFill()
|
||||
$sheet->getStyle('A' . $row . ':N' . $row)->getFill()
|
||||
->setFillType(Fill::FILL_SOLID)
|
||||
->getStartColor()->setRGB('FFEBEE');
|
||||
}
|
||||
|
|
@ -1052,7 +1062,7 @@ class Statistics extends Base
|
|||
}
|
||||
|
||||
// 调整列宽
|
||||
foreach (range('A', 'L') as $col) {
|
||||
foreach (range('A', 'N') as $col) {
|
||||
$sheet->getColumnDimension($col)->setAutoSize(true);
|
||||
}
|
||||
|
||||
|
|
@ -1066,14 +1076,25 @@ class Statistics extends Base
|
|||
$sheet->setCellValue('H' . $row, $summaryData['totalCost']);
|
||||
$sheet->setCellValue('I' . $row, $summaryData['totalReMoney']);
|
||||
$sheet->setCellValue('J' . $row, $summaryData['totalFhMoney']);
|
||||
$sheet->setCellValue('K' . $row, $summaryData['totalProfit']);
|
||||
|
||||
// 计算汇总单盒子利润和利润比
|
||||
$totalSingleBoxProfit = $summaryData['totalIncome'] - $summaryData['totalCost'];
|
||||
$sheet->setCellValue('K' . $row, $totalSingleBoxProfit);
|
||||
|
||||
$totalSingleBoxProfitRate = 0;
|
||||
if ($summaryData['totalIncome'] > 0) {
|
||||
$totalSingleBoxProfitRate = ($totalSingleBoxProfit / $summaryData['totalIncome']) * 100;
|
||||
}
|
||||
$sheet->setCellValue('L' . $row, round($totalSingleBoxProfitRate, 2));
|
||||
|
||||
$sheet->setCellValue('M' . $row, $summaryData['totalProfit']);
|
||||
|
||||
// 计算总体利润率
|
||||
$profitRate = 0;
|
||||
if ($summaryData['totalIncome'] > 0) {
|
||||
$profitRate = ($summaryData['totalProfit'] / $summaryData['totalIncome']) * 100;
|
||||
}
|
||||
$sheet->setCellValue('L' . $row, round($profitRate, 2));
|
||||
$sheet->setCellValue('N' . $row, round($profitRate, 2));
|
||||
|
||||
// 设置汇总行样式
|
||||
$summaryStyle = [
|
||||
|
|
@ -1083,7 +1104,7 @@ class Statistics extends Base
|
|||
'startColor' => ['rgb' => ($summaryData['totalProfit'] >= 0 ? 'E8F5E9' : 'FFEBEE')],
|
||||
],
|
||||
];
|
||||
$sheet->getStyle('A' . $row . ':L' . $row)->applyFromArray($summaryStyle);
|
||||
$sheet->getStyle('A' . $row . ':N' . $row)->applyFromArray($summaryStyle);
|
||||
|
||||
// 设置Excel文件属性
|
||||
$spreadsheet->getProperties()
|
||||
|
|
|
|||
|
|
@ -15,21 +15,108 @@
|
|||
$totalValue = 0;
|
||||
foreach($list as $item) {
|
||||
$totalCount += isset($item['goods_count']) ? $item['goods_count'] : 0;
|
||||
$sc_money = isset($item['sc_money']) ? $item['sc_money'] : 0;
|
||||
$money = isset($item['money']) ? $item['money'] : 0;
|
||||
$goods_count = isset($item['goods_count']) ? $item['goods_count'] : 0;
|
||||
$totalValue += $sc_money * $goods_count;
|
||||
$totalValue += $money * $goods_count;
|
||||
}
|
||||
?>
|
||||
|
||||
<!-- 统计摘要 -->
|
||||
{if condition="!empty($list)"}
|
||||
<div class="layui-card" style="margin-bottom: 20px;">
|
||||
<div class="layui-card-header">统计摘要</div>
|
||||
<div class="layui-card-body">
|
||||
<div class="layui-row layui-col-space15">
|
||||
<div class="layui-col-md6">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">总出货数量</div>
|
||||
<div class="layui-card-body" style="font-size: 24px; color: #01AAED;">
|
||||
{$totalCount}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-md6">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">总出货价值</div>
|
||||
<div class="layui-card-body" style="font-size: 24px; color: #FF5722;">
|
||||
¥ {$totalValue|round=2}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if($totalCount > 0): ?>
|
||||
<div class="layui-row layui-col-space15" style="margin-top: 15px;">
|
||||
<div class="layui-col-md4">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">平均每次出货价值/盒子单价</div>
|
||||
<div class="layui-card-body" style="font-size: 24px; color: #01AAED;">
|
||||
¥ <?php echo round($totalValue / $totalCount, 2); ?>/
|
||||
<?php echo round($boxInfo['price']); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-md4">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">平均出货价值/盒子单价</div>
|
||||
<div class="layui-card-body" style="font-size: 24px; color: #FF5722;">
|
||||
<?php
|
||||
$avgValue = $totalValue / $totalCount;
|
||||
$boxPrice = isset($boxInfo['price']) ? $boxInfo['price'] : 0;
|
||||
$ratio = $boxPrice > 0 ? round(($avgValue / $boxPrice), 2) : 0;
|
||||
echo $ratio . ' 倍';
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-md4">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">数据分析</div>
|
||||
<div class="layui-card-body">
|
||||
<?php
|
||||
// 寻找出货金额最多的奖品
|
||||
$maxValue = 0;
|
||||
$maxItem = null;
|
||||
foreach($list as $item) {
|
||||
$goods_count = isset($item['goods_count']) ? $item['goods_count'] : 0;
|
||||
$money = isset($item['money']) ? $item['money'] : 0;
|
||||
$itemValue = $money * $goods_count;
|
||||
if($itemValue > $maxValue) {
|
||||
$maxValue = $itemValue;
|
||||
$maxItem = $item;
|
||||
}
|
||||
}
|
||||
|
||||
if($maxItem) {
|
||||
$goods_count = isset($maxItem['goods_count']) ? $maxItem['goods_count'] : 0;
|
||||
$money = isset($maxItem['money']) ? $maxItem['money'] : 0;
|
||||
$itemValue = $money * $goods_count;
|
||||
echo "<p>出货金额最多的奖品: <strong>".$maxItem['title']."</strong> (¥".round($itemValue, 2).")</p>";
|
||||
|
||||
// 计算占总金额的百分比
|
||||
$valuePercent = $totalValue > 0 ? round(($itemValue / $totalValue) * 100, 2) : 0;
|
||||
echo "<p>占总出货金额的: <span style=\"color: #01AAED; font-weight: bold;\">".$valuePercent."%</span></p>";
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<table class="layui-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>奖品ID</th>
|
||||
<th>奖品类型</th>
|
||||
<th>奖品名称</th>
|
||||
<th>奖品图片</th>
|
||||
<th>出货数量</th>
|
||||
<th>奖品单价</th>
|
||||
<th>兑换金额</th>
|
||||
<th>出货金额</th>
|
||||
<th>理论概率</th>
|
||||
<th>实际概率</th>
|
||||
<th>概率偏差</th>
|
||||
|
|
@ -40,6 +127,7 @@
|
|||
{volist name="list" id="vo"}
|
||||
<tr>
|
||||
<td>{$vo.goodslist_id}</td>
|
||||
<td>{$vo.shang_id|default="0"}</td>
|
||||
<td>{$vo.title}</td>
|
||||
<td>
|
||||
<img src="{$vo.imgurl}" style="height:50px;" onerror="this.src='/static/admin/images/nopic.jpg'">
|
||||
|
|
@ -49,7 +137,6 @@
|
|||
</td>
|
||||
<td>¥ {$vo.price|default="0"}</td>
|
||||
<td>¥ {$vo.money|default="0"}</td>
|
||||
<td>¥ {$vo.sc_money|default="0"}</td>
|
||||
<td>
|
||||
<span class="layui-badge layui-bg-green">{$vo.real_pro|default="0"}%</span>
|
||||
</td>
|
||||
|
|
@ -74,9 +161,9 @@
|
|||
</td>
|
||||
<td>
|
||||
<?php
|
||||
$sc_money = isset($vo['sc_money']) ? $vo['sc_money'] : 0;
|
||||
$money = isset($vo['money']) ? $vo['money'] : 0;
|
||||
$goods_count = isset($vo['goods_count']) ? $vo['goods_count'] : 0;
|
||||
$total_value = $sc_money * $goods_count;
|
||||
$total_value = $money * $goods_count;
|
||||
?>
|
||||
¥ <?php echo round($total_value, 2); ?>
|
||||
</td>
|
||||
|
|
@ -89,78 +176,6 @@
|
|||
{/if}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<!-- 统计摘要 -->
|
||||
{if condition="!empty($list)"}
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">统计摘要</div>
|
||||
<div class="layui-card-body">
|
||||
<div class="layui-row layui-col-space15">
|
||||
<div class="layui-col-md6">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">总出货数量</div>
|
||||
<div class="layui-card-body" style="font-size: 24px; color: #01AAED;">
|
||||
{$totalCount}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-md6">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">总出货价值</div>
|
||||
<div class="layui-card-body" style="font-size: 24px; color: #FF5722;">
|
||||
¥ {$totalValue|round=2}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if($totalCount > 0): ?>
|
||||
<div class="layui-row layui-col-space15" style="margin-top: 15px;">
|
||||
<div class="layui-col-md6">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">平均每次出货价值</div>
|
||||
<div class="layui-card-body" style="font-size: 24px; color: #01AAED;">
|
||||
¥ <?php echo round($totalValue / $totalCount, 2); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-md6">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">数据分析</div>
|
||||
<div class="layui-card-body">
|
||||
<?php
|
||||
// 寻找实际概率最高的奖品
|
||||
$maxPercent = 0;
|
||||
$maxItem = null;
|
||||
foreach($list as $item) {
|
||||
$goods_count = isset($item['goods_count']) ? $item['goods_count'] : 0;
|
||||
$percent = round(($goods_count / $totalCount) * 100, 2);
|
||||
if($percent > $maxPercent) {
|
||||
$maxPercent = $percent;
|
||||
$maxItem = $item;
|
||||
}
|
||||
}
|
||||
|
||||
if($maxItem) {
|
||||
echo "<p>出货概率最高的奖品: <strong>".$maxItem['title']."</strong> (".$maxPercent."%)</p>";
|
||||
$real_pro = isset($maxItem['real_pro']) ? $maxItem['real_pro'] : 0;
|
||||
$diff = round($maxPercent - $real_pro, 2);
|
||||
$diffText = $diff >= 0 ? "高于" : "低于";
|
||||
$absDiff = abs($diff);
|
||||
$diffColor = $diff >= 0 ? "#5FB878" : "#FF5722";
|
||||
?>
|
||||
<p>与理论概率相比: <span style="color: <?php echo $diffColor; ?>"><?php echo $diffText; ?>理论值 <?php echo $absDiff; ?>%</span></p>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -217,7 +217,7 @@
|
|||
},
|
||||
cols: [[
|
||||
{ field: 'id', title: '盒子ID', width: 80, sort: true, fixed: 'left' },
|
||||
{ field: 'title', title: '盒子名称', width: 200 },
|
||||
{ field: 'title', title: '盒子名称', width: 180 },
|
||||
{
|
||||
templet: function (d) {
|
||||
var statusHtml = '';
|
||||
|
|
@ -235,7 +235,7 @@
|
|||
},
|
||||
{ field: 'price', title: '盒子单价', width: 100, templet: '<div>¥ {{d.price}}</div>' },
|
||||
{
|
||||
field: 'cj_count', title: '抽奖次数', width: 100, templet: function (d) {
|
||||
field: 'cj_count', title: '抽奖次数', width: 90, templet: function (d) {
|
||||
if (!d.loaded) {
|
||||
return '<div><i class="layui-icon layui-icon-loading layui-anim layui-anim-rotate layui-anim-loop"></i></div>';
|
||||
}
|
||||
|
|
@ -243,7 +243,7 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
field: 'use_money', title: '收入 <i class="layui-icon layui-icon-about" title="微信支付+钻石支付"></i>', width: 150, templet: function (d) {
|
||||
field: 'use_money', title: '收入 <i class="layui-icon layui-icon-about" title="微信支付+钻石支付"></i>', width: 140, templet: function (d) {
|
||||
if (!d.loaded) {
|
||||
return '<div><i class="layui-icon layui-icon-loading layui-anim layui-anim-rotate layui-anim-loop"></i></div>';
|
||||
}
|
||||
|
|
@ -251,7 +251,7 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
field: 'sc_money', title: '出货价值 <i class="layui-icon layui-icon-about" title="奖品的兑换价格"></i>', width: 150, templet: function (d) {
|
||||
field: 'sc_money', title: '出货价值 <i class="layui-icon layui-icon-about" title="奖品的兑换价格"></i>', width: 140, templet: function (d) {
|
||||
if (!d.loaded) {
|
||||
return '<div><i class="layui-icon layui-icon-loading layui-anim layui-anim-rotate layui-anim-loop"></i></div>';
|
||||
}
|
||||
|
|
@ -259,7 +259,7 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
field: 're_money', title: '已兑换达达卷', width: 150, templet: function (d) {
|
||||
field: 're_money', title: '已兑换达达卷', width: 120, templet: function (d) {
|
||||
if (!d.loaded) {
|
||||
return '<div><i class="layui-icon layui-icon-loading layui-anim layui-anim-rotate layui-anim-loop"></i></div>';
|
||||
}
|
||||
|
|
@ -274,6 +274,30 @@
|
|||
return '<div><span class="layui-badge" style="background-color: #673AB7;">¥ ' + d.fh_money.toFixed(2) + '</span></div>';
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'single_box_profit', title: '单盒子利润 <i class="layui-icon layui-icon-about" title="盒子单价 × 抽数 - 盒子出货总额"></i>', width: 120, templet: function (d) {
|
||||
if (!d.loaded) {
|
||||
return '<div><i class="layui-icon layui-icon-loading layui-anim layui-anim-rotate layui-anim-loop"></i></div>';
|
||||
}
|
||||
// 计算公式:盒子单价x抽数-盒子出货总额
|
||||
var totalIncome = d.price * d.cj_count;
|
||||
var singleBoxProfit = totalIncome - d.sc_money;
|
||||
var colorClass = singleBoxProfit >= 0 ? 'layui-bg-green' : 'layui-bg-red';
|
||||
return '<div><span class="layui-badge ' + colorClass + '">¥ ' + singleBoxProfit.toFixed(2) + '</span></div>';
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'single_box_profit_rate', title: '单盒子利润比 <i class="layui-icon layui-icon-about" title="(盒子单价 × 抽数 - 盒子出货总额) / (盒子单价 × 抽数) × 100%"></i>', width: 140, templet: function (d) {
|
||||
if (!d.loaded) {
|
||||
return '<div><i class="layui-icon layui-icon-loading layui-anim layui-anim-rotate layui-anim-loop"></i></div>';
|
||||
}
|
||||
// 计算公式:(盒子单价x抽数-盒子出货总额)/(盒子单价x抽数)
|
||||
var totalIncome = d.price * d.cj_count;
|
||||
var singleBoxProfitRate = totalIncome > 0 ? ((totalIncome - d.sc_money) / totalIncome * 100) : 0;
|
||||
var colorClass = singleBoxProfitRate >= 0 ? 'layui-bg-green' : 'layui-bg-red';
|
||||
return '<div><span class="layui-badge ' + colorClass + '">' + singleBoxProfitRate.toFixed(2) + '%</span></div>';
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'profit', title: '利润 <i class="layui-icon layui-icon-about" title="收入-出货价值"></i>', width: 110, templet: function (d) {
|
||||
if (!d.loaded) {
|
||||
|
|
@ -404,6 +428,17 @@
|
|||
tr.find('td[data-field="fh_money"] div').html('<span class="layui-badge" style="background-color: #673AB7;">¥ ' + data.fh_money.toFixed(2) + '</span>');
|
||||
tr.find('td[data-field="cj_count"] div').html(data.cj_count);
|
||||
|
||||
// 计算并更新单盒子利润
|
||||
var totalIncome = tableData[i].price * data.cj_count;
|
||||
var singleBoxProfit = totalIncome - data.sc_money;
|
||||
var singleBoxProfitClass = singleBoxProfit >= 0 ? 'layui-bg-green' : 'layui-bg-red';
|
||||
tr.find('td[data-field="single_box_profit"] div').html('<span class="layui-badge ' + singleBoxProfitClass + '">¥ ' + singleBoxProfit.toFixed(2) + '</span>');
|
||||
|
||||
// 计算并更新单盒子利润比
|
||||
var singleBoxProfitRate = totalIncome > 0 ? ((totalIncome - data.sc_money) / totalIncome * 100) : 0;
|
||||
var singleBoxColorClass = singleBoxProfitRate >= 0 ? 'layui-bg-green' : 'layui-bg-red';
|
||||
tr.find('td[data-field="single_box_profit_rate"] div').html('<span class="layui-badge ' + singleBoxColorClass + '">' + singleBoxProfitRate.toFixed(2) + '%</span>');
|
||||
|
||||
var profitColorClass = data.profit >= 0 ? 'layui-bg-green' : 'layui-bg-red';
|
||||
tr.find('td[data-field="profit"] div').html('<span class="layui-badge ' + profitColorClass + '">¥ ' + data.profit.toFixed(2) + '</span>');
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user