UserService.php 8.69 KB
<?php

namespace App\Http\Service;

use App\Exceptions\SingerLimitException;
use App\Helpers\ConfigHelper;
use App\Helpers\UserPermissionHelper;
use App\Models\Activity;
use App\Models\GroupHasMember;
use App\Models\Pivots\ActivityLinkPivot;
use App\Models\Project;
use App\Models\User;
use App\Models\UserDynamic;
use App\Models\UserFollowRelation;
use App\Models\UserVisitorRelation;
use App\Support\Model;
use Illuminate\Database\Eloquent\Builder;

class UserService
{

    private static function getKey(Model|int $key)
    {
        return $key instanceof Model ? $key->getKey() : $key;
    }

    /**
     * 移除团队成员
     * @param \App\Models\User $user
     * @return void
     */
    public static function deleteGroupMember(User $user): void
    {
        $businessId = $user->getAttribute('business_id');
        $user->update(['business_id' => 0, 'chat_mode' => 0]);
        GroupHasMember::query()->where('member_id', $user->getKey())->first()?->delete();
        self::syncBusinessIdentity($businessId);
    }

    /**
     * 检测是否拥有Demo权限
     * @param \App\Models\User|int $user
     * @return bool
     */
    public static function hasDemoPermission(User|int $user): bool
    {
        return UserPermissionHelper::user($user)->hasDemoPermission();
    }

    /**
     * 检测是否拥有试唱权限
     * @param \App\Models\User|int $user
     * @return bool
     */
    public static function hasSingPermission(User|int $user): bool
    {
        return UserPermissionHelper::user($user)->hasSingPermission();
    }

    /**
     * 检测是否用户试听权限
     * @param \App\Models\User|int $user
     * @return bool
     */
    public static function hasListenPermission(User|int $user): bool
    {
        return UserPermissionHelper::user($user)->hasListenPermission();
    }

    /**
     * 检测是否在试听白名单中
     * @param \App\Models\User|int $user
     * @return bool
     */
    public static function inSingOrListenWhite(User|int $user): bool
    {
        return in_array(self::getKey($user), ConfigHelper::getListenAndSingUserList()->flatten()->toArray(), false);
    }

    /**
     * @param \App\Models\User|int $user
     * @return bool
     */
    public static function isSinger(User|int $user): bool
    {
        return UserPermissionHelper::user($user)->isSinger();
    }

    /**
     * @param \App\Models\User|int $user
     * @return bool
     */
    public static function isBroker(User|int $user): bool
    {
        return User::query()
            ->where('business_id', self::getKey($user))
            ->whereHas('authTags', fn(Builder $builder) => $builder->whereIn('user_tag_relations.tag_id', ConfigHelper::getSingerTagIds()))
            ->exists();
    }

    public static function isCaptain(User|int $user): bool
    {
        return User::query()->where('business_id', self::getKey($user))->exists();
    }

    /**
     * 获取用户管理厂牌Ids
     * @param \App\Models\User|int $user
     * @return array
     */
    public static function getManageProjectIds(User|int $user): array
    {
        return Project::filter(['masterOrManager' => self::getKey($user)])->pluck('projects.id')->toArray();
    }

    /**
     * 检测用户是否为指定厂牌管理
     * @param \App\Models\User|int    $user
     * @param int|\App\Models\Project $project
     * @return bool
     */
    public static function isProjectManager(User|int $user, Project|int $project): bool
    {
        return Project::filter(['masterOrManager' => self::getKey($user)])->whereKey(is_numeric($project) ? $project : $project->getKey())->exists();
    }

    /**
     * 检测用户是否为活动外部管理员
     * @param \App\Models\User|int          $user
     * @param \App\Models\Activity|int|null $activity
     * @return bool
     */
    public static function isActivityManager(User|int $user, Activity|int|null $activity = NULL): bool
    {
        return ActivityLinkPivot::manager(self::getKey($user))
            ->when($activity, fn(Builder $query) => $query->where('activity_id', self::getKey($activity)))
            ->exists();
    }

    /**
     * @param \App\Models\User|int $user
     * @return array
     */
    public static function getManageActivityIds(User|int $user): array
    {
        return ActivityLinkPivot::manager(self::getKey($user))->distinct()->pluck('activity_id')->toArray();
    }

