Many fixes

This commit is contained in:
root
2026-01-16 21:58:12 +03:00
parent b810a17649
commit 77f76c8c28
45 changed files with 3392 additions and 1243 deletions
+151
View File
@@ -0,0 +1,151 @@
<?php
namespace App\Config;
use CodeIgniter\Config\BaseConfig;
/**
* Конфигурация бизнес-модулей системы
*
* Определяет доступные модули, их параметры и цены.
*/
class BusinessModules extends BaseConfig
{
/**
* Список доступных модулей
*
* @var array<string, array{
* name: string,
* description: string,
* price_monthly: int,
* price_yearly: int,
* trial_days: int,
* features: string[]
* }>
*/
public array $modules = [
'base' => [
'name' => 'Базовый модуль',
'description' => 'Основные функции управления клиентами',
'price_monthly' => 0,
'price_yearly' => 0,
'trial_days' => 0,
'features' => [
'Управление клиентами',
'Базовая история взаимодействий',
],
],
'crm' => [
'name' => 'CRM',
'description' => 'Полноценная CRM-система с воронками продаж',
'price_monthly' => 990,
'price_yearly' => 9900,
'trial_days' => 14,
'features' => [
'Воронки продаж',
'Управление контактами',
'Этапы сделок',
'Drag-n-drop сортировка',
'Автоматизация',
],
],
'booking' => [
'name' => 'Бронирования',
'description' => 'Управление бронированиями и расписанием',
'price_monthly' => 1490,
'price_yearly' => 14900,
'trial_days' => 14,
'features' => [
'Календарь бронирований',
'Управление ресурсами',
'Уведомления клиентам',
],
],
'tasks' => [
'name' => 'Задачи',
'description' => 'Управление задачами и проектами',
'price_monthly' => 790,
'price_yearly' => 7900,
'trial_days' => 14,
'features' => [
'Доски задач',
'Назначение ответственных',
'Сроки и дедлайны',
],
],
'proof' => [
'name' => 'Proof',
'description' => 'Система согласования документов',
'price_monthly' => 590,
'price_yearly' => 5900,
'trial_days' => 14,
'features' => [
'Согласование документов',
'Комментарии и версии',
'Утверждение',
],
],
];
/**
* Проверка существования модуля
*
* @param string $moduleCode
* @return bool
*/
public function exists(string $moduleCode): bool
{
return isset($this->modules[$moduleCode]);
}
/**
* Получение информации о модуле (без переопределений)
*
* @param string $moduleCode
* @return array|null
*/
public function getModule(string $moduleCode): ?array
{
return $this->modules[$moduleCode] ?? null;
}
/**
* Получение цены модуля
*
* @param string $moduleCode
* @param string $period 'monthly' или 'yearly'
* @return int
*/
public function getPrice(string $moduleCode, string $period = 'monthly'): int
{
$module = $this->getModule($moduleCode);
if (!$module) {
return 0;
}
return $period === 'yearly' ? $module['price_yearly'] : $module['price_monthly'];
}
/**
* Получение списка всех кодов модулей
*
* @return array
*/
public function getAllModuleCodes(): array
{
return array_keys($this->modules);
}
/**
* Получение списка платных модулей (с возможностью триала)
*
* @return array<string, array>
*/
public function getPaidModules(): array
{
return array_filter($this->modules, function ($module) {
return $module['trial_days'] > 0;
});
}
}
+1
View File
@@ -37,6 +37,7 @@ class Filters extends BaseFilters
'org' => \App\Filters\OrganizationFilter::class,
'role' => \App\Filters\RoleFilter::class,
'auth' => \App\Filters\AuthFilter::class,
'subscription' => \App\Filters\ModuleSubscriptionFilter::class,
];
/**
+19 -7
View File
@@ -88,26 +88,38 @@ $routes->group('', ['filter' => 'auth'], static function ($routes) {
require_once APPPATH . 'Modules/Clients/Config/Routes.php';
require_once APPPATH . 'Modules/CRM/Config/Routes.php';
});
# =============================================================================
# СУПЕРАДМИН ПАНЕЛЬ (требуется system_role: superadmin)
# =============================================================================
$routes->group('superadmin', ['filter' => 'role:system:superadmin'], static function ($routes) {
$routes->get('/', 'Superadmin::index');
$routes->get('plans', 'Superadmin::plans');
$routes->get('plans/create', 'Superadmin::createPlan');
$routes->post('plans/store', 'Superadmin::storePlan');
$routes->get('plans/edit/(:num)', 'Superadmin::editPlan/$1');
$routes->post('plans/update/(:num)', 'Superadmin::updatePlan/$1');
$routes->get('plans/delete/(:num)', 'Superadmin::deletePlan/$1');
# Управление модулями
$routes->get('modules', 'Superadmin::modules');
$routes->post('modules/update', 'Superadmin::updateModule');
# Управление подписками
$routes->get('subscriptions', 'Superadmin::subscriptions');
$routes->get('subscriptions/table', 'Superadmin::subscriptionsTable');
$routes->get('subscriptions/create', 'Superadmin::createSubscription');
$routes->post('subscriptions/store', 'Superadmin::storeSubscription');
$routes->get('subscriptions/delete/(:num)', 'Superadmin::deleteSubscription/$1');
# Поиск организаций
$routes->get('organizations/search', 'Superadmin::searchOrganizations');
# Управление организациями
$routes->get('organizations', 'Superadmin::organizations');
$routes->get('organizations/table', 'Superadmin::organizationsTable');
$routes->get('organizations/view/(:num)', 'Superadmin::viewOrganization/$1');
$routes->post('organizations/set-plan/(:num)', 'Superadmin::setOrganizationPlan/$1');
$routes->post('organizations/(:num)/add-subscription', 'Superadmin::addOrganizationSubscription/$1');
$routes->get('organizations/(:num)/remove-subscription/(:num)', 'Superadmin::removeOrganizationSubscription/$1/$2');
$routes->get('organizations/block/(:num)', 'Superadmin::blockOrganization/$1');
$routes->get('organizations/unblock/(:num)', 'Superadmin::unblockOrganization/$1');
$routes->get('organizations/delete/(:num)', 'Superadmin::deleteOrganization/$1');
# Управление пользователями
$routes->get('users', 'Superadmin::users');
$routes->get('users/table', 'Superadmin::usersTable');
$routes->post('users/update-role/(:num)', 'Superadmin::updateUserRole/$1');
+1 -1
View File
@@ -103,7 +103,7 @@ class Services extends BaseService
return static::getSharedInstance('moduleSubscription');
}
return new ModuleSubscriptionService();
return new \App\Services\ModuleSubscriptionService();
}
/**