微服务[学成在线] day07:课程管理开发

学成在线day07,课程管理实战,PageHelper 分页插件原理,数据字典,课程基本信息和营销信息的修改 需求1:需要分页显示,我的课程,并且显示图片,(暂时不用显示图片) 要求做出来的效果: 上边的查询要实现分页、会存在多表关联查询,所以建议使用mybatis实现我的课程查询。 1.2 API 接口 输入参数: 页码、每页显示个数、查询条件 输出结果类型: QueryResponseResult,这里面包括,操作状态的代码,和分页数据响应 @GetMapping("/coursebase/lis... 阅读详情

😎 知识点概览

为了方便后续回顾该项目时能够清晰的知道本章节讲了哪些内容,并且能够从该章节的笔记中得到一些帮助,所以在完成本章节的学习后在此对本章节所涉及到的知识点进行总结概述。

本章节为【学成在线】项目的 day07 的内容

  • 对课程管理的CRUD
  • 级联菜单
  • 使用 mongoDB 储存数据字典

目录

内容会比较多,小伙伴们可以根据目录进行按需查阅。

一、课程查询

0x01 需求分析

课程添加完成后可通过我的课程进入课程修改页面,此页面显示我的课程列表,如下图所示,可分页查询。

image-20200403212250200

上边的查询要实现分页、会存在多表关联查询,所以建议使用mybatis实现我的课程查询。

0x02 定义API接口

输入参数:页码、每页显示个数、查询条件

输出结果类型:QueryResponseResult<自定义类型>,在 api 工程创建 course 包,创建CourseControllerApi 接口。

@Api(value="课程管理API",description = "用于对课程的增删查改")
public interface CourseControllerApi {
	    @ApiOperation("分页查询课程列表1")
    public QueryResponseResult findCourseList(int page, int size, CourseListRequest courseListRequest);
}

0x03 课程管理服务

PageHelper

PageHelper 是 mybatis 的通用分页插件,通过 mybatis 的拦截器实现分页功能,拦截sql查询请求,添加分页语句,最终实现分页查询功能。

我的课程具有分页功能,本项目使用 Pagehelper 实现 Mybatis 分页功能开发,由于本项目使用 springboot 开发,在 springboot 上集成 pagehelper(https://github.com/pagehelper/pagehelper-spring-boot)PageHelper 的使用方法及原理如下:

  • 在调用 dao 的 service 方法中设置分页参数:PageHelper.startPage(page, size),分页参数会设置在 ThreadLocal 中
  • PageHelper 在 mybatis 执行 sql 前进行拦截,从 ThreadLocal 取出分页参数,修改当前执行的 sql 语句,添加分页 sql。
  • 最后执行添加了分页sql的 sql语句,实现分页查询。

image-20200403213815138

1)添加依赖

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper‐spring‐boot‐starter</artifactId>
    <version>1.2.4</version>
</dependency>

2)配置pageHelper

pagehelper:
  helper‐dialect: mysql

Dao

1)mapper 接口

import com.github.pagehelper.Page;
import com.xuecheng.framework.domain.course.CourseBase;
import com.xuecheng.framework.domain.course.ext.CourseInfo;
import com.xuecheng.framework.domain.course.request.CourseListRequest;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface CourseMapper {
    CourseBase findCourseBaseById(String id);
    Page<CourseInfo> findCourseListPage(CourseListRequest courseListRequest);
}

2)mapper.xml映射文件

<select id="findCourseListPage" resultType="com.xuecheng.framework.domain.course.ext.CourseInfo"
        parameterType="com.xuecheng.framework.domain.course.request.CourseListRequest">
    SELECT
    course_base.*,
    (SELECT pic FROM course_pic WHERE courseid = course_base.id) pic
    FROM
    course_base
</select>
  1. 测试dao
//测试分页
@Test
public void testPageHelper(){
    PageHelper.startPage(2, 1);
    CourseListRequest courseListRequest = new CourseListRequest();
    Page<CourseInfo> courseListPage = courseMapper.findCourseListPage(courseListRequest);
    List<CourseInfo> result = courseListPage.getResult();
    System.out.println(courseListPage);
}

测试前修改日志级别为debug,并跟踪运行日志,发现sql语句中已经包括分页语句。

Service

定义CourseService.java类,用于课程管理的service定义:

 /**
     * 分页查询课程信息
     */
    public QueryResponseResult findCourseList(int pageNum, int size, CourseListRequest courseListRequest){
        if(pageNum<=0){
            pageNum = 0;
        }
        if(size<=0){
            size = 20;
        }
        PageHelper.startPage(pageNum,size);  //设置分页参数
        Page<CourseBase> courseList = courseMapper.findCourseList(courseListRequest);
        QueryResult queryResult = new QueryResult();
        queryResult.setList(courseList.getResult());
        queryResult.setTotal(courseList.getTotal());
        return new QueryResponseResult(CommonCode.SUCCESS,queryResult);
    }

Controller

@RestController
@RequestMapping("/course")
public class CourseController implements CourseControllerApi {
    @Autowired
    CourseService courseService;
    @Override
    @GetMapping("/coursebase/list/{page}/{size}")
    public QueryResponseResult<CourseInfo> findCourseList(
            @PathVariable("page") int page,
            @PathVariable("size") int size,
            CourseListRequest courseListRequest) {
        return courseService.findCourseList(page,size,courseListRequest);
    }
}

测试

使用 postman 或 swagger-ui 测试课程列表接口。

0x04 前端开发

页面编写

创建 ourse_list.vue

1)使用element 的card组件

image-20200403214719252

页面布局代码如下:

<template>
  <section>
    <el‐row >
      <el‐col :span="8"  :offset=2 >
        <el‐card :body‐style="{ padding: '10px' }">
          <img src="/static/images/add.jpg" class="image" height="150px">
          <div style="padding: 10px;">
            <span>课程名称</span>
            <div class="bottom clearfix">
              <time class="time"></time>
              <router‐link class="mui‐tab‐item" :to="{path:'/course/add/base'}">
                  <el‐button type="text" class="button" >新增课程</el‐button>
              </router‐link>
            </div>
          </div>
        </el‐card>
      </el‐col>
      <el‐col :span="8" v‐for="(course, index) in courses" :key="course.id" :offset="index > 0 ?
2 : 2">
        <el‐card :body‐style="{ padding: '10px' }">
          <img :src="course.pic!=null?imgUrl+course.pic:'/static/images/nonepic.jpg'"
class="image" height="150px">
          <div style="padding: 10px;">
           <span>{{course.name}}</span>
            <div class="bottom clearfix">
              <time class="time"></time>
              <el‐button type="text" class="button" @click="handleManage(course.id)">管理课程