    /**
     * 是否为粉丝
     * @param \App\Models\User|int $following
     * @param \App\Models\User|int $follower
     * @return bool
     */
    public static function isFollower(User|int $following, User|int $follower): bool
    {
        return UserFollowRelation::query()->where('following_id', self::getKey($following))->where('follower_id', self::getKey($follower))->exists();
    }

    /**
     * 更新用户认证标签
     * @throws \App\Exceptions\SingerLimitException
     */
    public static function updateAuthTags(User $user, array $tags = [], array $fill = []): int
    {
        $currentIdentity = $user->getAttribute('identity');
        $business        = $user->loadMissing('business:id,identity,business_singer_limit')->getAttribute('business');

        if ($business && ConfigHelper::hasSingerTag($tags)) {
            $maxSingerNum = $business->getAttribute('business_singer_limit') ?? 0;

            if ((int)bcsub($maxSingerNum, $business->getSingerCount($user->getKey())) <= 0) {
                throw new SingerLimitException($user, $user->getAttribute('business_id'), $maxSingerNum, '歌手额度已满');
            }
        }



        $user->authTags()->wherePivot('type', 4)->syncWithPivotValues($tags, ['type' => 4]);

        self::syncBusinessIdentity($business);

        if (empty($tags)) {
            $updateIdentity = in_array($currentIdentity, [2, 3], true) ? 2 : 0;
        } else {
            $updateIdentity = in_array($currentIdentity, [2, 3], true) ? 3 : 1;
        }

        return $user->update(['identity' => $updateIdentity] + $fill);
    }

    /**
     * 同步团长Identity值
     * @param \App\Models\User|int|null $user
     * @return bool
     */
    public static function syncBusinessIdentity(User|int|null $user): bool
    {
        if (is_numeric($user)) {
            $user = User::query()->withTrashed()->find($user, ['id', 'identity']);
        }

        if ($user) {
            if ($user->getSingerCount() === 0) {
                $updateIdentity = in_array($user->getAttribute('identity'), [1, 3], true) ? 1 : 0;
            } else {
                $updateIdentity = in_array($user->getAttribute('identity'), [1, 3], true) ? 3 : 2;
            }
            return $user->update(['identity' => $updateIdentity]);
        }

        return true;
    }


    /**
     * 获取用户粉丝数
     * @param \App\Models\User|int $user
     * @param bool                 $unRead
     * @return int
     */
    public static function getFollowerCount(User|int $user, bool $unRead = false): int
    {
        return UserFollowRelation::query()
            ->where('following_id', self::getKey($user))
            ->when($unRead, fn(Builder $query) => $query->where('is_read', 0))
            ->whereRelation('follower', 'status', 1)
            ->count();
    }

    /**
     * 获取用户关注数
     * @param \App\Models\User|int $user
     * @param bool                 $unRead
     * @return int
     */
    public static function getFollowingCount(User|int $user, bool $unRead = false): int
    {
        return UserFollowRelation::query()
            ->where('follower_id', self::getKey($user))
            ->when($unRead, fn(Builder $query) => $query->where('is_read', 0))
            ->whereRelation('following', 'status', 1)
            ->count();
    }


    /**
     * 获取用户访客数
     * @param \App\Models\User|int $user
     * @param bool                 $unRead
     * @param int                  $day
     * @return int
     */
    public static function getVisitorCount(User|int $user, int $day = 0, bool $unRead = false): int
    {
        return UserVisitorRelation::query()
            ->where('user_id', self::getKey($user))
            ->when($unRead, fn(Builder $query) => $query->where('is_read', 0))
            ->when($day, fn(Builder $query) => $query->where('created_at', '>=', now()->subDays($day)->toDateTimeString()))
            ->whereRelation('visitor', 'status', 1)
            ->distinct()->count('visitor_id');
    }

    /**
     * 获取用户动态数
     * @param \App\Models\User|int $user
     * @param string|null          $type
     * @return int
     */
    public static function getDynamicCount(User|int $user, ?string $type = NULL): int
    {
        return UserDynamic::query()
            ->where('user_id', self::getKey($user))
            ->when($type, fn(Builder $query) => $query->where('type', $type))
            ->count();
    }
}