我的完成編寫的schoolnet校園網的仿酷我音樂專輯模塊中,用戶能夠收藏音樂專輯、下載專輯歌曲、關注好友音樂方面的最新動態及在線試聽音樂,用戶有權管理本身的收藏夾。javascript
實現頁面效果:css
patent.jsp音樂專輯詳情頁面html
music.jsp音樂大廳頁面前端
mymusic.jsp個人音樂頁面java
好友動態頁面web
後臺音樂管理設置:數據庫
數據庫表原型設計:數組
Song歌曲表:包含主鍵id、歌曲名name、歌曲地址src、歌曲封面photo、歌手id(用於關聯到singer歌手錶,暫時未作歌手模塊的功能,此字段用於之後作擴展)、所屬專輯patentid。session
Patent音樂專輯表:包含主鍵id、專輯名稱name、專輯描述descript、專輯封面photo。app
Usermusic用戶音樂關係表:包含主鍵id、用戶userid、音樂專輯patentid
一、完成編寫的schoolnet校園網主要目錄結構以下
音樂播放器的開發是比較艱辛的,從前端在html基礎上運用用於媒介回放的 video 和 audio 元素、使用css控制樣式並在CSS基礎上運用圓角邊框,向圖片添加陰影,字體圖標,2D轉換,過渡,動畫等CSS3新技術、使用javascript實現相關音樂播放、暫停、快進、後退、上一首、下一首、顯示相應歌曲圖片、歌曲名稱、歌手名稱等功能,到後臺準備數據下了很多功夫。
二、音樂播放器設計的html代碼:
<div id="t_wrapper"> <div id="t_cover"> <img src="images/logo_meitu_1.jpg"> </div> <div id="t_top"> <div id="t_title_info"> <span class="singername"></span> <span class="songname"></span> </div> </div> <div id="t_middle"> <span id="prev"></span> <div id="play"></div> <div id="pause" class="hidden"> </div> <span id="next"></span> <div class="ui-slider ui-slider-horizontal ui-widget ui-widget-content ui-corner-all" id="t_progress"> <div id="trackInfo"> <div id="error"> </div> <div id="current">0:00</div> <div id="duration">0:00</div> </div> <div style="width: 0%;" class="ui-slider-range ui-widget-header ui-corner-all ui-slider-range-min"></div> <span style="left: 0%;" class="ui-slider-handle ui-state-default ui-corner-all" tabindex="0"></span> </div> </div> <div id="t_bottom"> <div id="range"> <div id="val"></div> <div id="vol"></div> <div id="rangeVal"></div> </div> </div> </div>
三、音樂播放器設計的javascript代碼:
var styleChange = {pause:{}, play:{}, plsbutton:{}}; styleChange.play.change = function(){ $('#play').addClass('hidden'); $('#pause').removeClass('hidden'); }; styleChange.pause.change = function(){ $('#pause').addClass('hidden'); $('#play').removeClass('hidden'); }; styleChange.plsbutton.change = function(){ $('#t_pls_show').addClass('selectpls'); $('#t_pls_show').removeClass('noselectpls'); }; styleChange.plsbutton.recovery = function(){ $('#t_pls_show').addClass('noselectpls'); $('#t_pls_show').removeClass('selectpls'); }; function initAudio(elem) { var songname = elem.attr('songname'); var cover = elem.attr('t_cover'); var singername = elem.attr('singername'); $('.songname').text(' - ' + songname); $('.singername').text(singername); $('#t_cover').html('<img src="' + cover+'">'); } $(document).ready(function(){ var dur, durM, val, mus, elem, prog; var Pl = 0; $('#playlist ul li a').click(function(){ $('#t_title_info').animate({top: "-1.5em",opacity: "hide"}, 0); initAudio($(this).parent("li")); $('#error').text(''); styleChange.play.change(); console.log(mus); if(mus){mus[0].pause(); mus[0].currentTime = 0; $('li').removeClass('active'); } mus = $(this).next("audio"); $(this).parent("li").addClass('active'); mus[0].play(); }); $('#t_progress').slider({ value: 0, orientation: "horizontal", range: "min", animate: true, step: 1 }); $('audio').on("timeupdate", function() { mus[0].volume = val/100; d = this.duration; c = this.currentTime; curM = Math.floor(c/60); curS = Math.round(c - curM*60); $('#current').text(curM + ':' + curS); $('#t_progress').slider({ max: d, min: 0, value: c }); }); $('audio').on("playing", function () { dur = this.duration; durM = Math.floor(dur/60) + ':' + Math.round((dur - Math.floor(dur/60))/10); $('#duration').text(durM); $(this).parent("li").addClass('active'); $('#t_title_info').animate({top: "0.5em",opacity: "show"}, 500); }); $('audio').on("ended", function(){ mus = $(this).parent('li').next('li').first(); mus = mus.children('audio'); $(this).parent("li").addClass('active'); var next = $('li.active').next(); $('li').removeClass('active'); if(mus[0]){ initAudio(next); mus[0].play(); } else{ $('#error').text(''); $('#t_cover').html('<img src="images/userhead/01.gif">'); } }); //play button $('#play').click(function(){ if(mus){ mus[0].play(); styleChange.play.change(); $('#error').text(''); } else { $('#error').text(); } }); // pause button $('#pause').click(function() { if(mus){ mus[0].pause(); styleChange.pause.change(); } else { $('#error').text(); } }); //next button $('#next').click(function(){ mus[0].pause(); mus[0].currentTime = 0; mus = mus.parent('li').next('li').first(); mus = mus.children('audio'); var next = $('li.active').next(); $('#t_title_info').animate({top: "-1.25em",opacity: "hide"}, 0); $('li').removeClass('active'); if(mus[0]){ initAudio(next); mus[0].play(); } else{ $('#error').text(''); $('#t_cover').html('<img src="images/userhead/02.gif">'); mus = null; } }); //prev button $('#prev').click(function(){ mus[0].pause(); mus[0].currentTime = 0; mus = mus.parent('li').prev('li').last(); mus = mus.children('audio'); var prev = $('li.active').prev(); $('li').removeClass('active'); $('#t_title_info').animate({top: "-1.25em",opacity: "hide"}, 0); if(mus[0]){ initAudio(prev); mus[0].play(); } else{ $('#error').text(''); $('#t_cover').html('<img src="images/userhead/03.gif">'); mus = null; } }); //volume $('#rangeVal').slider({ value: 60, orientation: "horizontal", range: "min", animate: true, step: 1 }); // volume text val = $('#rangeVal').slider("value"); $('#val').text(val); var tooltip = $('#val'); tooltip.hide(); $('#rangeVal').slider({ start: function( event, ui ) { tooltip.fadeIn('fast'); }, stop: function(event,ui) { tooltip.fadeOut('fast'); }, slide: function( event, ui ) { val = ui.value; tooltip.css('left', val-30).text(ui.value); $('#val').text(val); if(mus){ mus[0].volume = val/100; } else { $('#error').text(); } } }); // progress $('#t_progress').slider({ start: function( event, ui ) { mus[0].pause(); }, stop: function( event, ui ) { prog = ui.value; mus[0].currentTime = prog; mus[0].play(); styleChange.play.change(); } }); //playlist button $('#t_pls_show').click(function(){ if (Pl == 0) { styleChange.plsbutton.change(); Pl = 1; } else { styleChange.plsbutton.recovery(); Pl = 0; } $('#playlist').slideToggle(); }); });
四、幾個經常使用的service層組件,暫時不作dao層
// 得到全部音樂歌單(專輯) public List<Patent>getallPatents(){ List<Patent>allPatents=getResult("from Patent order by id desc", null ); returnallPatents; } // 得到全部音樂歌單(分頁) public List<Patent>getallPatentsByPage(intpageNow,intpageSize){ List<Patent>allpPatentsByPage=executeQueryByPage("from Patent order by id desc", null, pageNow, pageSize); returnallpPatentsByPage; } // 得到某個音樂歌單的全部歌曲 public List<Song>getSongsByPatent(Patent patent) { List<Song> songs=getResult("from Song where pagentId=?", new Object[]{patent.getId()}); return songs; } // 分頁得到好友在音樂方面的最新動態 @Override public List<Usermusic>getUsermusicByFriend(List<Users>list,intpageNow,intpageSize) { // TODO Auto-generated method stub List<Usermusic>musicList = newArrayList<Usermusic>(); List<Usermusic>usermusics=null; for(inti=0;i<list.size();i++) { usermusics=executeQueryByPage("from Usermusic where userId=? order by id desc", newObject[]{list.get(i).getId()},pageNow,pageSize); for(int j=0;j<usermusics.size();j++) { //因爲用戶音樂關係表usermusic最初設計時,沒有設置建立時間CreTime字段,此處暫時沒作音樂動態更新的最近時間設置 // try { // if(MyTools.strDate(usermusics.get(j).getCreTime())<=date) // { musicList.add(usermusics.get(j)); // } // } catch (Exception e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } } } returnmusicList; }
其中executeQueryByPage引用基礎Service類
/** * 定義基礎Service類,並實現相應的接口,供各個模塊的Service類繼承 * */ @Transactional public abstract class BaseServiceImpl implements BaseServiceInter { //Spring屬性注入,會話工廠 @Resource SessionFactory sessionFactory; //實現分頁查詢,下行的註解表示該方法不需開啓事務 @Transactional(propagation=Propagation.NOT_SUPPORTED) /** * @param hql: 傳入的hql語句 * @param parameters:hql語句中問號對應的參數數組 * @param pageNow:當前頁面 * @param pageSize:每一個頁面容納記錄數 * */ Public List executeQueryByPage(String hql, Object[] parameters, int pageNow, int PagesSize) { Query query=sessionFactory.getCurrentSession().createQuery(hql); if(parameters!=null && parameters.length>0){ for(int i=0;i<parameters.length;i++){ query.setParameter(i, parameters[i]); } } if(pageNow<1) {pageNow=1;} //體現分頁 return query.setFirstResult((pageNow-1)*PagesSize).setMaxResults(PagesSize).list();
五、Controller層幾個核心處理代碼
// 獲取當前的網站的session狀況 Users user=(Users) request.getSession().getAttribute("loginuser"); // 獲取該用戶所在的大學 Useruniversityuseruniversity = userService.getUseruniversity(user); // 得到該用戶所在的高中 Userseniorusersenior = userService.getUsersenior(user); // 得到該用戶所在的初中 Junior junior = userService.getJunior(user); // 得到該用戶所在的城市 City city = userService.getCity(user); // 得到該用戶所在的省份 Province province = userService.getProvince(user); // 得到該用戶的好友個性表 List<Friend> friends = userService.getResult( "from Friend where f_hostId=? order by id desc", new Object[] { Long.valueOf(user.getId()) }); // List<Friend> // lists=userService.executeQueryByPage("from Friend where f_hostId=? order by id desc", // new Object[]{Long.valueOf(user.getId())}, 1, 6); // 經過好友關係表獲取該用戶的好友列表 List<Users>friendlList = userService.getFriends(friends); List<Friendapply>friendapplies = userService.getResult( "fromFriendapply where fa_getId=? andfa_read=?", new Object[] { Long.valueOf(user.getId()), Integer.valueOf("0") }); // 獲取向我發送了加好友申請的網頁 List<Users>friendSends = userService .getUsersByFriapp(friendapplies); // System.out.print(friends.size()); // 經過好友發表的日誌,獲取該好友信息 String pageNow=request.getParameter("pageNow"); intpageSize=10; intallrows=userService.getallPatents().size(); intpageCount=(allrows-1)/pageSize+1; if(pageNow.equals("0")) { pageNow="1"; } if(Integer.parseInt(pageNow)>pageCount) { pageNow=pageCount+""; } // 得到全部音樂歌單(分頁) List<Patent> patents=userService.getallPatentsByPage(Integer.valueOf(pageNow), pageSize); // 移除用戶收藏的音樂專輯 String pid=request.getParameter("pid"); Usermusicusermusic=(Usermusic) userService.uniqueQuery("from Usermusic where patentId=?", new Object[]{Integer.valueOf(pid)}); userService.delete(usermusic); Users user=(Users) request.getSession().getAttribute("loginuser"); //若是用戶等級小於4,則限制用戶音樂下載功能 if(user.getLevel()<4) { PrintWriter out = null; response.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); try { out = response.getWriter(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } out.print("<script>alert('用戶等級達到4以上才能下載,你的等級不夠');window.history.go(-1);</script>"); } else { String patentid=request.getParameter("patentid"); //獲取下載歌曲的id號 String songid=request.getParameter("songid"); //根據id號得到歌曲 Song song=(Song) userService.findById(Song.class, Integer.valueOf(songid)); //獲取歌曲名稱 String displayname=song.getName(); //獲取歌曲路徑 String songsrc=song.getSrc(); //調用業務邏輯層的歌曲下載功能 MyTools.downmusic(displayname, patentid, songsrc, request, response); //獲取用戶的積分 int website=user.getWebsite(); //扣除用戶5點積分 user.setWebsite(website-5);
六、前端音樂專輯展現頁面html代碼:
<!-- s_img begin --> <div class="s_img"> <img src="/schoolnet/Media/patent/${patent.photo }" width="240" height="240" alt="${patent.name }" title="${patent.name }"> </div> <!-- s_img end --> <!-- comm begin --> <div class="comm"> <h1 title="校園歌曲永遠不會老">${patent.name }</h1> <p class="button"> <img src="/schoolnet/images/front/bluray.png" /> </p> <ul> <li style="margin:5px">歌曲數:<span>${fn:length(songs)}</span></li> <li style="margin:5px">製做者:<span>校園admin</span></li> <li style="margin:5px">已有<span>${fn:length(patent.usermusics)}</span>個用戶收藏</li> </ul> <p class="tag" style="margin:10px"> 標籤:<span title="校園">校園</span> </p> </div> <!-- comm end --> </div> <!-- singer end --> <div class="tipcomm"> <div id="moreContent" style="height: auto; overflow: hidden;"> <p id="intro" style="word-wrap:break-word;">${patent.name }簡介:${patent.descript }</p> </div> </div> <!-- musiclist begin --> <div class="m_list"> <div class="pages"> <p class="fl" style="margin-left:20px; display:inline;">共${fn:length(songs) }首歌</p> <p class="fr"> <input id="patentid" value="${patent.id }" type="hidden"> <input id="userid" value="${loginuser.id }" type="hidden"> <a href="/schoolnet/music.do?flag=goMyMusic&pageNow=1" title="去個人收藏" class="current2" style="background:#1093d7;">去個人收藏</a> <c:if test="${usermusic==null }"> <span class="setmusic"><a href="javascript:void(0);" onclick="setPatent()" title="加入收藏" class="current" style="background:#1093d7;">加入收藏</a> </span> </c:if> <c:if test="${usermusic!=null }"> <a title="已經收藏" class="current" style="background:#999;">已經收藏</a> </c:if> </p> </div> <br /> <br /> <p style="float:right;margin-top:-30px;">每次下載歌曲,將扣除5點經驗值</p> <div class="list"> <div id="playlist" style="margin-top:5px"> <ul> <c:forEach var="song" items="${patent.songs }"> <li id="ll" t_cover="Media/patent/${patent.photo }" singername="${song.singername }" songname="${song.name }"><a href="javascript:void(0)">${song.singername } – ${song.name }</a> <audio preload="none"> <source src="Media/song/${patent.id }/${song.src }" type="audio/mp3"> <source src="http://www.sucaijiayuan.com" type="audio/ogg; codecs=vorbis"> </audio></li> <a href="/schoolnet/music.do?flag=downmusic&patentid=${patent.id }&songid=${song.id }" style="float:right;margin-top:-35px;margin-right:10px;">下載 </a> </c:forEach> </ul> </div> <div class="page" id="ge_page"></div> </div> </div>