feat: документация из Nextcloud, график у сотрудника, автоочистка фото, мониторинг, итог мастера, фильтр по местам; доп. сервисы в docker-compose
- docker-compose.yml: профили docs (Nextcloud), office (ONLYOFFICE Document Server), ai (Ollama + скачивание модели) - автонастройка: адреса Nextcloud, ONLYOFFICE, портала и модели подставляются из .env или по именам сервисов во внутренней сети Docker; значения из интерфейса важнее - локальная модель в своей сети (имя сервиса, частный IP) подключается без ключа API - .env.example, docs/DEPLOY.md (раздел 7а), README
This commit is contained in:
+62
-11
@@ -333,8 +333,9 @@ def build():
|
||||
["Наряд", "Одно задание: что проверить или обслужить, на каком оборудовании, кому, до какого срока и кто проверит."],
|
||||
["Чек-лист", "Список задач внутри наряда. У каждой задачи свой тип ответа: статус, выбор из списка, число или текст; "
|
||||
"у некоторых нужно приложить фото."],
|
||||
["Должность и график", "Сотрудник привязан к должности, у должности есть график (смены). Наряд, назначенный на должность, "
|
||||
"видят и могут взять только те, кто сейчас на смене."],
|
||||
["Должность и график", "Сотрудник занимает должность и работает по своему графику (смены). Одну должность могут занимать "
|
||||
"несколько сменщиков. Наряд, назначенный на должность, видят, берут и получают уведомление только те, "
|
||||
"кто сейчас на смене, — сменщики дома не беспокоятся."],
|
||||
["Расписание нарядов", "Наряд настраивается один раз и затем создаётся автоматически: каждый день, по дням недели, "
|
||||
"раз в месяц или каждые N дней."],
|
||||
["Проверка", "После сдачи наряд уходит проверяющему: он принимает его или возвращает на доработку с комментарием."],
|
||||
@@ -562,7 +563,8 @@ def build():
|
||||
pdf.bullets([
|
||||
"для **числа** задайте единицу измерения и границы нормы — отклонения будут подсвечиваться и попадут в отчёт;",
|
||||
"для **списка** — варианты ответа, по одному в строке;",
|
||||
"для любой задачи — режим фото: без фото, по желанию, обязательно;",
|
||||
"для любой задачи — режим фото: без фото, по желанию, обязательно; если фото нужно сохранить надолго (табличка, акт, "
|
||||
"дефект), отметьте **«хранить более года»** — такие снимки лежат в отдельном каталоге и не удаляются автоочисткой сервера;",
|
||||
"стрелками меняется порядок задач, галочкой «Обязательный» отмечаются пункты, без которых наряд не сдать.",
|
||||
])
|
||||
pdf.wide("d_checklist", "Редактор чек-листа")
|
||||
@@ -708,6 +710,15 @@ def build():
|
||||
"В приложении Android история открывается кнопкой «История машины».")
|
||||
pdf.wide("d_history", "История машины с фильтрами")
|
||||
pdf.phone("a_history", "История машины в приложении Android", width=70)
|
||||
pdf.h2("Документация машины (Nextcloud)")
|
||||
pdf.p("Если подключён Nextcloud, в карточке машины есть блок **«Документация»**: паспорта, руководства, схемы, хранящиеся "
|
||||
"в Nextcloud по машинам. Кнопка **«Открыть»** показывает папку машины: слева файлы и вложенные папки, справа — документ. "
|
||||
"**PDF, картинки и текстовые файлы** открываются прямо в портале, документы **Word, Excel, PowerPoint** — тоже, после перевода в PDF "
|
||||
"на сервере ONLYOFFICE (первое открытие — несколько секунд). Любой файл можно **скачать**. Заходить в Nextcloud не нужно: "
|
||||
"портал сам забирает файлы и показывает только документацию машин, которые видит сотрудник.")
|
||||
pdf.p("**Привязывают папку администратор или модератор**: «Привязать папку» в блоке «Документация» открывает проводник по "
|
||||
"документации — выберите папку машины и нажмите «Выбрать» или «Привязать эту папку». Рядом с папкой видно, к каким машинам "
|
||||
"она уже привязана. «Сменить папку» и «Отвязать» — там же.")
|
||||
pdf.h2("Сообщения об отказах извне")
|
||||
pdf.p("Об аварии может сообщить и человек без учётной записи — подрядчик, охрана, смежная служба. Для этого есть **публичная "
|
||||
"форма** по адресу **/report** (её удобно разместить на QR-коде у оборудования). В форме выбирается **место** — после этого "
|
||||
@@ -832,16 +843,22 @@ def build():
|
||||
"висит приглашение запустить мастер). Мастер проводит по шагам в порядке зависимостей данных:")
|
||||
pdf.bullets([
|
||||
"**Сервер** — проверить часовой пояс, каталог фото, время сервера.",
|
||||
"**Графики** — типовые одним нажатием (пятидневка, сутки через трое, 2/2 день-ночь, круглосуточно) или в конструкторе.",
|
||||
"**Графики** — типовые одним нажатием (пятидневка, сутки через трое, 2/2 день-ночь, круглосуточно) или в конструкторе. "
|
||||
"График потом назначается каждому сотруднику.",
|
||||
"**Должности → отделы → места → оборудование** — пакетным вводом: одна строка — одна запись, поля через «;». "
|
||||
"Для оборудования: «Название; инв. №; место; наработка; отдел; кран» — отдел закрепляет машину за службой, слово «кран» "
|
||||
"отправляет её в раздел «Краны».",
|
||||
"**Сотрудники** — строки «ФИО; логин; должность; отдел; роль». Логины и временные пароли создаются сами и показываются "
|
||||
"**Сотрудники** — строки «ФИО; логин; должность; отдел; график; роль». Логины и временные пароли создаются сами и показываются "
|
||||
"таблицей для печати или CSV — **только один раз**.",
|
||||
"**Карта завода** (и подсказка про отдельную карту кранов), **склады и начальные остатки инструмента**, **чек-листы и расписание**, **внешние обращения**, **резервные копии**.",
|
||||
])
|
||||
pdf.wide("d_setup", "Мастер первичной настройки")
|
||||
pdf.note("Шаг считается выполненным, когда в нём есть записи, или если отметить «шаг выполнен». К мастеру можно возвращаться в любое время.", "info")
|
||||
pdf.note("Шаг считается выполненным, когда в нём есть записи, или если отметить «шаг выполнен» — мастер сразу переходит к следующему. "
|
||||
"К мастеру можно возвращаться в любое время.", "info")
|
||||
pdf.p("Кнопка **«Завершить и проверить»** на последнем шаге открывает **проверку готовности**: мастер смотрит на введённые данные и "
|
||||
"показывает, что мешает работе — сотрудники без должности, должности, которые никто не занимает, должности, где сейчас по "
|
||||
"графикам никого нет на смене, машины без места, нет чек-листов или расписания, выключены автокопии или автоочистка фото. "
|
||||
"Рядом с каждым пунктом — кнопка, чтобы поправить. После завершения плитка мастера ведёт сразу к этой проверке.")
|
||||
|
||||
pdf.h2("AI-помощник (включает администратор)")
|
||||
pdf.p("В «Настройках сервера» администратор может включить **AI-помощника**: указать провайдера (OpenAI-совместимый — OpenAI, "
|
||||
@@ -855,6 +872,12 @@ def build():
|
||||
"Ключ API не показывается в настройках и не попадает в резервные копии.",
|
||||
])
|
||||
pdf.wide("d_assistant_settings", "Настройка AI-помощника")
|
||||
pdf.p("**«Работа с документацией»** — отдельная опция помощника в той же карточке. Включённая, она раз в сутки собирает индекс "
|
||||
"документации машин (имена файлов и начало текста PDF и документов Office), и помощник отвечает на вопросы вида "
|
||||
"«где схема двигателя компрессора?» ссылкой на нужный файл и подсказкой, что в нём искать.")
|
||||
pdf.note("Риски опции: имена файлов и фрагменты документов уходят провайдеру ИИ — с облачным провайдером документация покидает "
|
||||
"предприятие, для закрытых документов используйте локальную модель. Запросы становятся в разы длиннее, расход токенов "
|
||||
"растёт. Помощник видит только начало документов — ответ проверяйте в самом файле.", "warn")
|
||||
pdf.wide("d_assistant", "Помощник: ответ по данным пользователя и подсказка «как сделать»")
|
||||
pdf.phone("a_assistant", "Помощник в приложении Android (круглая кнопка справа внизу или пункт меню «Помощник»)", width=70)
|
||||
|
||||
@@ -883,9 +906,13 @@ def build():
|
||||
"пользователя. Остальным администраторам мастер первичной настройки и резервные копии доступны как обычно.")
|
||||
|
||||
pdf.h2("Должности и графики работы")
|
||||
pdf.p("**Должность** имеет тип (**техник** выполняет наряды, **инженер** проверяет и планирует) и **график**. По графику "
|
||||
"система определяет, кто сейчас «на смене» и кому показывать наряды, назначенные на должность. Должность без графика "
|
||||
"считается всегда на смене.")
|
||||
pdf.p("**Должность** имеет тип (**техник** выполняет наряды, **инженер** проверяет и планирует). **График** задаётся не должности, "
|
||||
"а **сотруднику** («Пользователи» → «Изменить» → «График работы»): должность выполняет тот, кто её занимает и сейчас на смене. "
|
||||
"Например, «Дежурный механик» — четыре сменщика с графиком «сутки через трое», каждый со своим первым днём цикла: наряд или "
|
||||
"задание на эту должность увидит и получит уведомление только тот, кто сегодня дежурит. Сотрудник без графика считается "
|
||||
"всегда на смене.")
|
||||
pdf.note("При обновлении портала графики, которые раньше были заданы должностям, автоматически перенесены их сотрудникам. "
|
||||
"Для сменщиков поправьте графики (или первый день цикла), чтобы на смене был один человек.", "info")
|
||||
pdf.p("Графики настраиваются **конструктором**: можно собрать любой цикл — дневные и ночные смены, отсыпные, сутки через трое. "
|
||||
"Каждый шаг цикла — это «Смена» или «Выходной», число дней подряд, время начала и конца и метка (например, «день», "
|
||||
"«ночь», «отсыпной»). Если конец смены раньше начала (20:00–08:00), смена ночная; одинаковое время (08:00–08:00) — сутки.")
|
||||
@@ -901,6 +928,8 @@ def build():
|
||||
pdf.p("Разделы **«Оборудование»** и **«Места»** — справочники для нарядов и отчётов. Оборудование можно привязать к месту "
|
||||
"(например, «Цех №1»), указать инвентарный номер, **отдел** (кто его видит) и отметку **«Кран»**. Неиспользуемое оборудование "
|
||||
"отключается флажком «Активно».")
|
||||
pdf.p("Над списком оборудования (и кранов) — фильтр **«Место»**: выберите цех или участок, и в списке останутся машины этого "
|
||||
"места и всех вложенных в него мест (например, «Цех №1» покажет и машины «Компрессорной», входящей в цех).")
|
||||
|
||||
pdf.h2("Обратная связь по порталу")
|
||||
pdf.p("Внизу каждой страницы сайта — неприметная ссылка **«Предложить улучшение портала или сообщить об ошибке»**; в мобильной версии и "
|
||||
@@ -914,6 +943,15 @@ def build():
|
||||
pdf.p("Раздел **«Настройки сервера»** позволяет изменить каталог для хранения фотографий и максимальный размер снимка, а также "
|
||||
"ключ для мгновенных уведомлений Android, включить публичную форму заявок и **«Краны — отдельная служба»**. Внизу виден "
|
||||
"расход места: сколько фото хранится и сколько свободно на диске.")
|
||||
pdf.p("**Автоочистка фото**: поле «удалять фото нарядов и заданий старше, дней» (например, 365). Раз в сутки сервер удаляет "
|
||||
"фото старше этого срока; 0 — не удалять. Снимки с отметкой **«хранить более года»** (в чек-листе у пункта или в задании) "
|
||||
"с самого начала лежат в отдельном каталоге **keep/** и не удаляются. В блоке «Состояние» видно, сколько фото будет удалено "
|
||||
"при следующей очистке; кнопка «Очистить сейчас» запускает её сразу.")
|
||||
pdf.note("Удалённые фото не восстановить, кроме как из резервной копии с фото. По умолчанию автоочистка выключена.", "warn")
|
||||
pdf.h2("Мониторинг сервера (только администратор портала)")
|
||||
pdf.p("«Администрирование → **Мониторинг сервера**»: круговые диаграммы загрузки **процессора**, занятой **памяти** и места на "
|
||||
"**дисках** с данными портала и фото. Значения обновляются каждые 5 секунд, пока страница открыта; от 75 % диаграмма "
|
||||
"становится жёлтой, от 90 % — красной. В Docker с лимитом памяти показывается память контейнера.")
|
||||
pdf.wide("d_server", "Настройки сервера", width=150)
|
||||
pdf.note("При смене каталога фото старые снимки автоматически **не переносятся** — скопируйте файлы вручную.", "warn")
|
||||
|
||||
@@ -935,6 +973,19 @@ def build():
|
||||
pdf.note("Рабочие данные в демо-режиме не изменяются и не удаляются.", "info")
|
||||
|
||||
# ================= 7 =================
|
||||
pdf.h2("Подключение Nextcloud и ONLYOFFICE")
|
||||
pdf.p("«Настройки сервера» → **«Документация из Nextcloud»** (только администратор портала).")
|
||||
pdf.bullets([
|
||||
"В Nextcloud заведите служебного пользователя (например, portal-docs), дайте ему **доступ только на чтение** к папке "
|
||||
"с документацией и создайте для него **пароль приложения** (Настройки → Безопасность).",
|
||||
"В портале укажите адрес Nextcloud (лучше внутренний, в локальной сети), учётную запись, пароль приложения и корневую папку "
|
||||
"документации. Кнопка «Проверить» покажет, сколько папок видно в корне.",
|
||||
"Для документов Office укажите адрес **ONLYOFFICE Document Server** в локальной сети, его **секрет JWT** (если включён) и "
|
||||
"**внутренний адрес портала** — по нему ONLYOFFICE забирает исходник по одноразовой ссылке. Без ONLYOFFICE документы "
|
||||
"Office только скачиваются.",
|
||||
"Сотрудникам Nextcloud не нужен: портал сам ходит в него и проверяет, кто какую машину видит. Пароль приложения и секрет "
|
||||
"JWT не показываются в настройках и не попадают в резервные копии.",
|
||||
])
|
||||
pdf.h1("14. Частые вопросы")
|
||||
faq = [
|
||||
("Я не вижу машину (или кран), которая точно есть.",
|
||||
@@ -944,8 +995,8 @@ def build():
|
||||
"Вы в демонстрационном режиме — это тестовые данные. Нажмите **«Выйти из демо»** в полосе. Если кнопки нет или не помогает, "
|
||||
"попросите администратора выключить демо для вас."),
|
||||
("Я не вижу наряд, который мне должны были назначить.",
|
||||
"Наряд, назначенный на должность, виден только сотрудникам этой должности **на смене**. Проверьте график смены и должность в "
|
||||
"настройках; если вы вне смены — наряд появится, когда смена начнётся. Нажмите обновление списка. Если наряд назначен "
|
||||
"Наряд, назначенный на должность, виден только сотрудникам этой должности **на смене** по их графику. Проверьте свой график "
|
||||
"и должность в карточке; если вы вне смены — наряд появится, когда смена начнётся. Нажмите обновление списка. Если наряд назначен "
|
||||
"другому человеку или уже взят коллегой, вы его не увидите."),
|
||||
("Пишет «Нет связи» или «не отправлено» и не исчезает.",
|
||||
"Проверьте интернет на телефоне. Данные сохранены и не пропадут: они уйдут сами. Для немедленной попытки нажмите кнопку "
|
||||
|
||||
Reference in New Issue
Block a user