1. 程式人生 > 實用技巧 >Day07_課程管理實戰

Day07_課程管理實戰

課程管理實戰

1 我的課程

1.1 需求分析

課程新增完成後可通過我的課程進入課程修改頁面,此頁面顯示我的課程列表,如下圖所示,可分頁查詢。

上邊的查詢要實現分頁、會存在多表關聯查詢,所以建議使用mybatis實現我的課程查詢。

1.2 API介面

輸入引數:

頁碼、每頁顯示個數、查詢條件

輸出結果型別:

QueryResponseResult<自定義型別>

在api工程建立course包,建立CourseControllerApi介面。

package com.xuecheng.api.course;

import com.xuecheng.framework.domain.course.Teachplan;
import com.xuecheng.framework.domain.course.ext.CourseInfo;
import com.xuecheng.framework.domain.course.ext.TeachplanNode;
import com.xuecheng.framework.domain.course.request.CourseListRequest;
import com.xuecheng.framework.model.response.QueryResponseResult;
import com.xuecheng.framework.model.response.ResponseResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

/**
 * @author HackerStar
 * @create 2020-08-08 19:20
 */
@Api(value = "課程管理介面", description = "課程管理介面,提供課程的增、刪、改、查")
public interface CourseControllerApi {
    @ApiOperation("課程計劃查詢")
    public TeachplanNode findTeachplanList(String courseId);

    @ApiOperation("新增課程計劃")
    public ResponseResult addTeachplan(Teachplan teachplan);

    @ApiOperation("查詢我的課程列表")
    public QueryResponseResult findCourseList(
            int page,
            int size,
            CourseListRequest courseListRequest);
}

1.3 課程管理服務

1.3.1 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語句,實現分頁查詢。

1)新增依賴(在xc-service-manage-course的pom下)

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

2)配置pageHelper

在application.yml中配置pageHelper操作的資料庫型別:

pagehelper:
	helper‐dialect: mysql

1.3.2 Dao

1)mapper 介面

package com.xuecheng.manage_course.dao;

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;

/**
 * Created by Administrator.
 */
@Mapper
public interface CourseMapper {
   CourseBase findCourseBaseById(String id);
   Page<CourseInfo> findCourseListPage(CourseListRequest courseListRequest);
}

2)mapper.xml對映檔案(CourseMapper.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>

3)測試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語句中已經包括分頁語句。

1.3.3 Service

定義CourseService.java類,用於課程管理的service定義:

//課程列表分頁查詢
    public QueryResponseResult findCourseList(int page, int size, CourseListRequest courseListRequest) {
        if(courseListRequest == null){ courseListRequest = new CourseListRequest(); }
        if(page<=0){
            page = 0;
        }
        if(size<=0){
            size = 20;
        }
        //設定分頁引數
        PageHelper.startPage(page, size);
        //分頁查詢
        Page<CourseInfo> courseListPage = courseMapper.findCourseListPage(courseListRequest);
        //查詢列表
        List<CourseInfo> list = courseListPage.getResult();
        //總記錄數
        long total = courseListPage.getTotal();
        //查詢結果集
        QueryResult<CourseInfo> courseIncfoQueryResult = new QueryResult<CourseInfo>();
        courseIncfoQueryResult.setList(list);
        courseIncfoQueryResult.setTotal(total);
        return new QueryResponseResult(CommonCode.SUCCESS, courseIncfoQueryResult);
    }

1.3.4 Controller

package com.xuecheng.manage_course.controller;

import com.xuecheng.api.course.CourseControllerApi;
import com.xuecheng.framework.domain.course.Teachplan;
import com.xuecheng.framework.domain.course.ext.TeachplanNode;
import com.xuecheng.framework.domain.course.request.CourseListRequest;
import com.xuecheng.framework.model.response.QueryResponseResult;
import com.xuecheng.framework.model.response.ResponseResult;
import com.xuecheng.manage_course.service.CourseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

/**
 * @author Administrator
 * @version 1.0
 **/
@RestController
@RequestMapping("/course")
public class CourseController implements CourseControllerApi {

