This commit is contained in:
youda 2025-04-27 17:27:12 +08:00
parent 2ae2ea87e1
commit ac5dce70dd
5 changed files with 480 additions and 1 deletions

View File

@ -1353,4 +1353,248 @@ class Statistics extends Base
];
}
/**
* 抽奖用户列表页面
*/
public function lotteryUsers()
{
return View::fetch("Statistics/lotteryUsers");
}
/**
* 抽奖用户数据接口
*/
public function lotteryUsersData()
{
$goodsId = input('goods_id', 0, 'intval');
if(empty($goodsId)) {
return json(['code' => 1, 'msg' => '参数错误']);
}
// 获取盒子信息
$boxInfo = \app\common\model\Goods::where('id', $goodsId)->field('id,title')->find();
// 获取测试用户ID
$testUsers = \app\common\model\User::where('istest', '>', 0)
->whereOr('status', '=', 2)
->column('id');
$testUserIds = empty($testUsers) ? [0] : $testUsers;
// 构建分页查询
$query = Db::name('order_list')
->alias('ol')
->join('user u', 'ol.user_id = u.id')
->where('ol.goods_id', $goodsId)
->where('ol.user_id', 'not in', $testUserIds)
->field([
'ol.user_id',
'u.nickname',
'COUNT(DISTINCT ol.id) as lottery_count',
'SUM(ol.goodslist_money) as output_value',
'0 as wx_payment',
'0 as diamond_payment'
])
->group('ol.user_id')
->order('lottery_count', 'desc')
->paginate(input('limit', 20))
->toArray();
// 获取每个用户的支付信息
if (!empty($query['data'])) {
$userIds = array_column($query['data'], 'user_id');
// 获取微信支付金额
$wxPayments = Db::name('order')
->where('goods_id', $goodsId)
->where('user_id', 'in', $userIds)
->where('price', '>', 0)
->where('status', 1)
->field('user_id, SUM(price) as payment')
->group('user_id')
->select()
->toArray();
$wxPaymentMap = [];
foreach ($wxPayments as $payment) {
$wxPaymentMap[$payment['user_id']] = $payment['payment'];
}
// 获取钻石支付金额
$diamondPayments = Db::name('order')
->where('goods_id', $goodsId)
->where('user_id', 'in', $userIds)
->where('use_money', '>', 0)
->where('status', 1)
->field('user_id, SUM(use_money) as payment')
->group('user_id')
->select()
->toArray();
$diamondPaymentMap = [];
foreach ($diamondPayments as $payment) {
$diamondPaymentMap[$payment['user_id']] = $payment['payment'];
}
// 更新用户支付信息
foreach ($query['data'] as &$user) {
$user['wx_payment'] = isset($wxPaymentMap[$user['user_id']]) ? floatval($wxPaymentMap[$user['user_id']]) : 0;
$user['diamond_payment'] = isset($diamondPaymentMap[$user['user_id']]) ? floatval($diamondPaymentMap[$user['user_id']]) : 0;
$user['total_payment'] = $user['wx_payment'] + $user['diamond_payment'];
$user['output_value'] = floatval($user['output_value']);
}
}
return json([
'code' => 0,
'msg' => '获取成功',
'count' => $query['total'],
'data' => $query['data'],
'boxInfo' => $boxInfo
]);
}
/**
* 用户抽奖详情页面
*/
public function userLotteryDetail()
{
return View::fetch("Statistics/userLotteryDetail");
}
/**
* 用户抽奖详情数据接口
*/
public function userLotteryDetailData()
{
$goodsId = input('goods_id', 0, 'intval');
$userId = input('user_id', 0, 'intval');
if(empty($goodsId) || empty($userId)) {
return json(['code' => 1, 'msg' => '参数错误']);
}
// 获取用户和盒子信息
$userInfo = \app\common\model\User::where('id', $userId)->field('id,nickname')->find();
$boxInfo = \app\common\model\Goods::where('id', $goodsId)->field('id,title')->find();
if(!$userInfo || !$boxInfo) {
return json(['code' => 1, 'msg' => '用户或盒子不存在']);
}
// 获取用户的抽奖记录
$records = Db::name('order_list')
->alias('ol')
->leftJoin('goods_list gl', 'ol.goodslist_id = gl.id')
->leftJoin('order o', 'ol.order_id = o.id')
->where('ol.goods_id', $goodsId)
->where('ol.user_id', $userId)
->field([
'ol.id',
'ol.addtime',
'ol.goodslist_id',
'gl.title as goodslist_title',
'ol.goodslist_money',
'ol.order_id',
'o.price',
'o.use_money',
'ol.send_num',
'CASE WHEN o.price > 0 THEN "wx" WHEN o.use_money > 0 THEN "diamond" ELSE "other" END as payment_type',
'CASE WHEN o.price > 0 THEN o.price WHEN o.use_money > 0 THEN o.use_money ELSE 0 END as payment_amount',
'IF(LENGTH(ol.send_num) > 0, 1, 0) as is_shipped'
])
->order('ol.addtime', 'desc')
->paginate(input('limit', 20))
->toArray();
// 获取用户抽奖汇总信息
$summary = $this->getUserLotterySummaryData($goodsId, $userId);
return json([
'code' => 0,
'msg' => '获取成功',
'count' => $records['total'],
'data' => $records['data'],
'userInfo' => $userInfo,
'boxInfo' => $boxInfo,
'summary' => $summary
]);
}
/**
* 用户抽奖汇总数据
*/
public function userLotterySummary()
{
$goodsId = input('goods_id', 0, 'intval');
$userId = input('user_id', 0, 'intval');
if(empty($goodsId) || empty($userId)) {
return json(['code' => 1, 'msg' => '参数错误']);
}
// 获取用户和盒子信息
$userInfo = \app\common\model\User::where('id', $userId)->field('id,nickname')->find();
$boxInfo = \app\common\model\Goods::where('id', $goodsId)->field('id,title')->find();
if(!$userInfo || !$boxInfo) {
return json(['code' => 1, 'msg' => '用户或盒子不存在']);
}
// 获取用户抽奖汇总数据
$data = $this->getUserLotterySummaryData($goodsId, $userId);
return json([
'code' => 0,
'msg' => '获取成功',
'data' => $data,
'userInfo' => $userInfo,
'boxInfo' => $boxInfo
]);
}
/**
* 获取用户抽奖汇总数据
*/
private function getUserLotterySummaryData($goodsId, $userId)
{
// 获取抽奖次数
$totalCount = Db::name('order_list')
->where('goods_id', $goodsId)
->where('user_id', $userId)
->count();
// 获取出货价值
$totalOutput = Db::name('order_list')
->where('goods_id', $goodsId)
->where('user_id', $userId)
->sum('goodslist_money');
// 获取微信支付金额
$wxPayment = Db::name('order')
->where('goods_id', $goodsId)
->where('user_id', $userId)
->where('price', '>', 0)
->where('status', 1)
->sum('price');
// 获取钻石支付金额
$diamondPayment = Db::name('order')
->where('goods_id', $goodsId)
->where('user_id', $userId)
->where('use_money', '>', 0)
->where('status', 1)
->sum('use_money');
// 总支付金额
$totalPayment = $wxPayment + $diamondPayment;
return [
'totalCount' => intval($totalCount),
'totalOutput' => floatval($totalOutput),
'wxPayment' => floatval($wxPayment),
'diamondPayment' => floatval($diamondPayment),
'totalPayment' => floatval($totalPayment)
];
}
}

