基于Springboot+vue实现前后端分离二手图书交易

简介: 基于Springboot+vue实现前后端分离二手图书交易

作者简介:Java领域优质创作者、CSDN博客专家 、掘金特邀作者、多年架构师设计经验、腾讯课堂常驻讲师

主要内容:Java项目、毕业设计、简历模板、学习资料、面试题库、技术互助

文末获取源码

项目编号:KS-029

一,项目简介

 本项目基于Springboot+vue实现的前后端分离的二手图书交易系统,实现的功能较为简单。用户登陆系统后可以进行图书的发布和浏览,并可以进行全文检索,别的用户可以查看详情联系发布人进行线下交易。

二,环境介绍

语言环境:Java:  jdk1.8

数据库:Mysql: mysql5.7

应用服务器:Tomcat:  tomcat8.5.31

开发工具:IDEA或eclipse

三,系统展示

用户登陆

首页展示

图书列表

图书详情

个人中心:可以发布图书和管理己发布的图片

添加图书

修改密码

四,核心代码展示

package com.znz.backend.wj.contorller;
import com.znz.backend.result.Result;
import com.znz.backend.wj.Service.BookService;
import com.znz.backend.wj.bean.Book;
import net.coobird.thumbnailator.Thumbnails;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Random;
/**
 * @author znz
 * @create 2020/02/07/10:52
 */
@RestController
public class LibraryController {
    @Resource(name="bookService")
    private BookService bookService;
    @Value("${fileupload.path}")
    private String path;
    //返回所有的图书
    @CrossOrigin
    @GetMapping("api/books")
    public List<Book>findAll() throws Exception{
        return bookService.findAll();
    }
    //根据用户账号返回所有的书
    @CrossOrigin
    @PostMapping("api/booksByUid")
    public List<Book>findAllByUid(@RequestBody Book book){
        return bookService.findAllByUid(book.getUid());
    }
    //根据种类查询图书
    @CrossOrigin
    @GetMapping("api/categories/{cid}/books")
    public List<Book> listByCategory(@PathVariable("cid") String cid) throws Exception {
        if (!cid.equals("0")) {
            return bookService.findAllByCategory(cid);
        } else {
           return findAll();
        }
    }
    //根据种类和用户名查询用户添加的图书
    @CrossOrigin
    @PostMapping("api/categories/uid/UserBooks")
    public List<Book> listByCategoryAndUid(@RequestBody Book book){
        System.out.println(book);
        if (!book.getCid().equals("0")) {
            return bookService.findAllByCategoryAndUid(book.getCid(),book.getUid());
        } else {
            return bookService.findAllByUid(book.getUid());
        }
    }
    //根据id删除图书
    @CrossOrigin
    @PostMapping("api/delete")
    public Result deleteBookById(@RequestBody Book book){
        int num=bookService.deleteBookById(book.getId());
        if(num==0){
            return new Result(400);
        } else {
            return new Result(200);
        }
    }
    //根据id和用户编号删除图书,并删除本地服务器存储的图片
    @PostMapping("api/deleteById")
    @CrossOrigin
    public Result deleteBookByIdAndUid(@RequestBody Book book){
        int num=bookService.deleteBookByIdAndUid(book);
        if(num==0){
            return new Result(400);
        } else {
            if(!book.getCover().equals("")){
                String cover=book.getCover().split("/api/file/")[1];
                deleteImg(cover);
            }
            if(!book.getImg_1().equals("")){
                String img_1=book.getImg_1().split("/api/file/")[1];
                deleteImg(img_1);
            }
            if(!book.getImg_2().equals("")){
                String img_2=book.getImg_2().split("/api/file/")[1];
                deleteImg(img_2);
            }
            if(!book.getImg_3().equals("")){
                String img_3=book.getImg_3().split("/api/file/")[1];
                deleteImg(img_3);
            }
            if(!book.getImg_4().equals("")){
                String img_4=book.getImg_4().split("/api/file/")[1];
                deleteImg(img_4);
            }
            if(!book.getImg_5().equals("")){
                String img_5=book.getImg_5().split("/api/file/")[1];
                deleteImg(img_5);
            }
            return new Result(200);
        }
    }
    @CrossOrigin
    public void deleteImg(String imgName){
        String imgUrl="/home/Youth-imgs/"+imgName;
        File img=new File(imgUrl);
        img.delete();
    }
    //添加一本图书
    @CrossOrigin
    @PostMapping("api/insert")
    public Result insertBook(@RequestBody Book book){
        System.out.println(book);
        if(bookService.insertBook(book)==0){
            return new Result(400);
        } else {
            return new Result(200);
        }
    }
    //根据书名查找图书
    //使用form表单传递数据
    @CrossOrigin
    @PostMapping("api/search")
    public List<Book> searchBooksByTitle(@RequestParam Map<String,Object> keywords, HttpSession session){
        return bookService.finAllByTitle((String)keywords.get("keywords"));
    }
    //上传图片
    @CrossOrigin
    @PostMapping("api/uploadImg")
    public String coversUpload(MultipartFile file) throws Exception {
        //查看图片类型
        String type=file.getContentType().split("/")[1];
        if(type==null||file.getSize()>1048576){
            return null;
        }
        String folder = path;
        File imageFolder = new File(folder);
        File f = new File(imageFolder, getRandomString(10) + file.getOriginalFilename()
                .substring(file.getOriginalFilename().length() - 4));
        if (!f.getParentFile().exists())
            //如果不存在文件则创建文件夹
            f.getParentFile().mkdirs();
        try {
            //存入图片
            file.transferTo(f);
            //对存入的图片进行压缩,并转换为jpeg格式
            Thumbnails.of(f)
                    .outputFormat("jpg")
                    .scale(0.5f)//图片比例压缩
                    .outputQuality(0.5f)//图片清晰度压缩
                    .toFile(f.getPath().split("\\.")[0]+".jpg");
            if(!type.equals("jpeg")){
                //删除图片
                f.delete();
            }
            String imgURL = "http://localhost:8443/api/file/" + f.getName().split("\\.")[0]+".jpg";
            return imgURL;
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }
    }
    //删除图片
    @CrossOrigin
    @PostMapping("api/deleteImg")
    public void deleteImg(@RequestParam Map<String,Object> requestMap){
        String imgName=requestMap.get("imgUrl").toString().split("/api/file/")[1];
        deleteImg(imgName);
    }
    //生成length个随机数组成的字符串
    public String getRandomString(int length) {
        String base = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }
}
package com.znz.backend.wj.contorller;
/**
 * @author znz
 * @create 2020/01/27/16:00
 */
