1.首页页面

首页主要有首页帖子列表数据、热议帖子列表数据以及分页数据等,需要在进入页面时就进行读取并显示到页面中。
这里首页主要包含四个部分:

  • 查询参数区域:大家可以理解为筛选区域,就是根据这些参数来查询帖子列表,参数包括帖子分类、发帖时间段、排序方式、还有右侧的搜索输入框。
  • 帖子列表展示区域:本页面主要的功能区域,所占用的面积也比较大。将查询出来的帖子列表数据渲染到这个区域进行展示。
  • 分页按钮区域:主要用于展示分页按钮,根据查询到的分页数据动态的生成这些页码和按钮。
  • 本周热议区域:一个简单的展示区域,动态的去展示近期评论量较高的帖子列表即可,无需分页。

2. 功能实现

2.1 前端传递的参数

首页中帖子分页列表所需的参数如下,后端主要负责接收这些参数,并根据这些参数对数据库中的发帖数据进行查询即可。

  • categoryId:帖子的分类
  • period:帖子的发布日期
  • orderBy:排序方式
  • keyword:搜索关键字
  • page:页码

前端则需要根据这些参数进行 URL 的封装。

th:href="@{/index(period=${period},page=${pageResult.currPage-1},keyword=${keyword},categoryId=${categoryId},orderBy=${orderBy})}"

2.2 返回结果封装

文章列表肯定是一个 List 对象,因为有分页功能,所以还需要返回分页字段,因此最终接收到的结果返回格式为 PageResult 对象,在util包下创建PageResult对象。

/**
 * 分页工具类
 *
 */
public class PageResult implements Serializable {

    //总记录数
    private int totalCount;
    //每页记录数
    private int pageSize;
    //总页数
    private int totalPage;
    //当前页数
    private int currPage;
    //列表数据
    private List<?> list;

    /**
     * 分页
     *
     * @param list       列表数据
     * @param totalCount 总记录数
     * @param pageSize   每页记录数
     * @param currPage   当前页数
     */
    public PageResult(List<?> list, int totalCount, int pageSize, int currPage) {
        this.list = list;
        this.totalCount = totalCount;
        this.pageSize = pageSize;
        this.currPage = currPage;
        this.totalPage = (int) Math.ceil((double) totalCount / pageSize);
    }

    public int getTotalCount() {
        return totalCount;
    }

    public void setTotalCount(int totalCount) {
        this.totalCount = totalCount;
    }

    public int getPageSize() {
        return pageSize;
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    public int getTotalPage() {
        return totalPage;
    }

    public void setTotalPage(int totalPage) {
        this.totalPage = totalPage;
    }

    public int getCurrPage() {
        return currPage;
    }

    public void setCurrPage(int currPage) {
        this.currPage = currPage;
    }

    public List<?> getList() {
        return list;
    }

    public void setList(List<?> list) {
        this.list = list;
    }

}

单条的帖子列表数据则是放在分页返回结果对象的 list 属性中,需要的字段如下所示:

  • 帖子的类别名称
  • 发帖人头像
  • 发帖人昵称
  • 帖子标题
  • 发帖时间
  • 收藏数量
  • 评论数量

这里通常会设计成可跳转的形式,即点击标题后会跳转到对应的帖子详情页面中,因此这里也会读取帖子的 id 字段。最终返回的对象格式如下,在entity包下创建BBSPostListEntity类。

/**
 * 帖子列表-实体类
 * 页面展示时需要的字段与帖子实体类不同,因此新增了这个类
 */
public class BBSPostListEntity {
    private Long postId;

    private Long publishUserId;

    private String postCategoryName;

    private String postTitle;

    private Long postViews;

    private Long postComments;

    private Long postCollects;

    private String nickName;

    private String headImgUrl;

    private Date createTime;

    public Long getPostId() {
        return postId;
    }

    public void setPostId(Long postId) {
        this.postId = postId;
    }

    public Long getPublishUserId() {
        return publishUserId;
    }

