User.php 9.24 KB
<?php

namespace App\Models;

use App\Enums\UserOfficialStatusEnum;
use App\Enums\UserScopeEnum;
use App\Enums\UserStatusEnum;
use App\Helpers\ConfigHelper;
use App\Models\Pivots\UserActivityCollectionPivot;
use App\Models\Pivots\UserActivityViewPivot;
use App\Models\Pivots\UserProjectPivot;
use App\Models\Pivots\UserRolePivot;
use App\Models\Views\ActivitySubmitWork;
use App\Support\AuthModel;
use App\Support\JsonAttributeCast;
use Awobaz\Compoships\Database\Eloquent\Relations\BelongsTo;
use Awobaz\Compoships\Database\Eloquent\Relations\HasMany;
use Awobaz\Compoships\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Arr;
use Overtrue\EasySms\PhoneNumber;

/**
 * @method static Builder phoneNumber(PhoneNumber $phoneNumber)
 */
class User extends AuthModel
{
    use HasFactory, Notifiable, SoftDeletes;

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var array<int, string>
     */
    protected $hidden = [
        'password', 'deleted_at', 'pivot'
    ];

    protected $guarded = [];

    protected $attributes = [
        'audit_status' => 1
    ];

    /**
     * The attributes that should be cast.
     *
     * @var array<string, string>
     */
    protected $casts = [
        'is_super'              => 'int',
        'audit_status'          => 'int',
        'business_id'           => 'int',
        'inviter_id'            => 'int',
        'sex'                   => 'int',
        'scope'                 => UserScopeEnum::class,
        'official_status'       => UserOfficialStatusEnum::class,
        'official_id'           => 'string',
        'status'                => UserStatusEnum::class,
        'identifier'            => 'int',
        'business_singer_limit' => 'int',
        'demo_type'             => 'int',
        'user_tag_id'           => 'int',
        'expand'                => 'json',
        'register_type'         => 'int'
        //        'email_verified_at' => 'datetime',
    ];

    public array $columnMap = [
        'nick_name'             => '艺名',
        'real_name'             => '真名',
        'email'                 => '邮箱',
        'lang'                  => '语种',
        'area_code'             => '手机区号',
        'phone'                 => '手机号',
        'scope'                 => '权限',
        'demo_type'             => 'Demo权限',
        'user_tag_id'           => '标签',
        'business_singer_limit' => '团队歌手',
        'audit_at'              => '音乐认证'
    ];

    /**
     * @param \Illuminate\Database\Eloquent\Builder $builder
     * @param \Overtrue\EasySms\PhoneNumber         $phoneNumber
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopePhoneNumber(Builder $builder, PhoneNumber $phoneNumber): Builder
    {
        return $builder->where('area_code', $phoneNumber->getIDDCode())->where('phone', $phoneNumber->getNumber());
    }

    /**
     * @return \Overtrue\EasySms\PhoneNumber
     */
    public function getPhoneNotificationKey(): PhoneNumber
    {
        return new PhoneNumber($this->phone, $this->area_code);
    }

    /**
     * @return string
     */
    public function getWechatNotificationKey(): string
    {
        return $this->getAttribute('official_id') ?? '';
    }

    /**
     * @param $value
     * @return string
     */
    public function getAvatarAttribute($value): string
    {
        return empty($value) ? 'https://hising-cdn.hikoon.com/image/20230925/heqk7stlm31695620862622v3gdnlhzars.png' : $value;
    }

    /**
     * @param $value
     * @return string
     */
    public function getCoverAttribute($value): string
    {
        return empty($value) ? 'https://hising-cdn.hikoon.com/file/20231116/vbhr3e6yk4l1700102812011wg18xstw9m.jpg' : $value;
    }


    /**
     * @param array|int $except
     * @return int
     */
    public function getSingerCount(array|int $except = []): int
    {
        return self::query()
            ->whereIn('users.id', self::query()->where('business_id', $this->getKey())->pluck('id')->toArray())
            ->whereNotIn('users.id', Arr::wrap($except))
            ->whereHas('authTags', fn(Builder $builder) => $builder->whereIn('system_tags.id', ConfigHelper::getSingerTagIds()))
            ->count();
    }

