This commit is contained in:
2025-08-14 17:19:26 +08:00
parent 30abda5ba7
commit 281248fd04
245 changed files with 21051 additions and 61 deletions

606
app/admin/model/User.php Normal file
View File

@@ -0,0 +1,606 @@
<?php
namespace app\admin\model;
use app\common\library\DatabaseRoute;
use think\facade\Cache;
use think\facade\Db;
use think\Model;
use think\model\relation\BelongsTo;
/**
* User 模型
* @property int $id 用户ID
* @property string password 密码密文
*/
class User extends Model
{
protected $autoWriteTimestamp = true;
public function getAvatarAttr($value): string
{
return full_url($value, false, config('buildadmin.default_avatar'));
}
public function setAvatarAttr($value): string
{
return $value == full_url('', false, config('buildadmin.default_avatar')) ? '' : $value;
}
public function getMoneyAttr($value): string
{
return bcdiv($value, 100, 2);
}
public function setMoneyAttr($value): string
{
return bcmul($value, 100, 2);
}
public function userGroup(): BelongsTo
{
return $this->belongsTo(UserGroup::class, 'group_id');
}
/**
* 重置用户密码
* @param int|string $uid 用户ID
* @param string $newPassword 新密码
* @return int|User
*/
public function resetPassword(int|string $uid, string $newPassword): int|User
{
return $this->where(['id' => $uid])->update(['password' => hash_password($newPassword), 'salt' => '']);
}
public static function queryCourseOrder($page, $limit, $type, $date, $sysUserId):array
{
// 1. 处理时间范围
$timestamp = strtotime($date);
if ($type == 2) {
// 按月统计
$startTime = date('Y-m-01 00:00:00', $timestamp);
$endTime = date('Y-m-t 23:59:59', $timestamp);
} elseif ($type == 3) {
// 按年统计
$startTime = date('Y-01-01 00:00:00', $timestamp);
$endTime = date('Y-12-31 23:59:59', $timestamp);
} else {
// 按日统计
$startTime = date('Y-m-d 00:00:00', $timestamp);
$endTime = date('Y-m-d 23:59:59', $timestamp);
}
// 2. 查询课程订单统计数据(带分页)
$courseList = self::selectGroupCourseId($startTime, $endTime, $page, $limit);
// 3. 提取课程ID集合
$courseIds = array_column($courseList['list'], 'orders_id');
// 4. 批量查询课程信息并构建映射
if (!empty($courseIds)) {
$courseMap = [];
$db = Db::connect(get_slave_connect_name());
$courses = $db->name('course')
->whereIn('course_id', $courseIds)
->field('course_id, title')
->select()
->toArray();
// 构建ID到课程的映射
foreach ($courses as $course) {
$courseMap[$course['course_id']] = $course;
}
// 5. 关联课程名称到订单统计数据
foreach ($courseList['list'] as &$item) {
if (isset($courseMap[$item['orders_id']])) {
$item['coursename'] = $courseMap[$item['orders_id']]['title'];
}
}
unset($item); // 释放引用
$courseList['list'] = convertToCamelCase($courseList['list']);
}
return $courseList;
}
public static function selectGroupCourseId($startTime, $endTime, $page, $limit)
{
return DatabaseRoute::paginateAllDb('orders', function($query) use($startTime, $endTime) {
return $query->alias('o')
->field([
'sum(o.pay_money) as coursemoney',
'count(*) as coursenum',
'o.course_id as courseId'
])
->where('o.status', 1)
->where('o.orders_type', 1)
->whereBetween('o.create_time', [$startTime, $endTime])
->group('o.course_id');
}, $page, $limit, 'coursenum');
}
public static function queryUserCount($type, $date, $platform, $qdCode)
{
// 检查日期是否为空
if (empty($date)) {
// 格式化当前时间注意PHP时间格式符与Java略有不同
$date = date('Y-m-d H:i:s');
}
return DatabaseRoute::getAllDbData('tb_user', function($query) use($type, $date, $platform, $qdCode) {
// 处理时间条件
$dateTime = strtotime($date);
if ($dateTime === false) {
throw new \InvalidArgumentException("无效的日期格式:{$date}");
}
switch ($type) {
case 1:
// 按日统计(精确到天)
$startDate = date('Y-m-d 00:00:00', $dateTime);
$endDate = date('Y-m-d 23:59:59', $dateTime);
$query->whereBetweenTime('create_time', $startDate, $endDate);
break;
case 2:
// 按月统计
$startDate = date('Y-m-01 00:00:00', $dateTime);
$endDate = date('Y-m-t 23:59:59', $dateTime);
$query->whereBetweenTime('create_time', $startDate, $endDate);
break;
case 3:
// 按年统计
$startDate = date('Y-01-01 00:00:00', $dateTime);
$endDate = date('Y-12-31 23:59:59', $dateTime);
$query->whereBetweenTime('create_time', $startDate, $endDate);
break;
default:
// 无效类型,不添加时间条件
break;
}
// 处理平台条件
if (!is_null($platform)) {
$query->where('platform', $platform);
}
// 处理渠道码条件
if (!is_null($qdCode)) {
$query->where('qd_code', $qdCode);
}
return $query;
})->count();
}
public static function queryPayMoney($type, $qdCode)
{
$date = date('Y-m-d H:i:s');
$result = DatabaseRoute::getAllDbData('pay_details', function($query) use($type, $date, $qdCode) {
$query->alias('p')
->leftJoin('tb_user u', 'u.user_id = p.user_id')
->where('p.state', 1) // 支付状态为1成功
->field('sum(p.money) as total_money'); // 聚合计算总金额
// 根据类型添加时间条件匹配date_format的逻辑
switch ($type) {
case 1:
// 按日:日期部分完全匹配
$query->whereRaw("date_format(p.create_time, '%Y-%m-%d') = date_format(?, '%Y-%m-%d')", [$date]);
break;
case 2:
// 按月:年月部分匹配
$query->whereRaw("date_format(p.create_time, '%Y-%m') = date_format(?, '%Y-%m')", [$date]);
break;
case 3:
// 按年:年份部分匹配
$query->whereRaw("date_format(p.create_time, '%Y') = date_format(?, '%Y')", [$date]);
break;
default:
// 默认为空,可根据业务补充默认条件
break;
}
// 可选条件:渠道码
if (!empty($qdCode)) {
$query->where('u.qd_code', $qdCode);
}
return $query;
})->find();
return $result['total_money'] ?? 0.0;
}
public static function userMessage($date, $type, $qdCode, $vipType)
{
// 1. 处理时间条件
$timestamp = strtotime($date);
if ($timestamp === false) {
throw new \InvalidArgumentException("无效的日期格式:{$date}");
}
if ($type == 1) {
// 按日开始00:00:00
$startTime = date('Y-m-d 00:00:00', $timestamp);
} elseif ($type == 2) {
// 按月开始当月1日 00:00:00
$startTime = date('Y-m-01 00:00:00', $timestamp);
} else {
// 按年开始当年1月1日 00:00:00
$startTime = date('Y-01-01 00:00:00', $timestamp);
}
$cachestr = 'userMessageUserIdList';
$userIds = Cache::get($cachestr);
if(!$userIds) {
if (!empty($qdCode)) {
$userIds = DatabaseRoute::getAllDbData('tb_user', function($query) use($qdCode, $startTime) {
$query->where('qd_code', $qdCode);
// 2. 查询符合条件的用户ID集合
$query->where('create_time', '>=', $startTime)
->field('user_id');
return $query;
})->column('user_id');
}
// 3. 若用户ID集合为空直接返回0
if (empty($userIds)) {
return 0;
}
Cache::set($cachestr, json_encode($userIds));
}else {
$userIds = json_decode($userIds, true);
}
$db = Db::connect(get_slave_connect_name());
// 4. 查询符合条件的VIP用户数量
$query = $db->name('user_vip');
if($userIds) {
$query = $query->whereIn('user_id', $userIds);
}
$query = $query->where('is_vip', 2);
if (!is_null($vipType)) {
$query = $query->where('vip_type', $vipType);
}
return $query->count();
}
/**
* 查询今日支付和提现统计信息
* @return array 包含支付金额、支付次数、提现金额、提现次数的关联数组
*/
public static function queryPayAndExtractInfo()
{
// 1. 计算今日开始和结束时间
$beginOfDay = date('Y-m-d 00:00:00'); // 今日0点
$endOfDay = date('Y-m-d 23:59:59'); // 今日23点59分59秒
// 2. 查询今日支付信息
$payInfo = self::queryPayInfo($beginOfDay, $endOfDay);
// 3. 查询今日提现信息
$extractInfo = self::queryExtractInfo($beginOfDay, $endOfDay);
// 4. 合并结果
return [
'payAmount' => $payInfo['totalMoney'] ?? null,
'payCount' => $payInfo['totalCount'] ?? null,
'extractAmount' => $extractInfo['totalMoney'] ?? null,
'extractCount' => $extractInfo['totalCount'] ?? null
];
}
/**
* 查询指定时间范围内的支付信息
* @param string $begin 开始时间格式Y-m-d H:i:s
* @param string $end 结束时间格式Y-m-d H:i:s
* @return array 支付统计数据
*/
private static function queryPayInfo($begin, $end)
{
return DatabaseRoute::getAllDbData('orders', function($query) use($begin, $end) {
return $query->where('create_time', 'between', [$begin, $end])
->where('status', 1) // 假设1表示支付成功
->where('pay_way', 9) // 假设1表示支付成功
->field([
'SUM(pay_money) as totalMoney', // 总支付金额
'COUNT(1) as totalCount' // 支付次数
]);
})->find() ?: [];
}
/**
* 查询指定时间范围内的提现信息
* @param string $begin 开始时间格式Y-m-d H:i:s
* @param string $end 结束时间格式Y-m-d H:i:s
* @return array 提现统计数据
*/
private static function queryExtractInfo($begin, $end)
{
return DatabaseRoute::getAllDbData('cash_out', function($query) use($begin, $end) {
return $query->where('create_at', 'between', [$begin, $end])
->where('state', 1)
->field([
'SUM(money) as totalMoney', // 总提现金额
'COUNT(1) as totalCount' // 提现次数
]);
})->find() ?: [];
}
public static function selectUserPage($page, $limit, $phone, $sex, $platform, $sysPhone, $status, $member,
$inviterCode, $userName, $invitationCode, $startTime, $endTime, $qdCode, $sysUserName, $vipType, $delegate)
{
$result = DatabaseRoute::paginateAllDb('tb_user', function ($query) use($page, $limit, $phone, $sex, $platform, $sysPhone, $status, $member,
$inviterCode, $userName, $invitationCode, $startTime, $endTime, $qdCode, $sysUserName, $vipType, $delegate) {
// 初始化查询
$query->alias('u')
// 左连接sys_user表别名s
->leftJoin('sys_user s', 's.qd_code = u.qd_code')
// 左连接user_money表别名m
->leftJoin('user_money m', 'm.user_id = u.user_id')
// 固定条件s.sys_user_id is null
->where('s.sys_user_id', null)
// 字段选择与原SQL一致
->field([
'u.*',
'1 as member',
's.username as sysUserName',
'm.cash_count as cashCount',
'm.cash_amount as cashAmount',
'm.amount as balance'
]);
// 搜索条件user_id/phone/user_name匹配
if (!is_null($phone) && $phone !== '') {
$query->where(function ($query) use ($phone) {
$query->where('u.user_id', $phone)
->whereOr('u.phone', $phone)
->whereOr('u.user_name', $phone);
});
}
// 系统用户名模糊查询
if (!is_null($sysUserName) && $sysUserName !== '') {
$query->where('s.username', 'like', "%{$sysUserName}%");
}
// 用户名模糊查询
if (!is_null($userName) && $userName !== '') {
$query->where('u.user_name', 'like', "%{$userName}%");
}
// 性别筛选非0值
if (!is_null($sex) && $sex != 0) {
$query->where('u.sex', $sex);
}
// 平台筛选
if (!is_null($platform) && $platform !== '') {
$query->where('u.platform', $platform);
}
// 系统手机号筛选
if (!is_null($sysPhone) && $sysPhone !== '') {
$query->where('u.sys_phone', $sysPhone);
}
// 邀请人编码模糊查询
if (!is_null($inviterCode) && $inviterCode !== '') {
$query->where('u.inviter_code', 'like', "%{$inviterCode}%");
}
// 邀请码模糊查询
if (!is_null($invitationCode) && $invitationCode !== '') {
$query->where('u.invitation_code', 'like', "%{$invitationCode}%");
}
// 渠道码精确匹配
if (!is_null($qdCode) && $qdCode !== '') {
$query->where('u.qd_code', $qdCode);
}
// 时间范围筛选
if (!is_null($startTime) && $startTime !== '' && !is_null($endTime) && $endTime !== '') {
// 开始时间和结束时间都存在
$query->whereBetween('u.create_time', [$startTime, $endTime]);
} elseif (!is_null($startTime) && $startTime !== '') {
// 仅开始时间
$query->where('u.create_time', '>=', $startTime);
} elseif (!is_null($endTime) && $endTime !== '') {
// 仅结束时间
$query->where('u.create_time', '<=', $endTime);
}
// 邀请人数筛选delegate
if (!is_null($delegate)) {
if ($delegate == 0) {
// 邀请人数=0
$query->where('u.invite_count', 0);
} elseif ($delegate == 1) {
// 邀请人数>0
$query->where('u.invite_count', '>', 0);
}
}
return $query;
}, $page, $limit, 'u.create_time');
return $result;
}
public static function upUserBlack($user, $status, $db)
{
$userId = $user['user_id']; // 获取用户ID
if ($status == 0) {
// 拉黑操作设置状态为0并更新
$db->name('tb_user')->where(['user_id' => $userId])->update(['status' => 0]);
return true;
}
// 解除拉黑操作设置状态为1平台为h5并更新
$db->name('tb_user')->where(['user_id' => $userId])->update(['status' => 1, 'platform' => 'h5']);
// 查询用户信息(身份证号)
$userInfo = $db->name('user_info')->where('user_id', $userId)->find();
// 若存在身份证号,则删除黑名单记录
if (!is_null($userInfo) && !empty($userInfo['cert_no'])) {
Db::connect(get_master_connect_name())->name('tb_user_blacklist')
->where('id_card_no', $userInfo['cert_no'])
->delete();
}
return true;
}
public static function selectInviteMoneyByUserId($user_id, $db)
{
return $db->name('invite_money')->where(['user_id' => $user_id])->find();
}
public static function instantselectSumPay($date, $userId, $db)
{
$startTime = date('Y-m-01 00:00:00', strtotime($date));
$endTime = date('Y-m-t 23:59:59', strtotime($date));
$sumMoney = $db->name('pay_details')
->where('create_time', '>', $startTime) // 创建时间大于开始时间
->where('create_time', '<', $endTime) // 创建时间小于结束时间
->where('state', 1) // 支付状态为1成功
->where('user_id', $userId) // 指定用户ID
->sum('money'); // 计算金额总和
return $sumMoney !== null ? (float)$sumMoney : 0.00;
}
public static function monthIncome($date, $userId, $db)
{
// 构建查询
$sumMoney = $db->name('user_money_details')
->where('user_id', $userId) // 固定条件用户ID匹配
->where('classify', 4) // 固定条件分类为4
->where('type', 2) // 固定条件类型为2
->where('state', 2) // 固定条件状态为2
// 时间条件当月匹配与原SQL的date_format逻辑一致
->whereRaw("date_format(create_time, '%Y-%m') = date_format(?, '%Y-%m')", [$date])
->sum('money'); // 计算金额总和
// 处理空值并保留两位小数
return $sumMoney !== null ? number_format($sumMoney, 2) : '0.00';
}
public static function queryInviterCount($inviterCode)
{
return DatabaseRoute::getAllDbData('tb_user', function($query) use($inviterCode) {
return $query->where('inviter_code', $inviterCode);
})->count();
}
public static function selectUserVipByUserId($userId)
{
return Db::connect(get_slave_connect_name())->name('user_vip')->where(['user_id' => $userId])->find();
}
public static function selectUserMoneyByUserId($userId)
{
$db_name = DatabaseRoute::getConnection('user_money', ['user_id' => $userId]);
$db = Db::connect($db_name);
// 查询用户钱包信息
$userMoney = $db->name('user_money')->where('user_id', $userId)->find();
// 若不存在,则创建新记录
if (is_null($userMoney)) {
$db_name = DatabaseRoute::getConnection('user_money', ['user_id' => $userId], true);
$userMoney = [
'user_id' => $userId,
'money' => 0.00,
'amount' => 0.00,
];
Db::connect($db_name)->name('user_money')->insert($userMoney);
}
return $userMoney;
}
public static function userListExcel($startTime, $endTime, $page = 1, $limit = 20, $userEntity = [])
{
$list = DatabaseRoute::getAllDbData('tb_user', function ($query) use ($startTime, $endTime, $page, $limit, $userEntity) {
$query->alias('u');
// 处理 phone 条件
if (!empty($userEntity['phone'])) {
$query->where('u.phone', 'like', "%{$userEntity['phone']}%");
}
// 处理 userName 条件
if (!empty($userEntity['userName'])) {
$query->where('u.user_name', 'like', "%{$userEntity['userName']}%");
}
// 处理 invitationCode 条件
if (!empty($userEntity['invitationCode'])) {
$query->where('u.invitation_code', 'like', "%{$userEntity['invitationCode']}%");
}
// 处理 inviterCode 条件
if (!empty($userEntity['inviterCode'])) {
$query->where('u.inviter_code', 'like', "%{$userEntity['inviterCode']}%");
}
// 处理 platform 条件
if (!empty($userEntity['platform'])) {
$query->where('u.platform', $userEntity['platform']);
}
// 处理时间范围条件
if (!empty($startTime) && !empty($endTime)) {
$query->whereTime('u.create_time', 'between', [$startTime, $endTime]);
} elseif (!empty($startTime)) {
$query->whereTime('u.create_time', '>=', $startTime);
} elseif (!empty($endTime)) {
$query->whereTime('u.create_time', '<=', $endTime);
}
if (!empty($page) && !empty($limit)) {
$query->limit(page($page, $limit), $limit);
}
return $query;
})->select()->toArray();
$export = new \alei\Export('用户列表');
$export->setColumn([
['field' => 'user_id', 'title' => '用户ID'],
['field' => 'user_name', 'title' => '用户名'], //格式化时间,时间戳格式化为时间日期格式,默认格式: “Y-m-d H:i:s”
['field' => 'phone', 'title' => '手机号'],
['field' => 'sys_phone', 'title' => '手机类型 1安卓 2ios'],
['field' => 'jifen', 'title' => '积分'],
['field' => 'invitation_code', 'title' => '邀请码'],
['field' => 'inviter_code', 'title' => '邀请人邀请码'],
['field' => 'zhi_fu_bao_name', 'title' => '支付宝名称'],
['field' => 'zhi_fu_bao', 'title' => '支付宝账号'],
['field' => 'cert_name', 'title' => '姓名'],
['field' => 'cert_no', 'title' => '身份证号码'],
['field' => 'create_time', 'title' => '创建时间'],
]);
//设置数据
$export->setData($list);
//生成表格返回url
$url = $export->build(); //'export/文章.xlsx'
return ['data' => config('buildadmin.run_api_url') . $url];
}
}