View File

@ -432,6 +432,10 @@ Route::rule('statistics_productsOverview', 'Statistics/productsOverview', 'GET')
Route::rule('statistics_getBoxStatistics', 'Statistics/getBoxStatistics', 'GET');
Route::rule('statistics_getSummaryStatistics', 'Statistics/getSummaryStatistics', 'GET');
Route::rule('statistics_exportProfit', 'Statistics/exportProfit', 'GET');
Route::rule('statistics_lotteryUsers', 'Statistics/lotteryUsers', 'GET');
Route::rule('statistics_userLotteryDetail', 'Statistics/userLotteryDetail', 'GET');
Route::rule('statistics_userLotteryDetailData', 'Statistics/userLotteryDetailData', 'GET');
Route::rule('statistics_lotteryUsersData', 'Statistics/lotteryUsersData', 'GET');
// 盒子下架日志相关路由
Route::post('goods_offshelf_read', 'GoodsOffshelfController/read');

View File

@ -0,0 +1,67 @@
{include file="Public:header3"/}
<body>
<div class="layui-fluid">
<div class="layui-card">
<div class="layui-card-header">
抽奖用户列表
<span class="layui-badge" id="boxInfo"></span>
</div>
<div class="layui-card-body">
<table id="lotteryUserTable" lay-filter="lotteryUserTable"></table>
</div>
</div>
</div>
{include file="Public:footer3"/}
<script>
layui.use(['table', 'layer', 'form'], function () {
var $ = layui.$;
var table = layui.table;
var layer = layui.layer;
// 获取URL参数
var goodsId = '{:input("goods_id")}';
// 初始化表格
table.render({
elem: '#lotteryUserTable',
url: '{:url("/admin/statistics_lotteryUsersData")}?goods_id=' + goodsId,
method: 'get',
page: true,
limit: 20,
cols: [[
{field: 'user_id', title: '用户ID', width: 100},
{field: 'nickname', title: '用户昵称', width: 150},
{field: 'lottery_count', title: '抽奖次数', width: 120, sort: true},
{field: 'output_value', title: '出货价值', width: 120, templet: '<div>¥ {{d.output_value.toFixed(2)}}</div>', sort: true},
{field: 'wx_payment', title: '微信支付', width: 120, templet: '<div>¥ {{d.wx_payment.toFixed(2)}}</div>', sort: true},
{field: 'diamond_payment', title: '钻石支付', width: 120, templet: '<div>¥ {{d.diamond_payment.toFixed(2)}}</div>', sort: true},
{field: 'total_payment', title: '总支付金额', width: 120, templet: '<div>¥ {{d.total_payment.toFixed(2)}}</div>', sort: true},
{title: '操作', width: 120, templet: function(d){
return '<button class="layui-btn layui-btn-xs" onclick="viewUserDetail(' + d.user_id + ')">查看详情</button>';
}}
]],
done: function(res) {
// 更新盒子信息
if(res.boxInfo) {
$('#boxInfo').html(res.boxInfo.title);
}
}
});
});
// 查看用户详情
function viewUserDetail(userId) {
var goodsId = '{:input("goods_id")}';
layer.open({
type: 2,
title: '用户抽奖详情',
shadeClose: false,
shade: 0.3,
area: ['80%', '80%'],
content: '{:url("/admin/statistics_userLotteryDetail")}?goods_id=' + goodsId + '&user_id=' + userId
});
}
</script>
</body>
</html>

