fix CRM contacts
This commit is contained in:
parent
77f76c8c28
commit
308c684aa2
|
|
@ -51,9 +51,14 @@ class TwigGlobalsExtension extends AbstractExtension
|
|||
// Module subscription functions
|
||||
new TwigFunction('is_module_active', [$this, 'isModuleActive'], ['is_safe' => ['html']]),
|
||||
new TwigFunction('is_module_available', [$this, 'isModuleAvailable'], ['is_safe' => ['html']]),
|
||||
new TwigFunction('csrf_meta', [$this, 'csrf_meta'], ['is_safe' => ['html']]),
|
||||
];
|
||||
}
|
||||
|
||||
public function csrf_meta()
|
||||
{
|
||||
return csrf_meta();
|
||||
}
|
||||
// ========================================
|
||||
// Access Functions для Twig
|
||||
// ========================================
|
||||
|
|
|
|||
|
|
@ -249,7 +249,10 @@ class ContactsController extends BaseController
|
|||
];
|
||||
}, $contacts);
|
||||
|
||||
return $this->response->setJSON([
|
||||
return $this->response
|
||||
->setHeader('X-CSRF-TOKEN', csrf_hash())
|
||||
->setHeader('X-CSRF-HASH', csrf_token())
|
||||
->setJSON([
|
||||
'success' => true,
|
||||
'items' => $items,
|
||||
'total' => count($items),
|
||||
|
|
@ -263,7 +266,12 @@ class ContactsController extends BaseController
|
|||
public function ajaxStore()
|
||||
{
|
||||
$organizationId = $this->requireActiveOrg();
|
||||
$customerId = $this->request->getPost('customer_id');
|
||||
|
||||
// Поддержка JSON и form-urlencoded данных
|
||||
$jsonData = $this->request->getJSON(true);
|
||||
$rawInput = $jsonData ?? $this->request->getPost();
|
||||
|
||||
$customerId = $rawInput['customer_id'] ?? null;
|
||||
|
||||
// Проверяем клиента если указан
|
||||
if ($customerId) {
|
||||
|
|
@ -279,10 +287,10 @@ class ContactsController extends BaseController
|
|||
$data = [
|
||||
'organization_id' => $organizationId,
|
||||
'customer_id' => $customerId ?: null,
|
||||
'name' => $this->request->getPost('name'),
|
||||
'email' => $this->request->getPost('email') ?: null,
|
||||
'phone' => $this->request->getPost('phone') ?: null,
|
||||
'position' => $this->request->getPost('position') ?: null,
|
||||
'name' => $rawInput['name'] ?? '',
|
||||
'email' => $rawInput['email'] ?? null,
|
||||
'phone' => $rawInput['phone'] ?? null,
|
||||
'position' => $rawInput['position'] ?? null,
|
||||
];
|
||||
|
||||
// Валидация
|
||||
|
|
@ -304,7 +312,10 @@ class ContactsController extends BaseController
|
|||
])->setStatusCode(422);
|
||||
}
|
||||
|
||||
return $this->response->setJSON([
|
||||
return $this->response
|
||||
->setHeader('X-CSRF-TOKEN', csrf_hash())
|
||||
->setHeader('X-CSRF-HASH', csrf_token())
|
||||
->setJSON([
|
||||
'success' => true,
|
||||
'message' => 'Контакт создан',
|
||||
'item' => [
|
||||
|
|
@ -334,11 +345,15 @@ class ContactsController extends BaseController
|
|||
])->setStatusCode(404);
|
||||
}
|
||||
|
||||
// Поддержка JSON и form-urlencoded данных
|
||||
$jsonData = $this->request->getJSON(true);
|
||||
$rawInput = $jsonData ?? $this->request->getPost();
|
||||
|
||||
$data = [
|
||||
'name' => $this->request->getPost('name'),
|
||||
'email' => $this->request->getPost('email') ?: null,
|
||||
'phone' => $this->request->getPost('phone') ?: null,
|
||||
'position' => $this->request->getPost('position') ?: null,
|
||||
'name' => $rawInput['name'] ?? '',
|
||||
'email' => $rawInput['email'] ?? null,
|
||||
'phone' => $rawInput['phone'] ?? null,
|
||||
'position' => $rawInput['position'] ?? null,
|
||||
];
|
||||
|
||||
// Валидация
|
||||
|
|
@ -360,7 +375,10 @@ class ContactsController extends BaseController
|
|||
])->setStatusCode(422);
|
||||
}
|
||||
|
||||
return $this->response->setJSON([
|
||||
return $this->response
|
||||
->setHeader('X-CSRF-TOKEN', csrf_hash())
|
||||
->setHeader('X-CSRF-HASH', csrf_token())
|
||||
->setJSON([
|
||||
'success' => true,
|
||||
'message' => 'Контакт обновлён',
|
||||
'item' => [
|
||||
|
|
@ -392,7 +410,10 @@ class ContactsController extends BaseController
|
|||
|
||||
$this->contactModel->delete($id);
|
||||
|
||||
return $this->response->setJSON([
|
||||
return $this->response
|
||||
->setHeader('X-CSRF-TOKEN', csrf_hash())
|
||||
->setHeader('X-CSRF-HASH', csrf_token())
|
||||
->setJSON([
|
||||
'success' => true,
|
||||
'message' => 'Контакт удалён',
|
||||
]);
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
{{ csrf_meta() }}
|
||||
<title>{% block title %}Бизнес.Точка{% endblock %}</title>
|
||||
|
||||
<!-- Bootstrap CSS -->
|
||||
|
|
@ -17,7 +18,7 @@
|
|||
<link href="{{ base_url('assets/css/base.css') }}" rel="stylesheet">
|
||||
{% block styles %}{% endblock %}
|
||||
</head>
|
||||
<body class="bg-light">
|
||||
<body class="bg-light" data-base-url="{{ base_url('/') }}">
|
||||
|
||||
<div class="d-flex" id="wrapper">
|
||||
<!-- SIDEBAR -->
|
||||
|
|
|
|||
587
dump.sql
587
dump.sql
|
|
@ -1,587 +0,0 @@
|
|||
/*M!999999\- enable the sandbox mode */
|
||||
-- MariaDB dump 10.19-11.8.3-MariaDB, for debian-linux-gnu (x86_64)
|
||||
--
|
||||
-- Host: localhost Database: bp_mirv_db
|
||||
-- ------------------------------------------------------
|
||||
-- Server version 11.8.3-MariaDB-0+deb13u1 from Debian
|
||||
|
||||
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
|
||||
/*!40101 SET NAMES utf8mb4 */;
|
||||
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
|
||||
/*!40103 SET TIME_ZONE='+00:00' */;
|
||||
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
|
||||
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
||||
/*M!100616 SET @OLD_NOTE_VERBOSITY=@@NOTE_VERBOSITY, NOTE_VERBOSITY=0 */;
|
||||
|
||||
--
|
||||
-- Table structure for table `ci_sessions`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `ci_sessions`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `ci_sessions` (
|
||||
`id` varchar(128) NOT NULL,
|
||||
`ip_address` varchar(45) NOT NULL,
|
||||
`timestamp` int(10) unsigned NOT NULL DEFAULT 0,
|
||||
`data` blob DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `timestamp` (`timestamp`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Dumping data for table `ci_sessions`
|
||||
--
|
||||
|
||||
LOCK TABLES `ci_sessions` WRITE;
|
||||
/*!40000 ALTER TABLE `ci_sessions` DISABLE KEYS */;
|
||||
set autocommit=0;
|
||||
/*!40000 ALTER TABLE `ci_sessions` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
commit;
|
||||
|
||||
--
|
||||
-- Table structure for table `contacts`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `contacts`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `contacts` (
|
||||
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`organization_id` int(11) unsigned NOT NULL,
|
||||
`customer_id` int(11) unsigned NOT NULL COMMENT 'Ссылка на клиента (компанию)',
|
||||
`name` varchar(255) NOT NULL COMMENT 'Имя контакта',
|
||||
`email` varchar(255) DEFAULT NULL,
|
||||
`phone` varchar(50) DEFAULT NULL,
|
||||
`position` varchar(255) DEFAULT NULL COMMENT 'Должность',
|
||||
`is_primary` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Основной контакт',
|
||||
`notes` text DEFAULT NULL,
|
||||
`created_at` datetime DEFAULT NULL,
|
||||
`updated_at` datetime DEFAULT NULL,
|
||||
`deleted_at` datetime DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `organization_id` (`organization_id`),
|
||||
KEY `customer_id` (`customer_id`),
|
||||
CONSTRAINT `contacts_customer_id_foreign` FOREIGN KEY (`customer_id`) REFERENCES `organizations_clients` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
CONSTRAINT `contacts_organization_id_foreign` FOREIGN KEY (`organization_id`) REFERENCES `organizations` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Dumping data for table `contacts`
|
||||
--
|
||||
|
||||
LOCK TABLES `contacts` WRITE;
|
||||
/*!40000 ALTER TABLE `contacts` DISABLE KEYS */;
|
||||
set autocommit=0;
|
||||
INSERT INTO `contacts` VALUES
|
||||
(1,12,1,'Петров',NULL,'+79999999955','Вахтер',0,NULL,'2026-01-15 02:50:50','2026-01-15 02:50:50',NULL);
|
||||
/*!40000 ALTER TABLE `contacts` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
commit;
|
||||
|
||||
--
|
||||
-- Table structure for table `deal_history`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `deal_history`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `deal_history` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`deal_id` bigint(20) unsigned NOT NULL,
|
||||
`user_id` int(11) unsigned NOT NULL,
|
||||
`action` varchar(50) NOT NULL,
|
||||
`field_name` varchar(50) DEFAULT NULL,
|
||||
`old_value` text DEFAULT NULL,
|
||||
`new_value` text DEFAULT NULL,
|
||||
`created_at` datetime DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `deal_id` (`deal_id`),
|
||||
KEY `user_id` (`user_id`),
|
||||
CONSTRAINT `deal_history_deal_id_foreign` FOREIGN KEY (`deal_id`) REFERENCES `deals` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
CONSTRAINT `deal_history_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Dumping data for table `deal_history`
|
||||
--
|
||||
|
||||
LOCK TABLES `deal_history` WRITE;
|
||||
/*!40000 ALTER TABLE `deal_history` DISABLE KEYS */;
|
||||
set autocommit=0;
|
||||
/*!40000 ALTER TABLE `deal_history` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
commit;
|
||||
|
||||
--
|
||||
-- Table structure for table `deal_stages`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `deal_stages`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `deal_stages` (
|
||||
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`organization_id` int(11) unsigned NOT NULL,
|
||||
`name` varchar(255) NOT NULL,
|
||||
`color` varchar(7) NOT NULL DEFAULT '#6B7280',
|
||||
`order_index` int(11) NOT NULL DEFAULT 0,
|
||||
`type` enum('progress','won','lost') NOT NULL DEFAULT 'progress',
|
||||
`probability` int(3) unsigned NOT NULL DEFAULT 0,
|
||||
`created_at` datetime DEFAULT NULL,
|
||||
`updated_at` datetime DEFAULT NULL,
|
||||
`deleted_at` datetime DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `organization_id` (`organization_id`),
|
||||
CONSTRAINT `deal_stages_organization_id_foreign` FOREIGN KEY (`organization_id`) REFERENCES `organizations` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Dumping data for table `deal_stages`
|
||||
--
|
||||
|
||||
LOCK TABLES `deal_stages` WRITE;
|
||||
/*!40000 ALTER TABLE `deal_stages` DISABLE KEYS */;
|
||||
set autocommit=0;
|
||||
INSERT INTO `deal_stages` VALUES
|
||||
(1,12,'Первый контакт','#6b7280',1,'progress',1,NULL,NULL,NULL),
|
||||
(2,12,'Второй контакт','#9a9996',2,'progress',5,NULL,NULL,NULL),
|
||||
(3,12,'Переговоры по договору','#c061cb',3,'progress',10,NULL,NULL,NULL);
|
||||
/*!40000 ALTER TABLE `deal_stages` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
commit;
|
||||
|
||||
--
|
||||
-- Table structure for table `deals`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `deals`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `deals` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`organization_id` int(11) unsigned NOT NULL,
|
||||
`contact_id` int(11) unsigned DEFAULT NULL,
|
||||
`company_id` int(11) unsigned DEFAULT NULL,
|
||||
`title` varchar(255) NOT NULL,
|
||||
`description` text DEFAULT NULL,
|
||||
`amount` decimal(15,2) NOT NULL DEFAULT 0.00,
|
||||
`currency` char(3) NOT NULL DEFAULT 'RUB',
|
||||
`stage_id` int(11) unsigned NOT NULL,
|
||||
`assigned_user_id` int(11) unsigned DEFAULT NULL,
|
||||
`expected_close_date` date DEFAULT NULL,
|
||||
`created_by` int(11) unsigned NOT NULL,
|
||||
`created_at` datetime DEFAULT NULL,
|
||||
`updated_at` datetime DEFAULT NULL,
|
||||
`deleted_at` datetime DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `organization_id` (`organization_id`),
|
||||
KEY `stage_id` (`stage_id`),
|
||||
KEY `assigned_user_id` (`assigned_user_id`),
|
||||
CONSTRAINT `deals_assigned_user_id_foreign` FOREIGN KEY (`assigned_user_id`) REFERENCES `users` (`id`) ON DELETE SET NULL ON UPDATE SET NULL,
|
||||
CONSTRAINT `deals_organization_id_foreign` FOREIGN KEY (`organization_id`) REFERENCES `organizations` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
CONSTRAINT `deals_stage_id_foreign` FOREIGN KEY (`stage_id`) REFERENCES `deal_stages` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Dumping data for table `deals`
|
||||
--
|
||||
|
||||
LOCK TABLES `deals` WRITE;
|
||||
/*!40000 ALTER TABLE `deals` DISABLE KEYS */;
|
||||
set autocommit=0;
|
||||
INSERT INTO `deals` VALUES
|
||||
(1,12,1,1,'Раскрутка сайта','',1000.00,'RUB',3,NULL,NULL,11,'2026-01-15 03:07:32','2026-01-15 03:07:32',NULL),
|
||||
(2,12,NULL,1,'Пупупу','',15000.00,'RUB',1,11,'2026-02-28',11,'2026-01-15 03:45:08','2026-01-15 07:43:07',NULL);
|
||||
/*!40000 ALTER TABLE `deals` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
commit;
|
||||
|
||||
--
|
||||
-- Table structure for table `migrations`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `migrations`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `migrations` (
|
||||
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`version` varchar(255) NOT NULL,
|
||||
`class` varchar(255) NOT NULL,
|
||||
`group` varchar(255) NOT NULL,
|
||||
`namespace` varchar(255) NOT NULL,
|
||||
`time` int(11) NOT NULL,
|
||||
`batch` int(11) unsigned NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=24 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Dumping data for table `migrations`
|
||||
--
|
||||
|
||||
LOCK TABLES `migrations` WRITE;
|
||||
/*!40000 ALTER TABLE `migrations` DISABLE KEYS */;
|
||||
set autocommit=0;
|
||||
INSERT INTO `migrations` VALUES
|
||||
(1,'2026-01-07-053357','App\\Database\\Migrations\\CreateUsersTable','default','App',1767769689,1),
|
||||
(2,'2026-01-07-053401','App\\Database\\Migrations\\CreateOrganizationsTable','default','App',1767769689,1),
|
||||
(3,'2026-01-07-053407','App\\Database\\Migrations\\CreateOrganizationUsersTable','default','App',1767769689,1),
|
||||
(4,'2026-01-07-053412','App\\Database\\Migrations\\CreateOrganizationSubscriptionsTable','default','App',1767769689,1),
|
||||
(5,'2026-01-07-053413','App\\Database\\Migrations\\CreateOrganizationSubscriptionsTable','default','App',1767769974,2),
|
||||
(6,'2026-01-08-000001','App\\Database\\Migrations\\AddEmailVerificationToUsers','default','App',1767870811,3),
|
||||
(7,'2026-01-08-200001','App\\Database\\Migrations\\CreateOrganizationsClientsTable','default','App',1767878430,4),
|
||||
(8,'2026-01-12-000001','App\\Database\\Migrations\\AddInviteFieldsToOrganizationUsers','default','App',1768267451,5),
|
||||
(9,'2026-01-13-000001','App\\Database\\Migrations\\CreateRememberTokensTable','default','App',1768267451,5),
|
||||
(10,'2026-01-13-163701','App\\Database\\Migrations\\AddTrialEndsAtToSubscriptions','default','App',1768295204,6),
|
||||
(11,'2026-01-13-200001','App\\Database\\Migrations\\CreateCiSessionsTable','default','App',1768313545,7),
|
||||
(12,'2026-01-13-200002','App\\Database\\Migrations\\AddPasswordResetFieldsToUsers','default','App',1768313545,7),
|
||||
(13,'2026-01-14-000001','App\\Database\\Migrations\\AddSystemRoleToUsers','default','App',1768317531,8),
|
||||
(14,'2026-01-15-000001','App\\Database\\Migrations\\AddPlansTable','default','App',1768317531,8),
|
||||
(15,'2026-01-15-000002','App\\Database\\Migrations\\CreateOrganizationPlanSubscriptionsTable','default','App',1768320790,9),
|
||||
(16,'2026-01-15-000003','App\\Database\\Migrations\\AddTokenExpiresToUsers','default','App',1768372597,10),
|
||||
(17,'2026-01-15-000004','App\\Database\\Migrations\\AddInviteExpiresToOrganizationUsers','default','App',1768372597,10),
|
||||
(18,'2026-01-15-000005','App\\Database\\Migrations\\AddStatusToOrganizations','default','App',1768376017,11),
|
||||
(19,'2026-01-15-000006','App\\Database\\Migrations\\CreateDealsTables','default','App',1768439721,12),
|
||||
(21,'2026-01-15-000007','App\\Database\\Migrations\\CreateContactsTable','default','App',1768440786,13),
|
||||
(22,'2026-01-16-210001','App\\Database\\Migrations\\DropOrganizationPlanSubscriptionsTable','default','App',1768572350,14),
|
||||
(23,'2026-01-16-220001','App\\Database\\Migrations\\CreateModuleSettingsTable','default','App',1768573190,15);
|
||||
/*!40000 ALTER TABLE `migrations` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
commit;
|
||||
|
||||
--
|
||||
-- Table structure for table `module_settings`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `module_settings`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `module_settings` (
|
||||
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`module_code` varchar(50) NOT NULL,
|
||||
`name` varchar(100) NOT NULL,
|
||||
`description` varchar(255) NOT NULL,
|
||||
`price_monthly` int(11) NOT NULL DEFAULT 0,
|
||||
`price_yearly` int(11) NOT NULL DEFAULT 0,
|
||||
`trial_days` int(11) NOT NULL DEFAULT 0,
|
||||
`is_active` tinyint(1) NOT NULL DEFAULT 1,
|
||||
`created_at` datetime DEFAULT NULL,
|
||||
`updated_at` datetime DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `module_code` (`module_code`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Dumping data for table `module_settings`
|
||||
--
|
||||
|
||||
LOCK TABLES `module_settings` WRITE;
|
||||
/*!40000 ALTER TABLE `module_settings` DISABLE KEYS */;
|
||||
set autocommit=0;
|
||||
/*!40000 ALTER TABLE `module_settings` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
commit;
|
||||
|
||||
--
|
||||
-- Table structure for table `organization_subscriptions`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `organization_subscriptions`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `organization_subscriptions` (
|
||||
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`organization_id` int(11) unsigned NOT NULL,
|
||||
`module_code` varchar(50) NOT NULL,
|
||||
`status` enum('trial','active','expired','cancelled') NOT NULL DEFAULT 'trial',
|
||||
`trial_ends_at` datetime DEFAULT NULL COMMENT 'Дата окончания триального периода',
|
||||
`expires_at` datetime DEFAULT NULL,
|
||||
`created_at` datetime DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `organization_id_module_code` (`organization_id`,`module_code`),
|
||||
CONSTRAINT `organization_subscriptions_organization_id_foreign` FOREIGN KEY (`organization_id`) REFERENCES `organizations` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Dumping data for table `organization_subscriptions`
|
||||
--
|
||||
|
||||
LOCK TABLES `organization_subscriptions` WRITE;
|
||||
/*!40000 ALTER TABLE `organization_subscriptions` DISABLE KEYS */;
|
||||
set autocommit=0;
|
||||
/*!40000 ALTER TABLE `organization_subscriptions` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
commit;
|
||||
|
||||
--
|
||||
-- Table structure for table `organization_users`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `organization_users`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `organization_users` (
|
||||
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`organization_id` int(11) unsigned NOT NULL,
|
||||
`user_id` int(11) unsigned NOT NULL,
|
||||
`role` enum('owner','admin','manager','guest') NOT NULL DEFAULT 'manager',
|
||||
`invite_token` varchar(64) DEFAULT NULL,
|
||||
`invited_by` int(10) unsigned DEFAULT NULL,
|
||||
`invited_at` datetime DEFAULT NULL,
|
||||
`invite_expires_at` datetime DEFAULT NULL,
|
||||
`status` enum('active','pending','invited','blocked') NOT NULL DEFAULT 'pending',
|
||||
`joined_at` datetime DEFAULT NULL,
|
||||
`created_at` datetime DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `organization_id_user_id` (`organization_id`,`user_id`),
|
||||
KEY `organization_users_user_id_foreign` (`user_id`),
|
||||
KEY `idx_org_users_token` (`invite_token`),
|
||||
CONSTRAINT `organization_users_organization_id_foreign` FOREIGN KEY (`organization_id`) REFERENCES `organizations` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
CONSTRAINT `organization_users_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Dumping data for table `organization_users`
|
||||
--
|
||||
|
||||
LOCK TABLES `organization_users` WRITE;
|
||||
/*!40000 ALTER TABLE `organization_users` DISABLE KEYS */;
|
||||
set autocommit=0;
|
||||
INSERT INTO `organization_users` VALUES
|
||||
(12,12,11,'owner',NULL,NULL,NULL,NULL,'active','2026-01-08 12:48:27',NULL),
|
||||
(13,13,11,'owner',NULL,NULL,NULL,NULL,'active','2026-01-08 15:29:08',NULL);
|
||||
/*!40000 ALTER TABLE `organization_users` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
commit;
|
||||
|
||||
--
|
||||
-- Table structure for table `organizations`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `organizations`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `organizations` (
|
||||
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`owner_id` int(11) unsigned NOT NULL,
|
||||
`name` varchar(255) NOT NULL,
|
||||
`type` enum('business','personal') NOT NULL DEFAULT 'business',
|
||||
`logo` varchar(255) DEFAULT NULL,
|
||||
`requisites` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid(`requisites`)),
|
||||
`trial_ends_at` datetime DEFAULT NULL,
|
||||
`settings` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid(`settings`)),
|
||||
`status` enum('active','blocked') NOT NULL DEFAULT 'active',
|
||||
`created_at` datetime DEFAULT NULL,
|
||||
`updated_at` datetime DEFAULT NULL,
|
||||
`deleted_at` datetime DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `organizations_owner_id_foreign` (`owner_id`),
|
||||
CONSTRAINT `organizations_owner_id_foreign` FOREIGN KEY (`owner_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Dumping data for table `organizations`
|
||||
--
|
||||
|
||||
LOCK TABLES `organizations` WRITE;
|
||||
/*!40000 ALTER TABLE `organizations` DISABLE KEYS */;
|
||||
set autocommit=0;
|
||||
INSERT INTO `organizations` VALUES
|
||||
(12,11,'Личное пространство','personal',NULL,NULL,NULL,NULL,'active','2026-01-08 12:48:27','2026-01-08 12:48:27',NULL),
|
||||
(13,11,'Редька','business',NULL,'{\"inn\":\"1112223334\",\"ogrn\":\"1231231231230\",\"kpp\":\"\",\"legal_address\":\"\\u041f\\u0438\\u0442\\u0435\\u0440, \\u041c\\u043e\\u0439\\u043a\\u0430 13\",\"actual_address\":\"\",\"phone\":\"\",\"email\":\"\",\"website\":\"\",\"bank_name\":\"\",\"bank_bik\":\"\",\"checking_account\":\"\",\"correspondent_account\":\"\"}',NULL,'[]','active','2026-01-08 15:29:08','2026-01-14 07:34:02',NULL);
|
||||
/*!40000 ALTER TABLE `organizations` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
commit;
|
||||
|
||||
--
|
||||
-- Table structure for table `organizations_clients`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `organizations_clients`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `organizations_clients` (
|
||||
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`organization_id` int(11) unsigned NOT NULL,
|
||||
`name` varchar(255) NOT NULL,
|
||||
`email` varchar(255) DEFAULT NULL,
|
||||
`phone` varchar(50) DEFAULT NULL,
|
||||
`notes` text DEFAULT NULL,
|
||||
`created_at` datetime DEFAULT NULL,
|
||||
`updated_at` datetime DEFAULT NULL,
|
||||
`deleted_at` datetime DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `organization_id` (`organization_id`),
|
||||
CONSTRAINT `organizations_clients_organization_id_foreign` FOREIGN KEY (`organization_id`) REFERENCES `organizations` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Dumping data for table `organizations_clients`
|
||||
--
|
||||
|
||||
LOCK TABLES `organizations_clients` WRITE;
|
||||
/*!40000 ALTER TABLE `organizations_clients` DISABLE KEYS */;
|
||||
set autocommit=0;
|
||||
INSERT INTO `organizations_clients` VALUES
|
||||
(1,12,'РогаКопыта','','','Текст','2026-01-08 13:40:47','2026-01-11 15:52:48',NULL),
|
||||
(2,12,'Третий','ttt@ttt.com','','','2026-01-08 14:15:49','2026-01-08 14:15:49',NULL),
|
||||
(3,12,'ыва','ddd@ddd.com','','','2026-01-08 21:34:38','2026-01-08 21:34:38',NULL),
|
||||
(4,12,'ппп','','','','2026-01-12 01:22:38','2026-01-12 01:22:38',NULL),
|
||||
(5,12,'ккк','','','','2026-01-12 01:22:43','2026-01-12 01:22:43',NULL),
|
||||
(6,12,'еее','','','','2026-01-12 01:22:49','2026-01-12 01:22:49',NULL),
|
||||
(7,12,'ннн','','','','2026-01-12 01:22:53','2026-01-12 01:22:53',NULL),
|
||||
(8,12,'ггг','test3@test.com','','Вот такие вот заметки ','2026-01-12 01:22:56','2026-01-15 03:51:00',NULL),
|
||||
(9,12,'шшш','','','','2026-01-12 01:22:59','2026-01-12 01:22:59',NULL),
|
||||
(10,12,'щщщ','','','','2026-01-12 01:23:04','2026-01-12 01:23:04',NULL),
|
||||
(11,12,'ффф','','','','2026-01-12 01:23:08','2026-01-12 01:23:08',NULL),
|
||||
(12,13,'Супер','','','','2026-01-12 02:56:33','2026-01-12 02:56:33',NULL),
|
||||
(13,13,'Супер222','','','','2026-01-12 09:04:04','2026-01-12 09:04:16',NULL);
|
||||
/*!40000 ALTER TABLE `organizations_clients` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
commit;
|
||||
|
||||
--
|
||||
-- Table structure for table `plans`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `plans`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `plans` (
|
||||
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(100) NOT NULL,
|
||||
`description` text DEFAULT NULL,
|
||||
`price` decimal(10,2) NOT NULL DEFAULT 0.00,
|
||||
`currency` varchar(3) NOT NULL DEFAULT 'RUB',
|
||||
`billing_period` enum('monthly','yearly','quarterly') NOT NULL DEFAULT 'monthly',
|
||||
`max_users` int(11) NOT NULL DEFAULT 5,
|
||||
`max_clients` int(11) NOT NULL DEFAULT 100,
|
||||
`max_storage` int(11) NOT NULL DEFAULT 10,
|
||||
`features` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid(`features`)),
|
||||
`is_active` tinyint(4) NOT NULL DEFAULT 1,
|
||||
`is_default` tinyint(4) NOT NULL DEFAULT 0,
|
||||
`created_at` datetime NOT NULL,
|
||||
`updated_at` datetime DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `name` (`name`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Dumping data for table `plans`
|
||||
--
|
||||
|
||||
LOCK TABLES `plans` WRITE;
|
||||
/*!40000 ALTER TABLE `plans` DISABLE KEYS */;
|
||||
set autocommit=0;
|
||||
INSERT INTO `plans` VALUES
|
||||
(1,'Бесплатный','Базовый тариф для небольших команд',0.00,'RUB','monthly',3,50,5,'[\"\\u0411\\u0430\\u0437\\u043e\\u0432\\u044b\\u0435 \\u043c\\u043e\\u0434\\u0443\\u043b\\u0438\",\"Email \\u043f\\u043e\\u0434\\u0434\\u0435\\u0440\\u0436\\u043a\\u0430\",\"\\u042d\\u043a\\u0441\\u043f\\u043e\\u0440\\u0442 \\u0432 CSV\"]',1,1,'2026-01-13 15:18:51',NULL),
|
||||
(2,'Старт','Тариф для растущих компаний',990.00,'RUB','monthly',10,500,50,'[\"\\u0412\\u0441\\u0435 \\u043c\\u043e\\u0434\\u0443\\u043b\\u0438\",\"\\u041f\\u0440\\u0438\\u043e\\u0440\\u0438\\u0442\\u0435\\u0442\\u043d\\u0430\\u044f \\u043f\\u043e\\u0434\\u0434\\u0435\\u0440\\u0436\\u043a\\u0430\",\"\\u042d\\u043a\\u0441\\u043f\\u043e\\u0440\\u0442 \\u0432 PDF \\u0438 Excel\",\"API \\u0434\\u043e\\u0441\\u0442\\u0443\\u043f\"]',1,0,'2026-01-13 15:18:51',NULL),
|
||||
(3,'Бизнес','Полный функционал для крупных компаний',4990.00,'RUB','monthly',50,5000,500,'[\"\\u0412\\u0441\\u0435 \\u043c\\u043e\\u0434\\u0443\\u043b\\u0438\",\"\\u041f\\u0435\\u0440\\u0441\\u043e\\u043d\\u0430\\u043b\\u044c\\u043d\\u044b\\u0439 \\u043c\\u0435\\u043d\\u0435\\u0434\\u0436\\u0435\\u0440\",\"\\u042d\\u043a\\u0441\\u043f\\u043e\\u0440\\u0442 \\u0432 PDF \\u0438 Excel\",\"\\u041f\\u043e\\u043b\\u043d\\u044b\\u0439 API \\u0434\\u043e\\u0441\\u0442\\u0443\\u043f\",\"\\u0418\\u043d\\u0442\\u0435\\u0433\\u0440\\u0430\\u0446\\u0438\\u0438\",\"\\u0411\\u0440\\u0435\\u043d\\u0434\\u0438\\u043d\\u0433\"]',1,0,'2026-01-13 15:18:51',NULL);
|
||||
/*!40000 ALTER TABLE `plans` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
commit;
|
||||
|
||||
--
|
||||
-- Table structure for table `remember_tokens`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `remember_tokens`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `remember_tokens` (
|
||||
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`user_id` int(11) unsigned NOT NULL,
|
||||
`selector` varchar(64) NOT NULL,
|
||||
`token_hash` varchar(128) NOT NULL,
|
||||
`expires_at` datetime NOT NULL,
|
||||
`created_at` datetime DEFAULT NULL,
|
||||
`user_agent` varchar(500) DEFAULT NULL,
|
||||
`ip_address` varchar(45) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `user_id` (`user_id`),
|
||||
KEY `selector` (`selector`),
|
||||
KEY `expires_at` (`expires_at`),
|
||||
CONSTRAINT `remember_tokens_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Dumping data for table `remember_tokens`
|
||||
--
|
||||
|
||||
LOCK TABLES `remember_tokens` WRITE;
|
||||
/*!40000 ALTER TABLE `remember_tokens` DISABLE KEYS */;
|
||||
set autocommit=0;
|
||||
INSERT INTO `remember_tokens` VALUES
|
||||
(4,11,'508781e7a1d7bfb7b15c4ed38a71e205','dc94c9825eed3efd9d960fdefb9e9048203a2b837d8168e1c78ce1cc3e38f90d','2026-02-13 07:17:58','2026-01-14 07:17:58','Mozilla/5.0 (X11; Linux x86_64; rv:146.0) Gecko/20100101 Firefox/146.0','91.234.172.241');
|
||||
/*!40000 ALTER TABLE `remember_tokens` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
commit;
|
||||
|
||||
--
|
||||
-- Table structure for table `users`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `users`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `users` (
|
||||
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`email` varchar(255) NOT NULL,
|
||||
`password` varchar(255) NOT NULL,
|
||||
`system_role` enum('user','admin','superadmin') DEFAULT 'user',
|
||||
`name` varchar(100) NOT NULL,
|
||||
`phone` varchar(20) DEFAULT NULL,
|
||||
`avatar` varchar(255) DEFAULT NULL,
|
||||
`created_at` datetime DEFAULT NULL,
|
||||
`updated_at` datetime DEFAULT NULL,
|
||||
`verification_token` varchar(255) DEFAULT NULL COMMENT 'Токен для подтверждения email',
|
||||
`token_expires_at` datetime DEFAULT NULL,
|
||||
`email_verified` tinyint(1) DEFAULT 0 COMMENT 'Статус подтверждения email (0 - не подтвержден, 1 - подтвержден)',
|
||||
`verified_at` datetime DEFAULT NULL COMMENT 'Дата и время подтверждения email',
|
||||
`reset_token` varchar(255) DEFAULT NULL,
|
||||
`reset_expires_at` datetime DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `email` (`email`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Dumping data for table `users`
|
||||
--
|
||||
|
||||
LOCK TABLES `users` WRITE;
|
||||
/*!40000 ALTER TABLE `users` DISABLE KEYS */;
|
||||
set autocommit=0;
|
||||
INSERT INTO `users` VALUES
|
||||
(11,'mirvtop@yandex.ru','$2y$12$lPkp/tIPEgltYiyIw5ZWuukNPrMdGzfzerRG1oSXbKuBSpVbBmhhu','superadmin','Mirivlad',NULL,'avatar_11_1768273671.jpg','2026-01-08 12:48:27','2026-01-13 15:29:21',NULL,NULL,1,'2026-01-08 12:48:38',NULL,NULL);
|
||||
/*!40000 ALTER TABLE `users` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
commit;
|
||||
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
|
||||
|
||||
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
|
||||
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
|
||||
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
|
||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
||||
/*M!100616 SET NOTE_VERBOSITY=@OLD_NOTE_VERBOSITY */;
|
||||
|
||||
-- Dump completed on 2026-01-16 17:43:45
|
||||
|
|
@ -5,7 +5,7 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||
const body = document.body;
|
||||
|
||||
// Базовая функция для получения base URL (объявляем ДО использования)
|
||||
const baseUrl = '{{ base_url("/") }}'.replace(/\/+$/, '');
|
||||
const baseUrl = '/'.replace(/\/+$/, '');
|
||||
|
||||
if (sidebarToggle) {
|
||||
// Обработчик клика
|
||||
|
|
|
|||
|
|
@ -24,6 +24,16 @@ class ContactsManager {
|
|||
this.loadContacts();
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить заголовки запроса
|
||||
*/
|
||||
getHeaders() {
|
||||
return {
|
||||
'Content-Type': 'application/json',
|
||||
'X-Requested-With': 'XMLHttpRequest'
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Загрузить список контактов
|
||||
*/
|
||||
|
|
@ -31,9 +41,8 @@ class ContactsManager {
|
|||
try {
|
||||
const response = await fetch(`${this.apiUrl}/list/${this.clientId}`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
credentials: 'same-origin',
|
||||
headers: this.getHeaders(),
|
||||
body: JSON.stringify({})
|
||||
});
|
||||
|
||||
|
|
@ -106,6 +115,7 @@ class ContactsManager {
|
|||
* Отобразить одну строку контакта
|
||||
*/
|
||||
renderRow(contact) {
|
||||
const escapedId = this.escapeJs(contact.id);
|
||||
return `
|
||||
<tr data-id="${contact.id}" class="contact-row">
|
||||
<td>
|
||||
|
|
@ -129,29 +139,27 @@ class ContactsManager {
|
|||
value="${this.escapeHtml(contact.position || '')}" style="display: none;" placeholder="Должность">
|
||||
</td>
|
||||
<td class="text-end">
|
||||
<div class="contact-actions">
|
||||
<div class="btn-group contact-actions">
|
||||
<button type="button" class="btn btn-outline-primary btn-sm"
|
||||
onclick="contactsManager.edit(${contact.id})" title="Редактировать">
|
||||
onclick="contactsManager.edit('${escapedId}')" title="Редактировать">
|
||||
<i class="fa-solid fa-pen"></i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-danger btn-sm"
|
||||
onclick="contactsManager.remove(${contact.id})" title="Удалить">
|
||||
onclick="contactsManager.remove('${escapedId}')" title="Удалить">
|
||||
<i class="fa-solid fa-trash"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="edit-actions" style="display: none;">
|
||||
<div class="btn-group edit-actions" style="display: none;">
|
||||
<button type="button" class="btn btn-outline-success btn-sm"
|
||||
onclick="contactsManager.save(${contact.id})" title="Сохранить">
|
||||
onclick="contactsManager.save('${escapedId}')" title="Сохранить">
|
||||
<i class="fa-solid fa-check"></i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-outline-secondary btn-sm"
|
||||
onclick="contactsManager.cancel(${contact.id})" title="Отмена">
|
||||
onclick="contactsManager.cancel('${escapedId}')" title="Отмена">
|
||||
<i class="fa-solid fa-times"></i>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
`;
|
||||
</td>`;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -225,18 +233,16 @@ class ContactsManager {
|
|||
// Создание нового
|
||||
response = await fetch(`${this.apiUrl}/store`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
credentials: 'same-origin',
|
||||
headers: this.getHeaders(),
|
||||
body: JSON.stringify(data)
|
||||
});
|
||||
} else {
|
||||
// Обновление существующего
|
||||
response = await fetch(`${this.apiUrl}/update/${contactId}`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
credentials: 'same-origin',
|
||||
headers: this.getHeaders(),
|
||||
body: JSON.stringify(data)
|
||||
});
|
||||
}
|
||||
|
|
@ -245,13 +251,15 @@ class ContactsManager {
|
|||
|
||||
if (result.success) {
|
||||
// Обновляем локальный массив
|
||||
const index = this.contacts.findIndex(c => c.id === contactId);
|
||||
// contactId может быть строкой из data-id, а c.id - числом из БД
|
||||
const contactIdStr = String(contactId);
|
||||
const index = this.contacts.findIndex(c => String(c.id) === contactIdStr);
|
||||
if (index !== -1) {
|
||||
if (result.item) {
|
||||
// Обновляем с реальным ID от сервера
|
||||
this.contacts[index] = { ...data, id: result.item.id };
|
||||
} else {
|
||||
this.contacts[index] = data;
|
||||
this.contacts[index] = { ...data, id: contactId };
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -270,9 +278,10 @@ class ContactsManager {
|
|||
* Отменить редактирование
|
||||
*/
|
||||
cancel(contactId) {
|
||||
if (contactId.toString().startsWith('new_')) {
|
||||
const contactIdStr = String(contactId);
|
||||
if (contactIdStr.startsWith('new_')) {
|
||||
// Удаляем новую строку
|
||||
this.contacts = this.contacts.filter(c => c.id !== contactId);
|
||||
this.contacts = this.contacts.filter(c => String(c.id) !== contactIdStr);
|
||||
this.render();
|
||||
} else {
|
||||
// Перезагружаем данные
|
||||
|
|
@ -291,16 +300,17 @@ class ContactsManager {
|
|||
try {
|
||||
const response = await fetch(`${this.apiUrl}/delete/${contactId}`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
credentials: 'same-origin',
|
||||
headers: this.getHeaders(),
|
||||
body: JSON.stringify({})
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
if (result.success) {
|
||||
this.contacts = this.contacts.filter(c => c.id !== contactId);
|
||||
// contactId может быть строкой, а c.id - числом
|
||||
const contactIdStr = String(contactId);
|
||||
this.contacts = this.contacts.filter(c => String(c.id) !== contactIdStr);
|
||||
this.render();
|
||||
this.showSuccess(result.message || 'Контакт удалён');
|
||||
} else {
|
||||
|
|
@ -361,6 +371,23 @@ class ContactsManager {
|
|||
div.textContent = text;
|
||||
return div.innerHTML;
|
||||
}
|
||||
|
||||
/**
|
||||
* Экранирование для JavaScript строки
|
||||
*/
|
||||
escapeJs(text) {
|
||||
if (!text) return '';
|
||||
// Приводим к строке, так как id может быть числом
|
||||
const str = String(text);
|
||||
return str
|
||||
.replace(/\\/g, '\\\\')
|
||||
.replace(/'/g, "\\'")
|
||||
.replace(/"/g, '\\"')
|
||||
.replace(/\n/g, '\\n')
|
||||
.replace(/\r/g, '\\r')
|
||||
.replace(/</g, '\\x3c')
|
||||
.replace(/>/g, '\\x3e');
|
||||
}
|
||||
}
|
||||
|
||||
// Инициализация при загрузке страницы
|
||||
|
|
|
|||
Loading…
Reference in New Issue