前言

今天学习了如何搭建一个后台管理系统,因此打算记录并总结一下今天的学习内容。

该项目是一个非常好用的后台管理系统模板,代码比较简单,项目功能比较通用,总之就是很推荐初学者学习。

项目的大体项目框架是:SpringBoot+Vue+ElementUI

后台是由SpringBoot,SpringData Jpa构成

前台是基于Vue+ElementUI

项目介绍:

这个项目包含登录页面,用户管理的页面,个人信息的页面。

项目包含登录和注册功能,用户可以从登录界面跳转到管理页面。

登录:

注册:

 用户管理:

在管理页面,用户可以跳转到个人信息页面,也可以退出用户,也可以回到主页。还可以在管理页面实现信息的增删改查,同时管理页面也基于ElementUI提供的分页工具实现了分页的功能。

新增用户:

 修改用户:

 

项目架构:

common:保存一些通用的配置

controller:是后台接口

dao:数据库访问层,这个项目使用的是Spring JPA,在Spring Jpa中整合了很多对数据库进行增删改查的方法

entity:对应数据库的实体类

exception:全局异常处理,比如在接口层抛了异常会给前台返回错误信息

service:业务处理层

utils:代码生成工具

resource:包含static(管理前台配置文件)和application.yml(springboot配置,数据库配置)

pom.xml:管理下载依赖dependency

架构各个部分的详解:

首先是common包:

Authintercepter:鉴权,拦截器。用户需要登录才能有权限进行访问。

package com.example.common;

import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 拦截器
 */
public class AuthInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
        Object user = request.getSession().getAttribute("user");
        if (user != null) {
            request.getSession().setAttribute("user", user);
            return true;
        }
        response.sendRedirect("/login.html");
        return false;
    }

}

CorsConfig:跨域处理。当非本地用户访问时本地服务器时,需要在此处配置。

package com.example.common;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

@Configuration
public class CorsConfig {

    // 当前跨域请求最大有效时长。这里默认1天
    private static final long MAX_AGE = 24 * 60 * 60;

    private CorsConfiguration buildConfig() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedOrigin("*"); // 1 设置访问源地址
        corsConfiguration.addAllowedHeader("*"); // 2 设置访问源请求头
        corsConfiguration.addAllowedMethod("*"); // 3 设置访问源请求方法
        corsConfiguration.setMaxAge(MAX_AGE);
        return corsConfiguration;
    }

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", buildConfig()); // 4 对接口配置跨域设置
        return new CorsFilter(source);
    }
}

result:封装结果类。统一返回接口数据,在controller层中,所有的的接口都会返回一个result对象,result会对所有请求的结果进行封装然后返回给前台。result类有三个属性:code,msg,data。code告诉前台访问是成功(1)还是失败(0)。如果失败了,会把错误信息放到msg返回给前台。data是查询数据的,将用户数据放到data中然后返回给前台,前台拿到data在页面进行渲染。

WebMvcConfig:拦截器。拦截或放开一些页面的请求

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;


@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new AuthInterceptor())
                .addPathPatterns("/**")
                .excludePathPatterns("/js/**", "/css/**", "/img/**", "/user/login", "/user/register", "/login.html", "/register.html");
    }
}

controller层:定义项目所有的接口

包含:增删改查接口、登录注册接口,其他业务接口

controller会通过@resource引入service并请求service

package com.example.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.example.common.Result;
import com.example.entity.User;
import com.example.exception.CustomException;
import com.example.service.UserService;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/user")
public class UserController {

    @Resource
    private UserService userService;

    /**
     * 登陆
     *
     * @param user
     * @param request
     * @return
     */
    @PostMapping("/login")
    public Result<User> login(@RequestBody User user, HttpServletRequest request) {
        User res = userService.login(user);
        request.getSession().setAttribute("user", res);
        return Result.success(res);
    }

    /**
     * 注册
     *
     * @param user
     * @param request
     * @return
     */
    @PostMapping("/register")
    public Result<User> register(@RequestBody User user, HttpServletRequest request) {
        User dbUser = userService.findByUsername(user.getUsername());
        if (dbUser != null) {
            throw new CustomException("-1", "用户已注册");
        }
        if (user.getPassword() == null) {
            user.setPassword("123456");
        }
        User res = userService.add(user);
        request.getSession().setAttribute("user", res);
        return Result.success(res);
    }