    @Autowired
    CourseService courseService;

    @Autowired
    CourseService courseService;

    @Override
    @GetMapping("/teachplan/list/{courseId}")
    public TeachplanNode findTeachplanList(@PathVariable("courseId") String courseId) {
        return courseService.findTeachplanList(courseId);

    }

    @Override
    @PostMapping("/teachplan/add")
    public ResponseResult addTeachplan(@RequestBody Teachplan teachplan) {
        return courseService.addTeachplan(teachplan);
    }

    @Override
    @GetMapping("/coursebase/list/{page}/{size}")
    public QueryResponseResult findCourseList(@PathVariable("page") int page, @PathVariable("size")int size, CourseListRequest courseListRequest) {
        return courseService.findCourseList(page,size,courseListRequest);
    }
}

1.3.5 測試

使用postman或swagger-ui測試課程列表介面。

1.4 前端

1.4.1 頁面

建立course_list.vue

1)使用element 的card元件

頁面佈局程式碼如下:

<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: [
          {
            id:'test01',
            name:'test01',
            pic:''
          },
          {
            id:'test02',
            name:'test02',
            pic:''
          }
          ],
        sels: [],//列表選中列
        imgUrl:sysConfig.imgUrl
      }
    },
    methods: {
        //分頁方法
      handleCurrentChange(val) {
        this.page = val;
        this.getCourse();
      },
      //獲取課程列表
      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;
          }

        });
      },
      handleManage: function (id) {
        console.log(id)
        this.$router.push({ path: '/course/manager/'+id})
      }

    },
    created(){

    },
    mounted() {
      //查詢我的課程
      this.getCourse();
    }
  }
</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 Home from '@/module/home/page/home.vue';
import course_list from '@/module/course/page/course_list.vue';
import course_add from '@/module/course/page/course_add.vue';
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';
export default [
  {
    path: '/course',
    component: Home,
    name: '課程管理',
    hidden: false,
    iconCls: 'el-icon-document',
    children: [
      { path: '/course/list', name: '我的課程',component: course_list,hidden: false },
      { path: '/course/add/base', name: '新增課程',component: course_add,hidden: true },
      { 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 }
        ]}
    ]
  }
]

1.4.2 Api呼叫

1、定義Api方法