View File

@ -111,6 +111,7 @@
<!-- 表格操作栏模板 -->
<script type="text/html" id="operationTpl">
<button class="layui-btn layui-btn-danger layui-btn-xs" lay-event="viewProductsOverview">出货概览</button>
<button class="layui-btn layui-btn-normal layui-btn-xs" lay-event="viewLotteryUsers">抽奖用户</button>
</script>
<!-- 利润和利润率模板 -->
@ -318,7 +319,7 @@
return '<div><span class="layui-badge ' + colorClass + '">' + d.profit_rate.toFixed(2) + '%</span></div>';
}
},
{ title: '操作', width: 110, toolbar: '#operationTpl', fixed: 'right' }
{ title: '操作', width: 180, toolbar: '#operationTpl', fixed: 'right' }
]],
done: function (res) {
// 清空加载队列
@ -562,6 +563,16 @@
area: ['90%', '90%'],
content: '{:url("/admin/statistics_productsOverview")}?goods_id=' + data.id
});
} else if (obj.event === 'viewLotteryUsers') {
// 查看抽奖用户
layer.open({
type: 2,
title: data.title + ' - 抽奖用户列表',
shadeClose: false,
shade: 0.3,
area: ['90%', '90%'],
content: '{:url("/admin/statistics_lotteryUsers")}?goods_id=' + data.id
});
}
});

View File

