springboot3+vue3项目实例练习1

项目概述

项目名称: 大事件管理系统
技术栈: SpringBoot3+Vue3
核心功能: 用户管理、文章管理、分类管理、文件上传、登录认证等。
目标用户: 管理员或普通用户,用于管理文章和分类。

功能模块

用户管理

功能描述:
用户注册、登录、个人信息管理。
用户头像上传(使用阿里云OSS)。
用户密码加密存储(使用MD5加密)。
相关表:
user 表:存储用户信息(用户名、密码、昵称、邮箱、头像等)。
相关工具类:
Md5Util:用于密码的MD5加密和校验。
AliOssUtil:用于用户头像上传到阿里云OSS。

登录与认证

功能描述:
用户登录后生成JWT令牌,用于后续请求的身份验证。
使用JWT进行权限校验,未登录用户无法访问受保护的资源。
相关工具类:
JwtUtil:用于生成和解析JWT令牌。
ThreadLocalUtil:用于存储当前登录用户信息,方便在业务逻辑中获取用户信息。

分类管理

功能描述:
管理员可以创建、编辑、删除文章分类。
分类信息包括分类名称、分类别名等。
相关表:
category 表:存储分类信息。
实体类:
Category:分类的实体类,包含分类名称、别名、创建人等信息。

文章管理

功能描述:
用户可以创建、编辑、删除文章。
文章信息包括标题、内容、封面图片、状态(草稿或已发布)、分类等。
相关表:
article 表:存储文章信息。
实体类:
Article:文章的实体类,包含标题、内容、封面图片、状态等信息。

文件上传

功能描述:
用户上传头像或文章封面图片时,使用阿里云OSS进行文件存储。
上传成功后返回文件的公网访问地址。
相关工具类:
AliOssUtil:封装了阿里云OSS的上传逻辑。

分页查询

功能描述:
支持文章和分类的分页查询。
返回分页结果,包括总条数和当前页数据。
相关类:
PageBean:分页返回结果对象,包含总条数和当前页数据集合。

统一响应格式

功能描述:
所有接口返回统一的响应格式,包含状态码、提示信息和数据。
相关类:
Result:统一响应结果类,包含状态码、提示信息和数据。

数据库设计

-- 创建数据库
create database big_event;

-- 使用数据库
use big_event;

-- 用户表
create table user (
                      id int unsigned primary key auto_increment comment 'ID',
                      username varchar(20) not null unique comment '用户名',
                      password varchar(32)  comment '密码',
                      nickname varchar(10)  default '' comment '昵称',
                      email varchar(128) default '' comment '邮箱',
                      user_pic varchar(128) default '' comment '头像',
                      create_time datetime not null comment '创建时间',
                      update_time datetime not null comment '修改时间'
) comment '用户表';

-- 分类表
create table category(
                         id int unsigned primary key auto_increment comment 'ID',
                         category_name varchar(32) not null comment '分类名称',
                         category_alias varchar(32) not null comment '分类别名',
                         create_user int unsigned not null comment '创建人ID',
                         create_time datetime not null comment '创建时间',
                         update_time datetime not null comment '修改时间',
                         constraint fk_category_user foreign key (create_user) references user(id) -- 外键约束
);

-- 文章表
create table article(
                        id int unsigned primary key auto_increment comment 'ID',
                        title varchar(30) not null comment '文章标题',
                        content varchar(10000) not null comment '文章内容',
                        cover_img varchar(128) not null  comment '文章封面',
                        state varchar(3) default '草稿' comment '文章状态: 只能是[已发布] 或者 [草稿]',
                        category_id int unsigned comment '文章分类ID',
                        create_user int unsigned not null comment '创建人ID',
                        create_time datetime not null comment '创建时间',
                        update_time datetime not null comment '修改时间',
                        constraint fk_article_category foreign key (category_id) references category(id),-- 外键约束
                        constraint fk_article_user foreign key (create_user) references user(id) -- 外键约束
)

后端代码

用户的实体类代码

package com.example.day0225.pojo;

//import net.minidev.json.annotate.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import org.springframework.validation.annotation.Validated;

