dashboard for org
This commit is contained in:
@@ -3,14 +3,148 @@
|
||||
namespace App\Models;
|
||||
|
||||
use CodeIgniter\Model;
|
||||
use App\Models\Traits\TenantScopedModel;
|
||||
|
||||
class OrganizationUserModel extends Model
|
||||
{
|
||||
use TenantScopedModel;
|
||||
|
||||
protected $table = 'organization_users';
|
||||
protected $primaryKey = 'id';
|
||||
protected $useAutoIncrement = true;
|
||||
protected $returnType = 'array';
|
||||
protected $allowedFields = ['organization_id', 'user_id', 'role', 'status', 'joined_at'];
|
||||
|
||||
protected $useTimestamps = false; // У нас есть только created_at, можно настроить вручную
|
||||
}
|
||||
protected $allowedFields = [
|
||||
'organization_id',
|
||||
'user_id',
|
||||
'role',
|
||||
'status',
|
||||
'invite_token',
|
||||
'invited_by',
|
||||
'invited_at',
|
||||
'joined_at',
|
||||
];
|
||||
|
||||
protected $useTimestamps = false;
|
||||
|
||||
// Константы статусов
|
||||
public const STATUS_ACTIVE = 'active';
|
||||
public const STATUS_PENDING = 'pending';
|
||||
public const STATUS_BLOCKED = 'blocked';
|
||||
|
||||
// Роли
|
||||
public const ROLE_OWNER = 'owner';
|
||||
public const ROLE_ADMIN = 'admin';
|
||||
public const ROLE_MANAGER = 'manager';
|
||||
public const ROLE_GUEST = 'guest';
|
||||
|
||||
/**
|
||||
* Поиск приглашения по токену
|
||||
*/
|
||||
public function findByInviteToken(string $token): ?array
|
||||
{
|
||||
return $this->where('invite_token', $token)
|
||||
->where('status', self::STATUS_PENDING)
|
||||
->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* Получение списка пользователей организации с данными из users
|
||||
*/
|
||||
public function getOrganizationUsers(int $organizationId): array
|
||||
{
|
||||
// Создаём новый чистый запрос с нуля
|
||||
$db = $this->db();
|
||||
$builder = $db->newQuery();
|
||||
|
||||
return $builder->select('ou.*, u.name as user_name, u.email as user_email, u.avatar as user_avatar')
|
||||
->from('organization_users ou')
|
||||
->join('users u', 'u.id = ou.user_id', 'left')
|
||||
->where('ou.organization_id', $organizationId)
|
||||
->orderBy('ou.joined_at', 'DESC')
|
||||
->get()
|
||||
->getResultArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверка, существует ли активное приглашение для пользователя
|
||||
*/
|
||||
public function hasPendingInvite(int $organizationId, int $userId): bool
|
||||
{
|
||||
return $this->where('organization_id', $organizationId)
|
||||
->where('user_id', $userId)
|
||||
->where('status', self::STATUS_PENDING)
|
||||
->countAllResults() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Получение всех приглашений организации
|
||||
*/
|
||||
public function getPendingInvites(int $organizationId): array
|
||||
{
|
||||
return $this->where('organization_id', $organizationId)
|
||||
->where('status', self::STATUS_PENDING)
|
||||
->orderBy('invited_at', 'DESC')
|
||||
->findAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Создание приглашения
|
||||
*/
|
||||
public function createInvitation(array $data): int
|
||||
{
|
||||
$data['invited_at'] = date('Y-m-d H:i:s');
|
||||
return $this->insert($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Принятие приглашения
|
||||
*/
|
||||
public function acceptInvitation(int $id, int $userId): bool
|
||||
{
|
||||
return $this->update($id, [
|
||||
'status' => self::STATUS_ACTIVE,
|
||||
'invite_token' => null,
|
||||
'joined_at' => date('Y-m-d H:i:s'),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Отклонение приглашения
|
||||
*/
|
||||
public function declineInvitation(int $id): bool
|
||||
{
|
||||
return $this->delete($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Отзыв приглашения
|
||||
*/
|
||||
public function cancelInvitation(int $id): bool
|
||||
{
|
||||
return $this->delete($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Изменение роли пользователя
|
||||
*/
|
||||
public function updateRole(int $id, string $role): bool
|
||||
{
|
||||
return $this->update($id, ['role' => $role]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Блокировка пользователя
|
||||
*/
|
||||
public function blockUser(int $id): bool
|
||||
{
|
||||
return $this->update($id, ['status' => self::STATUS_BLOCKED]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Разблокировка пользователя
|
||||
*/
|
||||
public function unblockUser(int $id): bool
|
||||
{
|
||||
return $this->update($id, ['status' => self::STATUS_ACTIVE]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Traits;
|
||||
|
||||
use CodeIgniter\Model;
|
||||
|
||||
/**
|
||||
* Trait TenantScopedModel
|
||||
*
|
||||
* Обеспечивает автоматическую фильтрацию данных по активной организации.
|
||||
* Использует organization_id из сессии пользователя.
|
||||
*/
|
||||
trait TenantScopedModel
|
||||
{
|
||||
/**
|
||||
* Фильтрует запрос по текущей активной организации из сессии.
|
||||
*
|
||||
* Применение:
|
||||
* $clients = $this->clientModel->forCurrentOrg()->findAll();
|
||||
* $client = $this->clientModel->forCurrentOrg()->find($id);
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function forCurrentOrg()
|
||||
{
|
||||
$session = session();
|
||||
$orgId = $session->get('active_org_id');
|
||||
|
||||
// Если организации в сессии нет, предотвращаем утечку данных
|
||||
// Возвращаем условие, которое всегда ложно
|
||||
if (empty($orgId)) {
|
||||
return $this->where('1=0');
|
||||
}
|
||||
|
||||
// Имя поля с organization_id (можно переопределить в модели)
|
||||
$field = $this->table . '.organization_id';
|
||||
|
||||
return $this->where($field, $orgId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверяет, что запись принадлежит текущей организации.
|
||||
*
|
||||
* @param int $id ID записи
|
||||
* @return bool
|
||||
*/
|
||||
public function belongsToCurrentOrg(int $id): bool
|
||||
{
|
||||
return $this->forCurrentOrg()->find($id) !== null;
|
||||
}
|
||||
}
|
||||
@@ -3,9 +3,12 @@
|
||||
namespace App\Models;
|
||||
|
||||
use CodeIgniter\Model;
|
||||
use App\Models\Traits\TenantScopedModel;
|
||||
|
||||
class UserModel extends Model
|
||||
{
|
||||
use TenantScopedModel;
|
||||
|
||||
protected $table = 'users';
|
||||
protected $primaryKey = 'id';
|
||||
protected $useAutoIncrement = true;
|
||||
|
||||
Reference in New Issue
Block a user