Projeto e implementação de um sistema inteligente de exames online baseado em SpringBoot+Vue

Homepage do autor: Programando mil guindastes de papel

Sobre o autor: Java, front-end e Python foram desenvolvidos por muitos anos e já trabalhou como engenheiro sênior, gerente de projeto e arquiteto

Conteúdo principal: desenvolvimento de projeto Java, desenvolvimento de projeto Python, dados universitários e desenvolvimento de projeto de IA, design de projeto MCU, arranjo de tecnologia de entrevista, compartilhamento de tecnologia mais recente

Favoritos, curtidas, não se perca, é bom seguir o autor

Obtenha o código-fonte no final do artigo

Número do item: BS-GX-064

Prefácio:

Com o rápido desenvolvimento da tecnologia de computadores e redes, os aplicativos de intranet estão se tornando cada vez mais populares em todo o mundo.A sociedade de hoje está se movendo rapidamente em direção a uma sociedade da informação, e o papel da automação da informação também está aumentando. Atualmente, existem vários tipos de exames em vários níveis, e suas várias tarefas dependem principalmente de preenchimento manual. Por exemplo, o registro de exames exige que os candidatos se desloquem ao local designado para concluí-los em ordem. Não apenas os procedimentos são complicados e problemático, mas também a eficiência do trabalho é muito baixa. Será afetado por vários fatores, como clima e tráfego. Ainda existem muitas desvantagens no gerenciamento manual. Devido a fatores humanos inevitáveis, omissões de dados e falsos positivos são causados. O gerenciamento de informações do computador tem muitas vantagens, como grande capacidade de armazenamento e velocidade rápida, e as informações de processamento fornecidas a nós são oportunas e rápidas.

Este sistema é baseado no framework SpringBoot e é projetado no modo B/S. A página front-end é desenvolvida com Vue.js e MySQL é usado como banco de dados. Use o IDEA como uma ferramenta de desenvolvimento front-end e back-end e use mybatis para interagir com o banco de dados como uma ferramenta de gerenciamento de banco de dados.

Os exames on-line podem economizar o custo de impressão de provas, reduzir a carga dos professores para corrigir provas e pontuar estatísticas, economizar recursos educacionais, acelerar o processo de exame e aproveitar ao máximo as vantagens dos computadores no processamento de informações, como a construção de um enorme banco de questões para fazer perguntas aleatoriamente, análise de questões de teste e resultados de testes, etc., não só economiza mão de obra, recursos materiais e financeiros, mas também melhora a eficiência do trabalho. O sistema de exame online excede em muito as limitações do modo de exame de tempo fixo e local fixo do exame tradicional e trará grande comodidade para alunos e professores. Os exames on-line podem economizar o custo de impressão de provas, reduzir a carga dos professores para corrigir provas e pontuar estatísticas, economizar recursos educacionais, acelerar o processo de exame e aproveitar ao máximo as vantagens dos computadores no processamento de informações, como a construção de um enorme banco de questões para fazer perguntas aleatoriamente, análise de questões de teste e resultados de testes, etc., não só economiza mão de obra, recursos materiais e financeiros, mas também melhora a eficiência do trabalho.

1. Introdução ambiental

Localidade: Java: jdk1.8

Banco de dados: Mysql: mysql5.7

Servidor de aplicativos: Tomcat: tomcat8.5.31

Ferramentas de desenvolvimento: IDEA ou eclipse

Tecnologia de desenvolvimento: Springboot+Vue

2. Introdução do projeto

Com o desenvolvimento contínuo da tecnologia de informática e tecnologia de rede, é uma tendência inevitável no futuro usar computadores para auxiliar o ensino e melhorar a qualidade da educação. Os computadores penetraram em todos os aspectos do trabalho e da vida diária e são nosso braço direito para estudo e trabalho. Pessoas de todas as esferas da vida usam computadores para realizar muitas, muitas tarefas complexas. Hoje, usamos computadores para pesquisar o sistema inteligente de exames on-line e construir uma plataforma conveniente para muitos alunos e professores universitários. O sistema de exame é uma parte indispensável de uma unidade educacional, mas as pessoas sempre usaram exames e avaliações tradicionais em papel. Este método de exame e avaliação tem muitas desvantagens, tais como: baixa eficiência, baixa confidencialidade e muito tempo, o que irá causa Um grande número de arquivos e dados trouxe muitas dificuldades para corrigir, pesquisar, atualizar e manter as provas. O uso de computadores para testar os alunos tem vantagens que os testes em papel não podem alcançar. As vantagens da pesquisa conveniente, alta confiabilidade, boa confidencialidade, vida longa e assim por diante podem melhorar muito a eficiência dos exames dos alunos. Claro, também existem algumas desvantagens no uso de computadores no sistema de exame.No processo de pesquisa, desenvolvimento e design do sistema de exame com separação de ensino e exame, também precisamos minimizar o impacto das desvantagens.