import java.time.LocalDateTime;

public class User {
//    实体参数校验
//    第一步实体类的成员变量上添加注解@NotNull/@NotEmpty/@Email
//    接口方法的实体参数上添加@Validated注解
    @NotNull//值不能为null
    private Integer id;//主键ID
    private String username;//用户名
    @JsonIgnore//让springmvc把当前对象转换成json字符串的时候,忽略password,最终的json字符串中就没有password这个属性了
    private String password;//密码
    @NotEmpty//值不能为null并且内容不为空
    @Pattern(regexp = "^\\S{1,10}$")
    private String nickname;//昵称
    @NotEmpty
    @Email//满足邮箱格式
    private String email;//邮箱
    private String userPic;//用户头像地址
    private LocalDateTime createTime;//创建时间
    private LocalDateTime updateTime;//更新时间

    public User(LocalDateTime updateTime, LocalDateTime createTime, String userPic, String email, String nickname, String password, String username, Integer id) {
        this.updateTime = updateTime;
        this.createTime = createTime;
        this.userPic = userPic;
        this.email = email;
        this.nickname = nickname;
        this.password = password;
        this.username = username;
        this.id = id;
    }

    public User() {
    }

    public LocalDateTime getUpdateTime() {
        return updateTime;
    }

    public void setUpdateTime(LocalDateTime updateTime) {
        this.updateTime = updateTime;
    }

    public LocalDateTime getCreateTime() {
        return createTime;
    }

    public void setCreateTime(LocalDateTime createTime) {
        this.createTime = createTime;
    }

    public String getUserPic() {
        return userPic;
    }

    public void setUserPic(String userPic) {
        this.userPic = userPic;
    }

    public String getEmail() {
        return email;
    }

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

    public String getNickname() {
        return nickname;
    }

    public void setNickname(String nickname) {
        this.nickname = nickname;
    }

    public String getPassword() {
        return password;
    }

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

    public String getUsername() {
        return username;
    }

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