</el‐button>
            </div>
          </div>
        </el‐card>
      </el‐col>
      <!‐‐分页‐‐>
      <el‐col :span="24" class="toolbar">
        <el‐pagination background layout="prev, pager, next" @current‐
change="handleCurrentChange" :page‐size="size"
                       :total="total" :current‐page="page"
                       style="float:right;">
        </el‐pagination>
      </el‐col>
    </el‐row>
  </section>
</template>
<script>
  import * as courseApi from '../api/course';
  import utilApi from '../../../common/utils';
  let sysConfig = require('@/../config/sysConfig')
  export default {
    data() {
      return {
        page:1,
        size:7,
        total: 0,
        courses: [],
        sels: [],//列表选中列
        imgUrl:sysConfig.imgUrl
      }
    },
    methods: {
        //分页方法
      handleCurrentChange(val) {
        this.page = val;
      },
      //获取课程列表
      getCourse() {
      
      },
      handleManage: function (id) {
        console.log(id)
        this.$router.push({ path: '/course/manager/'+id})
      }
    },
    created(){
     },
    mounted() {
    }
  }
</script>
<style scoped>
  .el‐col‐8{
    width:20%
  }
  .el‐col‐offset‐2{
    margin‐left:2%
  }
  .time {
    font‐size: 13px;
    color: #999;
  }
  .bottom {
    margin‐top: 13px;
    line‐height: 12px;
  }
  .button {
    padding: 0;
    float: right;
  }
  .image {
    width: 100%;
    display: block;
  }
  .clearfix:before,
  .clearfix:after {
    display: table;
    content: "";
  }
  .clearfix:after {
    clear: both
  }
</style> 

2)路由

import course_list from '@/module/course/page/course_list.vue';
import Home from '@/module/home/page/home.vue';
export default [
  {
     path: '/course',
    component: Home,
    name: '课程管理',
    hidden: false,
    iconCls: 'el‐icon‐document',
    children: [
      { path: '/course/list', name: '我的课程',component: course_list,hidden: false }
    ]
  }
]

Api调用

1、定义Api方法

//我的课程列表
export const findCourseList = (page,size,params) => {
     //对于查询条件,向服务端传入key/value串。
     //使用工具类将json对象转成key/value
     let queries = querystring.stringify(params)
    return http.requestQuickGet(apiUrl+"/course/coursebase/list/"+page+"/"+size+"?"+queries);
}

2、在页面调用 findCourseList 方法

//获取课程列表
getCourse() {
  courseApi.findCourseList(this.page,this.size,{}).then((res) => {
          console.log(res);
          if(res.success){
            this.total = res.queryResult.total;
            this.courses = res.queryResult.list;
          }
  });
}

在 mounted 钩子中调用 getCourse 方法

mounted() {
  //查询我的课程
  this.getCourse();
}

在分页方法中调用 getCourse 方法

 //分页方法
handleCurrentChange(val) {
  this.page = val;
  this.getCourse();
},

1测试

页面效果如下:

注意:由于课程图片服务器没有搭建,这里图片暂时无法显示。

image-20200403215009200

二、新增课程

0x01 需求分析

用户操作流程如下:

1、用户进入“我的课程”页面,点击“新增课程”,进入新增课程页面

image-20200403215030231

2、填写课程信息,选择课程分类、课程等级、学习模式等。

3、信息填写完毕,点击“提交”,课程添加成功或课程添加失败并提示失败原因。

需要解决的是在新增页面上输入的信息:

1、课程分类 多级分类,需要方便用户去选择。

2、课程等级、学习模式等这些选项建议是可以配置的。

0x02 课程分类查询

介绍

在新增课程界面需要选择课程所属分类, 分类信息是整个项目非常重要的信息,课程即商品,分类信息设置的好坏直接影响用户访问量。

分类信息在哪里应用?

1、首页分类导航

image-20200403215130650

2 、课程的归属地

添加课程时要选择课程的所属分类。

数据结构

分类表 category 的结构如下

image-20200403215159778

分类查询

1)数据格式

在添加课程时需要选择课程所属的分类,这里需要定义课程分类查询接口。

接口格式要根据前端需要的数据格式来定义,前端展示课程分类使用 elemenet-ui 的cascader(级联选择器)组件。

image-20200403215240113

数据格式例子如下:

[
  {
        value: 'zhinan',
        label: '指南',
        children: [{
          value: 'shejiyuanze',
          label: '设计原则',
          children: [{
            value: 'yizhi',
            label: '一致'
          }, {
            value: 'fankui',
            label: '反馈'
          }, {
            value: 'xiaolv',
            label: '效率'
          }, {
            value: 'kekong',
            label: '可控'
          }]
        }]
  }
]
2)数据模型

1)定义category的模型

category 模型对数据字段对应,如下:

@Data
@ToString
@Entity
@Table(name="category")
@GenericGenerator(name = "jpa‐assigned", strategy = "assigned")
public class Category implements Serializable {
    private static final long serialVersionUID = ‐906357110051689484L;
    @Id
    @GeneratedValue(generator = "jpa‐assigned")
    @Column(length = 32)
    private String id;
    private String name;
    private String label;
    private String parentid;
    private String isshow;
    private Integer orderby;
    private String isleaf;
}

2)定义数据返回格式

@Data
@ToString
public class CategoryNode extends Category {
    List<CategoryNode> children;
}

级联菜单属于三级菜单,所以每个菜单下面都会有一个 chaidren 的字段

3)API 接口
package com.xuecheng.api.web.controller.api.course;
import com.xuecheng.framework.domain.course.ext.CategoryNode;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Api(value = "课程分类管理",description = "课程分类管理",tags = {"课程分类管理"})

public interface CategoryControllerApi {
    @ApiOperation("查询分类")
    public CategoryNode findList();
}

4)DAO

1)定义mapper

@Mapper
public interface CategoryMapper {
    //查询分类
    public CategoryNode selectList();
}

2)定义mapper映射文件

采用表的自连接方式输出树型结果集。

<?xml version="1.0" encoding="UTF‐8" ?>
<!DOCTYPE mapper PUBLIC "‐//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis‐3‐
mapper.dtd" >
<mapper namespace="com.xuecheng.manage_course.dao.CategoryMapper" >
    <resultMap type="com.xuecheng.framework.domain.course.ext.CategoryNode" id="categoryMap" >
        <id property="id" column="one_id"/>
        <result property="name" column="one_name"/>
        <result property="label" column="one_label"/>
        <result property="isshow" column="one_isshow"/>
        <result property="isleaf" column="one_isleaf"/>
        <result property="orderby" column="one_orderby"/>
        <result property="parentid" column="one_parentid"/>
        <collection property="children"