O conteúdo de pesquisa deste tópico é desenvolver e projetar um sistema de exame separado para ensino e exame em faculdades e universidades, para que professores e alunos possam realizar exames online e avaliações de estudo por meio da rede.

Este artigo visa projetar e desenvolver um conjunto de sistema de exame online inteligente baseado em Springboot. Ele analisa a arquitetura do sistema de exame online inteligente em detalhes, estabelece a relação entre cada módulo e discute o gerenciamento de banco de questões, gerenciamento de assunto, composição de papel gerenciamento, função de exame, julgamento e assim por diante. A análise, design, implementação e teste de módulos funcionais, como função de papel de teste e gerenciamento de pontuação, completam um conjunto completo de sistema de exame online inteligente.

 O sistema projeta duas funções de usuário: função de administrador (professor) e função de examinando (aluno). O administrador pode entrar na interface de gerenciamento em segundo plano para gerenciar usuários, papéis de teste, tarefas, assuntos, notas, envio de centro de mensagens, gerenciamento de centro de log, etc. outras operações. O diagrama de blocos funcional do sistema é mostrado na Figura 3-1.

Figura 3-1 Diagrama do módulo de função do sistema

Os candidatos podem usar o papel de teste para responder a perguntas, fazer exercícios, ver papéis de teste e revisar seus resultados de teste após o teste, ou seja, registros de teste relacionados. O sistema coleta o conjunto de perguntas errado do aluno e os alunos também podem corrigir perguntas erradas. View, o diagrama de caso de uso da função do usuário é mostrado na Figura 3-2.

Figura 3-2 Diagrama de caso de uso da função do usuário

O administrador faz login por meio da conta integrada do sistema, e a conta do administrador pode realizar gerenciamento de usuários, gerenciamento de perguntas, gerenciamento de tarefas, gerenciamento educacional, gerenciamento de desempenho, envio de centro de mensagens e visualização do centro de log para segundo plano. O diagrama de caso de uso da função de administrador é mostrado na Figura 3-3.

Figura 3-3 Diagrama de caso de uso da função de administrador

Este sistema possui 7 módulos funcionais, incluindo módulo de usuário, módulo de login e registro, módulo de função de exame, módulo de armazenamento, módulo de envio de mensagens, módulo de pesquisa e módulo de gerenciamento de segundo plano. As principais funções são analisadas da seguinte forma:

1. Função do módulo do usuário

Tabela 3-1 Descrição da função do módulo do usuário

nome da função

Descrição Funcional

registro de usuário

Os usuários entram no sistema de teste para se registrar primeiro

ver informações pessoais

Os usuários modificam suas próprias informações, como modificação de avatar, etc.

alterar a senha

Modifique a senha de login do usuário

ver notícias

Exibir uma lista de mensagens de outros usuários

2. Faça login no módulo de registro

Tabela 3-2 Descrição funcional do módulo de registro de login

nome da função

Descrição Funcional

função de login

O usuário faz login na interface de primeiro plano e o administrador faz login em segundo plano

registro

Os usuários precisam registrar e gerenciar contas específicas

3. Módulos de função de exame

Tabela 3-3 Descrição Funcional dos Módulos de Função de Exame

nome da função

Descrição Funcional

liberar papel de teste

Admin publica papéis de exame

lista de assuntos

Publique o tipo de assunto do teste, como matemática ou inglês

tipo de exame

Papéis de teste de prática comum e papéis de teste de liberação regular

exame de candidato

Os candidatos recebem uma mensagem para fazer o exame

Prática do candidato

Os candidatos podem praticar os papéis de prática geralmente emitidos pelo professor

4. Módulo de armazenamento

Tabela 3-4 Descrição da função do módulo de armazenamento

nome da função

Descrição Funcional

armazenamento online

Utilize o armazenamento on-line em nuvem Qiniu

5. Módulo push de mensagem

Tabela 3-5 Descrição funcional do módulo push de mensagem

nome da função

Descrição Funcional

enviar mensagem

O administrador publica uma mensagem ao usuário para notificar as informações do exame

recepção de mensagem

Os usuários podem receber notificações de informações dos administradores

6. Módulo de pesquisa

Tabela 3-6 Descrição funcional do módulo de pesquisa

nome da função

Descrição Funcional

