161 lines
5.1 KiB
PHP
161 lines
5.1 KiB
PHP
<?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');
|
||
}
|
||
|
||
}
|
||
|
||
|