esoe
2 weeks ago
26 changed files with 16697 additions and 66 deletions
@ -0,0 +1 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
|
||||
# Курс: Работы на высоте |
@ -0,0 +1 @@
@@ -0,0 +1 @@
|
||||
# Курс: Первая помощь |
@ -1,10 +1,11 @@
@@ -1,10 +1,11 @@
|
||||
<!-- Коллекция фрагментов для построения страницы курса --> |
||||
<!DOCTYPE html> |
||||
<html xmlns:th="http://www.thymeleaf.org"> |
||||
|
||||
<body> |
||||
<div th:fragment="main"> |
||||
<div th:fragment="main(id)"> |
||||
<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> |
||||
</body> |
||||
</html> |
@ -0,0 +1,11 @@
@@ -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 @@
@@ -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