pesquisa de palavras-chave

Use o título da postagem de análise como palavra-chave para pesquisar o conteúdo correspondente

7. Módulo de gerenciamento de plano de fundo

Tabela 3-7 Descrição funcional do módulo de gerenciamento de segundo plano

nome da função

Descrição Funcional

gerenciamento de funções

Modifique e gerencie as informações da lista de alunos e administradores

gerenciamento de volume

Publicar o teste

gerenciamento de tarefas

Você pode modificar a lista de tarefas e criar tarefas

gerenciamento de assuntos

Modifique e gerencie as informações da lista de assuntos

gerenciamento de desempenho

Consulta sobre as notas dos candidatos

Gerenciamento de banco de perguntas

Você pode criar perguntas, consultar categorias de tópicos e publicar tópicos

Central de mensagens

Modifique a lista de mensagens para enviar mensagens

8. Módulo de recomendação

Tabela 3-8 Descrição funcional do módulo de gerenciamento de segundo plano

nome da função

Descrição Funcional

Gerenciamento de usuários

Gerenciamento de informações do usuário. Consultar, modificar e desabilitar usuários

Compartilhar gerenciamento de postagens

Encontre e modifique ou exclua postagens compartilhadas na plataforma

gerenciamento de notificação

Usado para publicar novas notificações, modificar e excluir notificações existentes

gerenciamento de relatórios

Visualize e processe as informações relatadas enviadas pelos usuários

3.2.2 Requisitos de desempenho

Este sistema é baseado na arquitetura B/S, e os usuários acessam para obter serviços através de navegadores.Para garantir a experiência do usuário, é necessário um desempenho relativamente estável.

1. Precisão dos dados

Quando o programa de back-end executa operações de adição, exclusão e modificação de dados, ele não suporta falha de operação devido a motivos do programa;

Quando o programa backend está adicionando dados, ele não suporta adições múltiplas ou repetidas;

Quando o programa de back-end exclui dados, ele não oferece suporte a vários dados excluídos;

Quando o programa de back-end exclui dados, ele exige que os dados associados sejam completamente excluídos. Se não puder ser excluído, lembre-se;

Quando o programa de back-end realiza modificação de dados, ele também precisa manter a precisão correspondente.

Características do tempo:

Ao executar operações como adicionar e excluir, o tempo de resposta do banco de dados deve estar dentro de 2 segundos;

Tempo de resposta do registro de login <= 3 segundos;

Tempo de resposta de atualização da página da Web <= 2 segundos;

Tempo de resposta de renderização de dados <= 0,5 segundos;

Tempo de resposta de atualização de dados <= 0,5 segundos;

Tempo de resposta para consulta de postagens compartilhadas <= 1 segundo;

Tempo de resposta da recomendação popular <= 1 segundo;

2. Segurança

O servidor back-end requer o estabelecimento de um firewall seguro e confiável;

Garantir a segurança dos serviços do servidor back-end e proibir o acesso anônimo aos serviços;

Para os dados de senha de candidatos (alunos) ou administradores (professores) no banco de dados, é necessária a criptografia MD5.

3. Software de suporte

(1) Software cliente:

Sistema operacional: Linux, Windows 7/10;

Navegadores: Chrome, Fire Fox, Edge.

(2) Software de servidor:

Sistema operacional: Windows Server 2012/2016, Windows 7/10, Linux;

Versão Java: 1.8;

Versão do banco de dados: MySQL5.7 ou superior;

Funções e serviços: serviço de armazenamento em nuvem Qiniu.

Três, exibição do sistema

5.1 Módulo do Usuário

5.1.1 Cadastro e login

前端登录与注册页面由login.vue实现,用户信息由userInfo.vue实现。用户首先需要输入用户名和邮箱,之后点击发送验证码,前端会将用户名和邮箱通过/api/sendCode提交到后端。后端接受到数据之后,首先会验证邮箱是否符合格式,邮箱是否已经被注册,如果条件成立,则返回相关提示信息。否则将生成验证码,通过邮件发送至用户邮箱,同时将邮箱和验证码存储于session中。之后用户需要将其他信息填写完毕,并且输入验证码,点击注册,前端会通过/api/register接口将数据提交到后端。后端收到数据后,首先会通过提交信息的邮箱从session中读取之前存储的验证码并进行对比,如果不一致,则返回验证码无效提示信息,否则继续业务。之后会验证邮箱是否符合规范,以及是否被注册,如果验证通过,则后端调用服务层类userService的register方法添加用户,register方法首先会将用户的密码进行MD5加密,填充注册时间,用户状态等信息,然后通过持久层类userMapper的方法将用户信息提交至数据库。提交成功之将创建用户的文件仓库,通过调用fileStoreService的 createFileStore方法创建对应用户的文件仓库并提交到数据库。界面实现效果如图5-1所示。