    public Integer getId() {
        return id;
    }

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

用户相关控制层代码

package com.example.day0225.controller;

import com.example.day0225.pojo.Result;
import com.example.day0225.pojo.User;
import com.example.day0225.service.UserService;
import com.example.day0225.utils.JwtUtil;
import com.example.day0225.utils.Md5Util;
import com.example.day0225.utils.ThreadLocalUtil;
import jakarta.validation.constraints.Pattern;
import org.hibernate.validator.constraints.URL;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/user")
@Validated
public class UserController {
    @Autowired
    private UserService userService;
    @PostMapping("/register")
    public Result register(@Pattern(regexp = "^\\S{5,16}$") String username, @Pattern(regexp = "^\\S{5,16}$")String password) {
        //查询用户
        User u =userService.findByUserName(username);
        if (u == null) {
            userService.register(username,password);
            return Result.success();
        }else{
            //占用
            return Result.error("用户名已被占用");
        }
    }
    @PostMapping("/login")
    public Result<String> login(@Pattern(regexp = "^\\S{5,16}$") String username, @Pattern(regexp = "^\\S{5,16}$")String password){
        //根据用户名查询用户
        User loginUser = userService.findByUserName(username);
        //判断该用户是否存在
        if(loginUser == null){
            return Result.error("用户名错误");
        }
        //判断密码是否正确
        if(Md5Util.getMD5String(password).equals(loginUser.getPassword())){
            //登录成功
            Map<String,Object> claims = new HashMap<>();
            claims.put("id",loginUser.getId());
            claims.put("username",loginUser.getUsername());
            String token = JwtUtil.genToken(claims);
            return Result.success(token);
        }
        return Result.error("密码错误");

    }
    @GetMapping("/userInfo")
    public Result<User> userInfo(/*@RequestHeader(name ="Authorization") String token*/){
        //根据用户名查询用户
//        Map<String,Object> map = JwtUtil.parseToken(token);
//        String username = (String) map.get("username");
        Map<String,Object> map = ThreadLocalUtil.get();
        String username = map.get("username").toString();
        User user = userService.findByUserName(username);
        return Result.success(user);
    }
    @PutMapping("/update")
    public Result update (@RequestBody @Validated User user){
        userService.update(user);
        return Result.success();
    }
//    @URL对传进来的参数进行校验,判断是否为网页图片链接
    @PatchMapping("/updateAvatar")
    public Result updateAvatar(@RequestParam @URL String avatarUrl){
        userService.updateAvatar(avatarUrl);
        return Result.success();
    }
    @PatchMapping("/updatePwd")
    public Result updatePwd(@RequestBody Map<String,String> params) {
        //1.校验参数
        String oldPwd = params.get("old_pwd");
        String newPwd = params.get("new_pwd");
        String rePwd = params.get("re_pwd");
        if (!StringUtils.hasLength(oldPwd) || !StringUtils.hasLength(newPwd) || !StringUtils.hasLength(rePwd)){
            return Result.error("缺少必要参数");
        }
        //校验原密码
        //调用userService根据用户名拿到原密码,再和old_Pwd比对
        Map<String,Object> map = ThreadLocalUtil.get();
        String username = map.get("username").toString();
        User loginUser = userService.findByUserName(username);
        if (!loginUser.getPassword().equals(Md5Util.getMD5String(oldPwd))){
            return Result.error("原密码填写不正确");
        }
        //newPwd和rePwd是否一致
        if(!rePwd.equals(newPwd)){
            return Result.error("两次填写的新密码不一致");
        }
        //2.调用service完成密码更新
        userService.updatePwd(newPwd);
        return Result.success();
    }



}

用户service层代码

package com.example.day0225.service;

import com.example.day0225.pojo.User;
import org.springframework.stereotype.Service;

@Service
public interface UserService {
    //根据用户名查询
    User findByUserName(String username);
    //注册
    void register(String username, String password);
    //更新
    void update(User user);
    //更新头像
    void updateAvatar(String avatarUrl);
    //更新密码
    void updatePwd(String newPwd);
}

serviceImpl实现

package com.example.day0225.service.impl;

import com.example.day0225.mapper.UserMapper;
import com.example.day0225.pojo.User;
import com.example.day0225.service.UserService;
import com.example.day0225.utils.Md5Util;
import com.example.day0225.utils.ThreadLocalUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Map;

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;

    @Override
    public User findByUserName(String username) {
        User u = userMapper.findByUserName(username);
        return userMapper.findByUserName(username);
    }

    @Override
    public void register(String username, String password) {
        //加密
        String md5String = Md5Util.getMD5String(password);
        //添加
        userMapper.add(username,md5String);

    }

    @Override
    public void update(User user) {
        user.setUpdateTime(LocalDateTime.now());
        userMapper.update(user);
    }

    @Override
    public void updateAvatar(String avatarUrl) {
        Map<String,Object> map = ThreadLocalUtil.get();
        Integer id = (Integer) map.get("id");
        userMapper.updateAvatar(avatarUrl,id);
    }

    @Override
    public void updatePwd(String newPwd) {
        Map<String,Object> map = ThreadLocalUtil.get();
        Integer id = (Integer) map.get("id");
        userMapper.updatePwd(Md5Util.getMD5String(newPwd),id);
    }


}

用户mapper层

package com.example.day0225.mapper;

import com.example.day0225.pojo.User;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

@Mapper
public interface UserMapper {
    //根据用户名查询用户
    @Select("select * from user where username=#{username}")
    User findByUserName(String username);
    //添加
    @Insert("insert into user(username,password,create_time,update_time)" +
    " values(#{username},#{password},now(),now()) ")
    void add(String username, String password);
    @Update("update user set nickname = #{nickname},email = #{email},update_time = #{updateTime} where id = #{id}")
    void update(User user);
    @Update("update user set user_pic = #{avatarUrl},update_time=now() where id = #{id}")
    void updateAvatar(String avatarUrl,Integer id);
    @Update("update user set password = #{md5String},update_time = now() where id = #{id}")
    void updatePwd(String md5String,Integer id);
}

posted @ 2025-03-04 20:20  haoyinuo  阅读(63)  评论(0)    收藏  举报