//我的課程列表
export const findCourseList = (page,size,params) => {
//使用工具類將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.4.3 測試

頁面效果如下:

注意:由於課程圖片伺服器沒有搭建,這裡圖片暫時無法顯示。

2 新增課程

2.1 需求分析

使用者操作流程如下:

1、使用者進入“我的課程”頁面,點選“新增課程”,進入新增課程頁面
2、填寫課程資訊,選擇課程分類、課程等級、學習模式等。
3、資訊填寫完畢,點選“提交”,課程新增成功或課程新增失敗並提示失敗原因。

需要解決的是在新增頁面上輸入的資訊:

1、課程分類
多級分類,需要方便使用者去選擇。
2、課程等級、學習模式等這些選項建議是可以配置的。

2.2 課程分類查詢

2.2.1 介紹

在新增課程介面需要選擇課程所屬分類, 分類資訊是整個專案非常重要的資訊,課程即商品,分類資訊設定的好 壞直接影響使用者訪問量。

分類資訊在哪裡應用?

1、首頁分類導航

2 、課程的歸屬地

新增課程時要選擇課程的所屬分類。

2.2.2 資料結構

分類表category的結構如下:

2.2.3 分類查詢

2.2.3.1 資料格式

在新增課程時需要選擇課程所屬的分類,這裡需要定義課程分類查詢介面。

介面格式要根據前端需要的資料格式來定義,前端展示課程分類使用elemenet-ui的cascader(級聯選擇器)組 件。

資料格式例子如下:

[{
          value: 'zhinan',
          label: '指南',
          children: [{
            value: 'shejiyuanze',
            label: '設計原則',
            children: [{
              value: 'yizhi',
              label: '一致'
            }, {
              value: 'fankui',
              label: '反饋'
            }, {
              value: 'xiaolv',
              label: '效率'
            }, {
              value: 'kekong',
              label: '可控'
}]
2.2.3.2 資料模型

1)定義category的模型

category模型對資料欄位對應,如下:

package com.xuecheng.framework.domain.course;

import lombok.Data;
import lombok.ToString;
import org.hibernate.annotations.GenericGenerator;

import javax.persistence.*;
import java.io.Serializable;

/**
 * Created by admin on 2018/2/7.
 */
@Data
@ToString
@Entity
@Table(name="category")
@GenericGenerator(name = "jpa-assigned", strategy = "assigned")
//@GenericGenerator(name = "jpa-uuid", strategy = "uuid")
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)定義資料返回格式

package com.xuecheng.framework.domain.course.ext;

import com.xuecheng.framework.domain.course.Category;
import lombok.Data;
import lombok.ToString;

import java.util.List;

/**
 * Created by admin on 2018/2/7.
 */
@Data
@ToString
public class CategoryNode extends Category {

    List<CategoryNode> children;

}
2.2.3.3 Api介面
package com.xuecheng.api.course;

import com.xuecheng.framework.domain.course.ext.CategoryNode;
import io.swagger.annotations.ApiOperation;

/**
 * @author HackerStar
 * @create 2020-08-11 13:47
 */
public interface CategoryControllerApi {
    @ApiOperation("查詢分類")
    public CategoryNode findList();
}
2.2.3.4 dao

根據資料格式的分析,此查詢需要返回樹型資料格式,為了開發方便我們使用mybatis實現查詢 。

1)定義mapper

package com.xuecheng.manage_course.dao;

import com.xuecheng.framework.domain.course.ext.CategoryNode;
import org.apache.ibatis.annotations.Mapper;

/**
 * @author HackerStar
 * @create 2020-08-11 13:49
 */
@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>
2.2.3.5 Service
package com.xuecheng.manage_course.service;

import com.xuecheng.framework.domain.course.ext.CategoryNode;
import com.xuecheng.manage_course.dao.CategoryMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author HackerStar
 * @create 2020-08-11 13:55
 */
@Service
public class CategoryService {
    @Autowired
    CategoryMapper categoryMapper;

    //查詢分類
    public CategoryNode findList() {
        return categoryMapper.selectList();
    }
}
2.2.3.6 Controller
package com.xuecheng.manage_course.controller;

import com.xuecheng.api.course.CourseControllerApi;
import com.xuecheng.framework.domain.course.Teachplan;
import com.xuecheng.framework.domain.course.ext.CategoryNode;
import com.xuecheng.framework.domain.course.ext.TeachplanNode;
import com.xuecheng.framework.domain.course.request.CourseListRequest;
import com.xuecheng.framework.model.response.QueryResponseResult;
import com.xuecheng.framework.model.response.ResponseResult;
import com.xuecheng.manage_course.service.CategoryService;
import com.xuecheng.manage_course.service.CourseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

/**
 * @author Administrator
 * @version 1.0
 **/
@RestController
@RequestMapping("/course")
public class CourseController implements CourseControllerApi {

    @Autowired
    CourseService courseService;

    @Autowired
    CategoryService categoryService;

    @Override
    @GetMapping("/teachplan/list/{courseId}")
    public TeachplanNode findTeachplanList(@PathVariable("courseId") String courseId) {
        return courseService.findTeachplanList(courseId);

    }

    @Override
    @PostMapping("/teachplan/add")
    public ResponseResult addTeachplan(@RequestBody Teachplan teachplan) {
        return courseService.addTeachplan(teachplan);
    }

    @Override
    @GetMapping("/coursebase/list/{page}/{size}")
    public QueryResponseResult findCourseList(@PathVariable("page") int page, @PathVariable("size") int size, CourseListRequest courseListRequest) {
        return courseService.findCourseList(page, size, courseListRequest);
    }

    @Override
    @GetMapping("/category/list")
    public CategoryNode findList() {
        return categoryService.findList();
    }
}
2.2.3.7 介面測試

介面描述如下:

使用swagger-ui或postman測試介面。

2.3 資料字典

2.3.1 介紹

在新增課程介面需要選擇課程等級、課程狀態等,這些資訊統一採用資料字典管理的方式。

本專案對一些業務的分類配置資訊,比如:課程等級、課程狀態、使用者型別、使用者狀態等進行統一管理,通過在數 據庫建立資料字典表來維護這些分類資訊。

資料字典對系統的業務分類進行統一管理,並且也可以解決硬編碼問題,比如新增課程時選擇課程等級,下拉框中 的課程等級資訊如果在頁面硬編碼將造成不易修改維護的問題,所以從資料字典表中獲取,如果要修改名稱則在數 據字典修改即可,提高系統的可維護性。

2.3.2 資料模型

在mongodb中建立資料字典表sys_dictionary

課程登記字典資訊如下:

{
	"_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不可用)

資料模型類(System包下):

package com.xuecheng.framework.domain.system;

import com.xuecheng.framework.domain.cms.CmsConfigModel;
import lombok.Data;
import lombok.ToString;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;

import java.util.List;

/**
 * Created by admin on 2018/2/6.
 */
@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型別:

package com.xuecheng.framework.domain.system;

import lombok.Data;
import lombok.ToString;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;

/**
 * Created by admin on 2018/2/6.
 */
@Data
@ToString
public class SysDictionaryValue {

    @Field("sd_id")
    private String sdId;

    @Field("sd_name")
    private String sdName;

    @Field("sd_status")
    private String sdStatus;

}

2.3.3 字典查詢介面

2.3.3.1 API介面

為了方便其它子系統使用,在cms模組下建立字典查詢介面,根據字典的type查詢字典資訊,介面定義如下:

package com.xuecheng.api.cms;

import com.xuecheng.framework.domain.system.SysDictionary;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

/**
 * @author HackerStar
 * @create 2020-08-11 15:52
 */
@Api(value = "資料字典介面", description = "提供資料字典介面的管理、查詢功能")
public interface SysDictionaryControllerApi {
    //資料字典
    @ApiOperation(value = "資料字典查詢介面")
    public SysDictionary getByType(String type);
}
2.3.3.2 Dao

在cms模組下建立資料庫的dao、service等類。

package com.xuecheng.manage_cms.dao;

import com.xuecheng.framework.domain.system.SysDictionary;
import org.springframework.data.mongodb.repository.MongoRepository;

/**
 * @author HackerStar
 * @create 2020-08-11 15:54
 */
public interface SysDictionaryDao extends MongoRepository<SysDictionary,String>  {
    //根據字典分類查詢字典資訊
    SysDictionary findBydType(String dType);
}
2.3.3.3 Service
package com.xuecheng.manage_cms.service;

import com.xuecheng.framework.domain.system.SysDictionary;
import com.xuecheng.manage_cms.dao.SysDictionaryDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author HackerStar
 * @create 2020-08-11 15:58
 */
@Service
public class SysdictionaryService {
    @Autowired
    SysDictionaryDao sysDictionaryDao;

    //根據字典分類type查詢字典資訊
    public SysDictionary findDictionaryByType(String type) {
        return sysDictionaryDao.findBydType(type);
    }
}
2.3.3.4 Controller
package com.xuecheng.manage_cms.web.controller;

import com.xuecheng.api.cms.SysDictionaryControllerApi;
import com.xuecheng.framework.domain.system.SysDictionary;
import com.xuecheng.manage_cms.service.SysdictionaryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author HackerStar
 * @create 2020-08-11 15:59
 */
@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);
    }
}
2.3.3.5 測試