完成注册之后用户就可以登录了。输入用户名和密码之后点击登录,前端会将携带用户名与密码通过/api/login接口提交至后端,后端调用服务层类userService的login方法来处理数据。首先会将用户的明文密码使用MD5加密,之后通过持久层类userMapper的方法去数据库中查询是否存在对应用户名的用户,然后对比密码是否正确,并返回相应结果至控制层。如果账户密码正确,则将查询到的用户数据存储于session中,并且生成token提交至数据库中。之后将提示信息与token返回至前端,前端会将token存储于cookie中,以保持登录状态。界面实现效果如图5-2所示。

用户完成登录之后,将跳转至网盘界面,同时通过/api/getTokenVerity接口验证token是否有效,然后通过/api/getLoggedUser接口向后端的session中获取当前登录用户信息,并存储于cookie中。

图5-1 注册界面

图5-2 登录界面

5.1.2 个人信息

用户信息页面由userinfo.vue实现。登入系统之后,用户可以通过右上角下拉菜单进入用户信息页面。前端会携带登录用户信息,通过/api/u/getUser接口向后端请求当前用户信息,前端返回信息之后会将用户信息渲染至页面上。界面实现效果如图5-3所示。

图5-3 个人信息界面

5.1.3 查看消息

修改密码需要输入原密码和新密码,点击确定之后前端会通过/api/u/ resetPass接口向后端发送请求,携带用户ID和新旧密码。后端收到请求之后会调用服务层类userService的resetPass方法来处理业务。首先会判断原密码是否正确,然后检查新旧密码是否一致,如果一致则返回提示信息,否则将新密码使用MD5加密之后提交至数据库,然后向前端返回成功更改提示信息。界面实现效果如图5-4所示。

图5-4 查看信息界面

5.2 登录模块

5.2.1 角色登录

网盘界面由files.vue实现。用户登入之后会跳转至网盘界面,用户可在此查看网盘内的文件并进行管理。点击文件夹即可查看对应文件夹,前端会向/api/f/getDir接口发出请求,携带文件仓库与目标文件夹参数,后端获取对应文件夹下目录的数据返回至前端,前端根据后端的数据重新渲染目录,并记录用户当前路径信息。点击上一级或根目录按钮,前端会读取存储的路径信息,通过/api/f/getDir接口向后端请求对应目录的数据并再次渲染,以返回上一级目录。界面实现效果如图5-7所示。

图5-5用户登录前台界面

图5-6 管理员登录后台界面

5.3 考试功能模块

5.3.1 发布试卷

回收站模块同样由files.vue实现用户在网盘界面删除的文件并非被真的删除了,而是移动到了回收站,这里展示的是用户文件仓库中,所有被标记为删除的文件与文件夹。选择一个或多个文件及文件夹之后,即可执行还原操作。

点击还原文件按钮后会显示路径选择窗口,选择文件夹存放的目录然后点击确定后前端调用/api/rf/recovery接口发送请求,将被还原的文件及文件夹信息传递至后端,后端调用服务层类recycleBinService的recycleOrRecovery方法处理业务。根据请求携带的文件及文件夹信息分别处理,首先与还原文件及文件夹数据的名称进行对比,若存在重名则返回提示信息,否则将对应文件对象重新设置为未回收状态并设置文件的新路径。而文件夹则会通过recycleFoldersFile方法并设置为还原模式进行进一步操作,以还原文件夹下所有的子文件夹以及文件。界面实现效果如图5-11所示。

图5-7发布试卷页面

5.3.2 学科列表

选择选择一个或多个文件及文件夹之后,即可删除选择的文件或文件夹,而清空操作则是直接删除对回收站下的所有文件。在回收站执行的删除的操作会删除FTP上的文件,彻底从系统中移除本文件。删除文件和清空回收站都调用/api/f/delete接口,如果执行删除操作,前端会将选择的文件及文件夹信息通过此接口发送的后端,如果是清空操作,前端则会将回收站所有的文件信息传递至后端。后端接受到请求与文件信息之后对文件及文件夹进行分别处理,文件夹通过调用服务层folderService类删除数据库信息。文件则调用服务层fileService类deleteFTPFIle方法进行处理。因为FTP上的一个物理文件很可能在逻辑上关联了多条数据库信息,如果贸然删除FTP上的物理文件可能导致其他保存了次文件的用户将无法下载该文件,所以deleteFTPFIle方法在删除文件之前首先会检查该文件是否有多个关联数据库条目。进入deleteFTPFIle方法后,首先通过文件ID获取文件对象,之后通过文件对象的FTP地址从数据库中查询文件,再通过文件ID从数据库中查找分享帖,如果查到到相同FTP路径的文件大于1,以及查找到存在分享此文件的分享帖,则仅从数据库中删除数据库信息,否则调用FtpUtil类删除FTP文件。

