阅读 170

SpringBoot+Vue豆宝社区前后端分离项目手把手实战系列教程23---文章搜索功能实现

豆宝社区项目实战教程简介

本项目实战教程配有免费视频教程,配套代码完全开源。手把手从零开始搭建一个目前应用最广泛的Springboot+Vue前后端分离多用户社区项目。本项目难度适中,为便于大家学习,每一集视频教程对应在Github上的每一次提交。

项目首页截图

image

代码开源地址

前端 后端

视频教程地址

视频教程

前端技术栈

Vue Vuex Vue Router Axios Bulma Buefy Element Vditor DarkReader

后端技术栈

Spring Boot Mysql Mybatis MyBatis-Plus Spring Security JWT Lombok

搜索前端实现

API

src\api\新增search.js

import request from '@/utils/request'

// 关键词检索
export function searchByKeyword(query) {
  return request({
    url: `/search`,
    method: 'get',
    params: {
      keyword: query.keyword,
      pageNum: query.pageNum,
      pageSize: query.pageSize
    }
  })
}
复制代码

路由

src\router\index.js

,
  // 搜索
  {
    name: 'search',
    path: '/search',
    component: () => import('@/views/Search'),
    meta: { title: '检索' }
  }
复制代码

新增Search.vue

src/views/Search

<template>
  <div>
    <el-card shadow="never">
      <div slot="header" class="clearfix">
        检索到 <code>{{ list.length }}</code>
        条关于 <code class="has-text-info">{{ query.keyword }}</code> 的记录
      </div>
      <div>
        <article v-for="(item, index) in list" :key="index" class="media">
          <div class="media-left">
            <figure class="image is-48x48">
              <img :src="`https://cn.gravatar.com/avatar/${item.userId}?s=164&d=monsterid`"> 
            </figure>
          </div>
          <div class="media-content">
            <div class="">
              <p class="ellipsis is-ellipsis-1">
                <el-tooltip class="item" effect="dark" :content="item.title" placement="top">
                  <router-link :to="{name:'post-detail',params:{id:item.id}}">
                    <span class="is-size-6">{{ item.title }}</span>
                  </router-link>
                </el-tooltip>
              </p>
            </div>
            <nav class="level has-text-grey is-mobile  is-size-7 mt-2">
              <div class="level-left">
                <div class="level-left">
                  <router-link class="level-item" :to="{ path: `/member/${item.username}/home` }">
                    {{ item.alias }}
                  </router-link>

                  <span class="mr-1">
                    发布于:{{ dayjs(item.createTime).format("YYYY/MM/DD") }}
                  </span>

                  <span
                    v-for="(tag, index) in item.tags"
                    :key="index"
                    class="tag is-hidden-mobile is-success is-light mr-1"
                  >
                    <router-link :to="{ name: 'tag', params: { name: tag.name } }">
                      {{ "#" + tag.name }}
                    </router-link>
                  </span>

                  <span class="is-hidden-mobile">浏览:{{ item.view }}</span>
                </div>
              </div>
            </nav>
          </div>
          <div class="media-right" />
        </article>
      </div>

      <!--分页-->
      <pagination
        v-show="query.total > 0"
        :total="query.total"
        :page.sync="query.pageNum"
        :limit.sync="query.pageSize"
        @pagination="fetchList"
      />
    </el-card>
  </div>
</template>

<script>
import { searchByKeyword } from '@/api/search'
import Pagination from '@/components/Pagination'
export default {
  name: 'Search',
  components: { Pagination },
  data() {
    return {
      list: [],
      query: {
        keyword: this.$route.query.key,
        pageNum: 1,
        pageSize: 10,
        total: 0
      }
    }
  },
  created() {
    this.fetchList()
  },
  methods: {
    fetchList() {
      searchByKeyword(this.query).then(value => {
        const { data } = value
        this.list = data.records
        this.query.total = data.total
        this.query.pageSize = data.size
        this.query.pageNum = data.current
      })
    }
  }
}
</script>

<style scoped>
</style>
复制代码

搜索后端实现

BmsSearchController

@RestController
@RequestMapping("/search")
public class BmsSearchController  {

    @Resource
    private BmsPostService postService;

    @GetMapping
    public ApiResult<Page<PostVO>> searchList(@RequestParam("keyword") String keyword,
                                              @RequestParam("pageNum") Integer pageNum,
                                              @RequestParam("pageSize") Integer pageSize) {
        Page<PostVO> results = postService.searchByKey(keyword, new Page<>(pageNum, pageSize));
        return ApiResult.success(results);
    }

}
复制代码

BmsPostService

   public Page<PostVO> searchByKey(String keyword, Page<PostVO> page) {
        // 查询话题
        Page<PostVO> iPage = this.baseMapper.searchByKey(page, keyword);
        return iPage;
    }
复制代码

BmsPostMapper.xml

<select id="searchByKey" resultType="com.notepad.blog.domain.vo.PostVO">
        SELECT t.id,
        t.title,
        t.user_id,
        t.comments,
        t.view,
        t.collects,
        t.top,
        t.essence,
        t.create_time,
        t.modify_time,
        u.username,
        u.alias,
        u.avatar
        FROM bms_post t
        LEFT JOIN ums_user u
        ON t.user_id = u.id
        <where>
            <if test="keyword!=null">
                and t.title like CONCAT('%','${keyword}')
                or t.title like CONCAT('${keyword}','%')
                or t.title like CONCAT('%','${keyword}','%')
                or t.title = #{keyword}
            </if>
        </where>
        order by t.view desc, t.create_time desc
    </select>
复制代码
文章分类
阅读
文章标签