    /**
     * @param string $format
     * @return string
     */
    public function getFullName(string $format = '%s(%s)'): string
    {
        return sprintf($format, $this->getAttribute('nick_name'), $this->getAttribute('real_name'));
    }

    /**
     * @return string
     */
    public function getFullAddress(): string
    {
        return implode('-', array_filter([$this->getAttribute('province'), $this->getAttribute('city')]));
    }

    /**
     * @return \Overtrue\EasySms\PhoneNumber
     */
    public function getFullPhone(): PhoneNumber
    {
        return new PhoneNumber($this->getAttribute('phone'), $this->getAttribute('area_code'));
    }

    /**
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
     */
    public function roles(): BelongsToMany
    {
        return $this->belongsToMany(SystemRole::class, UserRolePivot::class, 'user_id', 'role_id');
    }

    /**
     * 系统标签
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
     */
    public function tags(): BelongsToMany
    {
        return $this->belongsToMany(SystemTag::class, UserHasTag::class, 'user_id', 'tag_id')
            ->wherePivot('deleted_at', '=', NULL);
    }

    /**
     * 技能标签
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
     */
    public function artTags(): BelongsToMany
    {
        return $this->belongsToMany(SystemTag::class, UserTagRelation::class, 'user_id', 'tag_id')->wherePivot('type', '=', 2);

    }

    /**
     * 风格标签
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
     */
    public function styleTags(): BelongsToMany
    {
        return $this->belongsToMany(SystemTag::class, UserTagRelation::class, 'user_id', 'tag_id')->wherePivot('type', '=', 1);

    }

    /**
     * 审核认证标签
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
     */
    public function authTags(): BelongsToMany
    {
        return $this->belongsToMany(SystemTag::class, UserTagRelation::class, 'user_id', 'tag_id')
            ->wherePivot('type', '=', 4)->withTimestamps();
    }

    /**
     * @return \Awobaz\Compoships\Database\Eloquent\Relations\BelongsTo
     */
    public function userTag(): BelongsTo
    {
        return $this->belongsTo(UserTag::class, 'user_tag_id')
            ->where('user_tags.status', 1)
            ->withCasts(['frame' => JsonAttributeCast::class]);
    }

    /**
     * @return \Awobaz\Compoships\Database\Eloquent\Relations\HasMany
     */
    public function dynamics(): HasMany
    {
        return $this->hasMany(UserDynamic::class);
    }

    /**
     * @return \Awobaz\Compoships\Database\Eloquent\Relations\HasOne
     */
    public function singletonQuotation(): HasOne
    {
        return $this->hasOne(UserQuotation::class);
    }

    /**
     * @return \Awobaz\Compoships\Database\Eloquent\Relations\BelongsTo
     */
    public function business(): BelongsTo
    {
        return $this->belongsTo(__CLASS__, 'business_id');
    }

    /**
     * @return \Awobaz\Compoships\Database\Eloquent\Relations\BelongsTo
     */
    public function inviter(): BelongsTo
    {
        return $this->belongsTo(__CLASS__, 'inviter_id');
    }

    /**
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
     */
    public function listenActivities(): BelongsToMany
    {
        return $this->belongsToMany(Activity::class, UserActivityViewPivot::class)->wherePivotNull('deleted_at');
    }

    /**
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
     */
    public function likeActivities(): BelongsToMany
    {
        return $this->belongsToMany(Activity::class, UserActivityCollectionPivot::class)->wherePivotNull('deleted_at');
    }

    /**
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
     */
    public function submitActivities(): BelongsToMany
    {
        return $this->belongsToMany(Activity::class, ActivitySubmitWork::class)->wherePivotNull('deleted_at');
    }

    public function authInfo()
    {
        return $this->hasOne(UserCertify::class, 'user_id', 'id');
    }

    /**
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
     */
    public function projects(): BelongsToMany
    {
        return $this->belongsToMany(Project::class, UserProjectPivot::class, 'user_id', 'project_id')
            ->withTimestamps();
    }

    /**
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
     */
    public function opus(): BelongsToMany
    {
        return $this->belongsToMany(Activity::class, ActivityUser::class)->wherePivot('status', 1);
    }

    public function action()
    {
        return $this->hasMany(UserAction::class, 'user_id', 'id');
    }

    public function visitorProject()
    {
        return $this->hasMany(UserProjectPivot::class, 'user_id', 'id');
    }
}