ofType="com.xuecheng.framework.domain.course.ext.CategoryNode">
            <id property="id" column="two_id"/>
            <result property="name" column="two_name"/>
            <result property="label" column="two_label"/>
            <result property="isshow" column="two_isshow"/>
            <result property="isleaf" column="two_isleaf"/>
            <result property="orderby" column="two_orderby"/>
            <result property="parentid" column="two_parentid"/>
            <collection property="children"
ofType="com.xuecheng.framework.domain.course.ext.CategoryNode">
                <id property="id" column="three_id"/>
                <result property="name" column="three_name"/>
                <result property="label" column="three_label"/>
                <result property="isshow" column="three_isshow"/>
                <result property="isleaf" column="three_isleaf"/>
                <result property="orderby" column="three_orderby"/>
                <result property="parentid" column="three_parentid"/>
            </collection>
        </collection>
    </resultMap>
    <select id="selectList" resultMap="categoryMap" >
        SELECT
          a.id one_id,
          a.name one_name,
          a.label one_label,
          a.isshow one_isshow,
          a.isleaf one_isleaf,
          a.orderby one_orderby,
          a.parentid one_parentid,
          b.id two_id,
          b.name two_name,
          b.label two_label,
          b.isshow two_isshow,
          b.isleaf two_isleaf,
          b.orderby two_orderby,
          b.parentid two_parentid,
          c.id three_id,
          c.name three_name,
          c.label three_label,
          c.isshow three_isshow,
          c.isleaf three_isleaf,
          c.orderby three_orderby,
          c.parentid three_parentid
        FROM
          category a LEFT JOIN category b
            ON a.id = b.parentid
          LEFT JOIN category c
            ON b.id = c.parentid
        WHERE a.parentid = '0'
      
        ORDER BY a.orderby,
          b.orderby,
          c.orderby
   </select>
</mapper>
5)Service
@Service
public class CategoryService {
    @Autowired
    CategoryMapper categoryMapper;
    //查询分类
    public CategoryNode findList(){
        return categoryMapper.selectList();
    }
}
6)Controller
@RestController
@RequestMapping("/category")
public class CategoryController implements CategoryControllerApi {
    @Autowired
    CategoryService categoryService;
   
    @Override
    @GetMapping("/list")
    public CategoryNode list() {
        return categoryService.findList();
    }
}
7)接口测试

接口描述如下

image-20200403215645362

使用swagger-ui或postman测试接口。

image-20200403215654115

0x03 数据字典

介绍

在新增课程界面需要选择课程等级、课程状态等,这些信息统一采用数据字典管理的方式。
本项目对一些业务的分类配置信息,比如:课程等级、课程状态、用户类型、用户状态等进行统一管理,通过在数据库创建数据字典表来维护这些分类信息。

数据字典对系统的业务分类进行统一管理,并且也可以解决硬编码问题,比如添加课程时选择课程等级,下拉框中的课程等级信息如果在页面硬编码将造成不易修改维护的问题,所以从数据字典表中获取,如果要修改名称则在数据字典修改即可,提高系统的可维护性。

数据模型

在 mongodb 中创建数据字典表 sys_dictionary

image-20200403220146001

一个字典信息如下

 {
"_id" : ObjectId("5a7e8d2dd019f15418fa2b71"),
"d_name" : "课程等级",
"d_type" : "200",
"d_value" : [
    {
        "sd_name" : "低级",
        "sd_id" : "200001",
        "sd_status" : "1"
    },
    {
        "sd_name" : "中级",
        "sd_id" : "200002",
        "sd_status" : "1"
    },
    {
        "sd_name" : "高级",
        "sd_id" : "200003",
        "sd_status" : "1"
    }
]
}

字段说明如下:

d_name:字典名称

d_type:字典分类

d_value:字典数据

sd_name:项目名称

sd_id:项目id

sd_status:项目状态(1:可用,0不可用)

数据模型类:

@Data
@ToString
@Document(collection = "sys_dictionary")
public class SysDictionary {
    @Id
    private String id;
    @Field("d_name")
    private String dName;
    @Field("d_type")
    private String dType;
    @Field("d_value")
    private List<SysDictionaryValue> dValue;
}

SysDictionaryValue 类型:

@Data
@ToString
public class SysDictionaryValue {
    @Field("sd_id")
    private String sdId;
    @Field("sd_name")
    private String sdName;
    @Field("sd_status")
    private String sdStatus;
}

字典查询接口

API接口

为了方便其它子系统使用,在cms模块下创建字典查询接口,根据字典的type查询字典信息,接口定义如下:

@Api(value = "数据字典接口",description = "提供数据字典接口的管理、查询功能")
public interface SysDicthinaryControllerApi {
    //数据字典
    @ApiOperation(value="数据字典查询接口")
    public SysDictionary getByType(String type);
}
Dao

在cms模块下创建数据库的dao、service等类。

@Repository
public interface SysDictionaryDao extends MongoRepository<SysDictionary,String> {
     //根据字典分类查询字典信息
     SysDictionary findBydType(String dType);
}
Service
@Service
public class SysdictionaryService {
    @Autowired
    SysDictionaryDao sysDictionaryDao;
//根据字典分类type查询字典信息    
   public SysDictionary findDictionaryByType(String type){
       return sysDictionaryDao.findBydType(type);
   }
}
Controller
@RestController
@RequestMapping("/sys/dictionary")
public class SysDictionaryController implements SysDictionaryControllerApi {
    @Autowired
    SysdictionaryService sysdictionaryService;
    //根据字典分类id查询字典信息
    @Override
    @GetMapping("/get/{type}")
    public SysDictionary getByType(@PathVariable("type") String type) {
        return sysdictionaryService.findDictionaryByType(type);
    }
}
测试

image-20200403220513616

0x04 新增课程页面完善

本节完成数据字典显示及课程分类显示。

新增课程页面

1)页面效果如下:

image-20200403220536863

2)创建 course_add.vue 页面

在teach 前端工程的 course 模块下创建 course_add.vue 页面。

