|
Professor Seleznov
|
Всё началось с того, что студенты попросили нормальный онлайн-доступ к своим оценкам и расписанию. В нашем колледже стоит 1С:Колледж ПРОФ — всё там есть, но интерфейс десктопный и для студентов закрытый. Я решил сделать личный кабинет. Это история о том, что из этого вышло.
Официальное решение и почему я его не взял Фирма "1С" совместно с компанией "Онлайн" (г. Уфа) предлагает дополнительную лицензию на доступ из мобильных приложений и веб-сайтов. Идея хорошая: публикуешь HTTP-сервисы на сервере, покупаешь лицензию — и твоё приложение может обращаться к данным 1С напрямую. Цена — 15 000 рублей в год, с ежегодным продлением. Тут я задумался. HTTP-сервисы уже опубликованы на нашем сервере. Лицензия просто «разрешает» обращаться к ним извне. Но если обращаться к ним не из браузера, а с собственного сервера — никакой лицензии не нужно. Браузер студента работает с моим сервером, мой сервер — со служебной учёткой в 1С. Так появилась схема: браузер → Next.js → 1С. Next.js играет роль посредника: проверяет авторизацию, проксирует запросы, отдаёт клиенту уже готовые данные. В коде это выглядит просто — каждый API-роут делает ровно одну вещь:
// src/app/api/student/journal/route.ts export async function GET(request: Request) { return success(await oneCGet("/Students/StudentAssessment", { UID: requireValue(searchParams.get("uid")), DisciplineUID: requireValue(searchParams.get("discipline_uid")), })); }
oneCGet — обёртка над fetch, которая ставит Basic-авторизацию со служебной учёткой из .env. Браузер эту учётку никогда не видит. Что получилось

Личный кабинет студента Студент видит личные данные, информацию об обучении (группа, специальность, статус, куратор), список дисциплин с преподавателями, электронный журнал с оценками и посещаемостью, расписание. Ещё можно заказать справку — об этом ниже. Преподаватель работает с электронным журналом своих групп — выставляет оценки и отметки прямо в браузере. Куратор смотрит успеваемость группы и обязанности студентов. Авторизация: студенты и преподаватели логинятся по-разному

Форма авторизации Студент входит по логину и паролю из 1С — отправляю их в сервис 1С, получаю подтверждение, создаю сессию. Преподаватель входит через email и одноразовый код. Причина простая: у многих преподавателей нет пароля в 1С, зато есть корпоративная почта. Отправляю код письмом, человек вводит — получает сессию. Сессия хранится в httpOnly-куке. Это значит, что JavaScript в браузере её не видит — что важно, ведь там зашит uid пользователя и его роль. Middleware проверяет куку на каждый запрос к API — если её нет или она протухла, сразу 401. Сторона 1С: пишем сервисы на русском Я знал, что в 1С код пишется на русском языке. Просто после Python и других языков программирования это ощущается непривычно: вместо привычных англоязычных конструкций здесь используются русские ключевые слова, а запросы к базе выглядят как ВЫБРАТЬ, ИЗ, ГДЕ. Но это нормальная практика для экосистемы 1С. Тем более базовый опыт работы с ней я получил ещё в вузе, поэтому быстро разобрался в логике: принять HTTP-запрос, выполнить запрос к данным, сформировать JSON и вернуть ответ клиенту. Самый приятный момент — заказ справки. Студент заполняет форму в браузере: тип справки, формат (бумажная), куда нужна. В 1С тут же создаётся реальный документ, а ответственному сотруднику уходит напоминание прямо в его рабочий стол:
Справка = Документы.ЗаказСправки.СоздатьДокумент(); Справка.Студент = НайденныйСтудент; Справка.ТипСправки = ТипСправки; Справка.Статус = Перечисления.СтатусыОбработкиЗаказаСправки.Новый; Справка.Записать(); РаботаСДокументами.ПодключитьНапоминаниеПользователю( "Заказ справки студентом " + ФИО, ТекущаяДата() + 120, , Справка.Ссылка, "Заказ справки", Ответственный );
Студент кликнул кнопку в браузере — сотрудник увидел задачу в 1С через две минуты. Без почты, без звонков.

