zoukankan      html  css  js  c++  java
  • 基于SpringBoot打造在线教育系统(5)-- 课程分类模块

    1.做一个菜单

    左侧我们需要做一个菜单,还是用elementUI,container容器有一个aside可以用,稍微改一下代码:

    <el-container>
    	  <el-aside width="200px">Aside</el-aside>
    	   <el-main>Main</el-main>
    </el-container>
    

    效果:

    左侧边界,放置一个菜单,作为一类课程。
    改造一下aside:

    <el-aside width="200px">
      <el-menu
       default-active="2"
       class="el-menu-vertical-demo"
       >
       <el-submenu index="1">
         <template slot="title">
           <span>Java基础</span>
         </template>
        </el-submenu>
        <el-submenu index="1">
         <template slot="title">
           <span>Java中级</span>
         </template>
        </el-submenu>
        <el-submenu index="1">
         <template slot="title">
           <span>Spring框架</span>
         </template>
        </el-submenu>
     </el-menu>
    

    不要那个箭头,因为二级菜单我打算显示在右边,于是手动加一段css:

    	.el-submenu i {
    		display:none;
     	}
    

    好了,接下来就该去设计Type表了。

    2. 三级分类

    我们的课程是三级(不是三级片的那个三级),分别为一级课程,二级课程,三级课程。

    二话不说,咱直接建表。

    package com.edu.entity;
    
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.Id;
    
    import org.hibernate.annotations.GenericGenerator;
    
    @Entity
    public class Type {
    
    	@Id
    	@GenericGenerator(name="idGenerator", strategy="uuid") //这个是hibernate的注解/生成32位UUID
        @GeneratedValue(generator="idGenerator")
    	private String id;
    	
    	private Integer level; //课程等级
    	
    	private String pid; //父节点
    	
    	private String typeName;//课程名称
    
    	public String getId() {
    		return id;
    	}
    
    	// 省略 getters 和 setters
    
    

    然后,需要在原来的TypeController里面完善add方法,先去弄一个Dao。

    代码:

    package com.edu.dao;
    
    import org.springframework.data.jpa.repository.JpaRepository;
    import com.edu.entity.Type;
    
    public interface TypeDao  extends JpaRepository<Type, String> {
    
    }
    

    注入Controller

    @Autowired
    TypeDao typeDao;
    

    野路子了,不用service,直接用dao了,大家不要学我啊。

    重写后的add方法:

        @RequestMapping("/add")
    	@ResponseBody
    	public Map<String,Object> add(Type type){
    		Map<String,Object> result = new HashMap<>();
    		result.put("code",0);
    		
    		System.out.println("本次新增的类型是" + type);
    		typeDao.save(type);
    		
    		return result;
    	}
    

    然后做测试类:

    package com.edu.test;
    
    import org.junit.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    
    import com.edu.controller.TypeController;
    import com.edu.entity.Type;
    
    public class TypeTest extends BaseTest{
    
    	@Autowired
    	TypeController typeController;
    	
    	@Test
    	public void addType(){
    		Type type = new Type();
    		type.setLevel(1); //一级课程
    		type.setPid("0");
    		type.setTypeName("Java基础课程");
    		
    		typeController.add(type);
    	}
    }
    

    没想到吧,Controller也可以注入,哈哈,我也是突发奇想,毕竟以前咱都没这么干过不是。

    测试通过,数据进去了。

    ID生成策略改成了UUID。

    接下来,我们要在前端搞事情了。

    3. 用layui做个弹窗

    直接在页面上加一个新增按钮,其实也就是一个菜单。

    <el-submenu  index="999">
    	<template slot="title">
    	<span>新增</span>
    	</template>
    </el-submenu>
    

    index设置为999,为什么呢?

    因为我仍性啊!没想到吧~~

    。。。。。。

    开玩笑,是因为这个新增,我们打算当做按钮的,是一个业务上的东西,所以就取一个大点的值,999挺好的,当然998也不错。

    接下来,我们需要给menu添加一个open事件:

     @open="addMenu"
    

    然后在vue里面编写对应的函数:

     methods:{
      addMenu: function(index){
    	  alert(index);
      }
     }
    

    index就是submenu的index,比如,刚才的999,哈哈哈哈哈。

    如果点的菜单是999,我们就去做增加操作,嗯,就酱。

    点击新增,我们应该弹出一个窗口,让我们输入菜单的名字,这个窗口,私以为用layui更好一些。。。
    导入资源:

    <link rel="stylesheet" href="${basePath}/layui/css/layui.css"  media="all">
    
    <script src="${basePath}/layui/layui.all.js" charset="utf-8"></script>
    

    接下来,我们需要专门做一个div,作为这个新增页面,里面放一个form。

    	  <div id="typebox" style="display:none;margin:20px;">
    		<el-form :model="typeForm" status-icon :rules="rules" ref="typeForm" label-width="100px" class="demo-ruleForm">
    		  
    		  <el-form-item label="类型名称" prop="typeName">
    		    <el-input type="text" v-model="typeForm.typeName" autocomplete="off"></el-input>
    		  </el-form-item>
    		  
    		  <el-form-item>
    		    <el-button type="primary" @click="submitForm('typeForm')">提交</el-button>
    		    <el-button @click="resetForm('typeForm')">重置</el-button>
    		  </el-form-item>
    		</el-form>
    		
    	  </div>
    

    代码有点多,为了防止截屏遗漏,干脆全部贴上来:

        new Vue({
          el: '#app',
          data: function() {
            return { 
            	keywords:'',
            	
            	typeForm:{
            		typeName:''
            	},
            	
            	 //类型表单控制规则
                rules: {
                	typeName: [
                      { required: true, message: '请输入类型名称', trigger: 'blur' }
                    ]
                    
                  }
            }
            
           
          },
          methods:{
        	  addMenu: function(index){
        		  if(index == 999){
        			  layer.open({
        					type : 1,
        					area : [ '500px', '300px' ],
        					content : $('#typebox')
        				});
        		  }
        	  },
        	  
        	  submitForm(formName) {
       	        this.$refs[formName].validate((valid) => {
       	          if (valid) {
       	            alert('submit!');
       	          } else {
       	            console.log('error submit!!');
       	            return false;
       	          }
       	        });
       	      },
       	      
       	      resetForm(formName) {
       	        this.$refs[formName].resetFields();
       	      }
        	      
          },
          
          created:function(){
        	  
          }
        })
        
        layui.use("layer", function() {
    		window.layer = layui.layer;
    		
    	});
    

    逻辑还是比较简明的吧,当然了,你得有vue和element的基础。如果实在对这个一点都不清楚,那就先看个大概吧,反正我们学习的重点还是SpringBoot,所以也不必太纠结。

    我也是抄的API,其实。

    4.还是jquery的ajax香啊

    没错,还是用ajax,我不打算用axios,既然有jquery,那就用jq的ajax吧。

    <script src="${basePath}/js/jquery.js"></script>
    

    到这一步,就要提交数据了,一个typeName是我们自己填写的,不管了直接提交上去吧,就用ajax。

    //我们用jquery的ajax做提交
    	  $.post("${basePath}/type/add",this.typeForm,function(data){
    		  if(data.code < 0){
    			layer.alert('天啦撸,竟然提交失败了:' + data.msg, {
    				icon: 5,
    				title: "提示"
    				});
    			return;
    		  }
    		layer.msg("新增类型成功了~");
    	  });
    

    还是一样的配方,一样的味道,这丝滑的体验。虽然肯定会有人说我太古板,都什么年代了,还用jQuery。但是抵不住我的热爱啊。

    哦对了,顺带提一嘴,add方法要添加这么一段逻辑。

    //如果没有pid,说明是一级课程分类
    if(type.getPid() == null){
    	type.setLevel(1);
    	type.setPid("0");
    }
    


    爽了不?

    贼爽啊。

    5. 重新加载菜单

    现在我们的菜单是写死的,当然不行啦,我们得用后台真实的数据,不要怂,盘他!

    加一个list方法:

    	@RequestMapping("/list")
    	@ResponseBody
    	public Map<String,Object> list(Type type){
    		Map<String,Object> result = new HashMap<>();
    		result.put("code",0);
    		
    		//如果id为空,说明是加载一级课程分类
    		if(type.getId() == null){
    			type.setPid("0"); //我们规定一级分类的父ID是0
    		}
    		
    		List<Type> findByPid = typeDao.findByPid(type.getPid());
    		
    		result.put("data", findByPid);
    		return result;
    	}
    

    findByPid方法是在Dao里面的,JPA的这种奇技淫巧前面已经写过了,这边不再赘述。

    页面写一个查询的方法,现在还不够完善,后面慢慢弄。其实,vue也挺繁琐的,没有jquery来得简单粗暴。

           listType:function(){
       	    	//查询请求一般用get
       	    	$.get("${basePath}/type/list",{},function(data){
    				  if(data.code < 0){
    					layer.alert('天啦撸,竟然查询失败了:' + data.msg, {
    						icon: 5,
    						title: "提示"
    						});
    					return;
    				  }
    				console.log(data);
    			  });
       	      },
    

    再去created里面调用这个方法:

    created:function(){
       this.listType();
    }
    

    看下效果:

    数据拿到了,开始做数据绑定。

    去遍历:

              <div v-for="type in types01">
    			   <el-submenu :index="type.id">
    			     <template slot="title">
    			       <span>{{type.typeName}}</span>
    			     </template>
    			    </el-submenu>
    		   </div>
    

    结果一片空白,原因是ajax回调方法里面有个this指向问题,当然了,你可以使用箭头函数。不过为了兼容所有浏览器,我们还是老老实实写 var that=this 吧。嗯,这里我是故意写错的,为的是提醒大家注意这个小细节。(掩饰自己刚刚真的忘记了)

    刷新页面,这次可以看到数据出来了。

    美化一下新增按钮:

    	<el-submenu index="999" style="text-align:center;border:1px dotted #666;">
         <template slot="title">
           <span style="font-size:50px;color:#666;">+</span>
         </template>
        </el-submenu>
    

    其实现在还有一个bug,原本这个菜单是折叠的,点一下是开,再点一下就是关。那么我们设置的open方法,就是奇数点击的时候才会生效。

    写到这里我才发现,貌似我自己写个菜单更方便???

    额,既然用了el-menu,咱就用到底吧。解决思路也很简单啊,那就是我每次点击的时候,再把它关掉,不就好了吗,哈哈哈,我可真是个小机灵鬼。

    addMenu这个方法名也不恰当,改成clickMenu吧。

    哦哦对了,每次新增完毕的时候,我们得把那个窗口关掉,再重新加载菜单数据。

    今天代码较多,也较复杂,如果跟着做不出来,可以加群,下载本节源码比对哦。【java小白翻身】 -- 公号

  • 相关阅读:
    终止线程的三种方法
    spring bean scope 的几种类型
    耦合(软件工程)
    标签防止重复提交
    Struts2中的ognl标签
    struts2
    SQL PRIMARY KEY 约束:使用方法及撤销办法解析
    SQL UNIQUE 约束:使用方法及撤销办法剖析
    SQL NOT NULL 约束:语法及案例剖析
    SQL 约束(Constraints):语法及实例剖析
  • 原文地址:https://www.cnblogs.com/skyblue-li/p/14260001.html
Copyright © 2011-2022 走看看