# Корпоративное MAUI приложение Кроссплатформенное корпоративное приложение для общения между сотрудниками компании, построенное на .NET MAUI. ## 📱 Возможности - ✅ **Аутентификация** - безопасный вход в систему - ✅ **Список сотрудников** - просмотр всех пользователей с фильтрацией и поиском - ✅ **Личные сообщения** - обмен сообщениями между сотрудниками в реальном времени - ✅ **WebSocket подключение** - мгновенная доставка сообщений - ✅ **Статусы пользователей** - отображение онлайн/оффлайн статуса - ✅ **Индикатор набора текста** - видно, когда собеседник печатает - ✅ **Профиль пользователя** - просмотр информации о себе - ✅ **Поддержка Android, iOS, Windows, MacCatalyst** ## 🏗️ Архитектура ### Структура проекта ``` CORP-MAUI/ ├── Models/ # Модели данных │ ├── User.cs │ ├── Message.cs │ └── AuthResponse.cs ├── Services/ # Бизнес-логика │ ├── ApiService.cs # REST API клиент │ └── WebSocketService.cs # WebSocket клиент ├── Pages/ # Страницы приложения │ ├── LoginPage.xaml │ ├── UsersPage.xaml │ ├── ChatPage.xaml │ └── ProfilePage.xaml ├── ServiceProvider.cs # Singleton для сервисов ├── App.xaml.cs # Точка входа └── AppShell.xaml # Навигация ``` ### Компоненты #### 1. **ApiService** - REST API клиент Отвечает за HTTP запросы к серверу: - Аутентификация (`POST /auth/login`) - Получение списка пользователей (`GET /users`) - Получение сообщений (`GET /messages`) - Отправка сообщений (`POST /messages`) - Поиск пользователей (`GET /users/search`) - Обновление статуса (`PUT /users/status`) #### 2. **WebSocketService** - WebSocket клиент Обеспечивает real-time коммуникацию: - Подключение к WebSocket серверу - Отправка/получение сообщений - Индикаторы набора текста - Обновление статусов пользователей - Автоматическое переподключение #### 3. **ServiceProvider** - Singleton провайдер Централизованное управление сервисами приложения. ## 🔌 API Endpoints Базовый URL: `https://corp.robotail.pro/api/v1/` ### REST API ```http # Аутентификация POST /auth/login Content-Type: application/json { "username": "user", "password": "pass" } # Получить список пользователей GET /users Authorization: Bearer {token} # Получить текущего пользователя GET /users/me Authorization: Bearer {token} # Поиск пользователей GET /users/search?q={query} Authorization: Bearer {token} # Получить сообщения GET /messages?userId={id} Authorization: Bearer {token} # Отправить сообщение POST /messages Authorization: Bearer {token} Content-Type: application/json { "receiverId": 123, "content": "Текст сообщения" } # Обновить статус PUT /users/status Authorization: Bearer {token} Content-Type: application/json { "isOnline": true } ``` ### WebSocket ``` URL: wss://corp.robotail.pro/api/v1/ws Headers: Authorization: Bearer {token} # Отправка сообщения { "type": "message", "data": { "receiverId": 123, "content": "Текст сообщения" } } # Индикатор набора текста { "type": "typing", "data": { "recipientId": 123, "isTyping": true } } # Получение сообщения (от сервера) { "type": "message", "data": { "id": 456, "senderId": 789, "senderName": "Иван Иванов", "content": "Привет!", "timestamp": "2026-01-08T10:30:00Z" } } # Обновление статуса пользователя (от сервера) { "type": "user_status", "data": { "id": 123, "isOnline": true } } ``` ## 🚀 Установка и запуск ### Требования - .NET 9.0 SDK - Visual Studio 2022 / JetBrains Rider - Для Android: Android SDK (см. [ANDROID_SETUP.md](ANDROID_SETUP.md)) - Для iOS: Xcode и Mac ### ⚙️ Настройка Android SDK Если Android SDK установлен по нестандартному пути, создан файл `Directory.Build.props` в корне решения: ```xml D:\Applications\Android\SDK ``` **Важно:** Измените путь на ваш, если SDK установлен в другом месте. Подробная инструкция: [ANDROID_SETUP.md](ANDROID_SETUP.md) ### Скрипты сборки для Android Для удобной сборки Android используйте готовые скрипты: ```powershell # PowerShell (рекомендуется) .\build-android.ps1 # Batch .\build-android.bat ``` Скрипты автоматически настроят переменные окружения и соберут проект. ### Установка зависимостей ```powershell # CORP-MAUI - Корпоративное приложение для сотрудников Мобильное приложение для внутрикорпоративного общения между сотрудниками компании. ## 🚀 Технологии - **.NET MAUI 9.0** - Кросс-платформенный фреймворк - **C# 12** - Язык программирования - **WebSocket** - Обмен сообщениями в реальном времени - **REST API** - Взаимодействие с сервером - **JWT Authentication** - Безопасная аутентификация - **SecureStorage** - Безопасное хранение токенов ## 📱 Возможности ### Аутентификация - Вход по email и паролю - Автоматическое сохранение JWT токенов - Автоматическое обновление access токена при истечении - Безопасное хранение токенов в SecureStorage ### Профиль пользователя - Просмотр личной информации - Отображение статуса (в сети/не в сети) - Выход из системы ### Список сотрудников - Просмотр всех сотрудников компании - Поиск по имени, отделу, должности - Отображение статуса онлайн/офлайн - Pull-to-refresh для обновления списка ### Чат - Обмен личными сообщениями - Обмен в реальном времени через WebSocket - Отображение истории сообщений - Индикатор набора текста - Резервная отправка через REST API ## 🏗️ Архитектура ``` CORP-MAUI/ ├── Models/ # Модели данных │ ├── User.cs # Модель пользователя │ ├── Message.cs # Модель сообщения │ └── AuthResponse.cs # Ответ аутентификации ├── Services/ # Сервисы │ ├── ApiService.cs # HTTP-клиент для REST API │ └── WebSocketService.cs # WebSocket-клиент ├── Pages/ # Страницы приложения │ ├── LoginPage.xaml # Страница входа │ ├── ProfilePage.xaml # Профиль пользователя │ ├── UsersPage.xaml # Список сотрудников │ └── ChatPage.xaml # Чат с сотрудником └── ServiceProvider.cs # Глобальный провайдер сервисов ``` ## 🔌 API Endpoints **Базовый URL:** `https://corp.robotail.pro` ### Аутентификация ```http POST /api/auth/token/ Body: { "email": "user@example.com", "password": "password" } Response: { "access": "token", "refresh": "token" } POST /api/auth/token/refresh/ Body: { "refresh": "token" } Response: { "access": "new_token" } ``` ### Пользователи ```http GET /api/v1/employees/ Response: [{ "id": 1, "username": "user", ... }] GET /api/v1/employees/me/ Response: { "id": 1, "username": "user", ... } GET /api/v1/users/search/?q=query Response: [{ "id": 1, "username": "user", ... }] PUT /api/v1/users/status/ Body: { "isOnline": true } ``` ### Сообщения ```http GET /api/v1/messages/ Response: [{ "id": 1, "content": "Hello", ... }] GET /api/v1/messages/?user_id=1 Response: [{ "id": 1, "content": "Hello", ... }] POST /api/v1/messages/ Body: { "senderId": 1, "receiverId": 2, "content": "Hello" } ``` ### WebSocket ``` Поддерживаются следующие варианты URL (автоматический подбор): - wss://corp.robotail.pro/ws (основной) - ws://corp.robotail.pro/ws (без SSL) - wss://corp.robotail.pro/ws/ (со слешем) - и другие варианты... ВАЖНО! Обязательный заголовок при подключении: Authorization: Bearer {access_token} Пример подключения: var ws = new ClientWebSocket(); ws.Options.SetRequestHeader("Authorization", $"Bearer {token}"); await ws.ConnectAsync(new Uri("wss://corp.robotail.pro/ws"), cancellationToken); Типы сообщений: - message: Новое сообщение - user_status: Изменение статуса пользователя - typing: Индикатор набора текста Формат сообщений: { "type": "message", "data": { "senderId": 1, "receiverId": 2, "content": "Текст сообщения", "timestamp": "2026-01-09T12:00:00Z" } } ``` **Примечание**: - WebSocketService автоматически пробует разные варианты URL и подключается к первому работающему - Заголовок Authorization устанавливается автоматически при вызове `ConnectAsync(token)` - Токен передается в формате JWT Bearer token ## 🔐 Система управления токенами ApiService автоматически управляет JWT токенами: 1. **При входе:** - Получает access и refresh токены - Сохраняет их в SecureStorage - Устанавливает в HTTP заголовки 2. **При запросах:** - Автоматически добавляет Bearer токен - При 401/403 пытается обновить токен - Повторяет запрос после обновления 3. **При выходе:** - Очищает токены из SecureStorage - Удаляет заголовки авторизации ## 📝 Использование ### Пример авторизации ```csharp var result = await ServiceProvider.ApiService.LoginAsync(email, password); if (result.Success) { // Токены автоматически сохранены var user = result.User; await ServiceProvider.WebSocketService.ConnectAsync(result.Token); Application.Current.MainPage = new AppShell(); } ``` ### Пример получения данных ```csharp // Автоматически обновит токен при необходимости var employees = await ServiceProvider.ApiService.GetEmployeesAsync(); var currentUser = await ServiceProvider.ApiService.GetCurrentUserAsync(); ``` ### Пример отправки сообщения ```csharp var message = new Message { SenderId = currentUser.Id, ReceiverId = recipient.Id, Content = "Hello!", Timestamp = DateTime.Now, Type = MessageType.Personal }; // Через WebSocket (приоритет) if (ServiceProvider.WebSocketService.IsConnected) { await ServiceProvider.WebSocketService.SendMessageAsync(message); } else { // Резервный метод через REST API await ServiceProvider.ApiService.SendMessageAsync(message); } ``` ### Пример выхода ```csharp await ServiceProvider.ApiService.UpdateStatusAsync(false); await ServiceProvider.WebSocketService.DisconnectAsync(); ServiceProvider.ApiService.Logout(); // Очищает токены Application.Current.MainPage = new NavigationPage(new LoginPage()); ``` ## 🔧 Конфигурация Вы можете настроить ApiService при создании: ```csharp var config = new ApiConfig { BaseUrl = "https://your-api.com/api", TokenObtainPath = "/auth/token/", TokenRefreshPath = "/auth/token/refresh/", Timeout = 30, DefaultHeaders = new Dictionary { { "Accept", "application/json" }, { "X-Custom-Header", "value" } } }; var apiService = new ApiService(config); ``` ## 🛠️ Сборка и запуск ### Требования - Visual Studio 2022 или JetBrains Rider - .NET 9.0 SDK - Android SDK (для Android) - Xcode (для iOS/macOS) ### Запуск ```powershell # Android dotnet build -t:Run -f net9.0-android # iOS dotnet build -t:Run -f net9.0-ios # Windows dotnet build -t:Run -f net9.0-windows10.0.19041.0 ``` ## 📚 Документация - [API_REFACTORING.md](API_REFACTORING.md) - Подробное описание рефакторинга ApiService - [.NET MAUI Documentation](https://docs.microsoft.com/dotnet/maui/) ## ⚠️ Важные замечания 1. **SecureStorage** - Токены хранятся в защищенном хранилище платформы 2. **Автоматический Refresh** - Access токен обновляется прозрачно при 401/403 3. **WebSocket Reconnect** - При разрыве соединения нужно реализовать переподключение 4. **Offline Mode** - Можно добавить локальное кэширование сообщений ## 🤝 Вклад Проект находится в разработке. Приветствуются pull requests и issue reports. ## 📄 Лицензия Корпоративное приложение для внутреннего использования. --- **Версия:** 1.0.0 **Дата обновления:** 2026-01-09 dotnet restore ``` ### Сборка проекта ```powershell # Для Android dotnet build -f net9.0-android # Для Windows dotnet build -f net9.0-windows10.0.19041.0 # Для iOS dotnet build -f net9.0-ios # Для MacCatalyst dotnet build -f net9.0-maccatalyst ``` ### Запуск приложения ```powershell # Android dotnet run -f net9.0-android # Windows dotnet run -f net9.0-windows10.0.19041.0 ``` ## 🔧 Конфигурация ### Изменение API URL В файле `Services/ApiService.cs`: ```csharp private const string BaseUrl = "https://corp.robotail.pro/api/v1/"; ``` В файле `Services/WebSocketService.cs`: ```csharp private const string WebSocketUrl = "wss://corp.robotail.pro/api/v1/ws"; ``` ## 📚 Используемые технологии - **.NET 9.0** - фреймворк - **.NET MAUI** - UI фреймворк - **Newtonsoft.Json** - JSON сериализация - **System.Net.WebSockets** - WebSocket клиент - **SecureStorage** - безопасное хранение данных ## 🎨 UI/UX особенности - Material Design стиль - Адаптивный дизайн для разных экранов - Плавные анимации и переходы - Индикаторы загрузки - Обработка ошибок с user-friendly сообщениями - Pull-to-refresh для обновления данных ## 🔐 Безопасность - Токены хранятся в SecureStorage - HTTPS для REST API - WSS (WebSocket Secure) для real-time коммуникации - Автоматический выход при истечении токена ## 📝 Примеры использования ### Отправка сообщения через WebSocket ```csharp var message = new Message { SenderId = currentUser.Id, ReceiverId = recipient.Id, Content = "Привет!", Timestamp = DateTime.Now }; await ServiceProvider.WebSocketService.SendMessageAsync(message); ``` ### Поиск пользователей ```csharp var users = await ServiceProvider.ApiService.SearchUsersAsync("Иван"); ``` ### Подписка на новые сообщения ```csharp ServiceProvider.WebSocketService.MessageReceived += (sender, message) => { // Обработка нового сообщения Console.WriteLine($"Новое сообщение от {message.SenderName}: {message.Content}"); }; ``` ## 🐛 Известные проблемы - WebSocket может разрываться при неактивности (реализовано автоматическое переподключение) - На iOS требуются дополнительные разрешения для фоновой работы ## 🤝 Вклад в проект Пул-реквесты приветствуются! Для крупных изменений, пожалуйста, сначала откройте issue. ## 📄 Лицензия [MIT](https://choosealicense.com/licenses/mit/) ## 👥 Автор Создано для корпоративного использования в компании. ## 📞 Поддержка При возникновении проблем создайте issue в репозитории проекта.