2.4 新增課程頁面完善

本節完成資料字典顯示及課程分類顯示。

2.4.1 新增課程頁面

1、頁面效果如下:

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:'name',
          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 () {
          //處理課程分類
          // 選擇課程分類儲存到categoryActive
           this.courseForm.mt=  this.categoryActive[0]//大分類
           this.courseForm.st=  this.categoryActive[1]//小分類
          courseApi.addCourseBase(this.courseForm).then(res=>{
              if(res.success){
                  this.$message.success("提交成功")
                //跳轉到我的課程
                this.$router.push({ path: '/course/list'})
              }else{
                this.$message.error(res.message)
              }

          })
      }
    },
    created(){

    },
    mounted(){
      // 查詢課程分類
      courseApi.category_findlist().then(res=>{
          this.categoryList = res.children;
          console.log(this.categoryList)

      })

      //查詢資料字典
      //查詢課程等級
      systemApi.sys_getDictionary("200").then(res=>{

        this.gradeList = res.dvalue;
      })
      //查詢學習模式
      systemApi.sys_getDictionary("201").then(res=>{

        this.studymodelList = res.dvalue;
      })

    }
  }
</script>
<style scoped>


</style>

2)頁面路由

import Home from '@/module/home/page/home.vue';
import course_list from '@/module/course/page/course_list.vue';
import course_add from '@/module/course/page/course_add.vue';
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';
export default [
  {
    path: '/course',
    component: Home,
    name: '課程管理',
    hidden: false,
    iconCls: 'el-icon-document',
    children: [
      { path: '/course/list', name: '我的課程',component: course_list,hidden: false },
      { path: '/course/add/base', name: '新增課程',component: course_add,hidden: true },
      { 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 }
        ]}
    ]
  }
]