import com.znz.backend.result.Result;
import com.znz.backend.wj.Service.UserService;
import com.znz.backend.wj.bean.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.Map;
@Controller
public class UserController {
    //Mybatis操作数据库
    @Resource(name = "userService")
    private UserService userService;
    //登录账号
    //注解@CrossOrigin解决跨域问题
    //@CrossOrigin
    @CrossOrigin
    @PostMapping(value = "api/login")
    @ResponseBody
    public String login(@RequestBody User requestUser) {
        return userService.login(requestUser);
    }
    //注册账号
//    @PostMapping(value="api/register")
//    @ResponseBody
//    public Boolean register(@RequestBody User requestUser){
//        return userService.register(requestUser);
//    }
    //修改密码
    @PostMapping(value = "api/changePassword")
    @ResponseBody
    public Result ChangePassword(@RequestParam Map<String, Object> requestMap) {
        return userService.changePassword(requestMap);
    }
    //查找账户是否存在
    @PostMapping(value = "api/selectUser")
    @ResponseBody
    public Boolean selectUser(@RequestParam Map<String, Object> requestMap) {
        return userService.selectUser(requestMap);
    }
}
package com.znz.backend.wj.dao;
import com.znz.backend.wj.bean.Book;
import com.znz.backend.wj.bean.Category;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.mapping.FetchType;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
 * @author znz
 * @create 2020/02/06/23:21
 */
@Mapper
@Repository(value = "bookMapper")
public interface BookMapper {
    //根据书的种类找到这一类型的所有书
    @Select("select * from book\n" +
            "where book.cid=#{_parameter}")
    List<Book> findAllByCategory(String cid);
    根据书的种类和用户账户找到这一类型的所有书
    @Select("Select * from book where book.cid=#{param1} and book.uid=#{param2}")
    List<Book>findAllByCategoryAndUid(String cid,String uid);
    //根据书名模糊找到书
    @Select("select * from book\n" +
            "where book.title like '%${_parameter}%'")
    List<Book> findAllByTitle(String title);
    //找到所有的书
    @Select("select * from book")
    List<Book> findAllBooks();
    //根据用户账号返回所有的书
    @Select("Select * from book where uid=#{_parameter}")
    List<Book> findAllBooksByUid(String uid);
    //根据id删除书籍
    @Delete("delete  from book where id=#{id}")
    int deleteBookById(int id);
    //添加图书
    @Insert("insert into znz.book(cover,title,author,date,price,newOld,contact,phone,qq,weChat,img_1,img_2,img_3,img_4,img_5,abs,cid,uid)\n" +
            "values(#{param1},#{param2},#{param3},#{param4},#{param5},#{param6},#{param7},#{param8},#{param9},#{param10},#{param11},#{param12},#{param13},#{param14}, #{param15},#{param16},#{param17},#{param18})")
    int insertBook(String cover,String title,String author,String date,String price,String newOld,String contact,String phone,
                   String qq,String weChat,String img_1,String img_2,String img_3,String img_4,String img_5,String abs,
                   String cid,String uid);
    //根据用户账号和书的id删除书籍
    @Delete("delete  from book where id=#{param1} and uid=#{param2}")
    int deleteBookByIdAndUid(int id,String uid);
}
package com.znz.backend.wj.Service;
import com.znz.backend.wj.bean.Book;
import com.znz.backend.wj.bean.Category;
import com.znz.backend.wj.dao.BookMapper;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
/**
 * @author znz
 * @create 2020/02/07/10:38
 */