图5-7学科列表页面

5.3.3 考试种类

选择选择一个或多个文件及文件夹之后,即可删除选择的文件或文件夹,而清空操作则是直接删除对回收站下的所有文件。在回收站执行的删除的操作会删除FTP上的文件,彻底从系统中移除本文件。删除文件和清空回收站都调用/api/f/delete接口,如果执行删除操作,前端会将选择的文件及文件夹信息通过此接口发送的后端,如果是清空操作,前端则会将回收站所有的文件信息传递至后端。后端接受到请求与文件信息之后对文件及文件夹进行分别处理,文件夹通过调用服务层folderService类删除数据库信息。文件则调用服务层fileService类deleteFTPFIle方法进行处理。因为FTP上的一个物理文件很可能在逻辑上关联了多条数据库信息,如果贸然删除FTP上的物理文件可能导致其他保存了次文件的用户将无法下载该文件,所以deleteFTPFIle方法在删除文件之前首先会检查该文件是否有多个关联数据库条目。进入deleteFTPFIle方法后,首先通过文件ID获取文件对象,之后通过文件对象的FTP地址从数据库中查询文件,再通过文件ID从数据库中查找分享帖,如果查到到相同FTP路径的文件大于1,以及查找到存在分享此文件的分享帖,则仅从数据库中删除数据库信息,否则调用FtpUtil类删除FTP文件。

图5-8练习试卷页面

图5-9时段页面

5.7 后台管理模块

后台管理模块为系统管理员提供了对系统中数据进行查询与管理的平台。后台管理页面仅对管理员用户开放,管理用用户即用户等级为9的用户。用户查看此页面以及子页面时,前端会通过/api/a/verityUserLevel接口携带当前用户ID向后端验证用户是否为管理员,然后才允许继续操作。否则跳转回登录页面。

5.7.1 角色管理

用户管理由userManage.vue实现。此页面用于对系统中的用户账户进行查询与管理。当管理员进入用户管理页面,前端首先会通过/api/a/getAll接口向后端发送请求,以获取所有的用户账户数据并返回至前端,前端收到数据之后分页渲染。界面实现效果如图5-20所示。

管理员可以通过页面操作按钮来查看用户信息,也可以通过搜索栏来查找指定用户的信息。在搜索栏中输入用户名,点击查找,前端便会通过/api/a/getUserByKeyWord接口将关键词传递至后端,后端接受请求之之后将查找到的数据返回至前端,前端再将数据渲染到页面上。

当管理点击新增按钮就会显示添加用户窗口,管理员填写完相关数据之后,点击确认,前端就会将该数据通过/api/a/addUser接口提交到数据库中。点击编辑按钮会打开与添加用户窗口一致的编辑用户窗口,前端会自动将被编辑用户的数据填入输入框,管理员只需更改需要更改的数据即可,点击提交前端会通过/api/a/updateUser接口将数据更新至数据库中。以上操作完成后,后端会返回成功信息至前端,前端再次获取更新后的用户数据并渲染用户信息列表。界面实现效果如图5-21所示。

当管理员点击某个用户账户信息上的禁用按钮时,前端会弹出提示框,询问管理员是否进行操作,点击确定,前端便会通过/api/a/UpdateStatus/接口禁用此账户。禁用后,该用户就无法使用此账户来登录系统。

图5-20 角色管理界面

5.7.2 组卷管理

分享管理由postsManage.vue实现分享管理页面用于管理系统中的分享帖。当管理员进入本页面,前端首先会通过/api/a/getAllPosts接口获取所有分享帖的数据,然后渲染到页面上。

此页面也提供了按照用户昵称来检索其对应分享帖的功能,在搜索栏输入用户昵称然后点击搜索,前端就会/api/a/searchPosts接口携带搜索内容传递至后端,后端接收请求后查找数据库中的对应内容,并返回至前端。前端收到数据之后渲染到页面上。界面实现效果如图5-22所示。

