SSM项目实战——哈哈音乐(四)前台模块开发

1、项目准备

①导入依赖和前端资源

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <parent>
        <artifactId>hami-parent</artifactId>
        <groupId>com.qcby</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>hami-portal</artifactId>
    <packaging>war</packaging>
    <name>hami-portal Maven Webapp</name>
    <dependencies>
        <dependency>
            <groupId>com.qcby</groupId>
            <version>1.0-SNAPSHOT</version>
            <artifactId>hami-core</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
        </dependency>
    </dependencies>

</project>

 

②在resources下导入创建springmvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">
    <mvc:annotation-driven>
        <mvc:message-converters>
            <bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
                <property name="supportedMediaTypes" value="text/html;charset=UTF-8"/>
                <property name="features">
                    <array>
                        <value>WriteMapNullValue</value>
                        <value>WriteNullStringAsEmpty</value>
                    </array>

                </property>
                <property name="dateFormat" value="yyyy-MM-dd"></property>
            </bean>
        </mvc:message-converters>

    </mvc:annotation-driven>
    <context:component-scan base-package="com.qcby.controller"/>

    <bean id="viewResource" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/page/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>

    <mvc:view-controller path="/index" view-name="index"></mvc:view-controller>
    <mvc:default-servlet-handler/>
</beans>

③配置web.xml

<web-app
        version="2.5"
        xmlns="http://java.sun.com/xml/ns/javaee"
        xmlns:xml="http://www.w3.org/XML/1998/namespace"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

  <filter>
    <filter-name>SpringCharacterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>SpringCharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>


  <servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:springmvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
  </context-param>
</web-app>


2、歌曲界面

①展示所有歌曲

启动tomcat后,进入index.jsp页面,发送dofindAll,可以根据条件查询歌曲也可以查询所有歌曲信息

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <jsp:forward page="/song/dofindAll"></jsp:forward>
</body>
</html>

 创建SongController,编写dofindAll,给search.jsp页面返回歌曲和所有专辑信息

package com.qcby.controller;

import com.qcby.model.Mtype;
import com.qcby.model.Page;
import com.qcby.model.Song;
import com.qcby.query.SongQuery;
import com.qcby.service.MtypeService;
import com.qcby.service.SongService;
import com.qcby.service.SongerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;


@Controller
@RequestMapping("/song")
public class SongController {
    @Autowired
    private SongService songService;
    @Autowired
    private MtypeService mtypeService;

    @RequestMapping("/dofindAll")
    public String list(SongQuery mq, Model model){

        if(mq.getPageNo() == 0){
            mq.setPageNo(1);
        }
        Page<Song> page = songService.selectObjectByCondition(mq);
        model.addAttribute("page", page);
        model.addAttribute("mq", mq);
        List<Mtype> mtypes = mtypeService.selectObjectAll();
        model.addAttribute("mtypes", mtypes);
        return "search";
    }

research.jsp界面展示歌曲信息

<div id="body" class="gap">
    <input id="tid" type="hidden" value="${mq.tid}">
    <input id="isHot" type="hidden" value="${mq.isHot}">
    <input id="isNew" type="hidden" value="${mq.isNew}">
    <div class="wrapper">
        <div class="content_wrapper">
            <div class="content">
                <div class="filter" data-spm="1392350033">
                    <dl>
                        <dt>流派&nbsp;:</dt>
                        <dd>
                            <p>
                                <a href="#" ftype="mtype" value="" class="current">全部</a>
                                <c:forEach items="${mtypes}" var="mtype">
                                    <a href="#" ftype="mtype" value="${mtype.tid}">${mtype.tname}</a>
                                </c:forEach>
                            </p>
                        </dd>
                    </dl>
                    <dl>
                        <dt>热门&nbsp;:</dt>
                        <dd>
                            <p>
                                <a href="#" ftype="isHot" value="" class="current">全部</a>
                                <a href="#" ftype="isHot" value="1">热门</a>