3)課程新增連結

在我的課程頁面新增“新增課程”連結

在course_list.vue 中新增:

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

2.4.2 查詢資料字典

課程新增頁面中課程等級、學習模式需要從資料字典查詢字典資訊。

1)定義方法

資料字典查詢為公用方法,所以定義在/base/api/system.js中

import http from './public'
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("200").then(res=>{
	this.gradeList = res.dvalue;
})
//查詢學習模式
systemApi.sys_getDictionary("201").then(res=>{
	this.studymodelList = res.dvalue;
})

3)效果

2.4.3 課程分類

課程新增頁面中課程分類採用Cascader元件完成。

Cascader級聯選擇器

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+'/course/category/list')
}

3)在頁面獲取課程分類

在mounted鉤子中定義

// 查詢課程分類
      courseApi.category_findlist().then(res=>{
          this.categoryList = res.children;
          console.log(this.categoryList)

      })

4)效果

  1. 如何獲取選擇的分類

使用者選擇課程分類後,所選分類ID繫結到categoryActive(陣列)中,選擇了一級、二級分類,分別儲存在 categoryActive陣列的第一個、第二個元素中。

2.5 API介面

建立課程新增提交介面:

@Api(value = "課程管理介面", description = "課程管理介面,提供課程的增、刪、改、查")
public interface CourseControllerApi {
    @ApiOperation("新增課程基礎資訊")
    public AddCourseResult addCourseBase(CourseBase courseBase);
}

2.6 新增課程服務端

2.6.1 Dao

package com.xuecheng.manage_course.dao;

import com.xuecheng.framework.domain.course.CourseBase;
import org.springframework.data.jpa.repository.JpaRepository;

/**
 * Created by Administrator.
 */
public interface CourseBaseRepository extends JpaRepository<CourseBase,String> {
}

2.6.2 Service

//新增課程提交
    @Transactional
    public AddCourseResult addCourseBase(CourseBase courseBase) {
        //課程狀態預設為未釋出
        courseBase.setStatus("202001");
        courseBaseRepository.save(courseBase);
        return new AddCourseResult(CommonCode.SUCCESS, courseBase.getId());
    }

2.6.3 Controller

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

2.7 新增課程前端

2.7.1 Api方法定義

在前端定義請求服務端新增課程的api的方法,在course模組中定義方法如下(course.js):

/*新增課程基礎資訊*/
export const addCourseBase = params => {
  return http.requestPost(apiUrl+'/course/coursebase/add',params)
}

2.7.2 Api方法呼叫

在course_add.vue 呼叫api提交課程資訊