Заказ справки Главная боль: данные из 1С нестабильны Когда начал получать реальные ответы от сервисов, обнаружил несколько неприятных вещей. Имена полей гуляют. Одно и то же поле в разных сервисах называется UID, uid, StudentUID. Видимо, разные части писали разные люди. Пришлось написать хелпер:
function pickValue(source, keys, fallback = null) { for (const key of keys) { if (source[key] != null) return source[key]; } return fallback; } // pickValue(item, ["UID", "uid", "StudentUID"])
Строки приходят как объекты. Вместо "Иванов Иван" может прийти { Presentation: "Иванов Иван", Value: "..." }. Это особенность сериализации 1С — написал функцию, которая разворачивает такой конверт до строки. Дисциплины и практики вперемешку. В списке дисциплин могут оказаться учебная и производственная практика — с другим типом UID. Определяю тип по имени через регулярку. Некрасиво, но работает. Формат ошибок непредсказуем. Иногда HTTP 200 с { Result: false }, иногда HTTP 500 с пустым телом. Написал единый обработчик для всех случаев. На всю эту нормализацию ушло столько же времени, сколько на весь остальной код. Это самая скучная и самая важная часть. Электронный журнал преподавателя

Электронный журнал преподавателя Строки — студенты, столбцы — занятия, ячейки — оценки и посещаемость. Думал про UX: как сделать выставление оценок быстрым? Мышкой кликать в каждую ячейку неудобно — руки всё время между мышкой и клавиатурой. Сделал так: цифра на клавиатуре сразу ставит оценку в выбранную ячейку, стрелки переключают между ячейками, Enter открывает редактирование если нужно ввести что-то нестандартное. Преподаватели освоили быстрее, чем ожидал. Один сказал что работать в браузере удобнее, чем в десктопном клиенте 1С — там каждое сохранение ощущается, здесь нет. Что удивило в процессе React Query спас много нервов. Данные из 1С не самые свежие — расписание раз в день, журнал по мере занятий. React Query хранит ответ в кеше и показывает его, пока подгружает новый. Никакого мерцания, никакого «загрузка...» при каждом переходе. App Router оказался хорош именно для этого паттерна. Серверный код физически отделён от клиентского. Случайно утащить секрет из .env в браузерный бандл — сложно. Служебные данные 1С остаются на сервере. Пуш-уведомления добавил позже по просьбе студентов. Хотели знать о новых оценках. Сделал через Web Push — подписки хранятся у нас, рассылка происходит когда преподаватель сохраняет журнал. Итог Проект работает в production уже несколько месяцев. Студенты и преподаватели действительно пользуются системой: журнал и заказ справок стали самыми популярными разделами. При этом удалось сэкономить около 15 000 рублей в год на дополнительной лицензии (на самом деле не большие деньги). Но это не главное. Главное — система получилась именно такой, какой мы хотели её видеть. Если коротко о том, что стоит знать перед похожим проектом: основная работа здесь не столько в написании компонентов, сколько в борьбе с форматом данных на стыке двух очень разных систем. 1С и JSON живут в разных мирах, и переводчиком между ними становишься ты. При этом такой подход даёт большую свободу: через собственные HTTP-сервисы можно реализовать практически всё что угодно — личный кабинет, расписание, журнал, мероприятия, отчёты, роли пользователей и другие разделы. Вопрос чаще не в том, возможно ли это сделать, а в том, сколько времени потребуется. Нужно внимательно смотреть, как нужная логика уже реализована внутри самой 1С: где хранятся данные, какие документы, справочники и регистры используются, какие связи между объектами есть в конфигурации. Только после этого становится понятно, что и как правильно отдавать наружу. И здесь важный момент: я не отдельный 1С-разработчик и не человек, который годами занимается только интеграциями. Я обычный преподаватель, который ведёт веб-разработку. Поэтому этот проект стал не просто технической задачей, а практическим доказательством того, что при желании, внимательном разборе логики 1С и понимании веб-технологий можно собрать рабочую систему, которой реально пользуются.-Источник
|