SpringBoot+vue仿网易云音乐网站(四)- 系统设计及技术实现
一、首页概述通过上一章节,了解了前端的整个框架就是如上图所示,不管点击什么地方,顶部的导航栏,已经底部的播放栏都是不会变的,只有中间的页面在变化。那首先来看下首页的实现。为了方便观看,我将浏览器的显示比例调到了50%。可以看到首页的结构,最上面是轮播图,下来是推荐歌单,再下来是推荐歌手。来整体看下首页的前端代码(为了方便查看,我把所有的样式去掉了)<template><div&g
一、概述
针对每一个功能点,写出我的系统设计,以及具体的实现,其实写程序不难,主要是设计,设计出来了,遇到不会的,要知道自己想怎么做,想要实现什么样的效果,再去百度或者询问,一步一步往下做,就能完成整个项目。
二、首页
1. 系统设计
首页的系统设计很简单,点击首页是,查询有效的轮播图,随机查询十个歌单和十个歌手,前端渲染。
2. 后端(Service层和Dao层略过)
轮播图没有什么特殊点,就查询有效的数据
Controller
@GetMapping("/showSlide")
public Result showSlide(){
List<Slide> slides = slideService.showSlide();
return Result.success(slides);
}
Mapper.xml
<select id="showSlide" resultMap="BaseSlideMap">
select * from slide where slide_valid=1
</select>
<resultMap id="BaseSlideMap" type="Slide">
<result property="slideId" column="slide_id" />
<result property="slideImg" column="slide_img" />
<result property="slideAlbumId" column="slide_albumid" />
<result property="slideValid" column="slide_valid" />
</resultMap>
推荐歌手/歌单
controller
//SingerController
@GetMapping("/topSinger")
public Result topSinger(){
List<Singer> singerList=singerService.topSinger();
return Result.success(singerList);
}
//ListsController
@GetMapping("/topLists")
public Result topLists(HttpServletResponse response){
List<Lists> list=listsService.topLists();
return Result.success(list);
}
Mapper.xml
<!--SingerMapper.xml -->
<select id="topSinger" resultMap="BaseSingerMap">
SELECT * FROM singer ORDER BY RAND() LIMIT 10;
</select>
<!--ListMapper.xml -->
<select id="topLists" resultMap="BaseListsMap">
SELECT * FROM lists ORDER BY RAND() LIMIT 10;
</select>
3. 前端
home页面一加载时,就调用这个三个查询方法,再将数据渲染到视图中。
meunList是查询后的歌单数据,视图层渲染。
三、歌单页和歌手页
歌单歌手页实现方法一样,其实就是一个简单的分页查询。
1. 系统设计
一开始默认是全部歌手也就是不卡类型,当点击上方的类型时,再根据类型来查询。
2. 后端
Controller
//页面加载时,不卡类型
@GetMapping("/allSinger")
public Result querySingers(@RequestParam("pageNum")int pageNum,@RequestParam("pageSize") int pageSize){
//先根据页码(页码刚加载时,都为1),和一页的个数查询出所有歌手
//在sql中,这两个参数分别为起始下标,和数量,比如我要查询前十个,起始下标就是0,数量就是10
List<Singer> singerList=singerService.queryAllSinger((pageNum-1)*pageSize,pageSize);
//再查出总数量
int count=singerService.countOfSinger();
Map<String,Object> map = new HashMap<>();
//然后将数据和数量放入Map,返回给前台
map.put("list",singerList);
map.put("totalSize",count);
return Result.success(map);
}
//点击类型后,多加一个类型参数,分页方法如上
@GetMapping("/singerByType")
public Result singerByType(@RequestParam("pageNum")int pageNum,
@RequestParam("pageSize") int pageSize,
@RequestParam("singerType") int singerType){
List<Singer> singerList=singerService.querySingerByType((pageNum-1)*pageSize,pageSize,singerType);
int count=singerService.countOfSingerByType(singerType);
Map<String,Object> map = new HashMap<>();
map.put("list",singerList);
map.put("totalSize",count);
return Result.success(map);
}
SingerMapper.xml
<!--根据起始下标和数量查询所有歌手-->
<select id="queryAllSinger" parameterType="int" resultMap="BaseSingerMap">
select * from singer limit #{startIndex},#{pageSize}
</select>
<resultMap id="BaseSingerMap" type="Singer">
<result property="singerId" column="singer_id"/>
<result property="singerName" column="singer_name"/>
<result property="singerDetails" column="singer_details"/>
<result property="singerPhoto" column="singer_photo"/>
</resultMap>
<!--查询所有歌手的数量-->
<select id="countOfSinger" resultType="int">
select count(*) from singer
</select>
<!--根据起始下标、数量和类型查询所有歌手-->
<select id="querySingerByType" parameterType="int" resultMap="BaseSingerMap">
select * from singer where singer_type=#{singerType} limit #{startIndex},#{pageSize}
</select>
3. 前端
四、用户主页
1. 系统设计
点击个人中心时,要查询自己的个人信息,粉丝和关注数量,以及自己创建或者收藏的歌单。这个页面同时还会用作我查看其他用户的主页,例如我查看用户“老胡”的主页,所以左侧还有一个按钮,如果是我本人的主页,显示编辑个人信息,是其他用户,再根据关注情况,显示相互关注、已关注、+关注。
2. 后端
UserController
//根据Userid查询User信息
@GetMapping("/userById")
public Result userById(@RequestParam("userId") int userId){
User user= userService.userById(userId);
return Result.success(user);
}
ListsController
//根据userId查询创建的歌单
@GetMapping("/listByUserId")
public Result listByUserId(int userId){
List<Lists> list=listsService.queryListsByUserId(userId);
return Result.success(list);
}
//根据UserId查询收藏的歌单
@GetMapping("/colListByUserId")
public Result colListByUserId(int userId){
List<Lists> list=listsService.colListsByUserId(userId);
return Result.success(list);
}
FansController
//根据UserId查询关注的人的总数
@GetMapping("/focusCount")
public Result getFocusCount(@RequestParam("userId") int userId){
int count = fansService.getFocusCount(userId);
return Result.success(count);
}
//根据UserId查询粉丝的总数
@GetMapping("/fansCount")
public Result getFansCount(@RequestParam("userId") int userId){
int count = fansService.getFansCount(userId);
return Result.success(count);
}
//根据用户Id和我本人的Id查询,是不是我的关注者
@GetMapping("/userIsFocus")
public Result userIsFocus(@RequestParam("userId") int userId,@RequestParam("myId")int myId){
int count = fansService.userIsFocus(userId, myId);
return Result.success(count);
}
//根据用户Id和我本人的Id查询,是不是我的粉丝
@GetMapping("/userIsFans")
public Result userIsFans(@RequestParam("userId") int userId,@RequestParam("myId")int myId){
int count = fansService.userIsFans(userId, myId);
return Result.success(count);
}
FansMapper.xml
前面分析了粉丝表,主要字段,关注者Id,被关注者Id,和类型,一般情况下,歌手不可能关注别人,所有关注者Id只可能为用户,而被关注者可能为用户,也可能为歌手,所以再添加一个类型,来区分是歌手还是用户。
<!--根据UserId查询我的关注者 -->
<select id="getMyFocus" resultMap="BaseFansMap">
select * from fans
left join user on user_id = fans_focusid and fans_type = 1
left join singer on fans_focusid=singer_id and fans_type = 2
where fans_fansid =#{userId} ORDER BY fans_id desc
</select>
<!--根据UserId查询我的粉丝,粉丝只可能是用户 -->
<select id="getMyFans" resultMap="BaseFansMap">
select * from fans
left join user on user_id = fans_fansid
where fans_type = 1 and fans_focusid = #{userId} ORDER BY fans_id desc
</select>
<!--根据UserId查询我的关注者总数 -->
<select id="getFocusCount" resultType="int">
select count(*) from fans
left join user on user_id = fans_focusid and fans_type = 1
left join singer on fans_focusid=singer_id and fans_type = 2
where fans_fansid =#{userId}
</select>
<!--根据UserId查询我的粉丝总数 -->
<select id="getFansCount" resultType="int">
select count(*) from fans
left join user on user_id = fans_fansid
where fans_type = 1 and fans_focusid = #{userId}
</select>
<!--根据用户Id和我的Id查询是否为我的粉丝 -->
<select id="userIsFans" resultType="int">
select count(*) from fans where fans_type = 1 and fans_fansid =#{userId} and fans_focusid =#{myId}
</select>
<!--根据用户Id和我的Id查询是否为我的关注者 -->
<select id="userIsFocus" resultType="int">
select count(*) from fans where fans_type = 1 and fans_fansid =#{myId} and fans_focusid =#{userId}
</select>
3. 前端
主要讲解下粉丝。
五、歌手、歌单、专辑详情页
1. 系统设计
先上图
歌手页:
歌手页,上面显示了歌手图片,个人信息,歌曲量,专辑量,歌曲列表,专辑列表,已经根据当前登录用户是否关注此歌手,显示已关注或关注。
歌单页:(歌单和专辑页结构一样,不讲解)
歌单页:显示歌单封面、歌单标题、歌单创建者头像、昵称,歌单创建时间、类型标签、歌曲量、播放量,简介,已经根据是否是自己创建的,显示修改图标,或者已收藏、收藏,同事点击收藏时,会加入到自己的收藏,变为已收藏,点击已收藏,会删除掉自己的收藏,变为收藏。其实可以看出歌手详情页的结构和歌单也是大同小异,就拿更复杂的歌单讲解。
2. 后端
ListController
//根据歌单Id查询歌单信息,带有创建者信息
@GetMapping("/listById")
public Result listById(int listId){
Lists list=listsService.userOfList(listId);
//这里用redis实现了点击量的统计,后续介绍
String key="list_"+listId;
redisTemplate.opsForValue().increment(key);
return Result.success(list);
}
//通过用户id和歌单id,判断此歌单是否收藏
@GetMapping("/isCol")
public Result isCol(@RequestParam("listId") int listId,@RequestParam("userId") int userId){
int isCol=listsService.isCol(listId, userId);
return Result.success(isCol);
}
//通过用户id和歌单id,将此歌单收藏
@PostMapping("/addCol")
public Result addCol(@RequestParam("listId") int listId,@RequestParam("userId") int userId){
listsService.addCol(listId, userId);
return Result.success();
}
//通过用户id和歌单id,将此歌单取消收藏
@DeleteMapping("/delCol/{listId}/{userId}")
public Result delCol(@PathVariable("listId") int listId,@PathVariable("userId") int userId){
listsService.delCol(listId, userId);
return Result.success();
}
SongController
//根据歌单Id查询所有歌曲
@GetMapping("/songOfLists")
public Result songByList(int listId){
List<Song> songList=songService.querySongOfList(listId);
return Result.success(songList);
}
CommentsController
//根据评论目标Id,和目标类型查询所有评论,歌单默认类型1,专辑为2,这里相当于传目标Id为此歌单Id,类型为1.
@GetMapping("/allComments")
public Result allComments(int commTargetId,int commType){
List<Comments> list= commentsService.queryComments(commTargetId,commType);
System.out.println(list);
return Result.success(list);
}
ListMapper.xml
<!--根据歌单Id查询歌单信息,包含创建者信息,用了一对一的复合查询-->
<select id="userOfList" resultMap="UserListMap" parameterType="int">
select * from lists l left join user u on l.list_userid=u.user_id where l.list_id=#{listId}
</select>
<resultMap id="UserListMap" type="Lists">
<id property="listId" column="list_id"/>
<result property="listTitle" column="list_title"/>
<result property="listImg" column="list_img"/>
<result property="listTime" column="list_time"/>
<result property="listUserId" column="list_userid"/>
<result property="listDetails" column="list_details"/>
<result property="listType" column="list_type"/>
<result property="listPlayNum" column="list_playnum"/>
<association property="user" javaType="User">
<id property="userId" column="user_id"/>
<result property="userName" column="user_name" />
<result property="userPhoto" column="user_photo" />
</association>
</resultMap>
<!--通过用户id和歌单id,判断此歌单是否收藏 -->
<select id="isCol" resultType="int">
select count(*) from userlist where userlist_listid=#{listId} and userlist_userid = #{userId}
</select>
<!--通过用户id和歌单id,将此歌单收藏 -->
<insert id="addCol">
insert into userlist (userlist_listid,userlist_userid) value (#{listId},#{userId})
</insert>
<!--通过用户id和歌单id,将此歌单取消收藏 -->
<delete id="delCol">
delete from userlist where userlist_listid =#{listId} and userlist_userid = #{userId}
</delete>
SongMapper.xml
因为歌手列表不光显示歌曲信息,还有歌手名,专辑名,所以采用一对一的复合查询
<select id="querySongOfList" resultMap="SongMap" parameterType="int">
select * from songlist sl left join song s on s.song_id=sl.songlist_songid left join album a on s.song_album=a.album_id left join singer si on s.song_singer=si.singer_id where sl.songlist_listid=#{listId}
</select>
<resultMap id="SongMap" type="Song">
<result property="songId" column="song_id"/>
<result property="songName" column="song_name"/>
<result property="songSinger" column="song_singer"/>
<result property="songFilePath" column="song_filepath"/>
<result property="songAlbum" column="song_album"/>
<result property="songLyc" column="song_lyc"/>
<association property="album" javaType="Album">
<id property="albumId" column="album_id"/>
<result property="albumName" column="album_name" />
<result property="albumImg" column="album_img" />
</association>
<association property="singer" javaType="Singer">
<id property="singerId" column="singer_id"/>
<result property="singerName" column="singer_name"/>
</association>
</resultMap>
3. 前端
前端和用户主页很相似
收藏歌单,收藏歌曲,当前播放列表后面再写。
更多推荐
所有评论(0)