As postagens compartilhadas são exibidas na página na forma de uma lista e o administrador pode clicar no título da postagem para inserir a postagem compartilhada correspondente. Ou clique nos botões editar e excluir para operar na postagem. Quando o botão editar é clicado, a janela de edição do post será exibida e o front-end preencherá automaticamente os dados correspondentes do post na caixa de entrada. Depois que o administrador terminar de editar, clique no botão OK e o front-end passará os dados da postagem para o back-end através da interface /api/a/edit. O back-end aceita os dados e os envia para o banco de dados e, em seguida, retorna um mensagem de sucesso para o front-end, e o front-end solicita uma nova novamente. Postar informações e renderizar na página. O efeito de implementação da interface é mostrado na Figura 5-23.

Clique no botão excluir e o front-end enviará uma solicitação ao back-end com o ID da postagem por meio da interface /api/a/deletePosts. Depois de receber a solicitação, o back-end obterá o objeto de postagem específico por meio da ID da postagem e, em seguida, definir o atributo excluído do objeto de postagem como verdadeiro. Em seguida, através do método addNotice da classe de método da camada de serviço NoticeServer, envie uma notificação de que a postagem foi excluída para a postagem da postagem excluída. Em seguida, armazene o objeto de postagem modificado no banco de dados e retorne uma mensagem de sucesso para o front-end. Após o front-end receber a mensagem de sucesso, ele obtém todas as informações do post novamente para atualizar a página atual.

Figura 5-22 Página de gerenciamento de volume

Figura 5-23 Janela de edição de postagem

Em quarto lugar, a exibição do código principal

package com.zlf.exam.controller.student;

import com.zlf.exam.base.BaseApiController;
import com.zlf.exam.base.RestResponse;
import com.zlf.exam.domain.TaskExam;
import com.zlf.exam.domain.TaskExamCustomerAnswer;
import com.zlf.exam.domain.TextContent;
import com.zlf.exam.domain.User;
import com.zlf.exam.domain.enums.ExamPaperTypeEnum;
import com.zlf.exam.domain.task.TaskItemAnswerObject;
import com.zlf.exam.domain.task.TaskItemObject;
import com.zlf.exam.service.*;
import com.zlf.exam.utility.DateTimeUtil;
import com.zlf.exam.utility.JsonUtil;
import com.zlf.exam.viewmodel.student.dashboard.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@RestController("StudentDashboardController")
@RequestMapping(value = "/api/student/dashboard")
public class DashboardController extends BaseApiController {

    private final UserService userService;
    private final ExamPaperService examPaperService;
    private final QuestionService questionService;
    private final TaskExamService taskExamService;
    private final TaskExamCustomerAnswerService taskExamCustomerAnswerService;
    private final TextContentService textContentService;

    @Autowired
    public DashboardController(UserService userService, ExamPaperService examPaperService, QuestionService questionService, TaskExamService taskExamService, TaskExamCustomerAnswerService taskExamCustomerAnswerService, TextContentService textContentService) {
        this.userService = userService;
        this.examPaperService = examPaperService;
        this.questionService = questionService;
        this.taskExamService = taskExamService;
        this.taskExamCustomerAnswerService = taskExamCustomerAnswerService;
        this.textContentService = textContentService;
    }

    @RequestMapping(value = "/index", method = RequestMethod.POST)
    public RestResponse<IndexVM> index() {
        IndexVM indexVM = new IndexVM();
        User user = getCurrentUser();

        PaperFilter fixedPaperFilter = new PaperFilter();
        fixedPaperFilter.setGradeLevel(user.getUserLevel());
        fixedPaperFilter.setExamPaperType(ExamPaperTypeEnum.Fixed.getCode());
        indexVM.setFixedPaper(examPaperService.indexPaper(fixedPaperFilter));

        PaperFilter timeLimitPaperFilter = new PaperFilter();
        timeLimitPaperFilter.setDateTime(new Date());
        timeLimitPaperFilter.setGradeLevel(user.getUserLevel());
        timeLimitPaperFilter.setExamPaperType(ExamPaperTypeEnum.TimeLimit.getCode());

        List<PaperInfo> limitPaper = examPaperService.indexPaper(timeLimitPaperFilter);
        List<PaperInfoVM> paperInfoVMS = limitPaper.stream().map(d -> {
            PaperInfoVM vm = modelMapper.map(d, PaperInfoVM.class);
            vm.setStartTime(DateTimeUtil.dateFormat(d.getLimitStartTime()));
            vm.setEndTime(DateTimeUtil.dateFormat(d.getLimitEndTime()));
            return vm;
        }).collect(Collectors.toList());
        indexVM.setTimeLimitPaper(paperInfoVMS);
        return RestResponse.ok(indexVM);
    }


