SpringBoot聚合项目:达内知道(六)-学生发布问题(复用显示标签、富文本编辑器、多选列表)

1.学生发布问题

问答流程介绍:

SpringBoot聚合项目:达内知道(六)-学生发布问题(复用显示标签、富文本编辑器、多选列表)

学生提问功能流程:

SpringBoot聚合项目:达内知道(六)-学生发布问题(复用显示标签、富文本编辑器、多选列表)

1.1 复用显示标签

  我们看到问题发布页也显示所有标签信息,如果再次实现这个功能,会造成代码冗余。我们可以使用Vue模板来复用这个效果,减少冗余。

Vue模板的使用大概分为3个步骤:

  1. 定义模板

  1. 调用模板

  1. 添加引用

定义模板:在js文件夹中创建tags_nav_temp.js文件代码如下:

 /*定义Vue模板,名称为tags-app*/
 Vue.component("tags-app",{
    "props":["tags"],
    "template":`
     <div class="nav font-weight-light"><!--删除id,否则报错-->
         <a href="tag/tag_question.html" class="nav-item nav-link text-info"><small>全部</small></a>
         <a href="tag/tag_question.html"
            class="nav-item nav-link text-info"
            v-for="tag in tags">
           <small v-text="tag.name">Java基础</small></a><!--绑定内容-->
     </div>
    `
 })

调用模板:在需要显示模板中信息的位置编写代码,如在create.html页面186行附近添加代码如下:

 <!--引入标签的导航栏-->
 <div class="container-fluid" >
   <!-- 调用模板 -->
   <!-- tags-app 是模板的名称
       id="tagsApp" 是Vue绑定的id
       :tags对应模板代码中props:["tags"]
       ="tags" 对应的是Vue代码中的data中的tags
       -->
   <tags-app id="tagsApp" :tags="tags"></tags-app>
 </div>

添加引用:首页create.html页面的head标签结束前添加axios的引用

 <!--引入axios框架-->
 <script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js">
 </script>

页面末尾添加引用:

 </body>
 <script src="../js/utils.js"></script><!--..表示返回上一级路径-->
 <script src="../js/tags_nav_temp.js"></script><!--必须先添加模板,后加运行的内容-->
 <script src="../js/tags_nav.js"></script>
 </html>

然后重启服务,就可以看到页面上模板复用的标签列表了。

SpringBoot聚合项目:达内知道(六)-学生发布问题(复用显示标签、富文本编辑器、多选列表)

1.2 富文本编辑器

我们使用的富文本编辑器是summernote。

SpringBoot聚合项目:达内知道(六)-学生发布问题(复用显示标签、富文本编辑器、多选列表)

它的使用很简单,但是功能强大,官方给出的必要依赖如下:

 <link rel="stylesheet" href="../bower_components/bootstrap/dist/css/bootstrap.min.css"> 
 <link rel="stylesheet" href="../bower_components/font-awesome/css/font-awesome.min.css">
 <link rel="stylesheet" href="../bower_components/summernote/dist/summernote-bs4.min.css">  
 <script src="../bower_components/jquery/dist/jquery.min.js"></script>
 <script src="../bower_components/popper.js/dist/umd/popper.min.js"></script>
 <script src="../bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
 <script src="../bower_components/polyfill/dist/polyfill.min.js"></script>
 <script src="../bower_components/summernote/dist/summernote-bs4.js"></script>
 <script src="../bower_components/summernote/dist/lang/summernote-zh-CN.min.js"></script>

它支持我们添加各种常见的样式,甚至支持图片和视频的插入功能,它是怎么启动的呢?一般会定义一个<textarea>,在这个标签中定义id,然后使用summernote规定的固定代码启动。

 $(document).ready(function() {
   $(‘#summernote‘).summernote({
     height: 300,
     tabsize: 2,
     lang: ‘zh-CN‘,
     placeholder: ‘请输入问题的详细描述...‘
  });
 });

页面效果:

SpringBoot聚合项目:达内知道(六)-学生发布问题(复用显示标签、富文本编辑器、多选列表)

1.3 多选列表

  相对于单选的下拉框和复选框,多选列表的用户体验更好,方便用户选择和查看选择结果。我们使用Vue官方提供的一个模板插件来实现多选列表的功能:vue-select(v-select)。

SpringBoot聚合项目:达内知道(六)-学生发布问题(复用显示标签、富文本编辑器、多选列表)

使用该插件要添加必要依赖:

 <link rel="stylesheet"   href="../bower_components/vue-select/dist/vue-select.css"> 
 <script src="../bower_components/vue/dist/vue.js"></script>
 <script src="../bower_components/vue-select/dist/vue-select.js"></script>