@ -0,0 +1,153 @@
{include file="Public:header3"/}
<body>
<div class="layui-fluid">
<div class="layui-card">
<div class="layui-card-header">
用户抽奖详情
<span class="layui-badge layui-bg-blue" id="userInfo"></span>
<span class="layui-badge layui-bg-orange" id="boxInfo"></span>
</div>
<div class="layui-card-body">
<!-- 用户统计摘要 -->
<div class="layui-row layui-col-space15" id="userSummary">
<div class="layui-col-md3">
<div class="layui-card">
<div class="layui-card-header">抽奖次数</div>
<div class="layui-card-body" style="font-size: 24px; color: #01AAED;">
<span id="totalCount">0</span>
</div>
</div>
</div>
<div class="layui-col-md3">
<div class="layui-card">
<div class="layui-card-header">出货价值</div>
<div class="layui-card-body" style="font-size: 24px; color: #FFB800;">
¥ <span id="totalOutput">0.00</span>
</div>
</div>
</div>
<div class="layui-col-md3">
<div class="layui-card">
<div class="layui-card-header">总支付金额</div>
<div class="layui-card-body" style="font-size: 24px; color: #5FB878;">
¥ <span id="totalPayment">0.00</span>
</div>
</div>
</div>
<div class="layui-col-md3">
<div class="layui-card">
<div class="layui-card-header">微信/钻石支付</div>
<div class="layui-card-body" style="font-size: 24px;">
<span style="color: #FF9800;">¥ <span id="wxPayment">0.00</span></span> /
<span style="color: #673AB7;">¥ <span id="diamondPayment">0.00</span></span>
</div>
</div>
</div>
</div>
<!-- 数据表格区域 -->
<table id="detailTable" lay-filter="detailTable"></table>
</div>
</div>
</div>
{include file="Public:footer3"/}
<script>
layui.use(['table', 'layer', 'form'], function() {
var $ = layui.$;
var table = layui.table;
var layer = layui.layer;
// 获取URL参数
var goodsId = '{:input("goods_id")}';
var userId = '{:input("user_id")}';
// 加载用户抽奖详情数据
loadUserLotteryDetails();
// 初始化表格
table.render({
elem: '#detailTable',
url: '{:url("/admin/statistics_userLotteryDetailData")}?goods_id=' + goodsId + '&user_id=' + userId,
method: 'get',
page: true,
limit: 20,
cols: [[
{field: 'id', title: 'ID', width: 80},
{field: 'addtime', title: '抽奖时间', width: 180, templet: function(d){
return new Date(d.addtime * 1000).toLocaleString();
}},
{field: 'goodslist_title', title: '奖品名称', width: 200},
{field: 'goodslist_money', title: '奖品价值', width: 120, templet: '<div>¥ {{d.goodslist_money}}</div>'},
{field: 'order_id', title: '订单ID', width: 100},
{field: 'payment_type', title: '支付方式', width: 120, templet: function(d){
if(d.payment_type == 'wx') {
return '<span class="layui-badge layui-bg-green">微信支付</span>';
} else if(d.payment_type == 'diamond') {
return '<span class="layui-badge layui-bg-blue">钻石支付</span>';
} else {
return '<span class="layui-badge layui-bg-gray">未知</span>';
}
}},
{field: 'payment_amount', title: '支付金额', width: 120, templet: '<div>¥ {{d.payment_amount}}</div>'},
{field: 'is_shipped', title: '是否发货', width: 100, templet: function(d){
return d.is_shipped == 1 ?
'<span class="layui-badge layui-bg-green">已发货</span>' :
'<span class="layui-badge layui-bg-gray">未发货</span>';
}}
]],
done: function(res) {
if(res.summary) {
updateUserSummary(res.summary);
}
if(res.userInfo) {
$('#userInfo').html(res.userInfo.nickname);
}
if(res.boxInfo) {
$('#boxInfo').html(res.boxInfo.title);
}
}
});
// 获取用户抽奖汇总数据
function loadUserLotteryDetails() {
$.ajax({
url: '{:url("/admin/statistics_userLotterySummary")}',
type: 'GET',
data: {
goods_id: goodsId,
user_id: userId
},
success: function(res) {
if(res.code === 0) {
updateUserSummary(res.data);
if(res.userInfo) {
$('#userInfo').html(res.userInfo.nickname);
}
if(res.boxInfo) {
$('#boxInfo').html(res.boxInfo.title);
}
}
}
});
}
// 更新用户汇总数据
function updateUserSummary(data) {
if(!data) return;
$('#totalCount').text(data.totalCount);
$('#totalOutput').text(data.totalOutput.toFixed(2));
$('#totalPayment').text(data.totalPayment.toFixed(2));
$('#wxPayment').text(data.wxPayment.toFixed(2));
$('#diamondPayment').text(data.diamondPayment.toFixed(2));
}
});
</script>
</body>
</html>