    public void setPublishUserId(Long publishUserId) {
        this.publishUserId = publishUserId;
    }

    public String getPostTitle() {
        return postTitle;
    }

    public void setPostTitle(String postTitle) {
        this.postTitle = postTitle == null ? null : postTitle.trim();
    }

    public Long getPostViews() {
        return postViews;
    }

    public void setPostViews(Long postViews) {
        this.postViews = postViews;
    }

    public Long getPostComments() {
        return postComments;
    }

    public void setPostComments(Long postComments) {
        this.postComments = postComments;
    }

    public Long getPostCollects() {
        return postCollects;
    }

    public void setPostCollects(Long postCollects) {
        this.postCollects = postCollects;
    }

    public String getNickName() {
        return nickName;
    }

    public void setNickName(String nickName) {
        this.nickName = nickName;
    }

    public String getHeadImgUrl() {
        return headImgUrl;
    }

    public void setHeadImgUrl(String headImgUrl) {
        this.headImgUrl = headImgUrl;
    }

    public String getPostCategoryName() {
        return postCategoryName;
    }

    public void setPostCategoryName(String postCategoryName) {
        this.postCategoryName = postCategoryName;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(getClass().getSimpleName());
        sb.append(" [");
        sb.append("Hash = ").append(hashCode());
        sb.append(", postId=").append(postId);
        sb.append(", publishUserId=").append(publishUserId);
        sb.append(", postTitle=").append(postTitle);
        sb.append(", postViews=").append(postViews);
        sb.append(", postComments=").append(postComments);
        sb.append(", postCollects=").append(postCollects);
        sb.append("]");
        return sb.toString();
    }
}

2.3 数据查询实现

上面列表中的字段数据可以通过查询 tb_bbs_post 和 tb_bbs_user 两张表,同时需要注意分页功能实现,传参时也需要传上此时的页码,首页默认是第 1 页。

2.3.1 封装分页查询类

在util包下创建PageQueryUtil类。

/**
 * 分页查询参数
 *
 */
public class PageQueryUtil extends LinkedHashMap<String, Object> {
    //当前页码
    private int page;
    //每页条数
    private int limit;

    public PageQueryUtil(Map<String, Object> params) {
        this.putAll(params);

        //分页参数
        this.page = Integer.parseInt(params.get("page").toString());
        this.limit = Integer.parseInt(params.get("limit").toString());
        this.put("start", (page - 1) * limit);
        this.put("page", page);
        this.put("limit", limit);
    }


    public int getPage() {
        return page;
    }

    public void setPage(int page) {
        this.page = page;
    }

    public int getLimit() {
        return limit;
    }

    public void setLimit(int limit) {
        this.limit = limit;
    }

    @Override
    public String toString() {
        return "PageUtil{" +
                "page=" + page +
                ", limit=" + limit +
                '}';
    }
}
2.3.2 业务层
/**
     * 首页帖子列表
     *
     * @param pageUtil
     * @return
     */
    PageResult getBBSPostPageForIndex(PageQueryUtil pageUtil);
@Override
    public PageResult getBBSPostPageForIndex(PageQueryUtil pageUtil) {
        //查询帖子数据
        int total = bbsPostMapper.getTotalBBSPosts(pageUtil);
        List<BBSPost> bbsPostList = bbsPostMapper.findBBSPostList(pageUtil);
        List<BBSPostListEntity> bbsPostListEntities = new ArrayList<>();
        //数据格式转换
        if (!CollectionUtils.isEmpty(bbsPostList)) {
            bbsPostListEntities = BeanUtil.copyList(bbsPostList, BBSPostListEntity.class);
            List<Long> userIds = bbsPostListEntities.stream().map(BBSPostListEntity::getPublishUserId).collect(Collectors.toList());
            //查询user数据
            List<BBSUser> bbsUsers = bbsUserMapper.selectByPrimaryKeys(userIds);
            if (!CollectionUtils.isEmpty(bbsUsers)) {
                //封装user数据
                Map<Long, BBSUser> bbsUserMap = bbsUsers.stream().collect(Collectors.toMap(BBSUser::getUserId, Function.identity(), (entity1, entity2) -> entity1));
                for (BBSPostListEntity bbsPostListEntity : bbsPostListEntities) {
                    if (bbsUserMap.containsKey(bbsPostListEntity.getPublishUserId())) {
                        //设置头像字段和昵称字段
                        BBSUser tempUser = bbsUserMap.get(bbsPostListEntity.getPublishUserId());
                        bbsPostListEntity.setHeadImgUrl(tempUser.getHeadImgUrl());
                        bbsPostListEntity.setNickName(tempUser.getNickName());
                    }
                }
            }
        }
        PageResult pageResult = new PageResult(bbsPostListEntities, total, pageUtil.getLimit(), pageUtil.getPage());
        return pageResult;
    }

getBBSPostPageForIndex() 方法,然后定义 page 参数来确定查询第几页的数据,之后通过 SQL 查询出对应的分页数据,最终返回的数据是 PageResult 对象:

  • 根据传参查询帖子列表数据和帖子的数量
  • 根据获取的对应分页的帖子列表,查询对应的发帖人信息
  • 根据帖子实体中的字段和论坛用户实体中的字段封装 BBSPostListEntity 对象列表
  • 封装 PageResult 对象并返回
2.3.3 数据持久层

这里主要需要查询帖子数据,帖子分页列表,用户数据。
BBSPostMapper

int getTotalBBSPosts(PageQueryUtil pageUtil);
<select id="getTotalBBSPosts" parameterType="Map" resultType="int">
        select count(*)
        from tb_bbs_post where post_status = 1
        <if test="categoryId!=null and categoryId!=''">
            and post_category_id = #{categoryId}
        </if>
        <if test="keyword!=null and keyword!=''">
            and post_title like CONCAT('%',#{keyword},'%')
        </if>
        <choose>
            <!-- 周榜 -->
            <when test="period!=null and orderBy=='hot7'">
                and create_time ">> DATE_SUB(now(), INTERVAL 7 DAY)
            </when>
            <!-- 月榜 -->
            <when test="period!=null and orderBy=='hot30'">
                and create_time ">> DATE_SUB(now(), INTERVAL 30 DAY)
            </when>
            <!-- 全部数据 -->
            <otherwise>
            </otherwise>
        </choose>
    </select>

BBSPostMapper

List<BBSPost> findBBSPostList(PageQueryUtil pageUtil);
<select id="findBBSPostList" parameterType="Map" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List"/>
        from tb_bbs_post where post_status = 1
        <if test="categoryId!=null and categoryId!=''">
            and post_category_id = #{categoryId}
        </if>
        <if test="keyword!=null and keyword!=''">
            and post_title like CONCAT('%',#{keyword},'%')
        </if>
        <choose>
            <!-- 周榜 -->
            <when test="period!=null and period=='hot7'">
                and create_time ">> DATE_SUB(now(), INTERVAL 7 DAY)
            </when>
            <!-- 月榜 -->
            <when test="period!=null and period=='hot30'">
                and create_time ">> DATE_SUB(now(), INTERVAL 30 DAY)
            </when>
            <!-- 全部数据 -->
            <otherwise>
            </otherwise>
        </choose>
        <choose>
            <!-- 最新发布 -->
            <when test="orderBy!=null and orderBy=='new'">
                order by post_id desc
            </when>
            <!-- 热议 -->
            <when test="orderBy!=null and orderBy=='comment'">
                order by post_comments desc
            </when>
            <!-- 默认 -->
            <otherwise>
                order by last_update_time desc,post_views desc,post_comments desc
            </otherwise>
        </choose>
        <if test="start!=null and limit!=null">
            limit #{start},#{limit}
        </if>
    </select>

BBSUserMapper

List<BBSUser> selectByPrimaryKeys(@Param("userIds") List<Long> userIds);
<select id="selectByPrimaryKeys" parameterType="java.lang.Long" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List" />
        from tb_bbs_user
        where user_id in
        <foreach item="userId" collection="userIds" open="(" separator="," close=")">
            #{userId,jdbcType=BIGINT}
        </foreach>
    </select>

2.4 后端数据传递给前端

想要将数据通过 Thymeleaf 语法渲染到前端页面上,需要将查询出的数据带过来,需要在首页请求的 Controller 方法中将查询到的数据放入 request 域中,该功能在IndexController类中实现。

整体页面设计了一个热帖板块,这里同样需要将其查询出来放入 request 域。

近期热议帖子列表-实体类

/**
 * 近期热议帖子列表-实体类
 * 页面展示时需要的字段仅需要id、标题、评论数三个字段,因此新增了这个类
 */
public class HotTopicBBSPostListEntity {
    private Long postId;

    private String postTitle;

    private Long postComments;

    public Long getPostId() {
        return postId;
    }

    public void setPostId(Long postId) {
        this.postId = postId;
    }

    public String getPostTitle() {
        return postTitle;
    }

    public void setPostTitle(String postTitle) {
        this.postTitle = postTitle;
    }

    public Long getPostComments() {
        return postComments;
    }

    public void setPostComments(Long postComments) {
        this.postComments = postComments;
    }

    @Override
    public String toString() {
        return "HotTopicBBSPostListEntity{" +
                "postId=" + postId +
                ", postTitle='" + postTitle + '\'' +
                ", postComments=" + postComments +
                '}';
    }
}

BBSPostService

/**
     * 近期热议帖子列表
     *
     * @return
     */
    List getHotTopicBBSPostList();
@Override
    public List getHotTopicBBSPostList() {
        List<BBSPost> bbsPostList = bbsPostMapper.getHotTopicBBSPostList();
        List<HotTopicBBSPostListEntity> hotTopicBBSPostList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(bbsPostList)) {
            hotTopicBBSPostList = BeanUtil.copyList(bbsPostList, HotTopicBBSPostListEntity.class);
        }
        return hotTopicBBSPostList;
    }

BBSPostMapper

List<BBSPost> getHotTopicBBSPostList();
<select id="getHotTopicBBSPostList" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List"/>
        from tb_bbs_post
        where post_status = 1  and create_time ">> DATE_SUB(now(), INTERVAL 7 DAY) order by post_comments desc
        <!-- 近七天的热议帖子,默认读取6条数据,可自行修改 -->
        limit 6
    </select>

根据请求参数查询出对应的分页数据 pageResult 并放入到 request 对象中,之后跳转到 index 模板页面进行数据渲染。
实现逻辑如下:

  • 查询所有的分类数据,并封装到 request 域中
  • 查询出近期热议的帖子数据封装到 request 域中
  • 处理请求参数,并封装到 PageQueryUtil 对象中,进行后续的查询操作
  • 根据分页参数查询出对应的帖子分页列表数据,封装到 request 域中
  • 跳转到 index 模板页面

2.5 数据渲染

页面渲染大致分为四步:

渲染页面顶部的帖子分类信息:使用 th:each 循环语法将返回的 bbsPostCategories 对象,即帖子分类列表数据渲染到页面中。

渲染帖子分页列表数据:首先判断帖子的分页列表数据是否为空,如果为空,则依然显示“没有相关数据”,如果不为空,再进行帖子列表数据的渲染。在列表区域读取 pageResult 对象中的 list 数据,list 数据为文章列表数据,使用 th:each 循环语法将帖子的类别名称、发帖人头像、发帖人昵称、帖子标题、发帖时间、收藏数量、评论数量等字段渲染出来,点击对应的帖子后也需要跳转到帖子详情页面,所以 a 标签中的详情跳转链接需要读取 postId 字段。

生成分页按钮:读取 pageResult 对象中的分页数据,之后根据分页字段 currPage(当前页码)、 totalPage(总页码)以及其他回显字段将下方的分页按钮渲染出来。逻辑如下:通过分页区域的代码可以看出,最多的情况下会有 7 个翻页按钮,分别是“上一页”、“下一页”以及具体的页码翻页,“上一页”和“下一页”两个按钮是固定的,只是当前页是第 1 页时,点击“上一页”不进行跳转,因为此时没有上一页。当前页是最后一页时“下一页”不进行跳转,因为此时没有下一页。而中间的具体页码的生成,则是根据 currPage 来实现的,通过当前页变量和总页码进行判断,如果当前页之前应该有数据,则生成当前页码前面的页码,当前页码之后有数据则生成当前页码后面的页码,以当前页码为中点,前后最多分别生成两个分页按钮,这是楼楼商城项目中的实现方式,你也可以进行扩展,增加或者减少生成的翻页按钮数量。

渲染本周热议列表:首先判断查询的本周热议 hotTopicBBSPostList 列表数据是否为空,如果为空,则依然显示“没有相关数据”,如果不为空,再进行列表数据的渲染。在列表区域读取 hotTopicBBSPostList 对象,使用 th:each 循环语法将帖子的帖子标题、评论数量字段渲染出来,点击对应的帖子后也需要跳转到帖子详情页面,所以 a 标签中的详情跳转链接需要读取 postId 字段。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="header::head-fragment('首页')">
</head>
<body>
<div th:replace="header::header-fragment"></div>

<div class="fly-panel fly-column">
    <div class="layui-container">
        <!-- 1.渲染页面顶部的帖子分类信息 -->
        <ul class="layui-clear">
            <li th:class="${null == categoryId} ?'layui-hide-xs layui-this':''"><a href="/">首页</a></li>
            <th:block th:unless="${null == bbsPostCategories}">
                <th:block th:each="c : ${bbsPostCategories}">
                    <li th:class="${null !=categoryId and categoryId==c.categoryId} ?'layui-hide-xs layui-this':''">
                        <a th:href="@{${'/index?categoryId='+c.categoryId}}"
                           th:text="${c.categoryName}">分享</a>
                    </li>
                </th:block>
            </th:block>

            <li class="layui-hide-xs layui-hide-sm layui-show-md-inline-block"><span class="fly-mid"></span></li>
        </ul>

        <div class="fly-column-right layui-hide-xs">
            <span class="fly-search"><i class="layui-icon"></i></span>
            <a th:href="@{/addPostPage}" class="layui-btn">发布新帖</a>
        </div>
    </div>
</div>

<div class="layui-container">
    <div class="layui-row layui-col-space15">
        <div class="layui-col-md8">
            <div class="fly-panel" style="margin-bottom: 0;">
                <div class="fly-panel-title fly-filter">
                    <a th:href="@{/index(keyword=${keyword},categoryId=${categoryId},orderBy=${orderBy})}"
                       th:class="${period == null ? 'layui-this':''}">默认</a>
                    <span class="fly-mid"></span>
                    <a th:class="${period == 'hot7' ? 'layui-this':''}"
                       th:href="@{/index(period='hot7',keyword=${keyword},categoryId=${categoryId},orderBy=${orderBy})}">周榜</a>
                    <span class="fly-mid"></span>
                    <a th:class="${period == 'hot30' ? 'layui-this':''}"
                       th:href="@{/index(period='hot30',keyword=${keyword},categoryId=${categoryId},orderBy=${orderBy})}">月榜</a>
                    <span class="fly-mid"></span>
                    <span class="fly-filter-right layui-hide-xs">
                        <a th:href="@{/index(orderBy='new',period=${period},keyword=${keyword},categoryId=${categoryId})}"
                           th:class="${orderBy == 'new' ? 'layui-this':''}">按最新</a>
                            <span class="fly-mid"></span>
                        <a th:href="@{/index(orderBy='comment',period=${period},keyword=${keyword},categoryId=${categoryId})}"
                           th:class="${orderBy == 'comment' ? 'layui-this':''}">按热议</a>
                    </span>
                </div>
                <!-- 2.渲染帖子分页列表数据 -->
                <th:block th:if="${#lists.isEmpty(pageResult.list)}">
                    <!-- 无数据时 -->
                    <div class="fly-none">没有相关数据</div>
                </th:block>
                <th:block th:unless="${#lists.isEmpty(pageResult.list)}">
                    <ul class="fly-list">
                        <th:block th:each="bbsPostListEntity : ${pageResult.list}">
                            <li>
                                <a th:href="@{${'/userCenter/'+bbsPostListEntity.publishUserId}}" class="fly-avatar">
                                    <img th:src="@{${bbsPostListEntity.headImgUrl}}"
                                         th:alt="${bbsPostListEntity.nickName}">
                                </a>
                                <h2>
                                    <a href="##" class="layui-badge"
                                       th:text="${bbsPostListEntity.postCategoryName}">分享</a>
                                    <a th:href="@{${'/detail/'+bbsPostListEntity.postId}}"
                                       th:text="${bbsPostListEntity.postTitle}">My-BBS开源啦</a>
                                </h2>
                                <div class="fly-list-info">
                                    <a th:href="@{${'/userCenter/'+bbsPostListEntity.publishUserId}}" link>
                                        <cite th:text="${bbsPostListEntity.nickName}">程序员十三</cite>
                                    </a>
                                    <span th:text="${#dates.format(bbsPostListEntity.createTime, 'yyyy-MM-dd HH:mm:ss')}">刚刚</span>
                                    <span class="fly-list-kiss layui-hide-xs" title="赞"><i
                                            class="iconfont icon-zan"></i> <th:block
                                            th:text="${bbsPostListEntity.postCollects}"></th:block></span>
                                    <span class="fly-list-nums"><i class="iconfont icon-pinglun1" title="评论"></i> <th:block
                                            th:text="${bbsPostListEntity.postComments}"></th:block></span>
                                </div>
                                <div class="fly-list-badge">
                                </div>
                            </li>
                        </th:block>
                    </ul>
                    <!-- 3.生成分页按钮 -->
                    <div style="text-align: center">
                        <div class="laypage-main">
                            <th:block th:if="${pageResult.currPage>1}">
                                <a class="laypage-prev"
                                   th:href="@{/index(period=${keyword},page=${pageResult.currPage-1},keyword=${keyword},categoryId=${categoryId},orderBy=${orderBy})}">
                                    <<</a>
                            </th:block>
                            <th:block th:if="${pageResult.currPage==1}">
                                <a class="laypage-prev"
                                   href="##">
                                    <<</a>
                            </th:block>
                            <th:block th:if="${pageResult.currPage-2 >=1}">
                                <a class="laypage-prev"
                                   th:href="@{/index(period=${period},page=${pageResult.currPage-2},keyword=${keyword},categoryId=${categoryId},orderBy=${orderBy})}"
                                   th:text="${pageResult.currPage - 2}">1</a>
                            </th:block>
                            <th:block th:if="${pageResult.currPage-1 >=1}">
                                <a class="laypage-prev"
                                   th:href="@{/index(period=${period},page=${pageResult.currPage-1},keyword=${keyword},categoryId=${categoryId},orderBy=${orderBy})}"
                                   th:text="${pageResult.currPage - 1}">1</a>
                            </th:block>
                            <a href="##" class="laypage-curr" th:text="${pageResult.currPage}">1</a>
                            <th:block th:if="${pageResult.currPage+1<=pageResult.totalPage}">
                                <a class="laypage-next"
                                   th:href="@{/index(period=${period},page=${pageResult.currPage+1},keyword=${keyword},categoryId=${categoryId},orderBy=${orderBy})}"
                                   th:text="${pageResult.currPage + 1}">1</a>
                            </th:block>
                            <th:block th:if="${pageResult.currPage+2<=pageResult.totalPage}">
                                <a class="laypage-next"
                                   th:href="@{/index(period=${period},page=${pageResult.currPage+2},keyword=${keyword},categoryId=${categoryId},orderBy=${orderBy})}"
                                   th:text="${pageResult.currPage + 2}">1</a>
                            </th:block>
                            <th:block th:if="${pageResult.currPage<pageResult.totalPage}">
                                <a class="laypage-next"
                                   th:href="@{/index(period=${period},page=${pageResult.currPage+1},keyword=${keyword},categoryId=${categoryId},orderBy=${orderBy})}">
                                    ">>">></a>
                            </th:block>
                            <th:block th:if="${pageResult.currPage==pageResult.totalPage}">
                                <a class="laypage-next"
                                   href="##">
                                    ">>">></a>
                            </th:block>
                        </div>
                    </div>
                </th:block>
            </div>
        </div>
        <div class="layui-col-md4">

            <div class="fly-panel">
                <h3 class="fly-panel-title"></h3>

            </div>
            <!-- 4.渲染本周热议列表 -->
            <dl class="fly-panel fly-list-one">
                <dt class="fly-panel-title">本周热议</dt>
                <th:block th:if="${#lists.isEmpty(hotTopicBBSPostList)}">
                    <!-- 无数据时 -->
                    <div class="fly-none">没有相关数据</div>
                </th:block>
                <th:block th:unless="${#lists.isEmpty(hotTopicBBSPostList)}">
                    <th:block th:each="bbsEntity : ${hotTopicBBSPostList}">
                        <dd>
                            <a th:href="@{'/detail/'+${bbsEntity.postId}}" th:text="${bbsEntity.postTitle}">测试帖子</a>
                            <span><i class="iconfont icon-pinglun1"></i> <th:block
                                    th:text="${bbsEntity.postComments}"></th:block></span>
                        </dd>
                    </th:block>
                </th:block>
            </dl>

            <div class="fly-panel">
                <div class="fly-panel-title">
                    picacho
                </div>
                <div class="fly-panel-main">
                    <a href="" target="_blank">
                        <img style="max-width: 60%;" th:src="@{/images/picacho.jpg}">
                    </a>
                </div>
            </div>

            <div class="fly-panel">
                <div class="fly-panel-title">
                    picacho
                </div>
                <div class="fly-panel-main">
                    <a href="https://item.jd.com/12890115.html" target="_blank">
                        <img style="max-width: 60%;" th:src="@{/images/picacho.jpg}">
                    </a>
                </div>
            </div>

            <div class="fly-panel fly-link">
                <h3 class="fly-panel-title">友情链接</h3>
                <dl class="fly-panel-main">
                    <dd><a href="http://www.layui.com/" target="_blank">layui</a>
                    <dd>
                </dl>
            </div>

        </div>
    </div>
</div>

<div class="fly-footer">
    <p>My-BBS社区 2021 © <a href="https://github.com/ZHENFENG13/My-BBS" target="_blank">picacho</a></p>
</div>

<script th:src="@{/layui/layui.js}"></script>
<script type="text/javascript">
    layui.use(['layer', 'element', 'jquery'], function () {
        var layer = layui.layer, $ = layui.$, element = layui.element;
        var device = layui.device();
        //阻止IE7以下访问
        if (device.ie && device.ie < 8) {
            layer.alert('如果您非得使用 IE 浏览器访问社区,那么请使用 IE8+');
        }
        //搜索
        $('.fly-search').on('click', function () {
            layer.open({
                type: 1
                , title: false
                , closeBtn: false
                //,shade: [0.1, '#fff']
                , shadeClose: true
                , maxWidth: 10000
                , skin: 'fly-layer-search'
                , content: ['<form action="/index">'
                    , '<input autocomplete="off" placeholder="搜索内容,回车跳转" type="text" name="keyword">'
                    , '</form>'].join('')
                , success: function (layero) {
                    var input = layero.find('input');
                    input.focus();
                    layero.find('form').submit(function () {
                        var val = input.val();
                        if (val.replace(/\s/g, '') === '') {
                            return false;
                        }
                        input.val(input.val());
                    });
                }
            })
        });
    });
</script>
</body>
</html>

3. 测试效果

同样由于登陆拦截器,需要先登录才会跳转到index.html。

springboot如何配置首页 springboot项目首页_前端