                            </p>
                        </dd>
                    </dl>
                    <dl>
                        <dt>新歌&nbsp;:</dt>
                        <dd>
                            <p>
                                <a href="#" ftype="isNew" value="" class="current">全部</a>
                                <a href="#" ftype="isNew" value="1">最新</a>
                            </p>
                        </dd>
                    </dl>
                </div>
                <div class="chart" data-spm="1392350021">
                    <table>
                        <thead>
                        <tr>
                            <td width="40"></td>
                            <td width="45"></td>
                            <td></td>
                            <td width="180"></td>
                            <td width="180"></td>
                            <td width="130"></td>
                        </tr>
                        <tr>
                            <th align="right"><input type="checkbox" checked onclick="selectall(this);"></th>
                            <th align="left" colspan="5"><b class="play" onclick="playsongs();"></b>
                            </th>
                        </tr>
                        </thead>
                        <tbody id="content">

                        <c:forEach items="${page.list}" var="song" varStatus="status">
                            <tr data-index="0">
                                <td align="right"><input type="checkbox" name="chartids" checked="checked"
                                                         value="${song.sid}"></td>
                                <td align="center">${status.count}</td>
                                <td>
                                    <div class="song">
                                        <div class="image">
                                            <img src="${filePath}${song.songer.pic}" alt="Every Breath You Take"
                                                 height="55" width="55"/>
                                            <b></b>
                                        </div>
                                        <div class="info"><p><strong><a target="_blank" title="Every Breath You Take"
                                                                        href="#">${song.sname}</a></strong></p></div>
                                    </div>
                                </td>
                                <td><span>
                                            <a target="_blank" href="#" title="Karen Souza">${song.songer.srname}</a>
                                    	</span></td>
                                <td><span>
                <a target="_blank" title="Essentials" href="#">${song.album.aname}</a>
            </span></td>
                                <td>
                                    <div class="action">
                                        <button class="play" onclick="play(${song.sid});" title="试听">试听</button>
                                        <button class="download" title="下载">下载</button>
                                        <button class="offline" title="发送到">发送到</button>
                                    </div>
                                </td>
                            </tr>

                        </c:forEach>


                        </tbody>
                    </table>
                </div>
                <input type="hidden" id="pageNoPortal" value="${mq.pageNoPortal}">
                <c:if test="${page.pageNo < page.totalPage}">
                    <div class="loadr" id="loader"><a href="javascript:void(0);" onclick="loadMore()"><b></b>查看更多</a>
                    </div>
                </c:if>
                <c:if test="${page.pageNo == page.totalPage}">
                    <div class="loadr" id="nomore" style="font-size: 18px;">没有更多啦!</div>
                </c:if>
            </div>
        </div>
        <div class="sidebar" data-spm="1392350021">
            <div class="nav">
                <a class="index" href="#"><b></b>发现</a>
                <a class="top" href="#"><b></b>排行榜</a>
                <a class="magazines" href="#"><b></b>音乐人企划</a>
                <a class="artists" href="/songer/dofindAll"><b></b>音乐人</a>
                <a class="songs current" href="/song/dofindAll"><b></b>歌曲</a>
                <a class="albums" href="#"><b></b>专辑<sup>无损</sup></a>
            </div>
            <div class="genre">
                <c:forEach items="${mtypes}" var="mtype">
                    <a href="/song/dofindAll?tid=${mtype.tid}"><b></b>${mtype.tname}</a>
                </c:forEach>
            </div>
        </div>
    </div>

</div>

 

②根据条件搜索歌曲 

search.jsp页面的js请求

<script>

        var tid = "";
        var isHot = "";
        var isNew = "";

        $(function () {
            //指定点击事件
            $(".filter p a").click(function () {
                //移除同辈的a链接的样式
                $(this).siblings().removeClass("current");
                //把点击的a链接的样式加上
                $(this).addClass("current");
                //获得流派的选中值
                var tid = $("a[ftype='mtype'][class='current']").attr("value");
                var isHot = $("a[ftype='isHot'][class='current']").attr("value");
                var isNew = $("a[ftype='isNew'][class='current']").attr("value");
                //alert(tid+"   "+isHot+"   "+isNew);
                window.location.href = "/song/dofindAll?tid=" + tid + "&isHot=" + isHot + "&isNew=" + isNew;
            })

            tid = $("#tid").val();
            isHot = $("#isHot").val();
            isNew = $("#isNew").val();
            //流派的回显
            $("a[ftype='mtype'][class='current']").removeClass("current");
            $("a[ftype='mtype'][value='" + tid + "']").addClass("current");
            //热门回显
            $("a[ftype='isHot'][class='current']").removeClass("current");
            $("a[ftype='isHot'][value='" + isHot + "']").addClass("current");

            //新歌回显
            $("a[ftype='isNew'][class='current']").removeClass("current");
            $("a[ftype='isNew'][value='"+ isNew + "']").addClass("current");

        })

③查看更多