<template>
  <div>
    <el‐form :model="courseForm" label‐width="80px" :rules="courseRules" ref="courseForm">
      <el‐form‐item label="课程名称" prop="name">
        <el‐input v‐model="courseForm.name" auto‐complete="off" ></el‐input>
      </el‐form‐item>
      <el‐form‐item label="适用人群" prop="users">
        <el‐input type="textarea" v‐model="courseForm.users" auto‐complete="off" ></el‐input>
      </el‐form‐item>
      <el‐form‐item label="课程分类" prop="categoryActive">
        <el‐cascader
          expand‐trigger="hover"
          :options="categoryList"
          v‐model="categoryActive"
          :props="props">
        </el‐cascader>
      </el‐form‐item>
      <el‐form‐item label="课程等级" prop="grade">
        <b v‐for="grade in gradeList">
          <el‐radio v‐model="courseForm.grade" :label="grade.sdId" >{{grade.sdName}}</el‐
radio>&nbsp;&nbsp;
        </b>
      </el‐form‐item>
      <el‐form‐item label="学习模式" prop="studymodel">
        <b v‐for="studymodel_v in studymodelList">
          <el‐radio v‐model="courseForm.studymodel" :label="studymodel_v.sdId" >
{{studymodel_v.sdName}}</el‐radio>&nbsp;&nbsp;
        </b>
      </el‐form‐item>
      <el‐form‐item label="课程介绍" prop="description">
        <el‐input type="textarea" v‐model="courseForm.description" ></el‐input>
      </el‐form‐item>
    </el‐form>
    <div slot="footer" class="dialog‐footer">
      <el‐button type="primary"  @click.native="save" >提交</el‐button>
    </div>
  </div>
</template>
<script>
  import * as courseApi from '../api/course';
  import utilApi from '../../../common/utils';
  import * as systemApi from '../../../base/api/system';
  export default {
    data() {
      return {
             studymodelList:[],
        gradeList:[],
        props: {
          value: 'id',
          label:'label',
          children:'children'
        },
        categoryList: [],
        categoryActive:[],
        courseForm: {
          id:'',
          name: '',
          users: '',
          grade:'',
          studymodel:'',
          mt:'',
          st:'',
          description: ''
        },
        courseRules: {
          name: [
            {required: true, message: '请输入课程名称', trigger: 'blur'}
          ],
          category: [
            {required: true, message: '请选择课程分类', trigger: 'blur'}
          ],
          grade: [
            {required: true, message: '请选择课程等级', trigger: 'blur'}
          ],
          studymodel: [
            {required: true, message: '请选择学习模式', trigger: 'blur'}
          ]
        }
      }
    },
    methods: {
      save () {
      }
    },
    created(){
    },
    mounted(){
    }
  }
</script>
<style scoped>
</style>
3)页面路由
 import course_add from '@/module/course/page/course_add.vue'; 
     { path: '/course/add/base', name: '添加课程',component: course_add,hidden: true },
4)课程添加链接

在我的课程页面添加“新增课程”链接
在 course_list.vue 中添加

<router‐link class="mui‐tab‐item" :to="{path:'/course/add/base'}"> 
    <el‐button type="text" class="button" >新增课程</el‐button>
</router‐link>

查询数据字典

课程添加页面中课程等级、学习模式需要从数据字典查询字典信息。

1)定义方法

数据字典查询 为公用方法,所以定义在 /base/api/system.js 中

let sysConfig = require('@/../config/sysConfig') 
let apiUrl = sysConfig.xcApiUrlPre;
/*数据字典 */
export const sys_getDictionary= dType => {
  return http.requestQuickGet(apiUrl+'/sys/dictionary/get/'+dType)
}

2)在页面获取数据字典

在 mounted 钩子中定义方法如下:

// 查询数据字典字典
systemApi.sys_getDictionary('201').then((res) => {
this.studymodelList = res.dvalue;
});
systemApi.sys_getDictionary('200').then((res) => {
this.gradeList = res.dvalue;
});

3)效果

image-20200403221002719

课程分类

课程添加页面中课程分类采用 Cascader 组件完成。

Cascader 级联选择器

image-20200403221022081

1)页面

<el‐form‐item label=" 课程分类" prop="categoryActive">
  <el‐cascader
    expand‐trigger="hover"
    :options="categoryList"
    v‐model="categoryActive"
    :props="props">
  </el‐cascader>
</el‐form‐item>

2)定义方法
在本模块的course.js中定义

/* 查询课程分类 */
export const category_findlist= () => {
  return http.requestQuickGet(apiUrl+'/category/list')
}

3)在页面获取课程分类

在 mounted 钩子中定义

// 取课程分类
courseApi.category_findlist({}).then((res) => {
  this.categoryList = res.children;
});

4)效果

image-20200403221132985

5) 如何获取选择的分类

用户选择课程分类后,所选分类 ID 绑定到 categoryActive(数组)中,选择了一级、二级分类,分别存储在 categoryActive 数组的第一个、第二个元素中。

0x05 新增课程服务端

API接口

创建课程添加提交接口:

@Api(value = " 课程管理",description = "课程管理",tags = {"课程管理"})
public interface CourseControllerApi {
  
    @ApiOperation("添加课程基础信息")
    public AddCourseResult addCourseBase(CourseBase courseBase);
}

Dao

public interface CourseBaseRepository extends JpaRepository<CourseBase, String> { 
       
}

Service

  // 添加课程提交
    @Transactional
    public AddCourseResult addCourseBase(CourseBase courseBase) {
        //课程状态默认为未发布
        courseBase.setStatus("202001");
        courseBaseRepository.save(courseBase);
       return new AddCourseResult(CommonCode.SUCCESS,courseBase.getId());
    }

Controller

@Override 
    @PostMapping("/coursebase/add")
    public AddCourseResult addCourseBase(@RequestBody CourseBase courseBase) {
        return courseService.addCourseBase(courseBase);
    }

0x06 新增课程前端

Api方法定义

在前端定义请求服务端添加课程的api的方法,在course模块中定义方法如下:

/* 添加课程基础信息*/
export const addCourseBase = params => {
  return http.requestPost(apiUrl+'/course/coursebase/add',params)
}

Api方法调用

在course_add.vue 调用api提交课程信息

methods: { 
      save () {
          this.$refs.courseForm.validate((valid) => {
            if (valid) {
              this.$confirm('确认提交吗?', '提示', {}).then(() => {
                //当前选择的分类
                let mt = this.categoryActive[0];
                let st = this.categoryActive[1];
                this.courseForm.mt = mt;
                this.courseForm.st = st;
                //请求服务接口
                courseApi.addCourseBase(this.courseForm).then((res) => {
                  if(res.success){
                    this.$message.success('提交成功');
                    //跳转到课程图片
                    //this.$router.push({ path: '/course/add/picture/1/'+this.courseid})
                  }else{
                    if(res.message){
                      this.$message.error(res.message);
                    }else{
                      this.$message.error('提交失败');
                    }
                   }
                });
              });
            }
          });
      }
    },       