    @RequestMapping(value = "/task", method = RequestMethod.POST)
    public RestResponse<List<TaskItemVm>> task() {
        User user = getCurrentUser();
        List<TaskExam> taskExams = taskExamService.getByGradeLevel(user.getUserLevel());
        if (taskExams.size() == 0) {
            return RestResponse.ok(new ArrayList<>());
        }
        List<Integer> tIds = taskExams.stream().map(taskExam -> taskExam.getId()).collect(Collectors.toList());
        List<TaskExamCustomerAnswer> taskExamCustomerAnswers = taskExamCustomerAnswerService.selectByTUid(tIds, user.getId());
        List<TaskItemVm> vm = taskExams.stream().map(t -> {
            TaskItemVm itemVm = new TaskItemVm();
            itemVm.setId(t.getId());
            itemVm.setTitle(t.getTitle());
            TaskExamCustomerAnswer taskExamCustomerAnswer = taskExamCustomerAnswers.stream()
                    .filter(tc -> tc.getTaskExamId().equals(t.getId())).findFirst().orElse(null);
            List<TaskItemPaperVm> paperItemVMS = getTaskItemPaperVm(t.getFrameTextContentId(), taskExamCustomerAnswer);
            itemVm.setPaperItems(paperItemVMS);
            return itemVm;
        }).collect(Collectors.toList());
        return RestResponse.ok(vm);
    }


    private List<TaskItemPaperVm> getTaskItemPaperVm(Integer tFrameId, TaskExamCustomerAnswer taskExamCustomerAnswers) {
        TextContent textContent = textContentService.selectById(tFrameId);
        List<TaskItemObject> paperItems = JsonUtil.toJsonListObject(textContent.getContent(), TaskItemObject.class);

        List<TaskItemAnswerObject> answerPaperItems = null;
        if (null != taskExamCustomerAnswers) {
            TextContent answerTextContent = textContentService.selectById(taskExamCustomerAnswers.getTextContentId());
            answerPaperItems = JsonUtil.toJsonListObject(answerTextContent.getContent(), TaskItemAnswerObject.class);
        }


        List<TaskItemAnswerObject> finalAnswerPaperItems = answerPaperItems;
        return paperItems.stream().map(p -> {
                    TaskItemPaperVm ivm = new TaskItemPaperVm();
                    ivm.setExamPaperId(p.getExamPaperId());
                    ivm.setExamPaperName(p.getExamPaperName());
                    if (null != finalAnswerPaperItems) {
                        finalAnswerPaperItems.stream()
                                .filter(a -> a.getExamPaperId().equals(p.getExamPaperId()))
                                .findFirst()
                                .ifPresent(a -> {
                                    ivm.setExamPaperAnswerId(a.getExamPaperAnswerId());
                                    ivm.setStatus(a.getStatus());
                                });
                    }
                    return ivm;
                }
        ).collect(Collectors.toList());
    }
}
package com.zlf.exam.controller.student;

import com.github.pagehelper.PageInfo;
import com.zlf.exam.base.BaseApiController;
import com.zlf.exam.base.RestResponse;
import com.zlf.exam.domain.Message;
import com.zlf.exam.domain.MessageUser;
import com.zlf.exam.domain.User;
import com.zlf.exam.domain.UserEventLog;
import com.zlf.exam.domain.enums.RoleEnum;
import com.zlf.exam.domain.enums.UserStatusEnum;
import com.zlf.exam.event.UserEvent;
import com.zlf.exam.service.AuthenticationService;
import com.zlf.exam.service.MessageService;
import com.zlf.exam.service.UserEventLogService;
import com.zlf.exam.service.UserService;
import com.zlf.exam.utility.DateTimeUtil;
import com.zlf.exam.utility.PageInfoHelper;
import com.zlf.exam.viewmodel.student.user.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

@RestController("StudentUserController")
@RequestMapping(value = "/api/student/user")
public class UserController extends BaseApiController {

    private final UserService userService;
    private final UserEventLogService userEventLogService;
    private final MessageService messageService;
    private final AuthenticationService authenticationService;
    private final ApplicationEventPublisher eventPublisher;

    //后台登录代码
    @Autowired
    public UserController(UserService userService, UserEventLogService userEventLogService, MessageService messageService, AuthenticationService authenticationService, ApplicationEventPublisher eventPublisher) {
        this.userService = userService;
        this.userEventLogService = userEventLogService;
        this.messageService = messageService;
        this.authenticationService = authenticationService;
        this.eventPublisher = eventPublisher;
    }