 js代码

function loadMore() {
            //2  111111  5 10 15 20
            var pageNoPortal = parseInt($("#pageNoPortal").val());
            //计算pageSize
            var pageSize = 5 * (++pageNoPortal);
            window.location.href = "/song/dofindAll?tid=" + tid + "&isHot=" + isHot + "&isNew=" + isNew + "&pageSize=" + pageSize + "&pageNoPortal=" + pageNoPortal;
        }

前端代码

<c:if test="${page.pageNo < page.totalPage}">
<div class="loadr" id="loader"><a href="javascript:void(0);" onclick="loadMore()"><b></b>查看更多</a>
</div>
</c:if>
<c:if test="${page.pageNo == page.totalPage}">
<div class="loadr" id="nomore" style="font-size: 18px;">没有更多啦!</div>
</c:if>

上面三个功能都是通过controller中dofindAll这一个请求来实现,只是所传的参数不一致 

对于展示所有歌曲,dofindAll不传任何参数,直接查询所有的歌曲信息

对于根据条件搜索歌曲,传入歌曲流派、是否热门、是否是新歌这三个信息作为筛选条件进行歌曲搜索

对于查看更多,除了传入三个搜索条件还传入页面大小和当前页码作为条件进行查询

④歌曲播放

功能:可以通过点试听,单个歌曲播放,也可以选取多个歌曲放入播放列表中按顺序播放

实现思路:对于单个歌曲播放功能,直接根据当前传入的歌曲id查询歌曲信息,将歌曲信息传给play.jsp页面进行歌曲播放

对于播放列表播放歌曲,首先通过cookie获取上一次未播放完的歌曲id,然后本次传入的歌曲id列表加上上次的歌曲id列表,变成一个新的歌曲id列表,并将新的歌曲id列表存入cookie中。根据歌曲id列表查询歌曲信息,将其交给paly.jsp页面,进行歌曲播放

js代码

function selectall(checkallObj) {
            var checked = $(checkallObj).attr("checked");
            if(checked =="checked"){
                $("tbody tr td input[type='checkbox']").attr("checked","checked");
            }else{
                $("tbody tr td input[type='checkbox']").removeAttr("checked");
            }
        }

        function playsongs() {
            //拿到所有的复选框选中的元素
            var songs = $("tbody tr td input[type='checkbox']:checked")
            var sids = ""; //"1,2,3,4,5,"
            songs.each(function () {
                var sid = $(this).val();
                sids = sids + sid+","
            })
            window.open("/song/play?sids="+sids,"play");
        }

        function play(sid) {
            window.open("/song/play?sids="+sid,"play");
        }

    </script>

controller代码

/**
     * 实现歌曲播放列表
     * @param sids   选中的歌曲列表
     * @param model
     * @param request
     * @param response
     * @return
     * @throws UnsupportedEncodingException
     */
    @RequestMapping("/play")
    public String play(String sids, Model model, HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
        //1、处理sids字符串,变成集合给后台查询,变成cookie作为下一次使用的记录
        //idList记录歌曲播放列表,就是本次新添加的播放歌曲sids+上一次的播放歌曲列表
        List<String> idList = new ArrayList<>();
        String[] idArr = null;
        //程序严谨性判断
        if(sids != null && !"".equals(sids)){
            idArr = sids.split(",");
            for (String s : idArr) {
                idList.add(s);
            }
        }

        //如果是第一次添加歌曲列表,不考虑,否则需要拿到cookie查看上次播放记录
        //pids存储的是上次歌曲播放值
        String pids = "";
        Cookie[] cookies = request.getCookies();
        if(cookies != null && cookies.length > 0){
            for (Cookie cookie : cookies) {
                String name = cookie.getName();
                if("playids".equals(name)){
                    //解码  防止乱码
                    pids = URLDecoder.decode(cookie.getValue(),"UTF-8");

                }
            }
        }

        //oldArr存放的是上一次播放的歌曲列表
        String[] oldArr = pids.split(",");
        for (int i = 0; i < oldArr.length; i++) {
            //保证不重复添加相同的歌曲,如果上次歌曲播放列表中含有本次添加的播放列表,则不添加到新的播放列表
            if(!idList.contains(oldArr[i])){
                idList.add(oldArr[i]);
            }
        }

        //创建新的歌曲播放列表,原来存储的播放歌曲列表为list<String>类型,idsList变成list<Integer>,用于后台查询
        List<Integer> idsList = new ArrayList<>();
        //字符串类型的新的播放列表,用于cookie传值给前端作为上一次播放列表
        String playids = "";
        for (String s : idList) {
            if(!"".equals(s)){
                idsList.add(new Integer(s));
                playids = playids + s+",";
            }
        }

        List<Song> songs = new ArrayList<>();
        if(idsList.size() > 0)
            songs = songService.getSongByIds(idsList);


        model.addAttribute("songs",songs);
        System.out.println(songs);
        System.out.println(playids);
        playids = URLEncoder.encode(playids, "UTF-8");
        Cookie cookie = new Cookie("playids", playids);
        //cookie的有效时间
        cookie.setMaxAge(60*60*24*30);
        //设置cookie的访问有效路径
        cookie.setPath("/");

        response.addCookie(cookie);
        return "player";
    }