测试

注意:将 course_base 表中的 company_id 改为非必填,待认证功能开发完成再修改为必填

测试流程:

1、进入我的课程,点击“新增课程”打开新增课程页面

2、输入课程信息,点击提交

三、课程信息修改

0x01 需求分析

课程添加成功进入课程管理页面,通过课程管理页面修改课程的基本信息、编辑课程图片、编辑课程营销信息等。

本小节实现修改课程。

0x02 课程管理页面说明

页面结构

课程管理页面的结构如下:

image-20200403221706645

课程管理导航页面

1、定义course_manage.vue为课程管理导航页面。

导航效果使用 Element-UI 的 NavMenu 组件实现。

<template> 
  <div>
    <el‐menu
      :default‐active="activeIndex"
      class="el‐menu‐demo"
      mode="horizontal"
      background‐color="#eee"
      text‐color="#000"
      active‐text‐color="#000">
      <router‐link class="mui‐tab‐item" :to="{path:'/course/manage/summary/'+this.courseid}">
      <el‐menu‐item index="1">课程首页</el‐menu‐item>
      </router‐link>
      <router‐link class="mui‐tab‐item" :to="{path:'/course/manage/baseinfo/'+this.courseid}">
      <el‐menu‐item index="2">基本信息</el‐menu‐item>
      </router‐link>
      <router‐link class="mui‐tab‐item" :to="{path:'/course/manage/picture/'+this.courseid}">
        <el‐menu‐item index="3">课程图片</el‐menu‐item>
      </router‐link>
      <router‐link class="mui‐tab‐item" :to="{path:'/course/manage/marketinfo/'+this.courseid}">
      <el‐menu‐item index="4">课程营销</el‐menu‐item>
      </router‐link>
      <router‐link class="mui‐tab‐item" :to="{path:'/course/manage/plan/'+this.courseid}">
      <el‐menu‐item index="5">课程计划</el‐menu‐item>
      </router‐link>
      <router‐link class="mui‐tab‐item" :to="{path:'/course/manage/teacher/'+this.courseid}">
        <el‐menu‐item index="6">教师信息</el‐menu‐item>
      </router‐link>
      <router‐link class="mui‐tab‐item" :to="{path:'/course/manage/pub/'+this.courseid}">
              <el‐menu‐item index="7"> 发布课程</el‐menu‐item>
      </router‐link>
    </el‐menu>
    <router‐view class="main"></router‐view>
  </div>
</template>
<script>
  import * as courseApi from '../api/course';
  import utilApi from '../../../common/utils';
  export default {
    data() {
      return {
        activeIndex:'2',
        courseid:''
      }
    },
    methods: {
    },
    mounted(){
      //课程id
      this.courseid = this.$route.params.courseid
      console.log("courseid=" + this.courseid)
      //跳转到页面列表
      this.$router.push({ path: '/course/manage/baseinfo/'+this.courseid})
    }
  }
</script>
<style scoped>
 
</style>

2、创建各各信息管理页面

通过管理页面的导航可以进入各各信息管理页面,这里先创建各各信息管理页面,页面内容暂

时为空,待开发时再完善,在本模块的 page 目录下创建 course_manage 目录,此目录存放

各个信息管理页面,页面明细如下:

课程管理首页:course_summary.vue

基本信息修改页面:course_baseinfo.vue

图片管理页面:course_picture.vue

营销信息页面:course_marketinfo.vue

老师信息页面:course_teacher.vue

课程计划页面:course_plan.vue

课程发布页面:course_pub.vue

3 、创建路由

import course_manage from '@/module/course/page/course_manage.vue'; 
import course_summary from '@/module/course/page/course_manage/course_summary.vue';
import course_picture from '@/module/course/page/course_manage/course_picture.vue';
import course_baseinfo from '@/module/course/page/course_manage/course_baseinfo.vue';
import course_marketinfo from '@/module/course/page/course_manage/course_marketinfo.vue';
import course_teacher from '@/module/course/page/course_manage/course_teacher.vue';
import course_plan from '@/module/course/page/course_manage/course_plan.vue';
import course_pub from '@/module/course/page/course_manage/course_pub.vue';
{ path: '/course/manager/:courseid', name: '管理课程',component: course_manage,hidden: true ,
        children: [
          { path: '/course/manage/plan/:courseid', name: '课程计划',component: course_plan,hidden:
false },
          { path: '/course/manage/baseinfo/:courseid', name: '基本信息',component:
course_baseinfo,hidden: false },
          { path: '/course/manage/picture/:courseid', name: '课程图片',component:
course_picture,hidden: false },
          { path: '/course/manage/marketinfo/:courseid', name: '营销信息',component:
course_marketinfo,hidden: false },
          { path: '/course/manage/teacher/:courseid', name: '教师信息',component:
course_teacher,hidden: false},
          { path: '/course/manage/pub/:courseid', name: '发布课程',component: course_pub,hidden:
false},
          { path: '/course/manage/summary/:courseid', name: '课程首页',component:
course_summary,hidden: false }
        ]}

0x03 Api 接口

修改课程需要如下接口:

1、根据id查询课程信息

2、修改课程提交

接口定义如下:

  1. 根据课程ID查询课程信息
@ApiOperation(" 获取课程基础信息")
public CourseBase getCourseBaseById(String courseId) throws RuntimeException;

2)修改课程信息

@ApiOperation("更新课程基础信息")
public ResponseResult updateCourseBase(String id,CourseBase courseBase);

0x04 服务端

Dao

略

Service

public CourseBase getCoursebaseById(String courseid) { 
    Optional<CourseBase> optional = courseBaseRepository.findById(courseId);
    if(optional.isPresent()){
      return optional.get();
    }
    return null;
}
@Transactional
    public ResponseResult updateCoursebase(String id, CourseBase courseBase) {
        CourseBase one = this.getCoursebaseById(id);
        if(one == null){
          //抛出异常..
        }
        //修改课程信息
        one.setName(courseBase.getName());
        one.setMt(courseBase.getMt());
        one.setSt(courseBase.getSt());
        one.setGrade(courseBase.getGrade());
        one.setStudymodel(courseBase.getStudymodel());
        one.setUsers(courseBase.getUsers());
        one.setDescription(courseBase.getDescription());
        CourseBase save = courseBaseRepository.save(one);
        return new ResponseResult(CommonCode.SUCCESS);
    }

Controller

@Override 
    @GetMapping("/coursebase/get/{courseId}")
    public CourseBase getCourseBaseById(@PathVariable("courseId") String courseId) throws