    @PostMapping
    public Result<User> save(@RequestBody User user) {
        return Result.success(userService.save(user));
    }

    @PutMapping
    public Result<?> update(@RequestBody User user) {
        return Result.success(userService.save(user));
    }

    @DeleteMapping("/{id}")
    public Result<?> delete(@PathVariable Long id) {
        userService.delete(id);
        return Result.success();
    }

    @GetMapping("/{id}")
    public Result<User> findById(@PathVariable Long id) {
        return Result.success(userService.findById(id));
    }

    @GetMapping
    public Result<List<User>> findAll() {
        return Result.success(userService.findAll());
    }

    @GetMapping("/page")
    public Result<Page<User>> findPage(@RequestParam(required = false, defaultValue = "1") Integer pageNum,
                                       @RequestParam(required = false, defaultValue = "10") Integer pageSize) {
        return Result.success(userService.findPage(pageNum, pageSize));
    }

    @GetMapping("/export")
    public void export(HttpServletResponse response) throws IOException {

        List<Map<String, Object>> list = CollUtil.newArrayList();

        List<User> all = userService.findAll();
        for (User user : all) {
            Map<String, Object> row1 = new LinkedHashMap<>();
            row1.put("用户名", user.getUsername());
            row1.put("邮箱", user.getEmail());
            row1.put("电话", user.getTel());
            list.add(row1);
        }

        // 2. 写excel
        ExcelWriter writer = ExcelUtil.getWriter(true);
        writer.write(list, true);

        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        String fileName = URLEncoder.encode("用户表", "UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");

        ServletOutputStream out = response.getOutputStream();
        writer.flush(out, true);
        writer.close();
        IoUtil.close(System.out);
    }
}

service层:对数据库请求的数据进行逻辑处理。service会对项目的业务进行详细处理。

service会通过@Resource引入DAO来获取数据库数据

 

package com.example.service;

import com.example.dao.UserDao;
import com.example.entity.User;
import com.example.exception.CustomException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

@Service
public class UserService {

    @Resource
    private UserDao userDao;

    public User save(User user) {
        return userDao.save(user);
    }

    public void delete(Long id) {
        userDao.deleteById(id);
    }

    public User findById(Long id) {
        return userDao.findById(id).orElse(null);
    }

    public List<User> findAll() {
        return userDao.findAll();
    }

    public Page<User> findPage(int pageNum, int pageSize) {
        return userDao.findAll(PageRequest.of(pageNum - 1, pageSize));
    }

    public User login(User user) {
        User res = userDao.findByUsernameAndPassword(user.getUsername(), user.getPassword());
        if (res == null) {
            throw new CustomException("-1", "账号或密码错误");
        }
        return res;
    }

    public User add(User user) {
        return userDao.save(user);
    }

    public User findByUsername(String username) {
        return userDao.findByUsername(username);
    }
}

dao:从数据库查询数据的接口

 dao是由jpa提供各种对数据库进行操作的方法的

package com.example.dao;

import com.example.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Repository;

@Repository
public interface UserDao extends JpaRepository<User, Long>, JpaSpecificationExecutor<User> {

    User findByUsernameAndPassword(String username, String password);

    User findByUsername(String username);
}

entity:数据库实体类

实体类中的属性,与数据库表属性一一对应。

package com.example.entity;

import javax.persistence.*;
import java.util.Date;

@Entity
@Table(name = "t_user")
public class User {
    /**
     * 主键
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    /**
     * 用户名 
     */
    @Column(name = "username")
    private String username;

    /**
     * 密码 
     */
    @Column(name = "password")
    private String password;

    /**
     * 邮箱 
     */
    @Column(name = "email")
    private String email;

    /**
     * 电话 
     */
    @Column(name = "tel")
    private String tel;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
         this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
         this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
         this.password = password;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
         this.email = email;
    }

    public String getTel() {
        return tel;
    }

    public void setTel(String tel) {
         this.tel = tel;
    }

}

总结:

这个项目仍然只学了一半,前端和部署还没有完成。剩下的内容,下次再分享吧。

结语:坚定目标,日日精进,必有所成。共勉! !

Logo

前往低代码交流专区

更多推荐