 /**
     * 获取播放的歌曲信息,实现歌曲播放
     * @param sid
     * @return
     */
    @ResponseBody
    @RequestMapping("/getSong")
    public Song getSong(Integer sid){
        Song song = songService.getSong(sid);
        System.out.println(song);
        return song;
    }

 通过歌曲id获取歌曲信息的service接口

 //添加播放列表
    public List<Song> getSongByIds(List<Integer> idsList);
//实现歌曲播放
    Song getSong(Integer sid);

通过歌曲id获取歌曲信息的service实现类

 @Override
    public List<Song> getSongByIds(List<Integer> idsList) {
        return songMapper.getSongByIds(idsList);
    }
//实现歌曲播放
 @Override
    public Song getSong(Integer sid) {
        return songMapper.getSong(sid);
    }

通过歌曲id获取歌曲信息的mapper接口

//实现添加播放列表
    List<Song> getSongByIds(List<Integer> idsList);
//实现歌曲播放
    Song getSong(Integer sid);

通过歌曲id获取歌曲信息的sql

<resultMap id="getSongByIdsRM" type="com.qcby.model.Song" extends="ResultMapWithBLOBs">
    <association property="songer" javaType="com.qcby.model.Songer" resultMap="com.qcby.dao.SongerMapper.BaseResultMap"></association>
  </resultMap>

<!--  查询要播放的歌曲集合返回-->
  <select id="getSongByIds" parameterType="java.util.List" resultMap="selectObjectByConditionRM">
    select * from song s left join mtype m on s.tid=m.tid left join songer sr on s.srid=sr.srid left join album a on s.aid=a.aid
    <where>
      s.sid in
      <if test="list!=null">
        <foreach collection="list" open="(" close=")" separator="," item="sid">
          #{sid}
        </foreach>
      </if>
      order by field (s.sid,
      <foreach collection="list" separator="," item="sid">
        #{sid}
      </foreach>
      )
    </where>
  </select>

<resultMap id="getSongRM" type="com.qcby.model.Song" extends="ResultMapWithBLOBs">
    <association property="songer" javaType="com.qcby.model.Songer" resultMap="com.qcby.dao.SongerMapper.BaseResultMap"></association>
  </resultMap>

<!--  实现歌曲播放-->
  <select id="getSong" parameterType="int" resultMap="getSongRM">
    select * from song left join songer on song.srid=songer.srid where song.sid=#{sid}
  </select>

play.jsp页面

<c:forEach items="${songs}" var="song" varStatus="status">
								<li class="songList">
									<div class="songLMain">
										<div class="check">
											<input class="checkIn" type="checkbox" select="0" value="${song.sid}">
										</div>
										<div class="start" >
											<em sonN="${status.count}" msid="${song.sid}">${status.count}</em>
										</div>
										<div class="songBd">
											<div class="col colsn">${song.sname}</div>
											<div class="col colcn">${song.songer.srname}</div>
											<div class="col">${song.album.aname}</div>
										</div>
										<div class="control">
											<a class="cicon love"></a>
											<a class="cicon more" style="display:none"></a>
											<a class="cicon dele" style="display:none"></a>
										</div>
									</div>									
								</li>
</c:forEach>

3、音乐人界面

①展示所有音乐人

创建SongerController,编写controller

package com.qcby.controller;

import com.qcby.model.Mtype;
import com.qcby.model.Page;
import com.qcby.model.Songer;
import com.qcby.query.SongerQuery;
import com.qcby.service.MtypeService;
import com.qcby.service.SongService;
import com.qcby.service.SongerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.ArrayList;
import java.util.List;

@Controller
@RequestMapping("/songer")
public class SongerController {
    @Autowired
    private SongerService songerService;
    @Autowired
    private MtypeService mtypeService;