@Service(value = "bookService")
public class BookService {
    @Resource(name = "bookMapper")
    private BookMapper bookMapper;
    @Resource(name = "categoryService")
    private CategoryService categoryService;
    /*******查询******/
    //返回所有的图书
    public List<Book> findAll() {
        return bookMapper.findAllBooks();
    }
    //根据用户账号返回所有的书
    public List<Book> findAllByUid(String uid) {
        return bookMapper.findAllBooksByUid(uid);
    }
    //根据书的种类返回所有的书
    public List<Book> findAllByCategory(String cid) {
        return bookMapper.findAllByCategory(cid);
    }
    //根据书的种类和用户账户返回所有的书
    public List<Book> findAllByCategoryAndUid(String cid,String uid){
        return bookMapper.findAllByCategoryAndUid(cid,uid);
    }
    //根据书名找到所有的数据
    public List<Book> finAllByTitle(String title) {
        return bookMapper.findAllByTitle(title);
    }
    //根据id删除图书
    public int deleteBookById(int id) {
        return bookMapper.deleteBookById(id);
    }
    //添加一本书
    public int insertBook(Book book) {
        return bookMapper.insertBook(book.getCover(), book.getTitle(), book.getAuthor(), book.getDate(), book.getPrice(), book.getNewOld(), book.getContact()
                , book.getPhone(), book.getQq(), book.getWeChat(), book.getImg_1(), book.getImg_2(), book.getImg_3(), book.getImg_4(), book.getImg_5(), book.getAbs(), book.getCid(), book.getUid());
    }
    //根据用户账号和书的id删除书籍
    public int deleteBookByIdAndUid(Book book) {
        return bookMapper.deleteBookByIdAndUid(book.getId(), book.getUid());
    }
}

五,项目总结

  本项目结构简单,代码简洁,比较适合做课程设计或期未作业使用,也可以在这个基础上进行功能扩展和增加,实现一个比较完整的毕业设计系统

相关文章
|
1月前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,包括版本兼容性、安全性、性能调优等方面。
145 1
|
19天前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。首先,创建并配置 Spring Boot 项目,实现后端 API;然后,使用 Ant Design Pro Vue 创建前端项目,配置动态路由和菜单。通过具体案例,展示了如何快速搭建高效、易维护的项目框架。
95 62
|
17天前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,帮助开发者提高开发效率和应用的可维护性。
34 2
|
19天前
|
JavaScript Java 项目管理
Java毕设学习 基于SpringBoot + Vue 的医院管理系统 持续给大家寻找Java毕设学习项目(附源码)
基于SpringBoot + Vue的医院管理系统,涵盖医院、患者、挂号、药物、检查、病床、排班管理和数据分析等功能。开发工具为IDEA和HBuilder X,环境需配置jdk8、Node.js14、MySQL8。文末提供源码下载链接。
|
1月前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用
【10月更文挑战第8天】本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。首先,通过 Spring Initializr 创建并配置 Spring Boot 项目,实现后端 API 和安全配置。接着,使用 Ant Design Pro Vue 脚手架创建前端项目,配置动态路由和菜单,并创建相应的页面组件。最后,通过具体实践心得,分享了版本兼容性、安全性、性能调优等注意事项,帮助读者快速搭建高效且易维护的应用框架。
41 3
|
1月前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用
【10月更文挑战第7天】本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。首先,通过 Spring Initializr 创建 Spring Boot 项目并配置 Spring Security。接着,实现后端 API 以提供菜单数据。在前端部分,使用 Ant Design Pro Vue 脚手架创建项目,并配置动态路由和菜单。最后,启动前后端服务,实现高效、美观且功能强大的应用框架。
41 2
|
15天前
|
JavaScript NoSQL Java
CC-ADMIN后台简介一个基于 Spring Boot 2.1.3 、SpringBootMybatis plus、JWT、Shiro、Redis、Vue quasar 的前后端分离的后台管理系统
CC-ADMIN后台简介一个基于 Spring Boot 2.1.3 、SpringBootMybatis plus、JWT、Shiro、Redis、Vue quasar 的前后端分离的后台管理系统
30 0
|
1月前
|
JavaScript 前端开发 数据可视化
【SpringBoot+Vue项目实战开发】2020实时更新。。。。。。
【SpringBoot+Vue项目实战开发】2020实时更新。。。。。。
48 0
|
1月前
|
JavaScript 前端开发 Java
Springboot+vue实现文件的下载和上传
这篇文章介绍了如何在Springboot和Vue中实现文件的上传和下载功能,包括后端控制器的创建、前端Vue组件的实现以及所需的依赖配置。
207 0
|
1月前
|
JavaScript API
vue尚品汇商城项目-day06【37.获取交易数据+38.用户地址信息展示+39.交易信息展示及交易页面完成+40.提交订单+41.支付组件内获取订单号与展示支付信息】
vue尚品汇商城项目-day06【37.获取交易数据+38.用户地址信息展示+39.交易信息展示及交易页面完成+40.提交订单+41.支付组件内获取订单号与展示支付信息】
39 0