manghe/app/common/service/RankService.php
2025-04-12 06:27:11 +08:00

445 lines
15 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace app\common\service;
use app\common\model\User;
use app\common\model\Reward;
use app\common\model\CouponReceive;
use app\common\model\Coupon;
use app\common\model\Order;
use think\facade\Db;
/**
* 排行榜服务类
*/
class RankService
{
/**
* 获取排行榜数据
* 支持diamond(钻石排行榜)、integral(UU币排行榜)、dadajuan(达达卷排行榜)、invite(邀请新人排行榜)、loss(亏损补贴排行榜)
*
* @return \think\response\Json
*/
public function getRankList($type,$page,$limit)
{
// 验证排行榜类型是否有效
$validTypes = ['diamond', 'integral', 'dadajuan', 'invite', 'loss','loss_desc'];
if (!in_array($type, $validTypes)) {
throw new \Exception('无效的排行榜类型');
}
// 从配置助手获取排行榜时间设置
$timeSettings = \app\common\helper\ConfigHelper::getRankTime($type);
$startTime = !empty($timeSettings['start_time']) ? strtotime($timeSettings['start_time']) : 0;
$endTime = !empty($timeSettings['end_time']) ? strtotime($timeSettings['end_time']) : time();
$rankService = new \app\common\service\RankService();
// 初始化返回数据
$data = [];
// 根据不同排行榜类型查询数据
switch ($type) {
case 'diamond': // 钻石排行榜
$data = $rankService->getDiamondRank($startTime, $endTime, $page, $limit);
break;
case 'integral': // UU币排行榜
$data = $rankService->getIntegralRank($startTime, $endTime, $page, $limit);
break;
case 'dadajuan': // 达达卷排行榜
$data = $rankService->getDadajuanRank($startTime, $endTime, $page, $limit);
break;
case 'invite': // 邀请新人排行榜
$data = $rankService->getInviteRank($startTime, $endTime, $page, $limit);
break;
case 'loss': // 亏损补贴排行榜
$data = $rankService->getLossRank($startTime, $endTime, $page, $limit);
break;
case 'loss_desc'://亏损率排行榜
$data = $rankService->getLossRank($startTime, $endTime, $page, $limit,'loss_rate');
break;
}
// 返回数据
return $data;
}
/**
* 获取钻石排行榜数据
*
* @param int $startTime 开始时间戳
* @param int $endTime 结束时间戳
* @param int $page 页码
* @param int $limit 每页数量
* @return array 排行榜数据
*/
public function getDiamondRank($startTime, $endTime, $page, $limit)
{
// 构建查询条件
$where = [
['status', '=', 1],
['use_money', '>', 0],
[
'user_id',
'not in',
function ($query) {
$query->name('user')->where('istest', '>', 0)->where('status', '=', 1)->field('id');
}
]
];
// 添加时间范围条件
if ($startTime > 0) {
$where[] = ['pay_time', '>=', $startTime];
}
if ($endTime > 0) {
$where[] = ['pay_time', '<=', $endTime];
}
// 查询数据
$list = Order::where($where)
->field('user_id, sum(use_money) as use_money')
->group('user_id')
->order('use_money desc')
->page($page, $limit)
->select()
->toArray();
// 处理用户信息
$rankList = [];
foreach ($list as $index => $item) {
$userInfo = User::field('nickname, headimg, mobile')->where('id', $item['user_id'])->find();
if ($userInfo) {
$rankList[] = [
'rank' => ($page - 1) * $limit + $index + 1,
'user_id' => $item['user_id'],
'nickname' => $userInfo['nickname'],
'headimg' => imageUrl($userInfo['headimg']),
'value' => $item['use_money'],
'unit' => '钻石'
];
}
}
return $rankList;
}
/**
* 获取UU币排行榜数据
*
* @param int $startTime 开始时间戳
* @param int $endTime 结束时间戳
* @param int $page 页码
* @param int $limit 每页数量
* @return array 排行榜数据
*/
public function getIntegralRank($startTime, $endTime, $page, $limit)
{
// 构建查询条件
$where = [
['status', '=', 1],
['use_integral', '>', 0],
[
'user_id',
'not in',
function ($query) {
$query->name('user')->where('istest', '>', 0)->where('status', '=', 1)->field('id');
}
]
];
// 添加时间范围条件
if ($startTime > 0) {
$where[] = ['pay_time', '>=', $startTime];
}
if ($endTime > 0) {
$where[] = ['pay_time', '<=', $endTime];
}
// 查询数据
$list = Order::where($where)
->field('user_id, sum(use_integral) as use_money')
->group('user_id')
->order('use_money desc')
->page($page, $limit)
->select()
->toArray();
// 处理用户信息
$rankList = [];
foreach ($list as $index => $item) {
$userInfo = User::field('nickname, headimg, mobile')->where('id', $item['user_id'])->find();
if ($userInfo) {
$rankList[] = [
'rank' => ($page - 1) * $limit + $index + 1,
'user_id' => $item['user_id'],
'nickname' => $userInfo['nickname'],
'headimg' => imageUrl($userInfo['headimg']),
'value' => $item['use_money'],
'unit' => 'UU币'
];
}
}
return $rankList;
}
/**
* 获取达达卷排行榜数据
*
* @param int $startTime 开始时间戳
* @param int $endTime 结束时间戳
* @param int $page 页码
* @param int $limit 每页数量
* @return array 排行榜数据
*/
public function getDadajuanRank($startTime, $endTime, $page, $limit)
{
// 构建查询条件
$where = [
['status', '=', 1],
['use_money2', '>', 0],
[
'user_id',
'not in',
function ($query) {
$query->name('user')->where('istest', '>', 0)->where('status', '=', 1)->field('id');
}
]
];
// 添加时间范围条件
if ($startTime > 0) {
$where[] = ['pay_time', '>=', $startTime];
}
if ($endTime > 0) {
$where[] = ['pay_time', '<=', $endTime];
}
// 查询数据
$list = Order::where($where)
->field('user_id, sum(use_money2) as use_money')
->group('user_id')
->order('use_money desc')
->page($page, $limit)
->select()
->toArray();
// 处理用户信息
$rankList = [];
foreach ($list as $index => $item) {
$userInfo = User::field('nickname, headimg, mobile')->where('id', $item['user_id'])->find();
if ($userInfo) {
$rankList[] = [
'rank' => ($page - 1) * $limit + $index + 1,
'user_id' => $item['user_id'],
'nickname' => $userInfo['nickname'],
'headimg' => imageUrl($userInfo['headimg']),
'value' => $item['use_money'],
'unit' => '达达卷'
];
}
}
return $rankList;
}
/**
* 获取邀请新人排行榜数据
*
* @param int $startTime 开始时间戳
* @param int $endTime 结束时间戳
* @param int $page 页码
* @param int $limit 每页数量
* @return array 排行榜数据
*/
public function getInviteRank($startTime, $endTime, $page, $limit)
{
// 构建查询条件
$where = [
['pid', '>', 0],
['istest', '=', 0], // 排除测试用户
['status', '=', 1] // 只查询状态正常的用户
];
// 添加时间范围条件
if ($startTime > 0) {
$where[] = ['addtime', '>=', $startTime];
}
if ($endTime > 0) {
$where[] = ['addtime', '<=', $endTime];
}
// 查询数据
$list = User::where($where)
->field('pid, COUNT(1) as invite_count')
->group('pid')
->having('invite_count > 0')
->order('invite_count desc')
->page($page, $limit)
->select()
->toArray();
// 处理用户信息
$rankList = [];
foreach ($list as $index => $item) {
$userInfo = User::field('nickname, headimg, mobile')->where('id', $item['pid'])->find();
if ($userInfo) {
$rankList[] = [
'rank' => ($page - 1) * $limit + $index + 1,
'user_id' => $item['pid'],
'nickname' => $userInfo['nickname'],
'headimg' => imageUrl($userInfo['headimg']),
'value' => $item['invite_count'],
'unit' => '人'
];
}
}
return $rankList;
}
/**
* 获取亏损补贴排行榜数据
*
* @param int $startTime 开始时间戳
* @param int $endTime 结束时间戳
* @param int $page 页码
* @param int $limit 每页数量
* @param string $sortField 排序字段loss_money(亏损金额)或loss_rate(亏损率)
* @return array 排行榜数据
*/
public function getLossRank($startTime, $endTime, $page, $limit, $sortField = 'loss_money')
{
// 构建订单查询条件
$orderWhere = [
['status', '=', 1],
[
'user_id',
'not in',
function ($query) {
$query->name('user')->where('istest', '>', 0)->where('status', '=', 1)->field('id');
}
]
];
// 添加订单时间范围条件
if ($startTime > 0) {
$orderWhere[] = ['pay_time', '>=', $startTime];
}
if ($endTime > 0) {
$orderWhere[] = ['pay_time', '<=', $endTime];
}
// 构建订单详情查询条件
$orderListWhere = [];
if ($startTime > 0) {
$orderListWhere[] = ['addtime', '>=', $startTime];
}
if ($endTime > 0) {
$orderListWhere[] = ['addtime', '<=', $endTime];
}
// 查询用户订单总金额(消耗金额)
$orderSubQuery = Order::where($orderWhere)
->field('user_id, SUM(price) + SUM(use_money) as money')
->group('user_id')
->buildSql();
// 查询用户出货金额
$usersWithOutputMoney = [];
$users = Order::where($orderWhere)->field('DISTINCT user_id')->select()->toArray();
foreach ($users as $user) {
$userId = $user['user_id'];
// 构建特定用户的查询条件
$userOrderListWhere = $orderListWhere;
$userOrderListWhere[] = ['user_id', '=', $userId];
// 查询用户出货金额
$outputMoney = \app\common\model\OrderList::where($userOrderListWhere)
->sum('goodslist_money');
if ($outputMoney > 0) {
$usersWithOutputMoney[$userId] = $outputMoney;
}
}
// 计算亏损数据
$rankList = [];
$index = 0;
// 从订单总金额查询结果中获取数据
$moneyResult = Db::table($orderSubQuery . ' as t')->where('money', '>', 0)->select()->toArray();
foreach ($moneyResult as $item) {
$userId = $item['user_id'];
$consumeMoney = $item['money']; // 消耗金额
// 如果有出货金额数据
if (isset($usersWithOutputMoney[$userId])) {
$outputMoney = $usersWithOutputMoney[$userId]; // 出货金额
// 计算亏损金额和亏损率
$lossMoney = $consumeMoney - $outputMoney;
$lossRate = $consumeMoney > 0 ? round(($lossMoney / $consumeMoney) * 100, 2) : 0;
// 只有亏损的才纳入排行
if ($lossMoney > 0) {
$rankList[] = [
'user_id' => $userId,
'consume_money' => $consumeMoney, // 消耗金额
'output_money' => $outputMoney, // 出货金额
'loss_money' => $lossMoney, // 亏损金额
'loss_rate' => $lossRate // 亏损率(%)
];
}
}
}
// 根据排序字段对结果进行排序
if ($sortField == 'loss_rate') {
// 按亏损率降序排序
usort($rankList, function($a, $b) {
return $b['loss_rate'] <=> $a['loss_rate'];
});
} else {
// 默认按亏损金额降序排序
usort($rankList, function($a, $b) {
return $b['loss_money'] <=> $a['loss_money'];
});
}
// 分页处理
$offset = ($page - 1) * $limit;
$rankList = array_slice($rankList, $offset, $limit);
// 处理用户信息和排名
$result = [];
foreach ($rankList as $index => $item) {
$userInfo = User::field('nickname, headimg, mobile')->where('id', $item['user_id'])->find();
if ($userInfo) {
$result[] = [
'rank' => $offset + $index + 1,
'user_id' => $item['user_id'],
'nickname' => $userInfo['nickname'],
'headimg' => imageUrl($userInfo['headimg']),
'consume_money' => $item['consume_money'],
'output_money' => $item['output_money'],
'value' => $item['loss_money'], // 主要展示值为亏损金额
'loss_rate' => $item['loss_rate'], // 亏损率
'unit' => '元'
];
}
}
return $result;
}
}