RuntimeException {
        return courseService.getCoursebaseById(courseId);
    }
    @Override
    @PutMapping("/coursebase/update/{id}")
    public ResponseResult updateCourseBase(@PathVariable("id") String id, @RequestBody CourseBase
courseBase) {
        return courseService.updateCoursebase(id,courseBase);
    }

0x05 前端

修改页面

在 course 模块下的 course_manage 目录下创建 course_baseinfo.vue 页面,本页面实现课程修改

<template> 
  <div>
    <el‐form :model="courseForm" label‐width="80px" :rules="courseRules" ref="courseForm">
      <el‐form‐item label="课程名称" prop="name">
        <el‐input v‐model="courseForm.name" auto‐complete="off" ></el‐input>
      </el‐form‐item>
      <el‐form‐item label="适用人群" prop="users">
        <el‐input type="textarea" v‐model="courseForm.users" auto‐complete="off" ></el‐input>
      </el‐form‐item>
      <el‐form‐item label="课程分类" prop="categoryActive">
        <el‐cascader
          expand‐trigger="hover"
          :options="categoryList"
          v‐model="categoryActive"
          :props="props">
        </el‐cascader>
      </el‐form‐item>
      <el‐form‐item label="课程等级" prop="grade">
        <b v‐for="grade in gradeList">
          <el‐radio v‐model="courseForm.grade" :label="grade.sdId" >{{grade.sdName}}</el‐
radio>&nbsp;&nbsp;
        </b>
      </el‐form‐item>
      <el‐form‐item label="学习模式" prop="studymodel">
        <b v‐for="studymodel_v in studymodelList">
          <el‐radio v‐model="courseForm.studymodel" :label="studymodel_v.sdId" >
{{studymodel_v.sdName}}</el‐radio>&nbsp;&nbsp;
        </b>
      </el‐form‐item>
           <el‐form‐item label="课程介绍" prop="description">
        <el‐input type="textarea" v‐model="courseForm.description" ></el‐input>
      </el‐form‐item>
    </el‐form>
    <div slot="footer" class="dialog‐footer">
      <el‐button type="primary"  @click.native="save" :loading="editLoading">提交</el‐button>
    </div>
  </div>
</template>
<script>
  import * as courseApi from '../../api/course';
  import utilApi from '../../../../common/utils';
  import * as systemApi from '../../../../base/api/system';
  export default {
    data() {
      return {
        courseid:'',
        studymodelList:[],
        gradeList:[],
        editLoading: false,
        props: {
          value: 'id',
          label:'label',
          children:'children'
        },
        categoryList: [],
        categoryActive:[],
        courseForm: {
          id:'',
          name: '',
          users: '',
          grade:'',
          studymodel:'',
          mt:'',
          st:'',
          description: ''
        },
        courseRules: {
          name: [
            {required: true, message: '请输入课程名称', trigger: 'blur'}
          ],
          category: [
            {required: true, message: '请选择课程分类', trigger: 'blur'}
          ],
          grade: [
            {required: true, message: '请选择课程等级', trigger: 'blur'}
          ],
          studymodel: [
            {required: true, message: '请选择学习模式', trigger: 'blur'}
          ]
         }
      }
    },
    methods: {
      save () {
         
      }
    },
    created(){
    },
    mounted(){
    
    }
  }
</script>
<style scoped>
</style>

API方法

// 获取课程基本信息
export const getCoursebaseById = id => {
  return http.requestQuickGet(apiUrl+'/course/coursebase/get/'+id)
}
//更新课程基本信息
export const updateCoursebase= (id,course) => {
  return http.requestPut(apiUrl+'/course/coursebase/update/'+id,course)
}

课程信息显示

在 mounted 钩子方法中查询课程信息及数据字典:

mounted(){ 
      //查询数据字典字典
      systemApi.sys_getDictionary('201').then((res) => {
//        console.log(res);
        this.studymodelList = res.dvalue;
      });
      systemApi.sys_getDictionary('200').then((res) => {
        this.gradeList = res.dvalue;
      });
      //取课程分类
      courseApi.category_findlist({}).then((res) => {
           this.categoryList = res.children; 
      });
      //查询课程信息
        //课程id
        this.courseid = this.$route.params.courseid;
        courseApi.getCoursebaseById(this.courseid).then((res) => {
          this.courseForm = res;
          //课程分类显示,需要两级分类
          this.categoryActive.push(this.courseForm.mt);
          this.categoryActive.push(this.courseForm.st);
        });
    }

课程修改提交

编辑课程提交方法

methods: { 
  save () {
      //修改课程
      this.$refs.courseForm.validate((valid) => {
        if (valid) {
          this.$confirm('确认提交吗?', '提示', {}).then(() => {
            let mt = this.categoryActive[0];
            let st = this.categoryActive[1];
            this.courseForm.mt = mt;
            this.courseForm.st = st;
            let id = this.courseForm.id
            courseApi.updateCoursebase(id,this.courseForm).then((res) => {
              if(res.success){
                this.$message({
                  message: '提交成功',
                  type: 'success'
                });
              }else{
                if(res.message){
                  this.$message.error(res.message);
                }else{
                  this.$message.error('提交失败');
                }
              }
            });
          });
        }
      });
  }
},

四、课程营销

该部分内容略过,内容与课程信息修改相同

😁 认识作者

作者:👦 LCyee ,全干型代码🐕

自建博客:https://www.codeyee.com

记录学习以及项目开发过程中的笔记与心得,记录认知迭代的过程,分享想法与观点。

优快云 博客:https://blog.youkuaiyun.com/codeyee

记录和分享一些开发过程中遇到的问题以及解决的思路。

欢迎加入微服务练习生的队伍,一起交流项目学习过程中的一些问题、分享学习心得等,不定期组织一起刷题、刷项目,共同见证成长。

概率质量函数(PMF)、概率密度函数(PDF)、累积分布函数(CDF) 1.概率分布函数(Probability Distribution Functions) 笔记来源:Probability Distribution Functions (PMF, PDF, CDF) 1.1 离散型:PMF和CDF 1.2 连续型:PDF和CDF 累积分布函数的导数 === 概率密度函数的函数值 dF(x)dx=f(x) \frac{dF(x)}{dx}=f(x) dxdF(x)​=f(x) 概率密度函数与 xxx 轴围成的面积 === 累积分布函数的函数值 ∫−∞xf(x)d 阅读详情

相关推荐

LS-Dyna模态分析实战:从模型构建到结果解读的全流程指南

