版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、1 在线音乐网站的设计与实现在线音乐网站的设计与实现 摘摘 要要 随着全球移动互联网的发展,越来越多的上网设备被人们所使用,这带来了软件 跨平台的困难,Web 网站作为运行的软件,通过它诸多新特性实现了跨平台的运行使 得开发成本大大降低,而 web 音乐网站正是实现多平台下的数据共享以及使用,使得 用户能更加随心所欲地获取自己的音乐信息。 本次设计是基于 Vue 的在线音乐网站。 本次设计采用了 Vue 以及 Node.js 作为开发环境。在设计中使用了前后端分离的开 发模式,使用了 MVVM 架构的 Vue 实现前端的数据绑定以及展示,在网络交互的方 面上充分使用 Ajax 的技术来实现与后
2、端 Node 服务端交互,而本地数据库采用了 MongoDB 非关系数据库,在最终完成的作品中实现流行的 Token 认证登录,以及歌单 的收藏和获取,高性能的网站响应,以及歌曲播放历史,歌曲播放,歌曲排行榜,新 歌专辑推荐,歌手信息获取,和用户管理的前后端分离的 Web 系统。 本次设计的 Web 在音乐网站虽然功能并不太完善,但是使用到的诸多技术包括 Web 网络编程,数据库编程,以及前端架构使用和前后端分离的开发思想是具有一定 的实用价值的。 关键词:关键词:Web;音乐网站;前后端分离;数据库编程;Vue 框架; 2 Design and implementation of news
3、app system based on iOS Abstract With the development of the global mobile Internet, more and more Internet de vices are used by people, which brings the difficulty of cross-platform software, w eb site as the running software, through its many new features to achieve cross-platf orm operation makes
4、 the development cost greatly reduced, and web music website i s to achieve multi-platform data sharing and use, so that users can get their music i nformation more freely. This design uses Vue and Node.js as the development environment. In the design , the front-end development mode is separated fr
5、om the back-end, using the MVV M architecture of Vue to realize the front-end data binding and display, and using Ajax technology to fully interact with the back-end Node server, while the local dat abase uses MongoDB non-relational database to realize the popular Token authenticatio n login, song l
6、ist collection and acquisition, high performance website response, a nd song playback history, song playback, song charts, new album recommendatio n, singer information acquisition, and user management of the front-end separated Web system. The design of the Web in the music website is not perfect,
7、but the design uses many technologies including Web programming, database programming, and front-end architecture use and front-end separation of the development idea is of some practical value. Keywords: Web; music website; Network programming; Database programming;Vue 3 目目 录录 1 绪论.6 1.1 WEB 系统概述 .
8、6 1.2 在线音乐网站的特点及研究意义.6 2 总体设计 .7 2.1 系统功能要求 .7 2.2 方案论证 .7 2.2.1 首页模块.7 2.2.2 详细信息模块.7 2.2.3 播放模块.8 2.2.4 用户模块 .8 2.3 系统框图.9 3 软件开发环境及开发技术介绍 .10 3.1 软件开发环境 .10 3.1.1 VSCODE 简介 .10 3.1.2 POSTMEN 介绍 .10 3.2 开发技术介绍 .10 3.2.1 VUE 框架简介 .10 3.2.2 JSON 简介 .10 3.2.3 MONGODB 简介 .10 3.2.4 MVVM 设计模式简介 .10 4 系统
9、具体设计与实现 .11 4.1 首页的响应式布局的实现.11 4.2 最新专辑模块的实现.13 4.2.1 最新专辑的展示页.14 4 4.2.2 最新专辑详细页的实现.17 4.3 热门榜单模块的实现 .19 4.3.1 热门榜单详细页的实现.19 4.3.2 播放列表传值的实现.19 4.4 热门歌手模块的实现 .20 4.4.1 热门歌手列表页的实现.20 4.4.2 歌手详细页的实现.21 4.5 用户中心模块的实现 .23 4.5.1 用户注册功能的实现.23 4.5.2 用户登录功能的实现.26 4.5.3 个人中心的实现 .27 4.5.4 用户收藏列表以及历史列表的实现 .29
10、 5 软件测试.32 5.1 用户注册功能测试.32 5.2 用户登录功能测试.32 5.3 用户个人信息功能测试.33 5.4 首页模块测试.33 5.5 搜索功能模块测试.34 5.6 详细页模块测试.35 5.7 播放功能模块测试.36 6 结论 .37 参考文献.38 谢 辞.39 附 录.40 5 1 1 绪论绪论 1.1 Web 系统概述系统概述 1990 年 Tim 以 HTML 为开发基础完成了最初的 Web 服务器,其后他在 1991 年上推 广了 Web 的概念,直到 1994 年万维网联盟(World Wide Web Consortium)即 W3C 组 织成立标志了万
11、维网的面世。 目前实现前后端分离的关键即是异步数据交互技术 Ajax 即“Asynchronous Javascript And XML”和重要的基础框架 JavaScript 为后续的 Jquery,YUI 等框架的 实现提供了基础,这两项技术正是 Web 系统发展的“铁器时代” , 在 1998 年前后得 到了应用。但是由于标准的不统一使得发生了两次浏览器大战,于是 W3C 组织在 2014 年 10 月 28 日,W3C 正式发布 HTML 5.0 推荐标准,即 H5。而例如 Node.js、JSON、前端 MVVM 框架、Bootstrap、移动 Web、混合 App、则是 web“现
12、 代化时代” 。 1.2 在线音乐网站的特点及研究意义在线音乐网站的特点及研究意义 随着互联网的发展,人们早已无法离开网络,而在年轻人中有着不少热爱音乐的 群体,他们热爱与人分享自己喜爱的音乐,分享自己对音乐的感受和想法,而现在大 多的音乐网站想要使用完全的云服务都要下载客户端,并且由于在版权竞争的作用下, 更多的厂商花费资金去购买版权而忽视了一些云服务,以及前端排版的更新问题,且 传统的页面相对于 Vue 的单页面富应用的特性有着先天的弱势,导致了挺多线上的音 乐网站存在的操作不便,繁琐,加载时间长等诸多不利因素,为了避免这种问题在线 音乐系统应运而生。 目前国内拥有最大的手机用户群体,且作
13、为比较新兴的前端技术 Vue 的单页富应 用程序十分多,它不仅可以对移动端进行开发,以往人们想在别人的电脑上听自己曾 听过的歌需要一首一首搜索,这样做十分耗时,于是本项目就在于实现云端记录用户 歌单,历史和歌曲资源以及用户评论,让音乐更加贴近我们。本项目是基于 Node.js 后端以及 前端:Vue,Vuex,VueRouter,开发的在线音乐网站让用户能够轻松快速的 听上高品质的音乐。在 PC 端更是有着众多大厂使用它。这是使得本身就需要把资源放 在音乐传输上的在线音乐应用可以有更高的效率去运行。最大程度地复用可以让它有 更多的资源去实现高品质音乐的传输,并且音乐网站的交互可以使小范围的用户
14、更多 的交流,可以改变人们在信息传播上的被动。 6 2 2 总体设计总体设计 2.12.1 系统功能要求系统功能要求 该系统可以获取数据库,以及网易云音乐的歌曲歌单资源,并用特定样式显示出 来,并且支持对收听历史,歌曲,歌单收藏并对自己的信息进行管理。 1)获取音乐信息(包括推荐歌单、推荐榜单、推荐歌手)的浏览; 2)用户能够收藏自己喜欢的歌单以及音乐; 3)用户可以在自己的收藏界面中获取已经收藏的歌单,并可以进行浏览收藏的歌单。 4)用户可以在系统中注册并上传个人头像,注册完成后可使用账号登录。 5)用户登录后开放收藏,收听历史等使用权限。 2.22.2 方案论证方案论证 .
15、1 首页首页 首页分为三个部分,头部导航栏,中部内容,以及尾部。. 本次设计的音乐网站首页为响应式主页,头部导航栏以及中部内容显示都使用了 CSS3 媒体查询(media Media Queries)方式实现响应式的展示。头部导航栏会判断 当期的路由位置,选择对应的标签给予高亮,但是在低分辨率下即手机等设备下浏览 的话高亮路由标签列表以及搜索栏将隐藏,转而显示一个下拉按钮,变为类似下拉菜 单的显示模式以适应低分辨率下的展示。 中部推荐内容部分采用 Vue 组件封装好,一共有四种类型,首先是首页轮播图, 轮播图也采用响应式实现,信息皆是由进入首页时候在 Vue 的 created 生命周期通过
16、ajax 请求并发从后端获取的信息若网络请求有误将隐藏信息内容,首先展示的是每日 随机推荐,最新的专辑,再是流行歌手,最后是热门榜单的推荐,点击分别能进入随 机推荐页面,专辑的详细页,歌手的详细页,榜单的详细页或是直接播放。 2.2.2 详细信息模块详细信息模块 详细信息模块由歌曲详细,歌手详细,榜单详细,专辑详细构成。 详细页都有头部和尾部组成,头部采用 flex 布局,自适应宽度,由信息页的类型 决定头部图片的内容,进入头部也时会在 created 生命周期中后去 Vue 的$route 实例 下的 params 参数,部分的页面需要有分页操作所以会在创建时初始化并且通过 aioxs 访问
17、对应的后端 API 去获取信息并展示数据,由于有部分页是分页的,而 Vue 虚拟 Dom 的特性必须要给 img 标签加 key 提高 diff 算法的性能,否则会出现图片闪回的情况, 7 为了避免这种情况的发生,大部分是图片都是采用的懒加载并且会将 url 地址绑定为 key 以优化换页时的性能。页面提供包括(歌手,榜单,专辑,歌曲)的图片,介绍, 以及出版日期,类型,以及歌曲列表,并且会添加路由跳转形成回环。 2.2.3 播放模块播放模块 播放模块由播放器以及播放列表构成 播放页面包括有歌词的滚动显示,用户可以通过点击播放按钮实现暂停和继续播 放,上一首以及下一首按钮,并且展示已经在播放列
18、表中的歌曲,用户可以通过音量 按钮控制播放的音量大小,还能通过随机播放按钮以及单曲循环等选择自己想要的播 放模式。进度条提供拖动改变以及点击改变,通过监听 audio 标签的 ontimeupdate 事 件进行监听实现播放时间的实时更改以及歌曲的长度时间。 移动端播放模块实现图如下: 2.2.4 用户模块用户模块 系统用户模块的主要功能有用户的注册和登录、对个人信息的管理、用户对收藏 信息的管理。 注册登录是用户信息记录的基础功能,收藏音乐,收藏歌单,必须在用户在登录 状态下才能使用,否则将跳转至登录页面进行登录。注册功能可以自行上传图片作为 头像,并且可以设置自己的昵称,等。 登录后用户可
19、以进入个人中心查看到收藏以及历史信息,以实现多平台都能够共 享播放过的数据,并且登录状态会将服务端返回的 Token 暂时放存放在本地,以至于 使其维持登录状态。 8 2.3 系统框图系统框图 在未登录状态下,用户可以正常的使用音乐搜索,专辑推荐,获取音乐信息,歌手 信息等功能。 在登录状态下,用户可以查看自己收听的歌曲历史信息,以及编辑增加自己的收藏 歌单,以实现多平台的数据共享。 下图为本设计的在线音乐网站的功能模块图: 图 2.2 系统功能模块图 3 3 软件开发环境及开发技术介绍软件开发环境及开发技术介绍 3.13.1 软件开发环境软件开发环境 .1 VscodeVsc
20、ode 简介简介 VsCode 的全称是 Visual Studio Code,是微软于 2015 年发布的一款免费开源的现 代化轻量级代码编辑器。 VsCode 一经发布就非常受到前端开发者的欢迎,一是其插件生态环境十分良好, 有很多的插件可以使用和开发,而有由于前端技术迭代十分的快速,使得开发者需要 频繁的使用各种框架和工具,VsCode 的插件生态就使得这一个程序就可以完成各种各 9 样的开发任务,插件由开发者发布也是因为如此发布的插件可以让开发者提高开发效 率。 .2 PostmanPostman Postman 是款强大网页调试工具的客户端,postman 为用户提供
21、强大的 Web API ; setBannerHeight() if (document.body.clientWidth 768) this.imgHeight = 350px; else if (document.body.clientWidth let album = ; album.id = item.id; = ; album.picUrl = item.blurPicUrl; album.singer = item.artists.map(item) = ).join(/); album.alias = item.alias
22、; return album; ); return response(result.status, albums); 15 return response(result.status, ); 分页功能使用了 elementUi 中的 el-pagination 其中 current-page 属性记录当前 所在的分页,在页面初始化时候会使用 this.pageIndex = this.$route.params.id;去 获取 URL 中的页数,由于前端路由和后端路由的不同所以具体的页面是在前端获取页 面的页面值,并且再通过 ajax 请求去获取当页的数据,并且保存在一个数组中,而在 下一次更
23、改页面的时候需要先去数组内核对是否已经有数据了,如果有数据则直接从 数组内引用而不需要再次通过 ajax 请求获取使得服务器压力大大减小,而且也优化了 前端的用户体验不需要频繁的发出网络请求。 由于 Vue 的虚拟 dom 比对算法 Diff 算法的性能问题,会使得页面切换后 img 标签 的 Src 改变,但是还没有由于用户还没有取得图片资源的这段时间内,页面的图片还 会沿用此前的 Src 会使得页面的图片切换不统一或者说切换混乱,所以页面的 img 会 绑定 key 属性,以提高 Diff 算法的能力,并且在全局使用懒加载的形式加强前端的新 能,没有浏览到的图片不加载以实现更好的用户体验。
24、 .2 最新专辑详情页的实现最新专辑详情页的实现 最新专辑详情页由头部的专辑信息、播放全部按钮、列表信息,右侧的简介显示栏, 以及底部的云音乐的评论信息。 最新专辑详细页的信息由路由开始,首先采用动态路由实现详细页的路由,并且 在详细页的 created 生命周期中获取路由的 params 信息即在其他页面跳转到详细页的 时候会将专辑的 ID 当做 params 的一部分,然后到了最新专辑详细页的 created 周期 的时候就会获取这个 ID 再通过已经封装好的内容去调用获取信息的方法。 由于 Vue 虚拟 dom 渲染的机制问题,如果 data 中没有对应的信息就会报错所以
25、在 模板渲染的 dom 前加上了 v-if 判断,当 data 中的数据部位空时才会进行渲染,并且 由于部分专辑的歌曲可能会有首的原因我采取的是超过 10 首以上的默认为隐藏,使用 ShowMore=false 作为控制显示与否的控制,默认为不显示点击更多按钮则会显示。 并且渲染列表会通过使用 v-if 去判断 v-for 中 index 的数值是单数还是双数去决 定单双行的样式形式即:class=(index % 2 = 0 ? even : odd ),并且为了使 得列表的显示风格更为固定所以列表采用的 flex 布局,并且为其设置了固定的百分比 宽度并且超出影藏显示省略号,使得显示更加的
26、复合我们的日常使用。并且对原本数 据中歌曲长度仅返回时间戳形式的转换,并且将其算法封装成函数集成到 tool 目录下 的 moment.js 函数中使得之后的时间戳格式化有了一个更方便的转化方式,直接引入 该文件调用方法即可。 16 转换函数: clock(timeStamp) let result = parseInt(timeStamp); let h = Math.floor(result / 3600) 10 ? 0 + Math.floor(result / 3600) : Math.floor(result / 3600); let m = Math.floor(result /
27、60) % 60) 10 ? 0 + Math.floor(result / 60) % 60) : Math.floor(result / 60) % 60); let s = Math.floor(result % 60) let song = ; song.id = item.id; song.title = ; song.picUrl = item.al.picUrl; song.album = ; song.alias = item.alias; song.playTime = moment.clock(item.dt / 1000); so
28、ng.artist = item.ar.map(item) = ).join(/); song.lrc = $HOST/lyric?id=$item.id; song.src=http:/ p3; song.banned = !(item.st = 0 localStorage.setItem(avatar,avatar.png); localStorage.clear(); else / 设置头像 if (response.data.avatar!=null) localStorage.setItem(avatar,response.data.avatar); else l
29、ocalStorage.setItem(avatar,avatar.png); 28 / 收藏和历史信息获取 getPortaldata(token).then(res= window.console.log(res); if (res.data.status=1) this.$mit(setUserCollect, res.data.data) ) this.$mit(setUserinfo, response.data) this.$mit(setUsertoken, token) if (response.data.type = 1) this.$mit(changeIsSignIn,
30、1); /admin else if (response.data.type = 2) this.$mit(changeIsSignIn, 2); /游客 ) .catch(reject = console.log(reject); ); ; .4 用户收藏列表以及历史列表的实现用户收藏列表以及历史列表的实现 用户收藏列表这个功能由两个多钟情况的收藏组成,收藏信息只储存收藏的类型, 和收藏类型的 id 以及时间,用户通过在热门榜单,最新专辑,热门歌手页面等可以存 在收藏按钮的页面点击收藏后,会执行收藏方法,若是没有登录的用户会弹出对话框 提示没有登录,若用户已经成功登录并且有星
31、湖信息的情况就会调用收藏添加接口将 信息传入数据库,而历史信息的实现就是当歌曲进入播放列表后才会调用储存方法, 即在歌曲也或者其他播放页中将播放列表加入 Vuex 中,经过 Vuex 储存的歌曲信息都 会存入历史数据中,并且当用户没有登录的时候不会进行保存。当用户进入个人中心 页的时候会统一调用信息获取接口,获取用户的收藏以及历史的信息统一保存并渲染 在个人中心的选项卡中并完成展示。数据库用 MongoDB 的 popular 聚合展示信息,并 29 且用 ref 关联表。 数据库表结构如下: 图 4.13 收藏、历史、用户的数据库实现 历史列表实现图如下: 30 图 4.14 历史信息列表实
32、现 收藏列表实现图如下: 图 4.15 历史信息列表实现 31 5 软件软件测试测试 5.1 用户注册功能测试用户注册功能测试 主要测试了用户能否成功注册,不成功时则提示错误信息。用户注册时必须遵守 系统提示的信息填写规范。在本次设计中,用户名长度在 3 位以上密码长度必须在 8 位以上。 表 5.1 用户注册模块测试用例 测试功能测试功能前提条件前提条件操作步骤操作步骤预期条件预期条件实际结果实际结果 用户名测试用户名测试打开注册页用户输入正确的 用户名 成功,跳转登录通过 用户名长度测用户名长度测 试试 打开注册页用户输入错误用 户名格式 系统提示“注册 失败” 通过 不输入密码不输入密码
33、打开注册页用户输入正常的 用户名和昵称 弹出“有未填写 项” 通过 密码输入密码输入打开注册页用户输入正确密 码 注册成功并弹出 登录页面 通过 测试结果:100%通过。 5.2 用户登录功能测试用户登录功能测试 表 5.2 用户登录模块测试用例 测试功能测试功能前提条件前提条件操作步骤操作步骤预期条件预期条件实际结果实际结果 登录测试登录测试进入登陆界面用户输入正确的 用户名和密码 登录成功,并跳转 个人中心页 通过 用户名验证用户名验证进入登陆界面输入错误的用户 名,正确的密码 系统提示登陆失败通过 密码验证密码验证进入登陆界面输入正确的用户 名,错误的密码 系统提示登陆失败通过 测试结果
34、:100%通过。 32 5.3 用户个人信息功能测试用户个人信息功能测试 主要测试了用户对个人信息的管理。 表 5.3 用户个人信息管理测试用例 测试功能测试功能前提条件前提条件操作步骤操作步骤预期条件预期条件实际结果实际结果 用户修改昵称用户修改昵称 功能功能 进入个人用户 中心 输入修改的名字 并点击 save 系统提示“修改 成功” 通过 系统用户头像系统用户头像 管理管理 进入个人用户 中心 用户点击头像单 元格并点击 save 系统提示“设置 成功” 通过 登出功能测试登出功能测试进入个人用户 中心 点击登出按钮登出并返回主页通过 低分辨率显示低分辨率显示使用低分辨率 设备打开网页
35、查看导航头不并 点击按钮 系统提示“修改 成功 通过 测试结果:100%通过。 5.4 首页模块测试首页模块测试 主要为了测试主页的响应式头部和并发接口的数据获取 表 5.3 用户个人信息管理测试用例 测试功能测试功能前提条件前提条件操作步骤操作步骤预期条件预期条件实际结果实际结果 首页高分辨率首页高分辨率使用高分辨率 设备打开网页 查看导航头部并 观察头部内容 显示详细头部操 作 通过 首页搜索功能首页搜索功能使用高分辨率 设备打开网页 不输入内容直接 回车 停留首页通过 首页搜索功能首页搜索功能使用高分辨率 设备打开网页 点击头部的搜索 框并输入内容后 按回车键 进入搜索内容的 详细页 通
36、过 SingerSinger 按钮测按钮测 试试 使用高分辨率 设备打开网页 查看导航头部并 点击 Singer 进入热门歌手推 荐页 通过 RunkRunk 按钮测试按钮测试使用高分辨率 设备打开网页 查看导航头部并 点击 Rank 进入热门榜单推 荐页 通过 低分辨率头部低分辨率头部 按钮按钮 使用低分辨率 设备打开网页 查看导航头部并 点击下拉按钮 显示下拉操作通过 33 GalleryGallery 按钮测按钮测 试试 使用高分辨率 设备打开网页 查看导航头部并 点击 Gallery 进入热门专辑推 荐页 通过 低分辨率显示低分辨率显示使用低分辨率 设备打开网页 查看导航头部并显示缩略
37、式的头 部 通过 测试结果:100%通过。 5.5 搜索功能模块测试搜索功能模块测试 主要测试了用户搜索功能。 表 5.3 用户个人信息管理测试用例 测试功能测试功能前提条件前提条件操作步骤操作步骤预期条件预期条件实际结果实际结果 搜索框的使用搜索框的使用进入任意界面在头部搜索栏输 入任意内容并按 回车 跳转详细搜索详 细 通过 搜索框的使用搜索框的使用进入任意界面头部搜索栏不输 入内容并按回车 不会挑战详细页 内容 通过 搜索框的使用搜索框的使用进入搜索详细 页面 在搜索页内的搜 索框输入仍以内 容并回车 跳转制定内容的 搜索页并且头部 搜索框内容同步 搜索页的搜索框 通过 搜索框的使用搜索
38、框的使用进入搜索详细 页面 在头部导航栏的 搜索栏输入内容 并回车 搜索页的搜索框 同步头部的内容 通过 测试结果:100%通过 34 5.6 详细页模块测试详细页模块测试 主要测试了用户搜索功能。 表 5.3 用户个人信息管理测试用例 测试功能测试功能前提条件前提条件操作步骤操作步骤预期条件预期条件实际结果实际结果 热门榜单左侧热门榜单左侧 切换功能切换功能 进入热门榜单 页 进入热门榜单页 并且点击左侧音 乐巅峰榜的选项 按钮。 右侧内容切换至 选中的榜单内容。 通过 热门榜单右侧热门榜单右侧 播放全部单曲播放全部单曲 进入热门榜单 页 进入热门榜单页 并且点击右侧 “播放全部单曲” 按钮
39、。 播放列表会添加 当前榜单的内容, 并且开始播放。 通过 热门榜单右侧热门榜单右侧 更多按钮更多按钮 进入热门榜单 页 进入热门榜单页 并且点击右侧 “更多”按钮。 榜单歌曲若没有 超过 15 条就继 续显示 15 条。 通过 返回顶部按钮返回顶部按钮 测试测试 进入任意页面将页面往下滚动右下角出现 “UP”按钮,点 击 UP 按钮页面 返回顶部 通过 热门歌手顶部热门歌手顶部 类型选择类型选择 进入歌手列表 页 点击不同的歌手 类型选项 底部歌手会切换 至指定页面 通过 歌曲详细页的歌曲详细页的 歌词歌词 进入歌曲详细 页 点击右侧展开按 钮 若是有歌曲信息 则会将完整歌曲 信息显示出来
40、通过 热门榜单添加热门榜单添加 收藏收藏 进入热门榜单 页 进入热门榜单页 并且点击右侧 “收藏榜单”按 钮。 若用户已登录则 添加收藏内容并 提示收藏成功, 若是没有登录则 提示未登录 通过 测试结果:100%通过 35 5.7 播放功能模块测试播放功能模块测试 主要测试了用户搜索功能。 表 5.3 用户个人信息管理测试用例 测试功能测试功能前提条件前提条件操作步骤操作步骤预期条件预期条件实际结果实际结果 播放与暂停按播放与暂停按 钮钮 进入播放页点击播放器左侧 的带有音乐图片 的按钮 若是播放状态则 会暂停音乐播放, 若是暂停状态则 开始播放 通过 播放器进度条播放器进度条 拖动拖动 进入
41、播放页点击进度条的任 意地方或者拖动 进度条到任意地 方 在拖动时音乐暂 停播放,并且事 件显示与歌词会 同步移动 通过 播放器歌词显播放器歌词显 示模块示模块 进入播放页播放任意歌曲歌词显示页面会 随播放时间滚动, 并显示制定的歌 词 通过 随机按钮功能随机按钮功能进入播放页将复数音乐加入 播放列表 当前音乐播放完 后会随机播放 通过 播放列表切换播放列表切换 功能功能 进入播放页面将复数音乐加入 播放列表点击其 他没有在播放的 音乐 切换到点击的音 乐进行播放 通过 音量按钮音量按钮进入播放页播放任意音乐播放的音量随着 播放条的长度变 化 通过 测试结果:100%通过 36 6 结论结论
42、在起初毕业设计选题的过程中我对自身的选择的题目还有是有一定担忧和迷茫的, 因为其中运用到了很多比较新的开发技术,一是自己没有实际完成过这类新技术的摸 索,二是作为一个整体的全栈项目由个人完成也是没有经历过的。我认为这也是对我 个人的一种锻炼和提升,在参与工作的一个月里这些技术也经常的被运用到我在公司 的开发中实际上也有多问题是我从实际开发中反馈到毕设中的。 在本次设计中,最为突出的一点我认为就是前后端分离的思想,也是因为这是近期 各种互联网公司的发展趋势,所以我认为我做的这系统必须是要能经得住技术考验的, 与时俱进的。作为互联网开发的工程化的象征之一,前后端分离的 web 项目很多都是 Vue
43、 项目并且由于 Vue 框架是国人开发的框架本身对于国人开发者就有一定的友好度, 并且由于完善的机制如 VueRouter、VueX 等官方插件的补充使得 Vue 生态在国内互联 网的各种企业中都有着诸多引用,甚至发展到 mpVue 等使用 Vue 单页去做微信小程序 的。所以此次毕设选择使用 Vue 去写也是对我自己进入工作的一个考验,它让我近一 步的对将来要面对的技术以及开发问题有了一个提前的涉足,不至于进到公司就一脸 懵的情况在我身上发生,事实也正是如此我通过毕设制作中遇到的各种问题的深入了 解和探索使得我在公司面试中很轻松的就通过了。并且由于现在 Web 应用的跨平台特 性越来越多的公
44、司要求前端开发必须要有 PC 端开发以及移动端开发的经历,因为响应 式布局可以为公司节省大量的维护成本,以及开发的时间成本。使得现在越来越多的 Web 应用取代了原有的原生 APP 等技术。这也是此次我选择部分页面实行响应式布局的 原因,其中响应式布局的实现方法有几种,我用的是兼容性以及适用性最好是 flex+vh+vw+媒体查询这套比较成熟的思路去完成的。 这次毕业设计很好的锻炼了我的编程能力和全栈开发的过程中的理解和感受,最 重要的是它当我有了更多的机会去适应工作环境和工作状态,让我更加容易的过渡到 社会阶段。 37 参考文献参考文献 1阮一峰.ECMAScript6 入门M.电子工业出版
45、社:,2014-4-30. 2美 Adam Freeman.HTML5 权威指南M.人民邮电出版社:,2014-1. 3美 Nicholas C. Zakas.深入理解 ES6M.电子工业出版社:,2017-7-1. 4美 David Flanagan.JavaScript 权威指南(第 6 版)M.机械工业出版社:,2012-4-1. 5吉伦瓦特.CSS3 实用指南M.人民邮电出版社 :,2012-3; 6福达 (Ben Forta).SQL 必知必会(第 4 版)M.人民邮电出版社 :,2013-5-1. 7美 Andrew STanenbaum.计算机网络M.清华大学出社 :,2004-
46、8-1. 8张耀春.Vue.js 权威指南M.电子工业出版社 :,2016-8-1. 9法纪尧姆周.Vue.js 项目实战M.人民邮电出版社 :,2019-1. 10朴灵.深入浅出 Node.jsM.人民邮电出版社 :,2013-12-1. 38 附附 录录 附录 1 后端接口部分程序源码 const db = require(./db); const express = require(express); const router = express.Router(); const jwt = require(jsonwebtoken); const path = require(path)
47、; /* 创建(create) 读取(get) 更新(update) 删除(delete) */ / 注册 router.post(/api/admin/signUp, (req, res) = console.log(req, req); if (! | !req.body.password | !req.body.nickName) res.send( status: 0, msg: 注册失败 ); return; db.User.find( name: , (err, docs) = if (err) res.send(err); r
48、eturn; if (docs.length 0) res.send( status: 0, msg: 用户名已注册 ); else db.User.find( nickName: req.body.nickName , (err, docs) = if (err) res.send(err); return; if (docs.length 0) res.send( status: 0, msg: 昵称已注册 ); else 39 let newUser = new db.User( name: , password: req.body.password, nick
49、Name: req.body.nickName, avatar: null, type: 2, ); newUser.save(function(err) if (err) res.send(err); else res.send( status: 1, msg: 注册成功 ); ); ); ); ); /登录 router.post(/api/admin/signIn, (req, res) = db.User.find( name: , password: req.body.password , (err, docs) = if (err) res.send(er
50、r); return; if (docs.length 0) let content = name: ; / 要生成 token 的主题信息 let secretOrPrivateKey = 123456; / 这是加密的 key(密钥) let token = jwt.sign(content, secretOrPrivateKey, expiresIn: 60 * 60 * 24, / 24 小时过期 ); docs0.token = token; db.User(docs0).save(function(err) if (err) res.status(500
51、).send(); return; res.send( 40 status: 1, msg: 登陆成功, token: docs0.token, user_name: docs0name, type: docs0type, nickName: docs0nickName, avatar: docs0avatar, ); ); else res.send( status: 0, msg: 登录失败 ); ); ); / 退出 router.post(/api/admin/signOut, (req, res) = db.User.find( name: , token:
52、 req.body.token , (err, docs) = if (err) return; if (docs.length 0) docs0.token = ; db.User(docs0).save(function(err) if (err) res.status(500).send(); return; res.send( status: 1, msg: 退出成功 ); ); else res.send( status: 0, msg: 退出失败 ); ); ); / 用户信息更新 router.post(/api/admin/updateUser, (req, res) = db
53、.User.find( name: , token: req.body.token , (err, docs) = if (err) return; 41 if (docs.length 0) if (req.body.avatar = null | req.body.avatar = null) /不需更新图片 docs0.nickName = req.body.nickName; db.User(docs0).save(function(err) if (err) res.status(500).send(); return; res.send( status:
54、1, msg: 更新成功, user_name: docs0name, type: docs0type, nickName: docs0nickName, avatar: docs0avatar, ); ); else const fs = require(fs); let D = Date.now(); let saveImg = path.join(_dirname, ./static/upload/avatar/ + D + .png); let pathImg = D + .png; let base64 = req.body.avatar.replace(/data:image/w+
55、;base64,/, ); let dataBuffer = new Buffer(base64, base64); fs.writeFile(saveImg, dataBuffer, function(err) /用 fs 写入文件 if (err) console.log(err); else console.log(写入成功!, saveImg); docs0.nickName = req.body.nickName; docs0.avatar = pathImg; db.User(docs0).save(function(err) if (err) res.status(500).se
56、nd(); return; res.send( status: 1, 42 msg: 更新成功, user_name: docs0name, type: docs0type, nickName: docs0nickName, avatar: docs0avatar, ); ); ); else res.send( status: 0, msg: 更新失败 ); ); ); /检测 token router.post(/api/admin/checkUser, (req, res) = db.User.find( name: req.body.user_name, token: req.body
57、.token , (err, docs) = if (err) res.send(err); return; if (docs.length 0) let token = req.body.token; let secretOrPrivateKey = 123456; / 这是加密的 key jwt.verify(token, secretOrPrivateKey, function(err, decode) if (err) res.send( status: 0 ); else res.send( status: 1, type: docs0type, user_name: docs0na
58、me, avatar: docs0avatar, nickName: docs0nickName, ); ); else res.send( status: 0 ); 43 ); ); / 获取用户的收藏列表通过 token router.get(/api/collect/all, (req, res) = console.log(req); let token = req.body.token | req.query.token; console.log(token=, token); if (token) db.User.find( token , password: 0, token:
59、0, _id: 0 ) .populate(collections, _id: 0 ) .populate(history, _id: 0 ) .exec(function(error, doc) console.log(doc); if (error) console.log(error); res.send( status: 0, msg: 获取失败 ); return false; else if (doc.length 0) res.send( status: 1, msg: ok, data: doc0 ); ); ); / 添加 router.post(/api/collect/a
60、dd, (req, res) = console.log(req); let token, typeId, type,picSrc,name = req.body; console.log(token if (token db.User.findOneAndUpdate( token , $push: collections: doc._id , function(err, user) console.log(user=, user); if (err) console.log(错误=, err); res.send( status: 0, msg: error, data: err ); e
61、lse res.send( status: 1, msg: ok, data: 收藏成功 ); 44 ); ); else res.send( status: 0, msg: error, data: 参数错误 ); ); / 获取用户的历史列表通过 token router.get(/api/history/all, (req, res) = console.log(req); let token = req.body.token | req.query.token; console.log(token=, token); if (token) db.User.find( token , p
62、assword: 0, token: 0, _id: 0 ) .populate(history, _id: 0 ) .exec(function(error, doc) console.log(doc); if (error) console.log(error); res.send( status: 0, msg: 获取失败 ); return false; else if (doc.length 0) res.send( status: 1, msg: ok, data: doc ); ); ); router.post(/api/history/add, (req, res) = co
63、nsole.log(req=, req); let token = req.body.token | req.query.token; let songList = req.body.songList | req.query.songList; if (token if (doc.length 0) db.History.insertMany(songList, (error, history) = let list = history.map(e) = return e._id; ); db.User.findOneAndUpdate( 45 token , $addToSet: histo
64、ry: $each: list , (errorco, user) = console.log(user=, user); res.send( status: 1, msg: 添加历史成功 ); ); ); else res.send( status: 0, msg: 没有用户信息或参数错误 ); ); ); module.exports = router; 46 附录附录 2 用户模块数据库设计代码 const mongoose = require(mongoose); mongoose.connect(mongodb:/localhost/tao); const Schema = mong
65、oose.Schema; const db = mongoose.connection; db.once(error, () = console.log(Mongo connection error); db.once(open, () = console.log(Mongo connection successed); const userSchema = new mongoose.Schema( name: String, password: String, nickName: String, type: String, token: String, avatar: String, his
66、tory: type: Schema.Types.ObjectId, ref: History , collections: type: Schema.Types.ObjectId, ref: Collection , ); const history = new mongoose.Schema( al: Object, artist: String, id: String, lrc: String, pic: String, publishTime:String, singerId: Array, src: String, title: String, src: String, createTime: type: Date, default: Date.now, , updateTime: type: Date, default: Date.now, , 47 user: type: Schema.Types.ObjectId, ref: User , , versionKey: false, timestamps: createdAt: createTime, updatedAt:
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024至2030年中国隔断柜门行业投资前景及策略咨询研究报告
- 2024至2030年中国醋酸去氨加压素行业投资前景及策略咨询研究报告
- 2024至2030年中国远红外温热理疗床行业投资前景及策略咨询研究报告
- 2024至2030年法院案件管理信息系统项目投资价值分析报告
- 2024至2030年酸洗槽衬板项目投资价值分析报告
- 2024至2030年螺旋形小功率节能灯项目投资价值分析报告
- 2024至2030年自动永停滴定仪项目投资价值分析报告
- 2024至2030年男休闲鞋项目投资价值分析报告
- 2024至2030年玻璃幕墙角码项目投资价值分析报告
- 2024至2030年中国政府互联网接入管理/计费系统行业投资前景及策略咨询研究报告
- 养老院安全巡查记录制度
- 2024年度三方新能源汽车充电桩运营股权转让协议3篇
- 模拟集成电路设计知到智慧树章节测试课后答案2024年秋广东工业大学
- 恶性肿瘤中医中药治疗
- 2024年国家工作人员学法用法考试题库及参考答案
- 山东省济南市2023-2024学年高一上学期1月期末考试 地理 含答案
- 期末(试题)-2024-2025学年人教PEP版英语六年级上册
- 2024年公安基础知识考试题库及答案
- 三创赛获奖-非遗文化创新创业计划书
- 教你成为歌唱达人智慧树知到期末考试答案2024年
- 民间秘术绝招大全
评论
0/150
提交评论