esoe
2 weeks ago
26 changed files with 16697 additions and 66 deletions
@ -0,0 +1 @@ |
|||||||
|
,devpc/devuser,devpc,07.11.2024 10:34,file:///C:/Users/devuser/AppData/Roaming/LibreOffice/4; |
Binary file not shown.
@ -0,0 +1,157 @@ |
|||||||
|
@startuml |
||||||
|
!define primary_key(x) <b><color:#b8861b><&key></color> x</b> |
||||||
|
!define foreign_key(x) <b><color:#aaaaaa><&key></color> x</b> |
||||||
|
!define column(x) <b><color:#efefef><&media-record></color> x</b> |
||||||
|
!define table(x) entity x << (T, white) >> |
||||||
|
|
||||||
|
' left to right direction |
||||||
|
|
||||||
|
title "Entity Relationship Diagram (ERD): exam (пополнение и провера знаний)" |
||||||
|
|
||||||
|
' Аккаунты пользователей |
||||||
|
table(account) #eaa { |
||||||
|
primary_key(id): LONGSERIAL >>"Идентификатор" |
||||||
|
column(code): String >>"35-ичный код (логин)" |
||||||
|
foreign_key(orgstructure_id): LONGSERIAL >>"идентификатор места работы" |
||||||
|
} |
||||||
|
|
||||||
|
' Оргструктура |
||||||
|
table(orgstructure) #eaa { |
||||||
|
primary_key(id): LONGSERIAL >>"Идентификатор" |
||||||
|
foreign_key(organization_id): LONGSERIAL>>"Идентификатор организации" |
||||||
|
foreign_key(position_id): LONGSERIAL>>"Идентификатор должности" |
||||||
|
} |
||||||
|
|
||||||
|
orgstructure --{ account |
||||||
|
|
||||||
|
' Организации |
||||||
|
table(organization) #eaa { |
||||||
|
primary_key(id): LONGSERIAL >>"Идентификатор" |
||||||
|
column(name): STRING >>"Наименование" |
||||||
|
} |
||||||
|
|
||||||
|
organization --{ orgstructure |
||||||
|
|
||||||
|
' Должности |
||||||
|
table(position) #eaa { |
||||||
|
primary_key(id): LONGSERIAL >>"Идентификатор" |
||||||
|
column(name): STRING >>"Наименование" |
||||||
|
} |
||||||
|
|
||||||
|
position --{ orgstructure |
||||||
|
|
||||||
|
' Курсы |
||||||
|
' По идентификатору курса определяется положение соответствующего курса |
||||||
|
' в файловой системе сервиса |
||||||
|
table(course){ |
||||||
|
primary_key(id): LONGSERIAL >>"Идентификатор" |
||||||
|
column(name): STRING >>"Наименование" |
||||||
|
column(short): STRING >>"Сокращенно" |
||||||
|
} |
||||||
|
note top |
||||||
|
Не понятно, стоит ли хранить в базе пути до контента курса, |
||||||
|
или достаточно создавать курсы в виде статических директорий |
||||||
|
|
||||||
|
Если курс состоит из тем, где будет определен порядок представления тем пользователю |
||||||
|
end note |
||||||
|
|
||||||
|
' тема |
||||||
|
table(theme){ |
||||||
|
primary_key(id): LONGSERIAL >>"Идентификатор" |
||||||
|
column(name): STRING >>"Наименование" |
||||||
|
' foreign_key(course_id):LONGSERIAL >>"ID курса" |
||||||
|
} |
||||||
|
note top |
||||||
|
Курс может состоять из одной или нескольких тем |
||||||
|
тема определяет состав вопросов, которые смогут попасть в опрос по курсу |
||||||
|
|
||||||
|
Само тело курса также возможно разбить на отдельные темы, |
||||||
|
материал по которым будет оформляться в отдельных *.md файлах |
||||||
|
end note |
||||||
|
|
||||||
|
' course --{ theme |
||||||
|
|
||||||
|
' порядок расположения тем в курсе |
||||||
|
table(scheme){ |
||||||
|
primary_key(id): LONGSERIAL >>"Идентификатор" |
||||||
|
foreign_key(course_id): LONGSERIAL >>"Идентификатор курса" |
||||||
|
foreign_key(theme_id): LONGSERIAL >>"Идентификатор темы" |
||||||
|
column(position) INTEGER >>"Порядковый номер темы в курсе" |
||||||
|
} |
||||||
|
note top |
||||||
|
Схема курса |
||||||
|
определяет последовательность размещения тем в курсе |
||||||
|
end note |
||||||
|
|
||||||
|
course --{ scheme |
||||||
|
theme --{ scheme |
||||||
|
|
||||||
|
' Список задач |
||||||
|
table(target) #eaa { |
||||||
|
primary_key(id): LONGSERIAL >>"Идентификатор задачи" |
||||||
|
foreign_key(orgstructure_id): LONGSERIAL >>"Идентификатор категории должности" |
||||||
|
foreign_key(course_id): LONGSERIAL >>"Идентификатор курса" |
||||||
|
column(questions_count): INTEGER >>"Количество вопросов для тестирования" |
||||||
|
column(limit): INTEGER >>"Количество вопросов, для успешного завершения опроса" |
||||||
|
} |
||||||
|
note top |
||||||
|
Тут формируется перечень назначенных пользователю курсов, |
||||||
|
на основании наименования организации и должности работника |
||||||
|
|
||||||
|
Тут определено общее количество вопросов для тестирвоания, |
||||||
|
далее вопросы берутся случайным образом из тем, относящихся к курсу в равных пропорциях |
||||||
|
end note |
||||||
|
|
||||||
|
|
||||||
|
orgstructure --{ target |
||||||
|
course --{ target |
||||||
|
|
||||||
|
' Вопросы |
||||||
|
table(question){ |
||||||
|
primary_key(id): LONGSERIAL >>"Идентификатор вопроса" |
||||||
|
column(body): String >>"Содержание вопроса" |
||||||
|
foreign_key(theme_id): LONGSERIAL >>"Идентификатор темы вопроса" |
||||||
|
} |
||||||
|
theme --{ question |
||||||
|
|
||||||
|
table(answer){ |
||||||
|
primary_key(id): LONGSERIAL >>"Идентификатор ответа" |
||||||
|
column(body): STRING >>"Содержание ответа" |
||||||
|
foreign_key(question_id): LONGSERIAL >>"Идентификатор вопроса" |
||||||
|
column(status): BOOLEAN >>"статус ответа: верно / не верно" |
||||||
|
column(description): STRING >>"Пояснения, обоснование ответа" |
||||||
|
} |
||||||
|
question --{ answer |
||||||
|
|
||||||
|
' Опрос |
||||||
|
table(quiz) #88f { |
||||||
|
primary_key(id): LONGSERIAL >>"Идентификатор опроса" |
||||||
|
foreign_key(account_id): LONGSERIAL >>"Идентификатор аккаунта" |
||||||
|
foreign_key(target_id): LONGSERIAL >>"Идентификатор задания" |
||||||
|
foreign_key(question_id): LONGSERIAL >>"Назначенный вопрос" |
||||||
|
foreign_key(answer_id): LONGSERIAL >>"Идентификатор данного ответа" |
||||||
|
column(datetime): DATETIME >>"Дата и время ответа" |
||||||
|
} |
||||||
|
question --{ quiz |
||||||
|
target --{ quiz |
||||||
|
account --{ quiz |
||||||
|
answer --{ quiz |
||||||
|
|
||||||
|
' Результаты |
||||||
|
table(results) #88f { |
||||||
|
primary_key(id): LONGSERIAL >>"Идентификатор опроса" |
||||||
|
foreign_key(account_id): LONGSERIAL >>"Идентификатор аккаунта" |
||||||
|
foreign_key(target_id): LONGSERIAL >>"Идентификатор задания" |
||||||
|
column(status): BOOLEAN >>"сдано / не сдано" |
||||||
|
column(passed): DATETIME >>"Дата завершения" |
||||||
|
} |
||||||
|
note top |
||||||
|
Запись в таблицу результатов происходит |
||||||
|
по клику кнопки в графическом интерфейсе |
||||||
|
пишется время клика и пересчитываются правильные отвты |
||||||
|
end note |
||||||
|
quiz --{ results |
||||||
|
account -down-{ results |
||||||
|
|
||||||
|
|
||||||
|
@enduml |
@ -0,0 +1,29 @@ |
|||||||
|
package gsp.technologies.main.quiz; |
||||||
|
|
||||||
|
import org.slf4j.Logger; |
||||||
|
import org.slf4j.LoggerFactory; |
||||||
|
import org.springframework.stereotype.Controller; |
||||||
|
import org.springframework.ui.Model; |
||||||
|
import org.springframework.web.bind.annotation.GetMapping; |
||||||
|
import org.springframework.web.bind.annotation.RequestMapping; |
||||||
|
import org.springframework.web.bind.annotation.RequestParam; |
||||||
|
|
||||||
|
import gsp.technologies.main.account.dto.AccountDTO; |
||||||
|
|
||||||
|
@Controller |
||||||
|
@RequestMapping(path = "/quiz") |
||||||
|
public class QuizController { |
||||||
|
private static final Logger log = LoggerFactory.getLogger(QuizController.class); |
||||||
|
|
||||||
|
@GetMapping("") |
||||||
|
public String quiz(Model model, @RequestParam(name = "accountid", required = true) String accountid) { |
||||||
|
log.info("GET /quiz"); |
||||||
|
AccountDTO accountDTO = AccountDTO.builder() |
||||||
|
.id(accountid) |
||||||
|
.code(accountid) |
||||||
|
.build(); |
||||||
|
|
||||||
|
model.addAttribute("account", accountDTO); |
||||||
|
return "quiz"; |
||||||
|
} |
||||||
|
} |
File diff suppressed because one or more lines are too long
Binary file not shown.
@ -1,2 +1,17 @@ |
|||||||
# Первая помощь |
# Курс: Охрана труда |
||||||
![pic](/content/courses/1/pictures/states.png) |
## Структура фреймов интерфейса |
||||||
|
![структура фреймов интерфейса](/content/courses/1/pictures/states.png) |
||||||
|
|
||||||
|
## Структура базы данных |
||||||
|
![структура базы данных](/content/courses/1/pictures/main.png) |
||||||
|
|
||||||
|
## Посмотрите поучительное видео про медоедов! |
||||||
|
<!-- <video src='/content/courses/1/video/Медоеду похер.mp4' width=180/> --> |
||||||
|
|
||||||
|
<video controls src="/content/courses/1/video/001.mp4" title="Title"></video> |
||||||
|
|
||||||
|
## Документы на скачивание |
||||||
|
[скачать](/content/courses/1/download/7.xlsx) |
||||||
|
|
||||||
|
## документ на просмотр в новой вкладке |
||||||
|
<a href="/content/courses/1/docs/horstman_k_sovremennii_javascript_dlya_neterpelivih_2021.pdf" target="_blank">javascript_dlya_neterpelivih_2021 в новой вкладке</a> |
After Width: | Height: | Size: 218 KiB |
Binary file not shown.
@ -0,0 +1 @@ |
|||||||
|
# Курс: Работы на высоте |
@ -0,0 +1 @@ |
|||||||
|
# Курс: Первая помощь |
@ -1,10 +1,11 @@ |
|||||||
|
<!-- Коллекция фрагментов для построения страницы курса --> |
||||||
<!DOCTYPE html> |
<!DOCTYPE html> |
||||||
<html xmlns:th="http://www.thymeleaf.org"> |
<html xmlns:th="http://www.thymeleaf.org"> |
||||||
|
|
||||||
<body> |
<body> |
||||||
<div th:fragment="main"> |
<div th:fragment="main(id)"> |
||||||
<hr> |
<hr> |
||||||
<zero-md th:src="@{/content/courses/1/main.md}"></zero-md> |
<zero-md th:src="@{/content/courses/{id}/main.md (id=${id})}"></zero-md> |
||||||
</div> |
</div> |
||||||
</body> |
</body> |
||||||
</html> |
</html> |
@ -0,0 +1,11 @@ |
|||||||
|
<!-- Коллекция фрагментов для построения страницы опроса --> |
||||||
|
<!DOCTYPE html> |
||||||
|
<html xmlns:th="http://www.thymeleaf.org"> |
||||||
|
|
||||||
|
<body> |
||||||
|
<div th:fragment="main"> |
||||||
|
<hr> |
||||||
|
<h1>ОПРОС</h1> |
||||||
|
</div> |
||||||
|
</body> |
||||||
|
</html> |
@ -0,0 +1,29 @@ |
|||||||
|
<!DOCTYPE html> |
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" |
||||||
|
xmlns:th="http://www.thymeleaf.org"> |
||||||
|
<head> |
||||||
|
<meta charset="UTF-8"> |
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
||||||
|
<title>exam-account</title> |
||||||
|
<script src="https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs@2/webcomponents-loader.min.js"></script> |
||||||
|
<script type="module" src="https://cdn.jsdelivr.net/gh/zerodevx/zero-md@1/src/zero-md.min.js"></script> |
||||||
|
<style> |
||||||
|
.code { |
||||||
|
color: red; |
||||||
|
font-weight: bold; |
||||||
|
font-size: 300%; |
||||||
|
} |
||||||
|
</style> |
||||||
|
</head> |
||||||
|
<header> |
||||||
|
<!-- Информация об аккаунте: id, organization, position --> |
||||||
|
<div th:insert="~{fragments/account :: info(account=${account})}"></div> |
||||||
|
</header> |
||||||
|
<body> |
||||||
|
<!-- опрос --> |
||||||
|
<div th:insert="~{fragments/quiz :: main}"></div> |
||||||
|
</body> |
||||||
|
<footer> |
||||||
|
<div th:insert="~{fragments/common/footer :: copy}"></div> |
||||||
|
</footer> |
||||||
|
</html> |
After Width: | Height: | Size: 218 KiB |
Loading…
Reference in new issue