feat: 添加SECTL云服务集成功能

实现SECTL云服务的全面集成,包括:
1. 添加OAuth认证服务,支持PKCE流程
2. 实现云存储管理功能
3. 添加积分数据同步服务
4. 实现通知服务和KV存储服务
5. 添加多语言支持
6. 创建相关React组件和上下文
7. 更新依赖项添加crypto-js
8. 优化HTTP客户端重用
This commit is contained in:
Yukino_fox
2026-04-10 21:47:24 +08:00
parent 448df1a40b
commit bf9cb9af41
27 changed files with 8447 additions and 8 deletions
+668
View File
@@ -0,0 +1,668 @@
{
"common": {
"next": "Далее",
"prev": "Назад",
"finish": "Завершить",
"cancel": "Отмена",
"save": "Сохранить",
"loading": "Загрузка...",
"confirm": "Подтвердить",
"success": "Успех",
"error": "Ошибка",
"delete": "Удалить",
"edit": "Редактировать",
"add": "Добавить",
"search": "Поиск",
"clear": "Очистить",
"close": "Закрыть",
"yes": "Да",
"no": "Нет",
"submit": "Отправить",
"reset": "Сбросить",
"import": "Импорт",
"export": "Экспорт",
"create": "Создать",
"update": "Обновить",
"refresh": "Обновить",
"view": "Просмотр",
"name": "Имя",
"status": "Статус",
"operation": "Операция",
"description": "Описание",
"total": "Всего {{count}} элементов",
"noData": "Нет данных",
"pleaseSelect": "Пожалуйста, выберите",
"pleaseEnter": "Пожалуйста, введите",
"readOnly": "Режим только для чтения",
"none": "Нет",
"more": "Больше"
},
"oobe": {
"title": "Добро пожаловать в SecScore",
"subtitle": "Эксперт по управлению образовательными баллами",
"step": "Шаг {{current}}/{{total}}",
"skip": "Пропустить",
"steps": {
"entry": {
"title": "Начало работы",
"description": "Выберите процедуру, которую нужно выполнить",
"enterOobe": "Войти в OOBE",
"connectPostgresAutoSync": "Подключиться к PostgreSQL с автоматической синхронизацией",
"skipDirect": "Пропустить OOBE и войти напрямую"
},
"postgresql": {
"title": "Подключение к PostgreSQL",
"description": "Введите строку подключения к PostgreSQL. Система автоматически подключится и синхронизируется.",
"connectionPlaceholder": "postgresql://user:password@host:port/database?sslmode=require",
"autoSyncAndEnter": "Автоматическое подключение и синхронизация"
},
"language": {
"title": "Выбор языка",
"description": "Пожалуйста, выберите предпочитаемый язык"
},
"theme": {
"title": "Настройка темы",
"description": "Выберите внешний вид интерфейса",
"mode": "Режим",
"lightMode": "Светлый",
"darkMode": "Темный",
"primaryColor": "Основной цвет",
"backgroundGradient": "Градиент фона"
},
"password": {
"title": "Настройка пароля",
"description": "Установите пароль для защиты данных (необязательно)",
"adminPassword": "Пароль администратора",
"adminPasswordHint": "Доступ ко всем функциям, 6 цифр",
"pointsPassword": "Пароль баллов",
"pointsPasswordHint": "Только операции с баллами, 6 цифр",
"passwordPlaceholder": "Введите 6 цифр",
"hint": "Оставьте пустым для пропуска, настройте позже в настройках"
},
"students": {
"title": "Импорт списка студентов",
"description": "Добавьте список студентов, чтобы начать управление баллами",
"import": "Импорт списка",
"manual": "Добавить вручную",
"importHint": "Поддерживает файлы Excel (.xlsx) или JSON",
"manualHint": "Вставьте несколько строк, одно имя студента на строку",
"dragDrop": "Перетащите файлы сюда или нажмите для выбора",
"supportedFormats": "Поддерживаемые форматы: .xlsx, .json",
"studentName": "Имя студента",
"addStudent": "Добавить студента",
"noStudents": "Студентов пока нет, пожалуйста, добавьте или импортируйте",
"studentCount": "Добавлено {{count}} студентов",
"studentExists": "Студент уже существует",
"importSuccess": "Успешно импортировано {{count}} студентов",
"noNewStudents": "Нет новых студентов для импорта",
"parseFailed": "Ошибка анализа файла",
"unsupportedFormat": "Неподдерживаемый формат файла"
},
"reasons": {
"title": "Настройка причин",
"description": "Добавьте распространенные причины изменения баллов",
"addReason": "Добавить причину",
"reasonName": "Название причины",
"points": "Баллы",
"positive": "Добавить баллы",
"negative": "Снять баллы",
"noReasons": "Причин пока нет, пожалуйста, добавьте распространенные причины",
"reasonCount": "Добавлено {{count}} причин",
"reasonExists": "Причина уже существует"
},
"start": {
"title": "Готово к использованию",
"description": "Все готово. Давайте начнем использовать SecScore!",
"features": {
"score": "Легко управляйте баллами студентов",
"history": "Полная история изменений баллов",
"settlement": "Поддержка расчета и архивирования"
},
"startButton": "Начать"
}
}
},
"settings": {
"title": "Системные настройки",
"tabs": {
"appearance": "Внешний вид",
"security": "Безопасность",
"account": "Учетная запись",
"database": "Подключение к базе данных",
"dataManagement": "Управление данными",
"urlProtocol": "Протокол URL",
"about": "О программе"
},
"language": "Язык",
"languageHint": "Выберите язык отображения интерфейса",
"fontFamily": "Глобальный шрифт",
"fontFamilyHint": "Выберите шрифт интерфейса (требуется обновление)",
"theme": "Тема",
"password": "Настройка пароля",
"themeMode": "Режим",
"lightMode": "Светлый",
"darkMode": "Темный",
"primaryColor": "Основной цвет",
"backgroundGradient": "Градиент фона",
"searchKeyboard": {
"title": "Клавиатура поиска",
"hint": "Выберите раскладку клавиатуры под полем поиска",
"disableToggle": "Отключить клавиатуру поиска",
"disableHint": "Клавиатура больше не будет отображаться под полем поиска",
"options": {
"qwerty26": "26 клавиш (QWERTY)",
"t9": "9 клавиш (T9)"
}
},
"interfaceZoom": "Масштаб интерфейса",
"zoomOptions": {
"small70": "Маленький (70%)",
"default100": "По умолчанию (100%)",
"large150": "Большой (150%)"
},
"general": {
"saved": "Сохранено",
"saveFailed": "Ошибка сохранения"
},
"zoomHint": "Настройка общего размера интерфейса",
"mobile": {
"navigationTitle": "Входы на страницу",
"bottomNav": {
"label": "Функции нижней навигации",
"hint": "Выберите функции для отображения в нижней панели мобильного устройства. Панель отображает максимум 4 элемента, остальные переходят в «Ещё»."
},
"dragHint": "Перетащите для изменения порядка. Первые 4 элемента отображаются в нижней панели, остальные в «Ещё».",
"dropHere": "Отпустите здесь",
"bottomSection": "Нижняя панель (макс. 4)",
"moreSection": "Ещё",
"moveToMore": "Переместить в Ещё",
"moveToBottom": "Переместить вниз"
},
"zoomUpdated": "Масштаб интерфейса обновлен",
"updateFailed": "Ошибка обновления",
"security": {
"title": "Система защиты паролем",
"adminPassword": "Пароль администратора",
"pointsPassword": "Пароль баллов",
"recoveryString": "Строка восстановления",
"set": "Установлено",
"notSet": "Не установлено",
"generated": "Создано",
"notGenerated": "Не создано",
"enterPassword": "Введите 6 цифр (оставьте пустым для пропуска)",
"adminPasswordPlaceholder": "Введите 6 цифр пароля администратора (оставьте пустым для пропуска)",
"pointsPasswordPlaceholder": "Введите 6 цифр пароля баллов (оставьте пустым для пропуска)",
"recoveryPlaceholder": "Введите строку восстановления",
"savePassword": "Сохранить пароль",
"savePasswords": "Сохранить пароли",
"generateRecovery": "Создать строку восстановления",
"clearAllPasswords": "Очистить все пароли",
"recoveryReset": "Сброс строки восстановления",
"enterRecovery": "Введите строку восстановления",
"resetPassword": "Сброс пароля",
"resetHint": "Сброс очистит пароли администратора и баллов и создаст новую строку восстановления.",
"confirmClear": "Подтвердить очистку всех паролей?",
"clearHint": "После очистки защита будет отключена (без пароля по умолчанию - права администратора).",
"saved": "Пароль обновлен",
"saveFailed": "Ошибка обновления",
"generateFailed": "Ошибка создания",
"resetFailed": "Ошибка сброса",
"cleared": "Очищено",
"clearFailed": "Ошибка очистки",
"passwordClearedNewRecovery": "Пароль очищен, новая строка восстановления",
"newRecoveryString": "Новая строка восстановления (пожалуйста, сохраните)"
},
"account": {
"title": "Учетная запись SECTL Auth",
"notLoggedIn": "Не вошел в SECTL Auth",
"oauthHint": "Войдите в свою учетную запись SECTL Auth для использования единой аутентификации и удаленного выхода",
"loginButton": "Войти через SECTL Auth",
"loginSuccess": "Успешный вход",
"logout": "Выход",
"userId": "ID пользователя",
"permission": "Уровень разрешений"
},
"database": {
"title": "Подключение к базе данных",
"currentStatus": "Текущий статус базы данных",
"sqliteLocal": "Локальная база данных SQLite",
"postgresqlRemote": "Удаленная база данных PostgreSQL",
"connected": "Подключено",
"disconnected": "Отключено",
"postgresqlConnection": "Удаленное подключение PostgreSQL",
"connectionHint": "Введите строку подключения PostgreSQL для подключения к удаленной базе данных, поддержка синхронизации на нескольких платформах.",
"testConnection": "Тест подключения",
"switchToPostgreSQL": "Переключиться на PostgreSQL",
"switchToSQLite": "Переключиться на локальный SQLite",
"connectionTestSuccess": "Тест подключения успешен",
"connectionTestFailed": "Ошибка теста подключения",
"switchedTo": "Переключено на базу данных {{type}}",
"switchedToSQLite": "Переключено на локальную базу данных SQLite",
"switchFailed": "Ошибка переключения",
"syncDescription": "Инструкции по синхронизации на нескольких платформах",
"syncPoint1": "Использование удаленной базы данных PostgreSQL позволяет синхронизировать данные на нескольких платформах.",
"syncPoint2": "Встроенная очередь операций для обеспечения согласованности данных при одновременных операциях.",
"syncPoint3": "Требуется перезапуск приложения после переключения базы данных.",
"syncPoint4": "Рекомендуемые облачные сервисы баз данных: Neon, Supabase, AWS RDS и др.",
"enterConnectionString": "Пожалуйста, введите строку подключения PostgreSQL",
"connectionExample": "Пример: postgresql://xxxxxx_xxxxx:xxxxxxxx@xx-xxx.xxx.neon.xxxx/xxxxdxx?sslmode=require",
"uploadButton": "Загрузить локальные данные на удаленный сервер",
"uploadHint": "После подключения к удаленной базе данных загрузите и объедините локальную историю SQLite на удаленный сервер.",
"uploadNeedRemote": "Сначала переключитесь и подключитесь к удаленной базе данных PostgreSQL",
"noNeedUpload": "Локальные и удаленные данные уже согласованы",
"uploadConfirmTitle": "Подтвердить загрузку локальных данных на удаленный сервер?",
"uploadConfirmContent": "Синхронизация будет отдавать приоритет локальным данным. Обнаружено: только локальные {{localOnly}}, только удаленные {{remoteOnly}}, конфликты {{conflicts}}.",
"uploadSuccess": "Локальные данные загружены на удаленный сервер",
"uploadFailed": "Ошибка загрузки"
},
"data": {
"title": "Управление данными",
"settlement": "Расчет",
"settlementAndRestart": "Рассчитать и перезапустить",
"settlementHint": "Классифицирует нерассчитанные записи в один этап и сбрасывает все баллы студентов в ноль.",
"importExport": "Импорт / Экспорт",
"exportJson": "Экспорт JSON",
"importJson": "Импорт JSON",
"importHint": "Импорт перезапишет существующих студентов/причины/записи/настройки (настройки безопасности исключены).",
"logs": "Журналы",
"logLevel": "Уровень журнала",
"logOperation": "Операция с журналами",
"viewLogs": "Просмотр журналов",
"exportLogs": "Экспорт журналов",
"clearLogs": "Очистить журналы",
"logsCleared": "Журналы очищены",
"systemLogs": "Системные журналы (последние 200)",
"noLogs": "Нет журналов",
"logLevelUpdated": "Уровень журнала обновлен",
"readLogsFailed": "Ошибка чтения журналов",
"logsExported": "Журналы экспортированы",
"exportFailed": "Ошибка экспорта",
"exportSuccess": "Экспорт успешен",
"importSuccess": "Импорт успешен, обновление",
"importFailed": "Ошибка импорта",
"clearFailed": "Ошибка очистки",
"confirmSettlement": "Подтвердить расчет и перезапуск?",
"settlementConfirm1": "Это архивирует нерассчитанные записи в один этап и сбросит все баллы студентов в ноль.",
"settlementConfirm2": "Список студентов остается без изменений; история расчетов доступна на странице «История расчетов».",
"settlementSuccess": "Расчет успешен, баллы перезапущены",
"settlementFailed": "Ошибка расчета",
"settle": "Рассчитать",
"logLevels": {
"debug": "DEBUG (отладка)",
"info": "INFO (информация)",
"warn": "WARN (предупреждение)",
"error": "ERROR (ошибка)"
}
},
"url": {
"title": "Протокол URL (secscore://)",
"protocol": "Протокол URL",
"description": "Вы можете вызвать SecScore через URL для выполнения операций, например:",
"register": "Зарегистрировать протокол URL",
"registered": "Протокол URL зарегистрирован",
"registerFailed": "Ошибка регистрации",
"installerRequired": "Требуется установленная версия SecScore, может не работать в режиме разработки."
},
"mcp": {
"title": "Сервис MCP",
"description": "Управление встроенным HTTP-сервисом MCP для внешних клиентов MCP.",
"running": "Запущен",
"stopped": "Остановлен",
"noUrl": "Нет URL",
"host": "Хост",
"port": "Порт",
"start": "Запустить",
"stop": "Остановить",
"refresh": "Обновить состояние",
"hint": "Рекомендуется привязывать только к 127.0.0.1; после запуска конечная точка - http://host:port/mcp",
"hostRequired": "Пожалуйста, введите хост MCP",
"portInvalid": "Пожалуйста, введите действительный порт (1-65535)",
"startSuccess": "Сервер MCP запущен",
"startFailed": "Ошибка запуска сервера MCP",
"stopSuccess": "Сервер MCP остановлен",
"stopFailed": "Ошибка остановки сервера MCP",
"startTimeout": "Время ожидания запуска сервера MCP истекло, повторите попытку",
"stopTimeout": "Время ожидания остановки сервера MCP истекло, повторите попытку"
},
"app": {
"title": "Управление приложением",
"description": "Быстро перезапустить или закрыть приложение.",
"restart": "Перезапустить приложение",
"quit": "Закрыть приложение",
"confirmRestartTitle": "Подтвердить перезапуск приложения?",
"confirmRestartContent": "Приложение будет немедленно закрыто и перезапущено.",
"confirmQuitTitle": "Подтвердить закрытие приложения?",
"confirmQuitContent": "Приложение будет немедленно закрыто.",
"restartFailed": "Ошибка перезапуска",
"quitFailed": "Ошибка закрытия"
},
"about": {
"title": "О программе",
"appName": "Управление образовательными баллами",
"version": "Версия",
"copyright": "Авторские права",
"ipcStatus": "Статус IPC",
"ipcConnected": "Подключено",
"ipcDisconnected": "Отключено (Ошибка предварительной загрузки)",
"environment": "Среда",
"toggleDevTools": "Переключить инструменты разработчика",
"license": "SecScore распространяется по лицензии GPL3.0",
"copyRightText": "CopyRight © 2025-{{year}} SECTL"
}
},
"sidebar": {
"home": "Главная",
"students": "Управление студентами",
"score": "Операции с баллами",
"boards": "Доски",
"leaderboard": "Таблица лидеров",
"settlements": "История расчетов",
"reasons": "Управление причинами",
"autoScore": "Автоматическое добавление баллов",
"rewardExchange": "Обмен наградами",
"rewardSettings": "Настройки наград",
"settings": "Системные настройки",
"remoteDb": "Удаленная база данных",
"refreshStatus": "Обновить состояние",
"syncNow": "Синхронизировать сейчас",
"syncSuccess": "Синхронизация успешна",
"syncFailed": "Ошибка синхронизации",
"getDbStatusFailed": "Ошибка получения статуса базы данных",
"notRemoteMode": "Режим удаленной базы данных не активирован, перезапустите приложение",
"dbNotConnected": "База данных не подключена"
},
"auth": {
"unlock": "Разблокировать разрешение",
"unlockHint": "Введите 6-значный пароль: пароль администратора = полный доступ, пароль баллов = только операции с баллами.",
"unlockButton": "Разблокировать",
"unlocked": "Разрешение разблокировано",
"logout": "Переключено в режим только для чтения",
"passwordPlaceholder": "например, 123456",
"passwordError": "Неверный пароль",
"enterPassword": "Введите пароль",
"lock": "Заблокировать"
},
"languages": {
"zh-CN": "简体中文",
"en-US": "English",
"ja-JP": "日本語",
"fr-FR": "Français",
"es-ES": "Español",
"ko-KR": "한국어",
"ru-RU": "Русский",
"de-DE": "Deutsch",
"pt-BR": "Português",
"ar-SA": "العربية"
},
"theme": {
"colorAndBackground": "Цвет и фон",
"gradientLabels": {
"blue": "Свежий синий",
"pink": "Нежный розовый",
"cyan": "Голубой",
"purple": "Фиолетовый"
},
"gradientDirections": {
"vertical": "Вертикально",
"horizontal": "Горизонтально",
"diagonal": "По диагонали"
},
"generate": "Создать",
"saved": "Сохранено",
"saveFailed": "Ошибка сохранения",
"mode": "Режим",
"myTheme": "Моя тема"
},
"permissions": {
"admin": "Разрешение администратора",
"points": "Разрешение баллов",
"view": "Только для чтения"
},
"home": {
"title": "Домашняя страница баллов студентов",
"subtitle": "Всего {{count}} студентов, нажмите на карточку для выполнения операций",
"searchPlaceholder": "Поиск имени/пиньинь...",
"sortBy": {
"alphabet": "Сортировка по имени",
"surname": "Группа по фамилии",
"group": "Сортировка по группе",
"score": "Рейтинг по баллам"
},
"layoutBy": {
"grouped": "Группированный список",
"squareGrid": "Квадратная сетка"
},
"noStudents": "Нет данных о студентах, пожалуйста, добавьте в управлении студентами",
"noMatch": "Нет совпадающих студентов",
"clearSearch": "Очистить поиск",
"points": "баллы",
"currentScore": "Текущие баллы",
"quickOptions": "Быстрые опции",
"adjustPoints": "Настройка баллов",
"customPoints": "Пользовательские баллы",
"customPointsHint": "Введите любое значение в поле ввода",
"reason": "Причина",
"reasonPlaceholder": "Введите причину изменения баллов (необязательно)",
"preview": "Предпросмотр изменения",
"noReason": "(Без причины)",
"ungrouped": "Без группы",
"category": {
"others": "Другие"
},
"scoreAdded": "{{points}} баллов добавлено {{name}}",
"scoreDeducted": "{{points}} баллов снято у {{name}}",
"submitFailed": "Ошибка отправки",
"pleaseSelectPoints": "Пожалуйста, выберите или введите баллы",
"reasonDefault": "{{action}} {{points}} баллов",
"studentCount": "{{count}} студентов",
"operationTitle": "Операция с баллами: {{name}}",
"submitOperation": "Отправить операцию",
"operationTitleBatch": "Операция с баллами: выбрано {{count}}",
"undoLastAction": "Отменить",
"undoLastHint": "Отменить последнее: {{name}} {{delta}}",
"undoUnavailable": "Нет операций с баллами для отмены",
"undoLastSuccess": "Последняя операция с баллами отменена",
"multiSelect": "Множественный выбор",
"batchMode": "Пакетный режим",
"selectAll": "Выбрать все",
"clearSelected": "Очистить выбор",
"batchOperate": "Пакетные баллы",
"selected": "Выбрано",
"selectedCount": "Выбрано {{count}}",
"batchSuccess": "Баллы отправлены для {{count}} студентов",
"batchPartial": "Успешно отправлено {{success}}/{{total}} студентов",
"selectStudentFirst": "Пожалуйста, сначала выберите одного или нескольких студентов",
"addPoints": "Добавить баллы",
"deductPoints": "Снять баллы",
"pointsChange": "Изменение баллов",
"reasonLabel": "Причина: "
},
"students": {
"title": "Управление студентами",
"importList": "Импорт списка",
"addStudent": "Добавить студента",
"name": "Имя",
"group": "Группа",
"avatar": "Аватар",
"currentScore": "Текущие баллы",
"tags": "Теги",
"noTags": "Нет тегов",
"editTags": "Редактировать теги",
"editAvatar": "Настроить аватар",
"deleteConfirm": "Подтвердить удаление этого студента?",
"addTitle": "Добавить студента",
"addConfirm": "Добавить",
"namePlaceholder": "Введите имя студента",
"groupPlaceholder": "Введите название группы (необязательно)",
"nameRequired": "Пожалуйста, введите имя",
"nameExists": "Имя студента уже существует",
"addSuccess": "Добавлено успешно",
"addFailed": "Ошибка добавления",
"deleteSuccess": "Удалено успешно",
"deleteFailed": "Ошибка удаления",
"tagSaveSuccess": "Теги сохранены успешно",
"tagSaveFailed": "Ошибка сохранения тегов",
"importTitle": "Импорт списка",
"importTextHint": "Вставьте несколько строк, одно имя студента на строку",
"importTextPlaceholder": "Пример:\nИван\nМария\nПётр",
"importByText": "Импорт из текста",
"importByXlsx": "Импорт через xlsx",
"importByBanyou": "Импорт из BanYou",
"xlsxPreview": "Предпросмотр и импорт xlsx",
"file": "Файл",
"selectNameCol": "Нажмите на заголовок для выбора столбца с именами",
"previewRows": "Предпросмотр первых 50 строк",
"importConfirm": "Импорт",
"importComplete": "Импорт завершен: добавлено {{inserted}}, пропущено {{skipped}}",
"workerNotReady": "Рабочий не инициализирован",
"parseXlsxFailed": "Ошибка анализа xlsx",
"selectNameColFirst": "Пожалуйста, сначала выберите «Столбец с именами»",
"noNamesFound": "В выбранном столбце не найдено импортируемых имен",
"importFailed": "Ошибка импорта",
"banyouCookieHint": "После входа в BanYou Web скопируйте полную куку и вставьте ниже.",
"banyouCookiePlaceholder": "uid=...; accessToken=...; ...",
"banyouCookieRequired": "Пожалуйста, сначала вставьте куку",
"banyouFetch": "Получить список классов",
"banyouFetchSuccess": "Получено {{count}} классов",
"banyouFetchFailed": "Ошибка получения классов BanYou",
"banyouCreatedClasses": "Мои созданные классы",
"banyouJoinedClasses": "Мои присоединенные классы",
"banyouNoClasses": "Нет данных о классах"
},
"boards": {
"title": "Управление досками",
"addBoard": "Добавить доску",
"editBoard": "Редактировать доску",
"deleteBoard": "Удалить доску",
"name": "Название доски",
"description": "Описание",
"visibility": "Видимость",
"public": "Публичная",
"private": "Частная",
"studentsCount": "{{count}} студентов",
"noBoards": "Нет досок",
"addTitle": "Добавить доску",
"editTitle": "Редактировать доску",
"namePlaceholder": "Введите название доски",
"descriptionPlaceholder": "Введите описание",
"confirmDelete": "Подтвердить удаление этой доски?",
"saved": "Сохранено",
"saveFailed": "Ошибка сохранения",
"deleted": "Удалено",
"deleteFailed": "Ошибка удаления",
"boardExists": "Доска уже существует"
},
"leaderboard": {
"title": "Таблица лидеров",
"sortBy": "Сортировать по",
"score": "Баллы",
"name": "Имя",
"rank": "Ранг",
"student": "Студент",
"points": "Баллы",
"noData": "Нет данных рейтинга",
"topStudents": "Лучшие студенты",
"rankChanged": "Ранг: {{rank}}"
},
"settlements": {
"title": "История расчетов",
"phase": "Этап",
"date": "Дата",
"studentCount": "Количество студентов",
"totalPoints": "Всего баллов",
"actions": "Действия",
"viewDetails": "Просмотреть детали",
"noSettlements": "Нет расчетов",
"phaseDetail": "Детали этапа {{phase}}",
"settlementDate": "Дата расчета: {{date}}",
"totalStudents": "Всего студентов: {{count}}",
"totalPointsChange": "Общее изменение баллов: {{points}}"
},
"reasons": {
"title": "Управление причинами",
"addReason": "Добавить причину",
"editReason": "Редактировать причину",
"name": "Название причины",
"points": "Баллы",
"positive": "Положительный",
"negative": "Отрицательный",
"noReasons": "Нет причин",
"addTitle": "Добавить причину",
"editTitle": "Редактировать причину",
"namePlaceholder": "Введите название причины",
"pointsPlaceholder": "Введите баллы",
"confirmDelete": "Подтвердить удаление этой причины?",
"saved": "Сохранено",
"saveFailed": "Ошибка сохранения",
"deleted": "Удалено",
"deleteFailed": "Ошибка удаления",
"reasonExists": "Причина уже существует"
},
"autoScore": {
"title": "Автоматическое добавление баллов",
"addRule": "Добавить правило",
"editRule": "Редактировать правило",
"deleteRule": "Удалить правило",
"ruleName": "Название правила",
"trigger": "Триггер",
"action": "Действие",
"interval": "Интервал",
"enabled": "Включено",
"noRules": "Нет правил",
"addTitle": "Добавить правило",
"editTitle": "Редактировать правило",
"namePlaceholder": "Введите название правила",
"triggerPlaceholder": "Выберите триггер",
"actionPlaceholder": "Выберите действие",
"intervalPlaceholder": "Выберите интервал",
"confirmDelete": "Подтвердить удаление этого правила?",
"saved": "Сохранено",
"saveFailed": "Ошибка сохранения",
"deleted": "Удалено",
"deleteFailed": "Ошибка удаления",
"ruleExists": "Правило уже существует"
},
"rewardExchange": {
"title": "Обмен наградами",
"rewards": "Награды",
"exchange": "Обмен",
"history": "История",
"noRewards": "Нет наград",
"noHistory": "Нет истории",
"rewardName": "Название награды",
"cost": "Стоимость",
"stock": "Склад",
"exchangeSuccess": "Обмен успешен",
"exchangeFailed": "Ошибка обмена",
"insufficientPoints": "Недостаточно баллов",
"outOfStock": "Нет в наличии"
},
"rewardSettings": {
"title": "Настройки наград",
"addReward": "Добавить награду",
"editReward": "Редактировать награду",
"deleteReward": "Удалить награду",
"name": "Название",
"cost": "Стоимость",
"stock": "Склад",
"noRewards": "Нет наград",
"addTitle": "Добавить награду",
"editTitle": "Редактировать награду",
"namePlaceholder": "Введите название",
"costPlaceholder": "Введите стоимость",
"stockPlaceholder": "Введите склад",
"confirmDelete": "Подтвердить удаление этой награды?",
"saved": "Сохранено",
"saveFailed": "Ошибка сохранения",
"deleted": "Удалено",
"deleteFailed": "Ошибка удаления",
"rewardExists": "Награда уже существует"
},
"recovery": {
"title": "Строка восстановления SecScore",
"saved": "Я сохранил",
"export": "Экспорт текстового файла",
"exportHint": "Рекомендуется экспортировать и хранить в автономном режиме. При потере восстановить невозможно.",
"hint": "Рекомендуется экспортировать и хранить в автономном режиме после экспорта. При потере восстановить невозможно."
}
}