# Корпоративное 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 в репозитории проекта.