Sistema Web de Turismo Especializado de Yulin com SpringBoot, Vue e uniapp

Visão Geral da Arquitetura

Este sistema emprega uma arquitetura separada entre front-end e back-end. O back-end é construído com o framework SpringBoot, proporcionando uma base robusta para a lógica de negócios e serviços de API. O front-end, desenvolvido em Vue.js, fornece uma interface de usuário interativa e responsiva. Adicionalmente, uma aplicação multiplataforma é desenvolvida utilizando o uniapp, permitindo que o sistema seja acessado em diferentes dispositivos móveis. A persistência de dados é gerenciada pelo MyBatis-Plus, facilitando as operações de banco de dados.

Tecnologias Empregadas

SpringBoot no Back-end

O SpringBoot simplifica o desenvolvimento de aplicações Spring, fornecendo configuração automática e um servidor integrado. Ele permite que os desenvolvedores iniciem rapidamente projetos sem a necessidade de configurações complexas de sevridor. Recursos como Spring Data e Spring Security estão prontamente disponíveis para uso, acelerando o desenvolvimento de funcionalidades comuns e a integração com outros componentes.

Vue.js no Front-end

O Vue.js utiliza uma abordagem baseada em componentes e reatividade. Seu sistema de virtual DOM otimiza a manipulação da interface do usuário, atualizando apenas as partes necessárias do DOM quando o estado da aplicação muda. Isso resulta em um desemepnho eficiente e uma experiência de desenvolvimento simplificada, permitindo que os programadores foquem no tratamento de dados.

MyBatis-Plus para Acesso a Dados

O MyBatis-Plus estende as funcionalidades do MyBatis, reduzindo a necessidade de escrever código SQL repetitivo. Ele oferece recursos como paginação, consultas dinâmicas e uma ferramenta de geração de código, que pode criar entidades, interfaces Mapper e arquivos de mapeamento automaticamente, aumentando significativamente a produtividade no desenvolvimento da camada de persistência.

Estratégia de Testes do Sistema

A verificação completa do sistema é crucial para garantir sua qualidade e confiabilidade. O processo de teste visa identificar defeitos, validar a conformidade com os requisitos e assegurar uma experiência de usuário fluida. São realizados testes funcionais (caixa preta) para explorar diferentes cenários de uso.

Objetivos da Verificação

O teste visa descobrir vulnerabilidades e inconsistências lógicas antes da implantação. Ao simular interações reais do usuário, busca-se corrigir falhas que poderiam comprometer a funcionalidade do sistema e a satisfação do usuário final. Uma validação bem-sucedida confirma que o sistema atende às especificações definidas.

Cenários de Teste Funcional

Testes são conduzidos em módulos críticos, como autenticação e gerenciamento de usuários. As tabelas a seguir ilustram alguns casos de teste executados.

Cenário Dados de Entrada Resultado Esperado Resultado Obtido Análise
Login válido Usuário: admin_correto, Senha: senha_correta Autenticação bem-sucedida Sucesso no login Conforme esperado
Senha incorreta Usuário: admin_correto, Senha: senha_errada Falha na autenticação Mensagem de erro exibida Conforme esperado
Campo obrigatório vazio Usuário: [vazio], Senha: senha_qualquer Validação de campo obrigatório Mensagem solicitando preenchimento Conforme esperado
Ação Operação Resultado Esperado Resultado Obtido Análise
Criar usuário Inserir dados válidos Registro inserido com sucesso Novo usuário visível na lista Conforme esperado
Excluir usuário Confirmar remoção Registro removido do sistema Usuário não mais acessível Conforme esperado
Atualizar dados Modificar informações Dados atualizados corretamente Novas informações exibidas Conforme esperado

Conclusão dos Testes

Os testes abrangentes realizados demonstram que o sistema opera de acordo com as expectativas. Os módulos testados apresentam a lógica correta e uma usabilidade adequada, validando assim a integridade da implementação.

Exemplo de Código Refatorado

O trecho abaixo demonstra uma parte da lógica de autenticação e verificação de token, com estruturas e nomes de variáveis modificados para fins ilustrativos.


@RestController
@RequestMapping("/api/auth")
public class AuthenticationController {

    @Autowired
    private UserAuthenticationService authService;

    @PostMapping("/signin")
    public ResponseEntity<ApiResponse> authenticateUser(@RequestBody LoginRequest request) {
        Optional<UserPrincipal> userOpt = authService.validateCredentials(request.getUsername(), request.getPassword());
        if (userOpt.isEmpty()) {
            return ResponseEntity.badRequest().body(new ApiResponse("Credenciais inválidas", 401));
        }
        String jwtToken = authService.generateJwtToken(userOpt.get());
        return ResponseEntity.ok(new ApiResponse("Autenticação bem-sucedida", 200, Collections.singletonMap("accessToken", jwtToken)));
    }
}

@Service
public class TokenGenerationService {

    @Autowired
    private TokenRepository tokenRepo;

    public String createTokenForUser(Long userId, String userRole) {
        String randomToken = generateSecureRandomString(40);
        Instant expirationTime = Instant.now().plus(1, ChronoUnit.HOURS);

        tokenRepo.findByUserIdAndRole(userId, userRole)
            .ifPresentOrElse(
                existing -> {
                    existing.setTokenValue(randomToken);
                    existing.setExpiryTimestamp(expirationTime);
                    tokenRepo.save(existing);
                },
                () -> {
                    Token newToken = new Token();
                    newToken.setUserId(userId);
                    newToken.setRole(userRole);
                    newToken.setTokenValue(randomToken);
                    newToken.setExpiryTimestamp(expirationTime);
                    tokenRepo.save(newToken);
                }
            );
        return randomToken;
    }

    private String generateSecureRandomString(int length) {
        // Lógica para gerar string aleatória segura
        return ...;
    }
}

@Component
public class JwtRequestFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain chain)
            throws ServletException, IOException {
        String authHeader = req.getHeader("Authorization");
        if (authHeader != null && authHeader.startsWith("Bearer ")) {
            String token = authHeader.substring(7);
            // Lógica para validar o token JWT e carregar detalhes do usuário
            // ...
        }
        chain.doFilter(req, res);
    }
}

Esquema do Banco de Dados (Referência)

A tabela abaixo armazena as sessões de token dos usuários.


CREATE TABLE user_session_token (
    session_id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT 'Identificador único da sessão',
    user_id BIGINT NOT NULL COMMENT 'ID do usuário associado',
    user_login VARCHAR(100) NOT NULL COMMENT 'Login do usuário',
    user_profile VARCHAR(50) COMMENT 'Perfil ou papel do usuário',
    access_token VARCHAR(255) NOT NULL COMMENT 'Token de acesso gerado',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'Data de criação do registro',
    expires_at TIMESTAMP NOT NULL COMMENT 'Data e hora de expiração do token',
    INDEX idx_user_profile (user_id, user_profile)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='Tabela para gerenciamento de tokens de sessão de usuários';

Tags: SpringBoot Vue.js uniapp MyBatis-Plus java

Publicado em 6-6 05:43 por Thomas