    @RequestMapping(value = "/current", method = RequestMethod.POST)
    public RestResponse<UserResponseVM> current() {
        User user = getCurrentUser();
        UserResponseVM userVm = UserResponseVM.from(user);
        return RestResponse.ok(userVm);
    }


    //后台注册代码
    @RequestMapping(value = "/register", method = RequestMethod.POST)
    public RestResponse register(@RequestBody @Valid UserRegisterVM model) {
        User existUser = userService.getUserByUserName(model.getUserName());
        if (null != existUser) {
            return new RestResponse<>(2, "用户已存在");
        }
        User user = modelMapper.map(model, User.class);
        String encodePwd = authenticationService.pwdEncode(model.getPassword());
        user.setUserUuid(UUID.randomUUID().toString());
        user.setPassword(encodePwd);
        user.setRole(RoleEnum.STUDENT.getCode());
        user.setStatus(UserStatusEnum.Enable.getCode());
        user.setLastActiveTime(new Date());
        user.setCreateTime(new Date());
        user.setDeleted(false);
        userService.insertByFilter(user);
        UserEventLog userEventLog = new UserEventLog(user.getId(), user.getUserName(), user.getRealName(), new Date());
        userEventLog.setContent("欢迎 " + user.getUserName() + " 注册来到在线考试系统");
        eventPublisher.publishEvent(new UserEvent(userEventLog));
        return RestResponse.ok();
    }


    //后台个人信息更新代码
    @RequestMapping(value = "/update", method = RequestMethod.POST)
    public RestResponse update(@RequestBody @Valid UserUpdateVM model) {
        if (StringUtils.isBlank(model.getBirthDay())) {
            model.setBirthDay(null);
        }
        User user = userService.selectById(getCurrentUser().getId());
        modelMapper.map(model, user);
        user.setModifyTime(new Date());
        userService.updateByIdFilter(user);
        UserEventLog userEventLog = new UserEventLog(user.getId(), user.getUserName(), user.getRealName(), new Date());
        userEventLog.setContent(user.getUserName() + " 更新了个人资料");
        eventPublisher.publishEvent(new UserEvent(userEventLog));
        return RestResponse.ok();
    }

    @RequestMapping(value = "/log", method = RequestMethod.POST)
    public RestResponse<List<UserEventLogVM>> log() {
        User user = getCurrentUser();
        List<UserEventLog> userEventLogs = userEventLogService.getUserEventLogByUserId(user.getId());
        List<UserEventLogVM> userEventLogVMS = userEventLogs.stream().map(d -> {
            UserEventLogVM vm = modelMapper.map(d, UserEventLogVM.class);
            vm.setCreateTime(DateTimeUtil.dateFormat(d.getCreateTime()));
            return vm;
        }).collect(Collectors.toList());
        return RestResponse.ok(userEventLogVMS);
    }

    @RequestMapping(value = "/message/page", method = RequestMethod.POST)
    public RestResponse<PageInfo<MessageResponseVM>> messagePageList(@RequestBody MessageRequestVM messageRequestVM) {
        messageRequestVM.setReceiveUserId(getCurrentUser().getId());
        PageInfo<MessageUser> messageUserPageInfo = messageService.studentPage(messageRequestVM);
        List<Integer> ids = messageUserPageInfo.getList().stream().map(d -> d.getMessageId()).collect(Collectors.toList());
        List<Message> messages = ids.size() != 0 ? messageService.selectMessageByIds(ids) : null;
        PageInfo<MessageResponseVM> page = PageInfoHelper.copyMap(messageUserPageInfo, e -> {
            MessageResponseVM vm = modelMapper.map(e, MessageResponseVM.class);
            messages.stream().filter(d -> e.getMessageId().equals(d.getId())).findFirst().ifPresent(message -> {
                vm.setTitle(message.getTitle());
                vm.setContent(message.getContent());
                vm.setSendUserName(message.getSendUserName());
            });
            vm.setCreateTime(DateTimeUtil.dateFormat(e.getCreateTime()));
            return vm;
        });
        return RestResponse.ok(page);
    }

    @RequestMapping(value = "/message/unreadCount", method = RequestMethod.POST)
    public RestResponse unReadCount() {
        Integer count = messageService.unReadCount(getCurrentUser().getId());
        return RestResponse.ok(count);
    }

    @RequestMapping(value = "/message/read/{id}", method = RequestMethod.POST)
    public RestResponse read(@PathVariable Integer id) {
        messageService.read(id);
        return RestResponse.ok();
    }

}

V. Resumo do Projeto

Acho que você gosta

Origin blog.csdn.net/BS009/article/details/132079081
Recomendado
Clasificación