简单收藏功能的实现(SpringBoot,MybatisPlus,Vue)

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

  现在涉及到应用或者网站开发的东西都少不了收藏功能我本人在做一个新手项目时也需要这个功能于是我就通过自己的想法实现了一个简单的收藏功能下面分享给大家希望对大家思路有帮助。

目录

整体思路

数据库表的设计

收藏与取消收藏功能

查询用户的所有收藏功能


整体思路

  首先是数据库表的设计这里准备用两个表一个是课程内容的表一个是专门用来收藏的表我们在收藏的同时给课程表的选择人数加一并且在收藏表里新增一条相关内容用课程id这个字段将两张表联系起来。

数据库表的设计

课程表

public class Course {
    @TableId(type = IdType.AUTO)
    private int id;
    private String courseName;
    private String courseCover;
    private String courseVip;
    private String courseAge;
    private String courseAdmin;
    private long peopleNumber;
}

收藏表

public class Collect {
    @TableId(type = IdType.AUTO)
    private int id;
    private int userId;
    private int courseId;

    @TableField(fill = FieldFill.INSERT_UPDATE)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date collectDate;
}

这是我的持久层相关代码也就是与数据库的表相对应的工具类大家可以参考收藏表里的courseId就对应课程表里的id。

收藏与取消收藏功能

首先需要在前端绑定一个点击事件方法

collect(id) {
      this.$confirm('是否确定收藏课程?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(
          () => {
            this.$axios.post("/collect/course",{
              courseId: id,
              userId: 1,
            }).then(res => {
              if (res && res.status === 200) {
                this.isCollect = true;
                this.$message({
                  type: 'success',
                  message: '已收藏成功'
                })
              }
            })
          }
      )
    },

这里我们将相应的课程id与用户id发送到后端然后进行收藏表字段的增添和人数增加就行然后里面有一个属性叫isCollect是用于判断是否收藏的后面用于前端图标的显示。

然后是Controller接口的编写

@PostMapping("/course")
    public Result collectCourse(@RequestBody CollectDTO collect){
        try {
            collectService.collectCourse(collect);
            courseService.collectCourse(collect.getCourseId());
            return R.success();
        }
        catch (Exception e){
            e.printStackTrace();
            return R.fail("上传失败");
        }
    }

这里需要调用两个service因为我们既需要在收藏表里增添也需要在课程表里增加收藏人数。

Service层代码在MyBatis Plus的加持下很简单

//收藏课程
    @Override
    public void collectCourse(CollectDTO collect) {
        Collect newCollect = new Collect();
        newCollect.setCourseId(collect.getCourseId());
        newCollect.setUserId(collect.getUserId());
        newCollect.setCollectDate(new Date());
        collectMapper.insert(newCollect);
    }

增加人数我们将相应的课程字段取出然后数量加一再进行更新就行

//收藏使课程选择人数加一
    @Override
    public void collectCourse(int id) {
        Course course = courseMapper.selectById(id);
        long a = courseMapper.selectById(id).getPeopleNumber();
        a=a+1;
        course.setPeopleNumber(a);
        courseMapper.updateById(course);
    }

取消收藏也是同样的道理大家可以尝试自己编写。

然后是前端页面加载时判断是否收藏这里我们可以用到Vue的v-if和v-else

<!--          已收藏  如果iscollect为true显示已收藏绑定取消收藏功能-->
      <el-button class="button" v-if="isCollect" @click.prevent="delCollect(course.id)" circle><i class="el-icon-star-on"/></el-button>
      <!--          未收藏  绑定点击收藏按钮-->
      <el-button class="button" v-else @click.prevent="collect(course.id)" circle><i class="el-icon-star-off"/></el-button>

这里就与我们刚刚的收藏功能属性相关联了如果收藏了我们属性设置为true如果没有收藏则设置为false。

现在我们需要在加载页面时就判断是否收藏了当前课程需要在前端编写一个方法

api() {
      return [
        axios.get("/course/selectCourse",{
          params: {
            id: this.$route.query.id,
          }
        }),
        axios.get("/collect/isCollect",{
          params: {
            courseId: this.$route.query.id,
            userId: 1
          }
        })
      ]
    },
    loadCourse () {
      axios.all(this.api()).then(axios.spread((res1,res2) => {
        this.course = res1.data
        console.log(this.course);
        if(res2.data.hasOwnProperty('id')){
          this.isCollect = true;
        }
      }))
    },