methods: {
        //新增課程提交
      save () {
          //處理課程分類
          // 選擇課程分類儲存到categoryActive
           this.courseForm.mt=  this.categoryActive[0]//大分類
           this.courseForm.st=  this.categoryActive[1]//小分類
          courseApi.addCourseBase(this.courseForm).then(res=>{
              if(res.success){
                  this.$message.success("提交成功")
                //跳轉到我的課程
                this.$router.push({ path: '/course/list'})
              }else{
                this.$message.error(res.message)
              }

          })
      }
    },

2.7.3 測試

注意:將course_base表中的company_id改為非必填,待認證功能開發完成再修改為必填

測試流程:

1、進入我的課程,點選“新增課程”開啟新增課程頁面
2、輸入課程資訊,點選提交

3 課程資訊修改

3.1 需求分析

課程新增成功進入課程管理頁面,通過課程管理頁面修改課程的基本資訊、編輯課程圖片、編輯課程營銷資訊等。

本小節實現修改課程。

3.2 課程管理頁面說明

3.2.1 頁面結構

3.2.2 課程管理導航頁面

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 Home from '@/module/home/page/home.vue';
import course_list from '@/module/course/page/course_list.vue';
import course_add from '@/module/course/page/course_add.vue';
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';
export default [
  {
    path: '/course',
    component: Home,
    name: '課程管理',
    hidden: false,
    iconCls: 'el-icon-document',
    children: [
      { path: '/course/list', name: '我的課程',component: course_list,hidden: false },
      { path: '/course/add/base', name: '新增課程',component: course_add,hidden: true },
      { 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 }
        ]}
    ]
  }
]

3.3 Api介面

修改課程需要如下介面:

1、根據id查詢課程資訊

2、修改課程提交

介面定義如下:

  1. 根據課程ID查詢課程資訊
@Api(value = "課程管理介面", description = "課程管理介面,提供課程的增、刪、改、查")
public interface CourseControllerApi {
    @ApiOperation(" 獲取課程基礎資訊")
    public CourseBase getCourseBaseById(String courseId) throws RuntimeException;
}

2)修改課程資訊

@Api(value = "課程管理介面", description = "課程管理介面,提供課程的增、刪、改、查")
public interface CourseControllerApi {
    @ApiOperation("更新課程基礎資訊")
    public ResponseResult updateCourseBase(String id, CourseBase courseBase);
}

3.4 服務端

3.4.1 Dao

3.4.2 Service(CourseService)

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);
    }

3.4.3 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);
    }

3.5 前端

3.5.1 修改頁面

在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 {
        dotype:'',
        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 () {
          //修改課程
          this.$refs.courseForm.validate((valid) => {
            if (valid) {
              this.$confirm('確認提交嗎?', '提示', {}).then(() => {
                this.editLoading = true;
                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) => {
                  this.editLoading = false;
                  if(res.success){
                    this.$message({
                      message: '提交成功',
                      type: 'success'
                    });
                  }else{
                    if(res.message){
                      this.$message.error(res.message);
                    }else{
                      this.$message.error('提交失敗');
                    }
                  }
                });
              });
            }
          });
      }
    },
    created(){

    },
    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) => {
//          console.log(res);
          this.courseForm = res;
          //課程分類顯示,需要兩級分類
          this.categoryActive.push(this.courseForm.mt);
          this.categoryActive.push(this.courseForm.st);
        });
    }
  }
</script>
<style scoped>


</style>

3.5.2 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)
}

3.5.3 課程資訊顯示

在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) => {
//          console.log(res);
        this.courseForm = res;
        //課程分類顯示,需要兩級分類
        this.categoryActive.push(this.courseForm.mt);
        this.categoryActive.push(this.courseForm.st);
      });
    }

3.5.4 課程修改提

編輯課程提交方法:

 methods: {
      save() {
        //修改課程
        this.$refs.courseForm.validate((valid) => {
          if (valid) {
            this.$confirm('確認提交嗎?', '提示', {}).then(() => {
              this.editLoading = true;
              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) => {
                this.editLoading = false;
                if (res.success) {
                  this.$message({
                    message: '提交成功',
                    type: 'success'
                  });
                } else {
                  if (res.message) {
                    this.$message.error(res.message);
                  } else {
                    this.$message.error('提交失敗');
                  }
                }
              });
            });
          }
        });
      }
    },