本文提供了一份详尽的LS-Dyna模态分析实战指南。文章系统讲解了如何利用LS-Dyna内置的隐式求解器进行特征值求解,从模型构建、几何清理、材料与连接设置,到核心的边界条件与隐式求解控制(如*CONTROL_IMPLICIT_EIGENVALUE),最后完成计算并解读频率与振型结果。旨在帮助工程师在熟悉的环境中高效完成结构振动特性分析,为后续动态响应分析奠定基础。

info6的博客 263

学成在线--day07 课程管理实战

学成在线 第7天 讲义-课程管理实战 这个PageHelper导入的时候一定是导入github的page,springdata.damai里面也有一个page不要搞错了,搞错了就读取不到 成功获取道10条记录 个人感觉这个学成在线的这个项目和乐友相比差的很多,很多细节讲的都不行,不建议做这个项目 ...

zgz102928的博客 345

LCD工程师必看:MIPI DSI的LP/HS模式切换全流程拆解(附高通平台实测)

本文为LCD工程师深度解析MIPI DSI接口中低速(LP)与高速(HS)模式切换的全流程。文章结合高通平台实测波形,从协议状态机、时序关键参数到实战调试案例,系统拆解了模式切换的本质、协同机制及常见问题排查方法,重点阐述了LP模式在低功耗控制与HS模式在高速数据传输中的核心作用与切换时序。

weixin_29240711的博客 547

基于Django与Vue的数据库应用层加密系统设计与实现

数据安全是软件系统设计的核心考量之一,尤其在处理用户敏感信息时。其基本原理在于通过密码学技术,在数据存储与传输过程中对其进行变换,确保即使数据被非法获取,也无法被直接识别。从技术价值看,应用层加密方案不依赖于特定数据库产品,提供了更高的灵活性与可控性,能够有效防御拖库、内部越权等风险。在常见的Web应用场景中,如用户信息管理、电商后台等,系统通常采用Django、Vue等框架构建。针对这些场景,实现一套集成于ORM层、对业务代码透明的自动加解密机制,能显著提升数据生命周期内的安全性。本文聚焦于如何利用AES

weixin_33994429的博客 617

智能优化电池:基于单片机的电池管理系统

设计简介: 本设计是基于单片机的电池管理系统,主要实现以下功能: 可通过LCD1602显示温度、电压电流值; 可通过按键调整温度、电压和电流的阈值; 用ADC0832将模拟量转换为数字量。 标签:51单片机、LCD1602、ADC0832 效果图: 总体资料: 原理图: 软件设计流程: 系统框图: 本设计以STC89C52单片机为核心控制器,加上其他的模块一起组成电动汽车的电池管理的整个系统,...

专注单片机实战教学,分享单片机学习资料 375

VsCode+JLink+GCC替代Keil开发GD32程序-个人总结

对个人使用vscode+Jlink开发GD32程序做了总结,供需要者参考。

MyCollege1999的博客 2763

微服务实战笔记-学成在线-day07

知识点 springboot中实体字段为dType 传到前台json为dtype的原因与解决方案 vue中watch的基本用法 element-ui中MessageBox的自定义校验 mybatis中collection的用法 1. springboot中实体字段为dType 传到前台json为dtype的原因与解决方案 原因 springboot 使用fastjson 在对象的序列化和反序列化的时候对字段进行了处理 解决方案 在bean的get方法上添加@JsonProperty注解 @Data @T

sssdal19995的博客 304

基于 Go 的微信滑块验证码自动化:协议还原与图像算法深度解析

本文从协议层、算法层和工程优化三个维度,系统拆解了基于Go的微信滑块验证码自动化方案。在协议层,通过手写protobuf编码器和RSA加密复现了微信UUID生成机制;在算法层,采用图像匹配技术实现滑块缺口定位;在工程层面,构建了包含HTTP状态机和随机化设备指纹的完整验证流程。文章重点阐述了技术实现的形式化建模、算法选择依据和复杂度分析,为工程师和算法研究者提供了可验证的技术方案。核心代码结构包括UUID生成、滑块状态机和图像匹配算法等模块,通过分层设计实现了高效可靠的验证码自动化破解。

weixin_65409651的博客 1293

CSS页面制作-5

1. 学成网 页面制作 目标 理解 能够说写单页面我们基本的流程 能说出常见的css初始化语句 能说出我们CSS属性书写顺序 应用 能利用ps切图 能引入外部样式表 能把psd文件转换为html页面 学成在线的目的就是为了串联前面的所有知识。 1.1 前期准备素材 学成在线PSD源文件 开发工具 = PS(切图) + sublime(代码) + chrome(测试) 1.2 前期准备工作 欲先善其事,必先利其器。 先把我们的前期准备工作做好, 我们本次采取结构与样式相分离思想。

kkkk_1112的博客 413

(保姆教程)Spyder 配置Tensorflow(2.5.0)和keras(2.4.3)

(保姆教程)Spyder 配置Tensorflow(2.5.0)和keras(2.4.3)

qq_43102225的博客 1万+

双重分组进位跳跃进位链

跳跃进位链

qq_62260432的博客 941

微服务[学成在线] day20:项目总结

???? 写在前面 我为什么要花时间去写这个笔记? 由于在学习该项目的过程中发现了原讲义存在的一些问题,所以该笔记基于「学成在线」微服务项目 PDF 讲义进行编写,并且投入了时间去优化了笔记的格式、代码的高亮、重点的标记等。 以及一些原讲义中所描述的一些知识点使我无法理解的内容,我会对这些内容的表达方式进行修改或者提出一些问题,并且用我自己所理解的一些想法去重新的解释这个问题。 总结一下原 PDF 讲义中已知的一些问题: 从 PDF 中复制出来的代码,部分特殊符号的编码有问题,并且不易被发现,例如横杠

通往体面生活的路上 3261

Unreal5.6从入门到精通之 如何实现MetaHuman数字人

本文介绍了使用HYPER3D-ChatAvatar网站生成3D头部模型,并导入Unreal Engine制作数字人的完整流程。首先上传照片生成头部模型(约2分钟),设置参数后下载模型文件。然后在UE5.6中创建项目,激活MetaHuman插件,导入头部模型并调整肤色、面部特征和身体模板。通过MetaHuman Creator组装数字人蓝图,支持添加音频/视频动画功能。关键步骤包括:取消Rigging选项节省时间、切换英文模式避免材质问题、使用Live Link Face应用实现面部捕捉等。整个流程约需5-1

TxNet 1348

微服务[学成在线] day06:页面发布以及课程管理