这里我用到了axios的并发请求因为需要取到课程数据渲染到页面的同时判断是否收藏判断收藏时我们需要向后端发送userId和courseId两个字段同时比对才能判断出是否收藏如果收藏了就返回相应的数据没有收藏的话就会返回空这里我们就取其中的id属性判断是否存在就行isCollect默认为false。

判断收藏的Controller很简单直接调用collectService就行

@GetMapping("/isCollect")
    public Collect isCollect(int userId,int courseId){
        return collectService.isCollect(userId,courseId);
}

然后是service层代码

//通过两个字段判断用户是否收藏
    @Override
    public Collect isCollect(int userId, int courseId) {
        LambdaQueryWrapper<Collect> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Collect::getUserId,userId).eq(Collect::getCourseId,courseId);
        return collectMapper.selectOne(wrapper);
    }

直接使用MyBatis Plus的相关功能进行比对就行很方便以上就是简易的收藏功能。

查询用户的所有收藏功能

这个问题最开始非常困扰我因为我也是第一次做我这样实现的收藏功能如果要查看一个用户的所有收藏的话我需要先从收藏表里将所有的课程id查询出来再用这些id去课程表里面查询查询出来还需要是Page类型因为方便前端布局好在最后实现了想法。

首先是前端页面编写一个初始加载方法将用户的id以及页码和当页大小传给后端

methods: {
    load() {
      axios.get('/collect/view',{
        params: {
          userId: 1,
          page: 1,
          size: this.size
        }
      }).then(
          res => {
            this.courses = res.data.records
            this.total = res.data.total
            console.log(this.courses)
          }
      )
    },
    handleCurrentChange(page) {
      axios.get('/course/view?',{
        params: {
          userId: 1,
          page: page,
          size: this.size
        }
      }).then(
          res => {
            this.courses = res.data.records
            this.total = res.data.total
            console.log(this.courses)
          }
      )
    }
  },
  created() {
    this.load()
  },

分页的地方我用了element-ui的分页工具。

然后是Controller的编写

@GetMapping("/view")
    public Page<Course> view(int userId,int page, int size) {
        List<Collect> collects = collectService.view(userId);
        return courseService.selectCollect(collects,page,size);
    }

这里我先用list将收藏表的相关对象查询后放在里面然后再遍历这个list来进行查询相关课程

collectService

//找出收藏的书籍
    @Override
    public List<Collect> view(int userId) {
        LambdaQueryWrapper<Collect> wrapper = new LambdaQueryWrapper<>();
        List<Collect> collects = collectMapper.selectList(wrapper.eq(Collect::getUserId,userId));
        return collects;
    }

courseService

//遍历list获取书籍信息再修改为page类型
    @Override
    public Page<Course> selectCollect(List<Collect> collects,int pageNum,int pageSize) {
        List<Course> list = new ArrayList<>();
        for(int i=0;i<collects.size();i++){
            Collect c = collects.get(i);
            list.add(courseMapper.selectById(c.getCourseId()));
        }
        System.out.println(list);
        Page<Course> page = new Page<>(pageNum, pageSize);
        int start = (int)((page.getCurrent() - 1) * page.getSize());
        // 当前页最后一条数据在List中的位置
        int end = (int)((start + page.getSize()) > list.size() ? list.size() : (page.getSize() * page.getCurrent()));
        page.setRecords(new ArrayList<>());
        if (page.getSize()*(page.getCurrent()-1) <= page.getTotal()) {
            // 分隔列表 当前页存在数据时 设置
            page.setRecords(list.subList(start, end));
        }
        page.setTotal(list.size());
        return page;
    }

这里我没有想到直接查询成为Page类型的方法所以我先一个个查询之后放入list里面再将list转化为page。

以上就是简单收藏功能的实现方法肯定不是最好的但是思路希望对大家有帮助需要源码可以私。

VX公众号 loquat分享站回复 收藏 获取源码

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: Springvue