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

news2025/1/19 22:12:28

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>

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Educational Codeforces Round 162 (Rated for Div. 2) ----- E. Count Paths --- 题解

E. Count Paths&#xff1a; 题目大意&#xff1a; 思路解析&#xff1a; 根据题目中定义的美丽路径&#xff0c;我们可以发现路径只有两种情况&#xff1a; 当前结点作为起始结点&#xff0c;那我们只需要知道它的子树下有多少个相同颜色的结点&#xff0c;并且相同颜色的结…

攻防世界:mfw[WriteUP]

根据题目提示考虑是git库泄露 这里在地址栏后加.git也可以验证是git库泄露 使用GitHack工具对git库进行恢复重建 在templates目录下存在flag.php文件&#xff0c;但里面并没有flag 有内容的只有主目录下的index.php index.php源码&#xff1a; <?phpif (isset($_GET[page…

2024年最新版FL Studio21.2.3 Build 4004 for Mac 版激活下载和图文激活教程

FL studio21中文别名水果编曲软件&#xff0c;是一款全能的音乐制作软件&#xff0c;包括编曲、录音、剪辑和混音等诸多功能&#xff0c;让你的电脑编程一个全能的录音室&#xff0c;它为您提供了一个集成的开发环境&#xff0c;使用起来非常简单有效&#xff0c;您的工作会变得…

重读Java设计模式: 桥接模式详解

引言 在软件开发中&#xff0c;经常会遇到需要在抽象与实现之间建立连接的情况。当系统需要支持多个维度的变化时&#xff0c;使用传统的继承方式往往会导致类爆炸和耦合度增加的问题。为了解决这一问题&#xff0c;我们可以使用桥接模式。桥接模式是一种结构型设计模式&#…

机器学习中的GBDT模型及其优缺点(包含Python代码样例)

目录 一、简介 二、优缺点介绍 三、Python代码示例 四、总结 一、简介 GBDT&#xff08;Gradient Boosting Decision Tree&#xff09;是一种集成学习算法&#xff0c;被广泛应用于机器学习中的回归和分类问题。它由多个决策树组成&#xff0c;每个决策树都通过迭代逐渐提升…

巧用 STM32CubeIDE 之编译警告

1. 前言 编译警告对于工程师们来说&#xff0c;是再常见不过的了。对于严谨的工程师们来说&#xff0c;任何warning 都是不可忽视的。 2. 巧妙使用 warning 在 STM32CubeIDE 中&#xff0c;我们可以通过主动 warning&#xff08;甚至 error&#xff09;的方式来通知工程师&a…

计算机网络-TCP基础、三次挥手、四次握手过程

TCP基础 定义&#xff1a;TCP是面向连接的、可靠的、基于字节流的传输层通信协议。这意味着在发送数据之前&#xff0c;TCP需要建立连接&#xff0c;并且它能确保数据的可靠传输。此外&#xff0c;TCP将数据视为无结构的连续字节流。面向连接&#xff1a;TCP只能一对一进行连接…

ES6中数组新增的扩展和方法

文章目录 一、扩展运算符的应用二、构造函数新增的方法Array.from()Array.of()三、实例对象新增的方法copyWithin()find()、findIndex()fill()entries()&#xff0c;keys()&#xff0c;values()includes()flat()&#xff0c;flatMap()四、数组的空位五、sort排序稳定性 参考文献…

响应式网站设计哪个类型比较适合你?

响应式网站设计哪个类型比较适合你&#xff1f;有很多人对于响应式网站还不太了解&#xff0c;其实这种网站就是以创建页面的图片排版大小&#xff0c;来根据浏览网站用户所使用网络设备&#xff0c;自动化适应这些设备。 不管是出于网站兼容性还是用户信息需求&#xff0c;它都…

RK3568测试

作者简介&#xff1a; 一个平凡而乐于分享的小比特&#xff0c;中南民族大学通信工程专业研究生在读&#xff0c;研究方向无线联邦学习 擅长领域&#xff1a;驱动开发&#xff0c;嵌入式软件开发&#xff0c;BSP开发 作者主页&#xff1a;一个平凡而乐于分享的小比特的个人主页…