绑定多选列表数据:create.html的203行附近有一个div需要添加id

 <div class="col-8" id="createQuestionApp"><!--添加id-->

create.html的213行附近开始,需要绑定多选列表,代码如下:

 <div class="form-group">
   <label >请至少选择一个标签:</label>
   <!-- multiple支持多选 required必须选
  :options为模板中需要的数据赋值,这里是绑定所有选项
  tags是数据库中所有标签
  selectedTags是用户选择的所有标签
   -->
   <v-select multiple required :options="tags"
     v-model="selectedTags" placeholder="请选择问题相关标签">
   </v-select>
 </div>
 <div class="form-group">
   <label >请选择老师:</label>
   <!--下面同上-->
   <v-select multiple required :options="teachers"
             v-model="selectedTeachers" placeholder="请选择回答老师">
   </v-select>
 </div>

js代码已经准备好,页面尾部添加引用:

 </body>
 <script src="../js/utils.js"></script><!--..表示返回上一级路径-->
 <script src="../js/tags_nav_temp.js"></script><!--必须先添加模板,后加运行的内容-->
 <script src="../js/tags_nav.js"></script>
 <!-- ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ -->
 <script src="../js/createQuestion.js"></script><!--一定要添加,否则没有多选列表-->
 </html>

编写绑定所有讲师的代码:从业务逻辑层开始,先在接口IUserService中添加方法:

 //查询所有讲师的方法
 List<User> getTeachers();

再在实现类UserServiceImpl编写实现代码如下:

 @Override
 public List<User> getTeachers() {
     QueryWrapper<User> query=new QueryWrapper();
     query.eq("type",1);//学生类型为0,老师类型为1
     List<User> list=userMapper.selectList(query);
     //千万别忘了返回!!!!
     return list;
 }

控制层UserController添加代码如下,注意之前的两个测试方法可以删除:

 package cn.tedu.knows.portal.controller;
 ?
 import cn.tedu.knows.portal.model.User;
 import cn.tedu.knows.portal.service.IUserService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 ?
 import org.springframework.web.bind.annotation.RestController;
 ?
 import java.util.List;
 ?
 /**
  * <p>
  * 前端控制器
  * </p>
  *
  * @author tedu.cn
  * @since 2021-08-23
  */
 @RestController
 //为今后微服务项目方便起见,根据微服务标准,
 //将@RequestMapping("/portal/user")改为@RequestMapping("/v1/users")
 @RequestMapping("/v1/users")
 public class UserController {
     //控制层调用业务逻辑层
     @Autowired
     private IUserService userService;
 ?
     //查询所有讲师的控制层方法
     @GetMapping("/master")
     public List<User> master(){
         List<User> list = userService.getTeachers();
         return list;
    }
 }
 ?

最终效果:

SpringBoot聚合项目:达内知道(六)-学生发布问题(复用显示标签、富文本编辑器、多选列表)

讲师业务逻辑层添加list和map的缓存:

在IUserService接口添加方法:

 //查询所有讲师的Map
 Map<String,User> getTeacherMap();

修改UserServiceImpl实现类最终代码如下:

 //创建缓存对象
 private List<User> teachers=new CopyOnWriteArrayList<>();//线程安全,存对象
 private Map<String,User> teacherMap=new ConcurrentHashMap<>();//线程安全,存名称和对象
 ?
 //查询所有讲师
 @Override
 public List<User> getTeachers() {
     if(teachers.isEmpty()) {//提高效率
         synchronized (teachers) {//加锁,避免线程并发问题
             if(teachers.isEmpty()) {//再次判断
                 QueryWrapper<User> query = new QueryWrapper();
                 query.eq("type", 1);//学生类型为0,老师类型为1
                 List<User> list = userMapper.selectList(query);
                 teachers.addAll(list);//将查询结果存到线程安全的集合中
                 for (User u:list) {//遍历list,存储Map
                     teacherMap.put(u.getNickname(),u);//注意:选老师选昵称
                }
            }
        }
    }
     //千万别忘了返回!!!!
     return teachers;
 }
 ?
 //查询所有讲师的Map
 @Override
 public Map<String, User> getTeacherMap() {
     if(teacherMap.isEmpty()){//保证效率
  getTeachers();//通过添加list进而给map赋值
  }
     //千万别返回null!!!!
     return teacherMap;
 }

最终效果:

SpringBoot聚合项目:达内知道(六)-学生发布问题(复用显示标签、富文本编辑器、多选列表)

 

SpringBoot聚合项目:达内知道(六)-学生发布问题(复用显示标签、富文本编辑器、多选列表)

上一篇:Android 操作系统的架构


下一篇:iOS 拍照录频画质问题相关