    @RequestMapping("/dofindAll")
    public String listType(SongerQuery mq, Model model) {
        if (mq.getPageNo() == 0) {
            mq.setPageNo(1);
        }
        mq.setPageSize(20);
        Page<Songer> page = songerService.selectObjectByCondition(mq);
        List<Mtype> mtypes = mtypeService.selectObjectAll();

        List<List<Songer>> list = new ArrayList<>();
        List<Songer> slist = (List<Songer>) page.getList();
        List<Songer> list1 = null;
        for (int i = 0; i < 20; i++) {
            if (i % 5 == 0) {
                list1 = new ArrayList<>();
                list.add(list1);
            }
            Songer s = null;
            if (i < slist.size()) {
                s = slist.get(i);
                list1.add(s);
            }
        }
        model.addAttribute("sList", list);
        model.addAttribute("page", page);
        model.addAttribute("mq", mq);
        model.addAttribute("mtypes", mtypes);
        return "songers";
    }

前端songers.jsp页面展示

<div id="body" class="gap">
    <input id="tid" type="hidden" value="${mq.tid}">
    <input id="isHot" type="hidden" value="${mq.isHot}">
    <div class="wrapper">
        <div class="content_wrapper">
            <div class="content">
                <div class="filter" data-spm="1392350033">
                    <dl>
                        <dt>流派&nbsp;:</dt>
                        <dd>
                            <p>
                                <a href="#" ftype="mtype" value="" class="current">全部</a>
                                <c:forEach items="${mtypes}" var="mtype">
                                    <a href="#" ftype="mtype" value="${mtype.tid}">${mtype.tname}</a>
                                </c:forEach>
                            </p>
                        </dd>
                    </dl>
                    <dl>
                        <dt>热门&nbsp;:</dt>
                        <dd>
                            <p>
                                <a href="#" ftype="isHot" value="" class="current">全部</a>
                                <a href="#" ftype="isHot" value="1">热门</a>

                            </p>
                        </dd>
                    </dl>
                </div>


                <div class="albums" data-spm="1392350021">
                    <c:forEach items="${sList}" var="subList">
                        <div class="album_list">
                            <c:forEach items="${subList}" var="songer">
                                <div class="album" data-needpay="0" data-playstatus="1" data-downloadstatus="1">
                                    <div class="image">
                                        <a target="_blank" title="${songer.srname}" href="/songer/getSonger?srid=${songer.srid}">
                                            <img src="${filePath}${songer.pic}" alt="${songer.srname}">

                                            <b class="icon toplay" onclick="playalbum(406532);return false;" style="display: none;"></b>
                                            <dl style="display: none;">
                                                <dt>
                                                    <b class="icon toheart"></b>
                                                    <b class="icon todropmenu"></b>
                                                </dt>
                                                <dd style="display: none;">
                                                    <ul>
                                                        <li onclick="tag(406532,5);return false;"><b class="icon tofavourite"></b>收藏</li>
                                                        <li onclick="album2collect(406532);return false;"><b class="icon tocollect"></b>添加到</li>
                                                        <li onclick="recommend(406532,33);return false;"><b class="icon toshare"></b>分享到</li>
                                                    </ul>
                                                </dd>
                                            </dl>
                                            <sup title="${songer.srname}"></sup>			</a>
                                    </div>
                                    <div class="info">

                                        <p>
                                            <a target="_blank" title="${songer.srname}" href="#">${songer.srname}</a>
                                        </p>
                                    </div>
                                </div>
                            </c:forEach>
                        </div>
                    </c:forEach>


                </div>