???? 知识点概览 为了方便后续回顾该项目时能够清晰的知道本章节讲了哪些内容,并且能够从该章节的笔记中得到一些帮助,所以在完成本章节的学习后在此对本章节所涉及到的知识点进行总结概述。 本章节为【学成在线】项目的 day06 的内容 使用 Spring boot 集成 RabbitMQ 和 GridFS 实现基于生产者和消费者模型的页面静态化发布的流程。 在本章节的知识点中,再次复习了基于 GridFS 和 RabbitMQ 的分布式静态页面发布的知识点,深化了记忆。 使用三级菜单实现课程计

通往体面生活的路上 627

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

微服务[学成在线] day10:课程发布、ElasticSearch

???? 知识点概览 为了方便后续回顾该项目时能够清晰的知道本章节讲了哪些内容,并且能够从该章节的笔记中得到一些帮助,所以在完成本章节的学习后在此对本章节所涉及到的知识点进行总结概述。 本章节为【学成在线】项目的 day10 的内容 课程发布功能开发 ElasticsSearch 安装部署 ElasticsSearch 快速入门、IK 分词器、映射、索引。 目录 内容会比较多,小伙伴们可以根据目录进行按需查阅。 文章目录???? 知识点概览目录一、课程发布0x01 需求分析0x02 CMS一键

通往体面生活的路上 1205

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

学习笔记(上)| 微服务项目《学成在线》

本文介绍了《学成在线》微服务项目的学习内容和实践过程。项目基于B2B2C模式,采用SpringCloudAlibaba等技术栈,主要包含内容管理、课程管理、媒资管理等模块。 学习过程中解决了跨域问题、事务失效等常见问题,并通过Swagger进行接口测试。项目采用分层架构设计,通过代码生成器提高开发效率,为后续微服务开发奠定了基础。

猿来是你 679

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

黑马学成在线项目

记录黑马学成在线项目的学习

Electric Sheep 889

微服务[学成在线] day18:基于oauth2实现RBAC认证授权、微服务间认证实现

???? 知识点概览 为了方便后续回顾该项目时能够清晰的知道本章节讲了哪些内容,并且能够从该章节的笔记中得到一些帮助,所以在完成本章节的学习后在此对本章节所涉及到的知识点进行总结概述。 本章节为【学成在线】项目的 day18 的内容 基于方法的权限校验 基于 RBAC 进行用户权限配置以及动态查询。 根据教师所属的公司来实现课程信息查询的细粒度授权。也就是 A 公司的老师只能查询到 A 公司下的课程。 使用 Feign 拦截器实现获取前端请求中的 header 信息,并将 header 中带有

通往体面生活的路上 2004

微服务实战学成在线day01——(一)搭建环境

学成在线项目的搭建,主要介绍了项目,还有完成一些基础性的工作。

聂泳的博客 527

微服务[学成在线] day15:媒资管理系统集成

???? 知识点概览 为了方便后续回顾该项目时能够清晰的知道本章节讲了哪些内容,并且能够从该章节的笔记中得到一些帮助,所以在完成本章节的学习后在此对本章节所涉及到的知识点进行总结概述。 本章节为【学成在线】项目的 day15 的内容 根据 课程ID 搜索该课程已发布的课程信息,并返回该课程的所有课程计划信息。 将指定课程 发布时 所的课程计划的媒资信息保存到 teachplan_media_publish 表中, 根据 课程计划id 搜索该课程计划所对应的媒资信息,需要用到的是该课程计划对应的

通往体面生活的路上 639

最新传智学成在线JAVAEE微服务项目实战视频教程

目录 ├─day01 搭建环境 CMS服务端开发 ├─day02 CMS前端开发 ├─day03 CMS页面管理开发 ├─day04 页面静态化 ├─day05 消息中间件RabbitMQ ├─day06 页面发布 课程管理 ├─day07 课程管理实战 ├─day08 课程图片管理 分布式文件系统 ├─day09 课程预览 Eureka Feign ├─day10 课程发布 ElasticSea...

u011576602的博客 992

微服务[学成在线] day08:FastDFS 实现课程图片管理

???? 知识点概览 为了方便后续回顾该项目时能够清晰的知道本章节讲了哪些内容,并且能够从该章节的笔记中得到一些帮助,所以在完成本章节的学习后在此对本章节所涉及到的知识点进行总结概述。 本章节为【学成在线】项目的 day08 的内容 FastDFS 的 安装与基本使用流程。 基于 Java Api 来操作 FastDFS 结合 FastDFS 实现对课程图片的 CRUD 图片删除的场景使用 Promise 解决一些问题 目录 内容会比较多,小伙伴们可以根据目录进行按需查阅。 文章目录????

通往体面生活的路上 559

学成在线--day01 搭建环境 CMS服务端开发

1.1 项目背景受互联网+概念的催化,当今中国在线教育市场的发展可谓是百花齐放、如火如荼。按照市场领域细分为:学前教 育、K12教育、高等教育、留学教育、职业教育、语言教育、兴趣教育以及综合平台,其中,职业教育和语言教育 的市场优势突出。根据Analysys易观发布的数据显示,预计2019年中国互联网教育市场交易规模将达到3718亿元 人民币,未来三年互联网教育市场规模保持高速增长。

you4580的专栏 221

Java的新项目学成在线笔记-day9(四)

1.3.3 服务注册 1.3.3.1 将cms注册到Eureka Server 下边实现cms向Eureka Server注册。 1、在cms服务中添加依赖 [AppleScript]纯文本查看复制代码 ? 1 2 3 <!‐‐ 导入Eureka客户端的依赖 ‐‐> <dependency> <groupId&...

czbkzmj的博客 214

Java的新项目学成在线笔记-day18(十)

4 微服务之间认证 4.1 需求分析 前边章节已经实现了用户携带身份令牌和JWT令牌访问微服务,微服务获取jwt并完成授权。 当微服务访问微服务,此时如果没有携带JWT则微服务会在授权时报错。测试课程预览:1、将课程管理服务和CMS全部添加授权配置 2、用户登录教学管理前端,进入课程发布界面,点击课程发布,观察课程管理服务端报错如下:[mw_shl_code=applescript,true]fe...

beiqiang1641的博客 168

Java的新项目学成在线笔记-day17(十四)

5.3 测试 1、配置代理 通过nginx转发到gateway,在www.xuecheng.com虚拟主机来配置 [AppleScript]纯文本查看复制代码 ? 1 2 3 4 5 6 7 #微服务网关 upstream api_server_pool{ ...

czbkzmj的博客 239
上一篇: 微服务[学成在线] day06:页面发布以及课程管理
下一篇: 微服务[学成在线] day08:FastDFS 实现课程图片管理
cory_lin
博客等级 码龄7年 22粉丝 24原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值