4 課程營銷

4.1 需求分析

課程營銷資訊包括課程價格、課程有效期等資訊。

4.2 資料模型

課程營銷資訊使用course_market表儲存。

資料模型如下:

package com.xuecheng.framework.domain.course;

import lombok.Data;
import lombok.ToString;
import org.hibernate.annotations.GenericGenerator;

import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;

/**
 * Created by admin on 2018/2/10.
 */
@Data
@ToString
@Entity
@Table(name="course_market")
@GenericGenerator(name = "jpa-assigned", strategy = "assigned")
public class CourseMarket implements Serializable {
    private static final long serialVersionUID = -916357110051689486L;
    @Id
    @GeneratedValue(generator = "jpa-assigned")
    @Column(length = 32)
    private String id;
    private String charge;
    private String valid;
    private String qq;
    private Float price;
    private Float price_old;
//    private Date expires;
    @Column(name = "start_time")
    private Date startTime;
    @Column(name = "end_time")
    private Date endTime;
}

4.3 API

  1. 查詢課程營銷資訊
@Api(value = "課程管理介面", description = "課程管理介面,提供課程的增、刪、改、查")
public interface CourseControllerApi {
    @ApiOperation(" 獲取課程營銷資訊")
    public CourseMarket getCourseMarketById(String courseId);
}

2)更新課程營銷資訊

@Api(value = "課程管理介面", description = "課程管理介面,提供課程的增、刪、改、查")
public interface CourseControllerApi {
    @ApiOperation(" 更新課程營銷資訊")
    public ResponseResult updateCourseMarket(String id, CourseMarket courseMarket);
}

4.4 課程管理服務

4.4.1 Dao

package com.xuecheng.manage_course.dao;

import com.xuecheng.framework.domain.course.CourseMarket;
import org.springframework.data.jpa.repository.JpaRepository;

/**
 * @author HackerStar
 * @create 2020-08-11 18:40
 */
public interface CourseMarketRepository extends JpaRepository<CourseMarket, String> {
}

4.4.2 Service

public CourseMarket getCourseMarketById(String courseId) {
        Optional<CourseMarket> optional = courseMarketRepository.findById(courseId);
        if (optional.isPresent()) {//在這之前有一個!,找到半天錯誤才找到因為邏輯取反導致出錯
            return optional.get();
        }
        return null;
}
 @Transactional
    public CourseMarket updateCourseMarket(String id, CourseMarket courseMarket) {
        CourseMarket one = this.getCourseMarketById(id);
        if (one != null) {
            one.setCharge(courseMarket.getCharge());
            one.setStartTime(courseMarket.getStartTime());;//課程有效期,開始時間
            one.setEndTime(courseMarket.getEndTime());//課程有效期,結束時間
            one.setPrice(courseMarket.getPrice());
            one.setQq(courseMarket.getQq());
            one.setValid(courseMarket.getValid());
            courseMarketRepository.save(one);
        } else {
            //新增課程營銷資訊
            one = new CourseMarket();
            BeanUtils.copyProperties(courseMarket, one);
            //設定課程id
            one.setId(id);
            courseMarketRepository.save(one);
        }
        return one;
    }

4.4.3 Controller

@Override
    @PostMapping("/coursemarket/update/{id}")
    public ResponseResult updateCourseMarket(@PathVariable("id") String id,@RequestBody CourseMarket courseMarket) {
        CourseMarket courseMarket_u = courseService.updateCourseMarket(id, courseMarket);
        if (courseMarket_u != null) {
            return new ResponseResult(CommonCode.SUCCESS);
        } else {
            return new ResponseResult(CommonCode.FAIL);
        }
    }

    @Override
    @GetMapping("/coursemarket/get/{courseId}")
    public CourseMarket getCourseMarketById(@PathVariable("id") String courseId) {
        return courseService.getCourseMarketById(courseId);
    }

