Files

161 lines
5.1 KiB
PHP
Raw Permalink Normal View History

2026-08-31 11:33:59 +08:00
<?php
declare(strict_types=1);
namespace app\dao\member;
use app\scope\global\AccessPermissionScope;
use app\service\admin\member\MemberTagRelationService;
use app\service\admin\member\MemberTagService;
use core\base\BaseDao;
use app\model\member\Member;
use madong\query\QueryBuilderHelper;
use madong\query\QueryParamConverter;
use madong\query\enum\ParamFormat;
use InvalidArgumentException;
use support\Container;
/**
* 会员DAO
*/
class MemberDao extends BaseDao
{
/**
* 设置模型
*/
protected function setModel(): string
{
return Member::class;
}
/**
* 获取活跃用户
*
* @param int $limit
*
* @return \Illuminate\Database\Eloquent\Collection
* @throws \Exception
*/
public function getActiveUsers(int $limit = 5): \Illuminate\Database\Eloquent\Collection
{
// last_time 字段存储为时间戳格式(dateFormat = 'U')
// 计算30天前的时间戳
$thirtyDaysAgo = time() - (30 * 24 * 60 * 60);
return $this->query()->withoutGlobalScope(AccessPermissionScope::class)
->where('last_login_time', '>=', $thirtyDaysAgo)
->orderBy('last_login_time', 'desc')
->limit($limit)
->get();
}
/**
* 根据标签ID获取用户列表
*
* @param array $where 查询条件,支持多种格式自动转换
* @param string $field 查询字段
* @param int $page 页码
* @param int $limit 每页数量
* @param array|null $withoutScopes 移除的作用域
*
* @return array ['total' => int, 'items' => array]
* @throws \Exception
*/
public function getUsersListByTagId(array $where, string $field, int $page, int $limit, ?array $withoutScopes = null): array
{
try {
//传入的是标准filters格式
$tagId = QueryParamConverter::getValue($where, 'tag_id');
if (!$tagId) {
throw new InvalidArgumentException("Tag ID is required.");
}
// 从 where 中移除 tag_id
$where = QueryParamConverter::removeFilter($where, 'tag_id');
$query = $this->query()->with(['tags' => function ($query) use ($withoutScopes) {
$this->applyScopeRemoval($query, $withoutScopes);
}])
->whereHas('tags', function ($query) use ($tagId) {
$query->where('id', $tagId);
});
$this->applyScopeRemoval($query, $withoutScopes);
// 应用剩余的 filters 条件
if (!empty($where['filters'])) {
QueryBuilderHelper::applyFiltersToQuery($query, $where['filters']);
}
$total = $query->count();
$items = $query->when($page > 0 && $limit > 0, function ($query) use ($page, $limit) {
return $query->skip(($page - 1) * $limit)->take($limit);
})
->select(explode(',', $field))
->get()
->toArray();
return compact('total', 'items');
} catch (\Throwable $e) {
throw new \Exception("获取用户列表失败: " . $e->getMessage(), 0, $e);
}
}
/**
* 排除标签ID-用户列表
*
* @param array $where
* @param string $field
* @param int $page
* @param int $limit
* @param array|null $withoutScopes
*
* @return array
* @throws \ReflectionException|\Exception
*/
public function getUsersExcludingTag(array $where, string $field, int $page, int $limit, ?array $withoutScopes = null): array
{
// 使用 QueryParamConverter 获取 tag_id 值(自动识别格式)
$tagId = QueryParamConverter::getValue($where, 'tag_id');
// 从 where 中移除 tag_id
$where = QueryParamConverter::removeFilter($where, 'tag_id');
// 获取排除的用户ID列表
if ($tagId) {
$memberTagRelationService = Container::make(MemberTagRelationService::class);
$excludedMemberUserIds = $memberTagRelationService->getColumn(['tag_id' => $tagId], 'member_id');
} else {
$excludedMemberUserIds = [];
}
$query = $this->getModel()->whereNotIn('id', $excludedMemberUserIds)
->with(['tags' => function ($query) use ($withoutScopes) {
$this->applyScopeRemoval($query, $withoutScopes);
}]);
$this->applyScopeRemoval($query, $withoutScopes);
// 应用剩余的 filters 条件
if (!empty($where['filters'])) {
QueryBuilderHelper::applyFiltersToQuery($query, $where['filters']);
}
$total = $query->count();
// 如果没有用户,则返回空结果
if ($total === 0) {
return ['total' => 0, 'items' => []];
}
$items = $query->when($page > 0 && $limit > 0, function ($query) use ($page, $limit) {
return $query->skip(($page - 1) * $limit)->take($limit);
})->select($field)->get()->toArray();
return compact('total', 'items');
}
}