                <input type="hidden" id="pageNoPortal" value="${mq.pageNoPortal}">
                <c:if test="${page.pageNo < page.totalPage}">
                    <div class="loadr" id="loader"><a href="javascript:void(0);" onclick="loadMore01()"><b></b>查看更多</a></div>
                </c:if>
                <c:if test="${page.pageNo == page.totalPage}">
                    <div class="loadr" id="nomore" style="font-size: 18px;">没有更多啦!</div>
                </c:if>
            </div>
        </div>
        <div class="sidebar" data-spm="1392350021">
            <div class="nav">
                <a class="index" href="#"><b></b>发现</a>
                <a class="top" href="#"><b></b>排行榜</a>
                <a class="magazines" href="#"><b></b>音乐人企划</a>
                <a class="artists current" href="#"><b></b>音乐人</a>
                <a class="songs " href="/song/dofindAll"><b></b>歌曲</a>
                <a class="albums" href="#"><b></b>专辑<sup>无损</sup></a>
            </div>
            <div class="genre">
                <c:forEach items="${mtypes}" var="mtype">
                    <a href="/songer/dofindAll?tid=${mtype.tid}"><b></b>${mtype.tname}</a>
                </c:forEach>
            </div>
        </div>
    </div>

</div>

②根据条件搜索音乐人

songers.jsp页面的js请求

<script>
        $(function () {
            var tid = "";
            var isHot = "";
            $(function () {

                //指定点击事件
                $(".filter p a").click(function () {
                    //移除同辈的a链接的样式
                    $(this).siblings().removeClass("current");
                    //把点击的a链接的样式加上
                    $(this).addClass("current");
                    //获得流派的选中值
                    var tid = $("a[ftype='mtype'][class='current']").attr("value");
                    var isHot = $("a[ftype='isHot'][class='current']").attr("value");
                    //alert(tid+"   "+isHot+"   "+isNew);

                    window.location.href = "/songer/dofindAll?tid="+tid+"&isHot="+isHot;
                })


                tid = $("#tid").val();
                isHot = $("#isHot").val();
                //流派的回显
                $("a[ftype='mtype'][class='current']").removeClass("current");
                $("a[ftype='mtype'][value='"+tid+"']").addClass("current");
                //热门回显
                $("a[ftype='isHot'][class='current']").removeClass("current");
                $("a[ftype='isHot'][value='"+isHot+"']").addClass("current");



            })

③查看更多

songers.jsp页面的js请求

 function loadMore01() {
                var pageNoPortal = parseInt($("#pageNoPortal").val());
                //计算pageSize
                var pageSize = 5*(++pageNoPortal);
                window.location.href = "/song/dofindAll?tid="+tid+"&isHot="+isHot+"&pageSize="+pageSize+"&pageNoPortal="+pageNoPortal;
            }

这里前三个共用一个请求—dofindAll,和歌曲界面相似,也只是请求参数不一样 

④查看音乐人的详细信息

点击音乐人的图片,就可以查看音乐人的详细信息,发送getSonger请求,并带有音乐人的id

<a target="_blank" title="${songer.srname}" href="/songer/getSonger?srid=${songer.srid}">

controller编写,根据音乐人的id联表查询歌曲信息,将其返回给songer,jsp页面

@RequestMapping("/getSonger")
    public String getSong(Integer srid, Model model) {
        Songer songer = songerService.getSongs(srid);
        model.addAttribute("songer",songer);
        System.out.println(songer);
        return "songer";
    }

根据音乐人的id联表查询歌曲信息的service接口

//根据歌手id联表查询歌曲信息
    public Songer getSongs(Integer srid);

根据音乐人的id联表查询歌曲信息的service实现类

@Override
    public Songer getSongs(Integer srid) {
        return songerMapper.getSongs(srid);
    }

根据音乐人的id联表查询歌曲信息的mapper接口

 //根据歌手id联表查询歌曲信息
    public Songer getSongs(Integer srid);

根据音乐人的id联表查询歌曲信息的sql

 <resultMap id="getSongsRM" type="com.qcby.model.Songer" extends="ResultMapWithBLOBs">
    <collection property="songs" ofType="com.qcby.model.Song" resultMap="com.qcby.dao.SongMapper.BaseResultMap"></collection>
    <collection property="mtype" ofType="com.qcby.model.Mtype" resultMap="com.qcby.dao.MtypeMapper.BaseResultMap"></collection>
  </resultMap>

  <select id="getSongs" parameterType="Integer" resultMap="getSongsRM">
    select sr.srid, sr.srname, sr.area, sr.intro, sr.pic, m.*, s.* from songer sr left join mtype m on sr.tid=m.tid left join song s on sr.srid=s.srid where sr.srid=#{srid}
  </select>

songer.jsp页面

 <div id="artist_info">
                            <table>
                                <tbody>
                                <tr>
                                    <td width="56" valign="top" class="item">地区:</td>
                                    <td valign="top">${songer.area}</td>
                                </tr>
                                <tr>
                                    <td width="56" valign="top" class="item">风格:</td>
                                    <td valign="top"><a href="/songer/dofindAll?tid="${songer.mtype.tid}>
                                        ${songer.mtype.tname}</a>
                                    </td>
                                </tr>
                                <tr>
                                    <td width="56" valign="top" class="item">档案:</td>
                                    <td valign="top">
                                        <div class="record">
                                            ${songer.intro}
                                        </div>
                                    </td>
                                </tr>
                                </tbody>
                            </table>
                        </div>
                        <div id="artist_photo">
                            <a id="cover_lightbox"
                               href="#" target="_blank"
                               title="${songer.srname}" data-lightbox="lightbox"> <img
                                    src="${filePath}${songer.pic}"
                                    alt="${songer.srname}"/></a>
                        </div>

至此,一个哈哈音乐项目就全部完成啦!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/519554.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

路由策略与路由控制之双点双向重发布(OSPF-ISIS)实验

双点双向重发布在路由协议中&#xff0c;特别是在OSPF&#xff08;开放式最短路径优先&#xff09;与IS-IS&#xff08;中间系统到中间系统&#xff09;等协议之间&#xff0c;指的是在两个协议间或者两个进程间进行路由信息共享的机制。这种机制涉及到在两个不同的协议区域使用…

微软推出GPT-4 Turbo优先使用权:Copilot for Microsoft 365商业用户享受无限制对话及增强图像生成能力

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

电脑上音频太多,播放速度又不一致,如何批量调节音频播放速度?

批量调节音频速度是现代音频处理中的一个重要环节&#xff0c;尤其在音乐制作、电影剪辑、有声书制作等领域&#xff0c;它能够帮助制作者快速高效地调整音频的播放速度&#xff0c;从而满足特定的制作需求。本文将详细介绍批量调节音频速度的方法、技巧和注意事项&#xff0c;…

Docker 安装 Linux 系统可视化监控 Netdata

docker 安装 netdata 前提准备Docker 两种方式部署 Netdata1、使用 docker run 命令运行 netdata 服务2、使用 docker compose 运行 netdata 服务 Netdata 服务可视化界面Netdata 汉化处理 前提准备 说明&#xff1a;此处使用 windows11 安装的 docker desktop & wsl2/apli…

【Rust】环境搭建

Rust 支持很多的集成开发环境&#xff08;IDE&#xff09;或开发专用的文本编辑器。 官方网站公布支持的工具如下&#xff08;工具 - Rust 程序设计语言&#xff09; 本课程将使用 Visual Studio Code 作为我们的开发环境&#xff08;Eclipse 有专用于 Rust 开发的版本&#…

政安晨:【Keras机器学习实践要点】(十七)—— 利用 EfficientNet 通过微调进行图像分类

政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收录专栏: TensorFlow与Keras机器学习实战 希望政安晨的博客能够对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff01; 本文目标&#xff1a; 使用 EfficientNet 和在图…

比nestjs更优雅的ts控制反转策略-依赖查找

一、Cabloy5.0内测预告 Cabloy5.0采用TS对整个全栈框架进行了脱胎换骨般的大重构&#xff0c;并且提供了更加优雅的ts控制反转策略&#xff0c;让我们的业务开发更加快捷顺畅 1. 新旧技术栈对比&#xff1a; 后端前端旧版js、egg2.0、mysqljs、vue2、framework7新版ts、egg3…

Git 如何去使用

目录 1. Git暂存区的使用 1.1. 暂存区的作用 1.2. 暂存区覆盖工作区&#xff08;注意&#xff1a;完全确认覆盖时使用&#xff09; 1.3. 暂存区移除文件 1.4. 练习 2. Git回退版本 2.1. 概念 2.2. 查看提交历史 2.3. 回退命令 2.4. 注意 3. Git删除文件 3.1. 需求 …

Centos7使用docker安装Jenkins

一、下载Jenkins docker pull jenkins/jenkins:lts 二、启动Jenkins docker run \-u root \--rm \-d \-p 8081:8080 \-p 50000:50000 \-v /root/docker/jenkins/var/jenkins_home:/var/jenkins_home \-v /var/run/docker.sock:/var/run/docker.sock \-v /usr/bin/docker:/usr…

苹果CMSV10整合dplayer播放器增加记忆+P2P播放+自动下一集功能插件详细保姆级教程

1.本站已打包&#xff0c;可以直接下载然后上传到你服务器的苹果CMS网站static/player目录下就可以了&#xff0c;下面是教程 wlm3u8.js代码&#xff1a; MacPlayer.Html <iframe border"0" src"mac<span class"wp_keywordlink"><a hre…

Pandas:sort_index、sort_values方法的使用

sort_index和sort_values既是Series类型数据自带的方法&#xff0c;也是DataFrame数据自带的方法。本篇博客以DataFrame为例进行讲述。 1 概览 sort_index和sort_values可以将DataFrame中的数据按照索引及值的大小进行排序。这两个方法所包含的参数及其作用都基本一致。如下表…

注解,自定义注解和元注解

1.注解 1.1.注解概述、作用 注解&#xff08;Annotation&#xff09;&#xff0c;也叫元数据。一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性&#xff0c;与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面&#xff0…

Unity类银河恶魔城学习记录12-3 p125 Limit Inventory Slots源代码

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释&#xff0c;可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili Inventory.cs using Newtonsoft.Json.Linq; using System.Collections; us…

Django--admin 后台管理站点

Django最大的优点之一&#xff0c;就是体贴的提供了一个基于项目model创建的一个后台管理站点admin。这个界面只给站点管理员使用&#xff0c;并不对大众开放。虽然admin的界面可能不是那么美观&#xff0c;功能不是那么强大&#xff0c;内容不一定符合你的要求&#xff0c;但是…

正则表达式(2)

文章目录 专栏导读1、贪婪与非贪婪2、转义匹配 专栏导读 ✍ 作者简介&#xff1a;i阿极&#xff0c;CSDN 数据分析领域优质创作者&#xff0c;专注于分享python数据分析领域知识。 ✍ 本文录入于《python网络爬虫实战教学》&#xff0c;本专栏针对大学生、初级数据分析工程师精…

完美运营版商城源码 虚拟商品全功能商城 全能商城小程序 智慧商城系统 全品类百货商城(带安装教程)

完美运营版商城/拼团/团购/秒杀/积分/砍价/实物商品/虚拟商品等全功能商城 干干净净 没有一丝多余收据 还没过手其他站 还没乱七八走的广告和后门 后台可以自由拖曳修改前端UI页面 还支持虚拟商品自动发货等功能 挺不错的一套源码 前端UNIAPP 后端PHP 一键部署版本 源码下载…

Chatgpt掘金之旅—有爱AI商业实战篇|专业博客|(六)

演示站点&#xff1a; https://ai.uaai.cn 对话模块 官方论坛&#xff1a; www.jingyuai.com 京娱AI 一、AI技术创业博客领域有哪些机会&#xff1f; 人工智能&#xff08;AI&#xff09;技术作为当今科技创新的前沿领域&#xff0c;为创业者提供了广阔的机会和挑战。随着AI技…

SketchUp Pro 2024 for mac 草图大师 专业的3D建模软件

SketchUp Pro 2024 for Mac是一款功能强大的三维建模软件&#xff0c;适用于Mac电脑。其简洁易用的界面和强大的工具集使得用户可以轻松创建复杂的3D模型。 软件下载&#xff1a;SketchUp Pro 2024 for mac v24.0.483 激活版下载 SketchUp Pro 2024 for Mac支持导入和导出多种文…

[C++初阶]初识C++(二)

建议先看完上篇&#xff1a;[C初阶]初识C(一)—————命名空间和缺省函数-CSDN博客 本篇部分代码和文案来源&#xff1a;百度文库&#xff0c;知乎&#xff0c;比特就业课 1.函数重载 自然语言中&#xff0c;一个词可以有多重含义&#xff0c;人们可以通过上下文来判断该词真…

7种链游媒体宣发工具助力游戏营销-华媒舍

一. 什么是链游媒体 链游媒体是指以区块链技术为基础&#xff0c;实现游戏与媒体资源之间的连接和交互的媒体形态。通过区块链技术&#xff0c;链游媒体能够确保游戏内容和媒体信息的透明性和不可篡改性&#xff0c;提供更加公正、透明的游戏环境。 二. 链游媒体宣发工具的重要…