4.5 前端

4.5.1 Api 方法

// 獲取課程營銷資訊
export const getCourseMarketById = id => {
  return http.requestQuickGet(apiUrl + '/course/coursemarket/get/' + id)
}

// 更新課程營銷資訊
export const updateCourseMarket = (id, courseMarket) => {
  return http.requestPost(apiUrl + '/course/coursemarket/update/' + id, courseMarket)
}

4.5.2 頁面

編寫 course_marketinfo.vue

<template>
  <div>
    <el-form :model="courseMarketForm" label-width="110px" :rules="courseMarketFormRules" ref="courseMarketForm">
      <el-form-item label="課程價格" prop="charge">
        <b v-for="charge in chargeList">
          <el-radio v-model="courseMarketForm.charge" :label="charge.sdId" >{{charge.sdName}}</el-radio>
          &nbsp;&nbsp;
        </b>
        <br/>
        金額(元):<el-input :disabled="this.courseMarketForm.charge == '203002'?false:true" v-model="courseMarketForm.price" ></el-input>
      </el-form-item>
      <el-form-item label="課程有效期" prop="expires">
        <b v-for="valid in validList">
          <el-radio v-model="courseMarketForm.valid" :label="valid.sdId" >{{valid.sdName}}</el-radio>&nbsp;&nbsp;
        </b>
        <br/>
        開始時間:
        <el-date-picker :disabled="this.courseMarketForm.valid == '204002'?false:true"  type="date" placeholder="選擇日期" v-model="courseMarketForm.startTime"></el-date-picker>
        結束時間:
        <el-date-picker :disabled="this.courseMarketForm.valid == '204002'?false:true"  type="date" placeholder="選擇日期" v-model="courseMarketForm.endTime"></el-date-picker>
      </el-form-item>
      <el-form-item label="服務諮詢QQ" prop="qq">
        <el-input v-model="courseMarketForm.qq" ></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 {
        active: 1,
        dotype:'',
        courseid:'',
        chargeList:[],
        validList:[],
        price_tag:false,
        expires_tag:false,
        courseMarketForm: {
          id:'',
          charge:'',
          valid:'',
          price:'',
          expires: '',
          startTime: '',
          endTime: '',
          users: '',
          expiration:[],
          courseid:this.courseid
        },
        courseMarketFormRules: {
          free: [
            {required: true, message: '請選擇收費規則', trigger: 'blur'}
          ],
          valid: [
            {required: true, message: '請選擇有效期', trigger: 'blur'}
          ]
        }
      }
    },
    methods: {
      save: function () {
        this.$refs.courseMarketForm.validate((valid) => {
          if (valid) {
            this.$confirm('確認提交嗎?', '提示', {}).then(() => {
              courseApi.updateCourseMarket(this.courseid,this.courseMarketForm).then((res) => {
               this.editLoading = false;
               if(res.success){
                 this.$message.success('提交成功');
                 if(this.dotype == '1'){
                   //跳轉到課程圖片
                   this.$router.push({ path: '/course/add/plan/3/1/'+this.courseid})
                 }
               }else{
                 this.$message.error('提交失敗');
               }
               });
            });
          }
        });
      }
    },
     //在mounted鉤子方法中查詢課程營銷資訊及資料字典資訊
    mounted(){
        //操作型別
      this.dotype = this.$route.params.dotype;
      //課程id
      this.courseid = this.$route.params.courseid;

      this.courseMarketForm.id = this.courseid;
      //查詢字典
      systemApi.sys_getDictionary('203').then((res) => {
        this.chargeList = res.dvalue;
      });
      systemApi.sys_getDictionary('204').then((res) => {
        this.validList = res.dvalue;
      });

      //獲取課程營銷資訊
      courseApi.getCourseMarketById(this.courseid).then((res) => {
         //console.log(res);
        if(res && res.id){
           this.courseMarketForm = res;
        }
      });
    }
  }
</script>
<style scoped>
</style>