深入浅出 -- 系统架构之微服务架构的新挑战

尽管微服务架构有着高度独立的软件模块、单一的业务职责、可灵活调整的技术栈等优势&#xff0c;但也不能忽略它所带来的弊端。本篇文章&#xff0c;我们从网络、性能、运维、组织架构和集成测试五个方面来聊一下设计微服务架构需要考虑哪些问题&#xff0c;对设计有哪些挑战呢…

使用 Apipost 管理项目接口文档

目录 前言 基本使用教程 注册账号 创建项目 创建接口 编辑接口 ​编辑 接口设计 生成文档 接口用例 前言 在 web 后端开发中&#xff0c;开发接口之前通常需要先写接口文档&#xff0c;然后前后端再根据接口文档开始开发系统模块。接口文档形式多种多样&#xff0c…

Aurora8b10b(1)IP核介绍并基于IP核进行设计

文章目录 前言一、IP核设置二、基于IP核进行设计2.1、设计框图2.2、aurora_8b10b_0模块2.3、aurora_8b10b_0_CLOCK_MODULE2.4、aurora_8b10b_0_SUPPORT_RESET_LOGIC2.5、aurora8b10b_channel模块2.6、IBUFDS_GTE2模块2.7、aurora_8b10b_0_gt_common_wrapper模块2.8、aurora8b10…

基于MPPT的风力机发电系统simulink建模与仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 4.1风能与风力发电机模型 4.2风力机功率特性与最大功率点 4.3 MPPT 5.完整工程文件 1.课题概述 基于MPPT的风力机发电系统simulink建模与仿真。MPPT使用S函数编写实现。基于最大功率点跟踪&#xff08…

【OpenCV-颜色空间】

OpenCV-颜色空间 ■ RGB■ BGR■ HSV■ HSL■ HUE■ YUV ■ RGB ■ BGR BGR 就是RGB R和B调换位置。 OpenCV 默认使用BGR ■ HSV ■ HSL ■ HUE ■ YUV

免费搭建:雾锁王国Enshrouded游戏服务器,10秒完成!

免费自建雾锁王国Enshrouded服务器&#xff0c;先领取阿里云300元无门槛代金券&#xff0c;然后在雾锁王国Enshrouded专题页一键部署&#xff0c;不需要基础&#xff0c;鼠标点选即可10秒钟创建一台雾锁王国游戏服务器&#xff0c;超简单&#xff0c;阿里云服务器网aliyunfuwuq…

利用IP地址判断羊毛用户:IP数据云提供IP风险画像

在当今数字化社会&#xff0c;互联网已经成为人们日常生活和商业活动中不可或缺的一部分。然而&#xff0c;随着网络的普及&#xff0c;网络欺诈行为也日益猖獗&#xff0c;其中包括了羊毛党这一群体。羊毛党指的是利用各种手段获取利益、奖励或者优惠而频繁刷取优惠券、注册账…

leetcode热题100.跳跃游戏2

Problem: 45. 跳跃游戏 II 文章目录 题目思路复杂度Code 题目 给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说&#xff0c;如果你在 nums[i] 处&#xff0c;你可以跳转到任意 nums[i j] 处: …

【排列回溯】Leetcode 46. 全排列

【排列回溯】Leetcode 46. 全排列 ---------------&#x1f388;&#x1f388;题目链接&#x1f388;&#x1f388;------------------- used数组&#xff0c;其实就是记录此时temp 里都有哪些元素使用了&#xff0c;一个排列里一个元素只能使用一次。 class Solution {List&…

Dockerd的使用

端口映射 存储卷 类似于mount&#xff0c;把真机的某个目录映射都容器里面 -v 选项可以有多个 利用存储卷修改配置文件 容器间网络模式 共享网络为 --networkcontainer&#xff1a;容器名 微服务架构 一种由容器为载体&#xff0c;使用多个小型服务组合来构建复杂的架构为…