add superadmin dashboard. subscriptions

This commit is contained in:
root
2026-01-13 20:03:16 +03:00
parent 3c24c250e5
commit edb4df7e37
36 changed files with 3329 additions and 100 deletions
+10 -1
View File
@@ -11,7 +11,16 @@ class OrganizationModel extends Model
protected $useAutoIncrement = true;
protected $returnType = 'array';
protected $useSoftDeletes = true; // Включаем мягкое удаление (deleted_at)
protected $allowedFields = ['owner_id', 'name', 'type', 'logo', 'requisites', 'trial_ends_at', 'settings'];
protected $allowedFields = [
'owner_id',
'name',
'type',
'logo',
'requisites',
'trial_ends_at',
'settings',
'status',
];
protected $useTimestamps = true;
protected $dateFormat = 'datetime';
+79
View File
@@ -0,0 +1,79 @@
<?php
namespace App\Models;
use CodeIgniter\Model;
/**
* PlanModel - Модель тарифов
*/
class PlanModel extends Model
{
protected $table = 'plans';
protected $primaryKey = 'id';
protected $useAutoIncrement = true;
protected $returnType = 'array';
protected $useSoftDeletes = false;
protected $allowedFields = [
'name',
'description',
'price',
'currency',
'billing_period',
'max_users',
'max_clients',
'max_storage',
'features',
'is_active',
'is_default',
];
protected $useTimestamps = true;
protected $createdField = 'created_at';
protected $updatedField = 'updated_at';
protected $validationRules = [
'name' => 'required|min_length[2]|max_length[100]',
'price' => 'required|numeric|greater_than_equal[0]',
'max_users' => 'required|integer|greater_than[0]',
'max_clients' => 'required|integer|greater_than[0]',
'max_storage' => 'required|integer|greater_than[0]',
];
protected $validationMessages = [
'name' => [
'required' => 'Название тарифа обязательно',
'min_length' => 'Название должно быть минимум 2 символа',
],
'price' => [
'required' => 'Цена обязательна',
'numeric' => 'Цена должна быть числом',
],
];
/**
* Получение активных тарифов
*/
public function getActivePlans()
{
return $this->where('is_active', 1)->findAll();
}
/**
* Получение тарифа по умолчанию
*/
public function getDefaultPlan()
{
return $this->where('is_default', 1)->where('is_active', 1)->first();
}
/**
* Проверка, является ли тариф системным
*/
public function isSystemPlan($planId)
{
$plan = $this->find($planId);
return $plan !== null;
}
}
+78 -1
View File
@@ -24,7 +24,13 @@ class UserModel extends Model
// Поля для верификации email
'verification_token',
'email_verified',
'verified_at'
'verified_at',
// Поля для восстановления пароля
'reset_token',
'reset_expires_at',
//системная роль
'system_role',
'status',
];
// Dates
@@ -44,4 +50,75 @@ class UserModel extends Model
}
return $data;
}
/**
* Генерация токена для сброса пароля
*
* @param int $userId ID пользователя
* @param int $expiresInHours Срок действия токена в часах (по умолчанию 24 часа)
* @return string Сгенерированный токен
*/
public function generateResetToken(int $userId, int $expiresInHours = 24): string
{
$token = bin2hex(random_bytes(32));
$expiresAt = date('Y-m-d H:i:s', strtotime("+{$expiresInHours} hours"));
$this->update($userId, [
'reset_token' => $token,
'reset_expires_at' => $expiresAt,
]);
return $token;
}
/**
* Проверка токена сброса пароля
*
* @param string $token Токен сброса
* @return array|null Данные пользователя или null если токен недействителен
*/
public function verifyResetToken(string $token): ?array
{
$user = $this->where('reset_token', $token)->first();
if (!$user) {
return null;
}
// Проверяем срок действия токена
if (empty($user['reset_expires_at'])) {
return null;
}
if (strtotime($user['reset_expires_at']) < time()) {
return null;
}
return $user;
}
/**
* Очистка токена сброса пароля
*
* @param int $userId ID пользователя
* @return bool
*/
public function clearResetToken(int $userId): bool
{
return $this->update($userId, [
'reset_token' => null,
'reset_expires_at' => null,
]);
}
/**
* Поиск пользователя по email
*
* @param string $email Email адрес
* @return array|null
*/
public function findByEmail(string $email): ?array
{
return $this->where('email', $email)->first();
}
}