ソースを参照

完善创建课程

dusenyao 4 年 前
コミット
8f864b844f

+ 17 - 1
src/api/course.js

@@ -16,8 +16,24 @@ export function CreateCourse(data) {
 }
 
 /**
+ * 修改课程
+ * @param {Object} data
+ * @returns
+ */
+export function UpdateCourse(data) {
+  let params = getRequestParams('teaching-course_manager-UpdateCourse');
+
+  return request({
+    method: 'post',
+    url: process.env.VUE_APP_LearnWebSI,
+    params,
+    data
+  });
+}
+
+/**
  * 得到课程信息(包含课节信息)
- * @param {Object} id 课程ID
+ * @param {Object} { id 课程ID }
  */
 export function GetCourseInfo_ContainCSItem(data) {
   let params = getRequestParams('teaching-course_manager-GetCourseInfo_ContainCSItem');

+ 15 - 0
src/api/list.js

@@ -58,3 +58,18 @@ export function PageQueryOrgTeacherUserList(data) {
     data
   });
 }
+
+/**
+ * 分页查询课程学员列表
+ * @param {Object} data
+ */
+export function PageQueryCourseStudentList(data) {
+  let params = getRequestParams('teaching-course_manager-PageQueryCourseStudentList');
+
+  return request({
+    method: 'post',
+    url: process.env.VUE_APP_LearnWebSI,
+    params,
+    data
+  });
+}

+ 4 - 1
src/components/select/SelectCourse.vue

@@ -81,7 +81,6 @@ export default {
     getCourseBookListByCSItemID() {
       GetCourseBookListByCSItemID({ cs_item_id: this.id }).then(({ book_list }) => {
         this.book_list = book_list;
-
         this.curBook = book_list[0];
       });
     },
@@ -108,6 +107,10 @@ export default {
     color: $color;
   }
 
+  .el-dialog__title {
+    font-weight: 700;
+  }
+
   .el-dropdown-link {
     font-size: 24px;
     color: $color;

+ 6 - 0
src/icons/svg/more.svg

@@ -0,0 +1,6 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M24 0H0V24H24V0Z" fill="white" fill-opacity="0.01"/>
+<path d="M12 7.5C12.8284 7.5 13.5 6.82843 13.5 6C13.5 5.17157 12.8284 4.5 12 4.5C11.1716 4.5 10.5 5.17157 10.5 6C10.5 6.82843 11.1716 7.5 12 7.5Z" fill="#333333"/>
+<path d="M12 13.5C12.8284 13.5 13.5 12.8284 13.5 12C13.5 11.1716 12.8284 10.5 12 10.5C11.1716 10.5 10.5 11.1716 10.5 12C10.5 12.8284 11.1716 13.5 12 13.5Z" fill="#333333"/>
+<path d="M12 19C12.8284 19 13.5 18.3284 13.5 17.5C13.5 16.6716 12.8284 16 12 16C11.1716 16 10.5 16.6716 10.5 17.5C10.5 18.3284 11.1716 19 12 19Z" fill="#333333"/>
+</svg>

+ 7 - 0
src/icons/svg/students.svg

@@ -0,0 +1,7 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M24 0H0V24H24V0Z" fill="white" fill-opacity="0.01"/>
+<path d="M9.5 10C11.433 10 13 8.433 13 6.5C13 4.56701 11.433 3 9.5 3C7.567 3 6 4.56701 6 6.5C6 8.433 7.567 10 9.5 10Z" stroke="#333333" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M16.3038 3.5C17.3202 4.11245 18 5.22685 18 6.5C18 7.77315 17.3202 8.88755 16.3038 9.5" stroke="#333333" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M2 20.4V21H17V20.4C17 18.1598 17 17.0397 16.5641 16.184C16.1806 15.4314 15.5686 14.8195 14.816 14.436C13.9603 14 12.8402 14 10.6 14H8.4C6.1598 14 5.0397 14 4.18404 14.436C3.43139 14.8195 2.81947 15.4314 2.43598 16.184C2 17.0397 2 18.1598 2 20.4Z" stroke="#333333" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M22 20.9996V20.3996C22 18.1594 22 17.0393 21.564 16.1836C21.1805 15.431 20.5686 14.819 19.8159 14.4355" stroke="#333333" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+</svg>

+ 2 - 1
src/layouts/components/BreadCrumb.vue

@@ -1,7 +1,8 @@
 <template>
   <div v-show="isShow" class="breadcrumb">
     <div class="breadcrumb-container">
-      <svg-icon icon-class="homepage" /><i class="el-icon-arrow-right" />
+      <router-link to="/"><svg-icon icon-class="homepage" /></router-link>
+      <i class="el-icon-arrow-right" />
       <span v-for="item in routerList" :key="item.path">
         <span class="router-title">
           <template v-if="item.meta.link">

+ 9 - 4
src/layouts/components/LayoutHeader.vue

@@ -11,9 +11,13 @@
               <i class="el-icon-arrow-down el-icon--right"></i>
             </span>
             <el-dropdown-menu slot="dropdown">
-              <el-dropdown-item v-for="item in dropdownList" :key="item.id">
-                <svg-icon icon-class="teaching-manager" /><span>{{ item.name }}</span>
-              </el-dropdown-item>
+              <template v-for="item in dropdownList">
+                <router-link :key="item.id" :to="item.link">
+                  <el-dropdown-item>
+                    <svg-icon :icon-class="item.icon" /><span>{{ item.name }}</span>
+                  </el-dropdown-item>
+                </router-link>
+              </template>
             </el-dropdown-menu>
           </el-dropdown>
         </span>
@@ -68,7 +72,8 @@ export default {
         {
           id: 1,
           name: '教学管理系统',
-          icon: 'el-icon-search'
+          icon: 'teaching-manager',
+          link: '/'
         }
       ],
       isDot: false,

+ 33 - 18
src/router/index.js

@@ -54,7 +54,7 @@ const routes = [
     path: '/create_course',
     component: Layout,
     redirect: '/create_course/index',
-    meta: { title: '课程列表', link: '/' },
+    meta: { title: '课程列表', link: '/?tab=CurriculaList' },
     children: [
       {
         path: '/create_course/index',
@@ -68,19 +68,23 @@ const routes = [
     component: Layout,
     redirect: '/create_course_step_table/course_info',
     children: [
+      // 分步表单 -> 第一步
       {
         path: '/create_course_step_table/course_info',
         component: () => import('@/views/teacher/create_course/step_table/CourseInfo')
       },
+      // 分步表单 -> 第二步
       {
         path: '/create_course_step_table/select_book/:id',
         name: 'SelectBook',
         component: () => import('@/views/teacher/create_course/step_table/SelectBook')
       },
+      // 分步表单 -> 第三步
       {
         path: '/create_course_step_table/create_task/:id',
         component: () => import('@/views/teacher/create_course/step_table/CreateTask')
       },
+      // 分步表单 -> 第三步 -> 新建课节任务
       {
         path: '/create_course_step_table/new_task/:time_type/:id/:cs_item_id',
         component: () => import('@/views/teacher/create_course/step_table/NewTask')
@@ -88,29 +92,40 @@ const routes = [
     ]
   },
   {
-    path: '/cs_item_detail',
+    path: '/student_list',
     component: Layout,
-    redirect: '/cs_item_detail/index/:id',
+    redirect: '/student_list/index/:id',
     children: [
       {
-        path: '/cs_item_detail/index/:id',
-        name: 'CSItemDetail',
-        component: () => import('@/views/teacher/cs_item_detail')
-      }
-    ]
-  },
-  {
-    path: '/add_course',
-    component: Layout,
-    redirect: '/add_course/index',
-    children: [
-      {
-        path: '/add_course/index',
-        name: 'AddCourse',
-        component: () => import('@/views/teacher/add_course')
+        path: '/student_list/index/:id',
+        component: () => import('@/views/teacher/student_list')
       }
     ]
   },
+  // {
+  //   path: '/cs_item_detail',
+  //   component: Layout,
+  //   redirect: '/cs_item_detail/index/:id',
+  //   children: [
+  //     {
+  //       path: '/cs_item_detail/index/:id',
+  //       name: 'CSItemDetail',
+  //       component: () => import('@/views/teacher/cs_item_detail')
+  //     }
+  //   ]
+  // },
+  // {
+  //   path: '/add_course',
+  //   component: Layout,
+  //   redirect: '/add_course/index',
+  //   children: [
+  //     {
+  //       path: '/add_course/index',
+  //       name: 'AddCourse',
+  //       component: () => import('@/views/teacher/add_course')
+  //     }
+  //   ]
+  // },
   {
     path: '/live',
     component: Layout,

+ 54 - 9
src/views/teacher/create_course/step_table/CourseInfo.vue

@@ -121,7 +121,7 @@
 import StepBar from '@/components/StepBar';
 import SelectTeacher from '@/components/select/SelectTeacher.vue';
 import { fileUpload } from '@/api/app';
-import { CreateCourse } from '@/api/course';
+import { CreateCourse, GetCourseInfo_ContainCSItem, UpdateCourse } from '@/api/course';
 import { twoDecimal } from '@/utils/validate';
 import { getMyOrgList } from '@/api/list';
 import { GetUserListByIDList } from '@/api/user';
@@ -131,6 +131,7 @@ export default {
   components: { StepBar, SelectTeacher },
   data() {
     return {
+      id: this.$route.query.id,
       form: {
         imageUrl: '',
         picture_id: '',
@@ -160,6 +161,43 @@ export default {
     getMyOrgList().then(({ org_list }) => {
       this.orgList = org_list;
     });
+    if (this.id) {
+      GetCourseInfo_ContainCSItem({ id: this.id }).then(
+        ({
+          name,
+          org_id,
+          picture_id,
+          picture_url,
+          intro,
+          begin_date,
+          end_date,
+          student_count_start,
+          is_auto_close,
+          student_enter_control_type,
+          price,
+          is_enable_KHPJ,
+          is_enable_XYZP,
+          teacher_list
+        }) => {
+          this.form.name = name;
+          this.form.org_id = org_id;
+          this.form.picture_id = picture_id;
+          this.form.imageUrl = picture_url;
+          this.form.intro = intro;
+          this.form.date = [begin_date, end_date];
+          this.form.student_count_start = student_count_start;
+          this.form.is_auto_close = is_auto_close === 'true';
+          this.form.student_enter_control_type = student_enter_control_type;
+          this.form.price = price;
+          this.form.is_enable_KHPJ = is_enable_KHPJ === 'true';
+          this.form.is_enable_XYZP = is_enable_XYZP === 'true';
+          teacher_list.forEach(item => {
+            this.form.teacher_id_list.push(item.teacher_id);
+            this.user_list.push({ id: item.teacher_id, real_name: item.teacher_name });
+          });
+        }
+      );
+    }
   },
   methods: {
     nextStep() {
@@ -168,10 +206,18 @@ export default {
           this.form.begin_date = this.form.date[0];
           this.form.end_date = this.form.date[1];
 
-          CreateCourse(this.form).then(response => {
-            this.$message.success('创建课程成功!');
-            this.$router.push({ path: `/create_course_step_table/select_book/${response.id}` });
-          });
+          if (this.id) {
+            this.form.id = this.id;
+            UpdateCourse(this.form).then(() => {
+              this.$message.success('修改课程成功!');
+              this.$router.push({ path: `/create_course_step_table/select_book/${this.id}` });
+            });
+          } else {
+            CreateCourse(this.form).then(res => {
+              this.$message.success('创建课程成功!');
+              this.$router.push({ path: `/create_course_step_table/select_book/${res.id}` });
+            });
+          }
         } else {
           return false;
         }
@@ -208,8 +254,8 @@ export default {
     dialogClose() {
       this.dialogVisible = false;
     },
-    selectTeaher(orgList) {
-      this.form.teacher_id_list = this.form.teacher_id_list.concat(orgList);
+    selectTeaher(teacherList) {
+      this.form.teacher_id_list = this.form.teacher_id_list.concat(teacherList);
       this.dialogVisible = false;
       this.getUserList();
     },
@@ -220,8 +266,7 @@ export default {
     },
     // 授课教师 tag 删除事件
     tagClose(id, index) {
-      let list = this.user_list;
-      list.splice(index, 1);
+      this.user_list.splice(index, 1);
 
       let teacherList = this.form.teacher_id_list;
       teacherList.splice(teacherList.indexOf(id), 1);

+ 3 - 2
src/views/teacher/create_course/step_table/CreateTask.vue

@@ -12,7 +12,6 @@
     <!--按钮-->
     <div class="task-button">
       <el-button class="prev-step" @click="preStep"><i class="el-icon-back" />选择教材</el-button>
-      <el-button class="preserve" type="primary"><svg-icon icon-class="preserve" />保存</el-button>
       <el-button><router-link to="/create_course">关闭</router-link></el-button>
     </div>
     <!--任务课节-->
@@ -352,7 +351,9 @@ export default {
           this.begin_date = begin_date;
           this.end_date = end_date;
           this.cs_item_list = cs_item_list;
-          this.curItemID = cs_item_list[cs_item_list.length - 1].id;
+          if (cs_item_list.length > 0) {
+            this.curItemID = cs_item_list[cs_item_list.length - 1].id;
+          }
         }
       );
     },

+ 21 - 24
src/views/teacher/create_course/step_table/SelectBook.vue

@@ -26,7 +26,7 @@
                 :class="['book-list-item-img', { selected: item.is_selected === 'true' }]"
                 @click="addOrRemoveBookToCourse($event, item.id)"
               >
-                <img :src="item.picture_url" alt="book" />
+                <el-image :src="item.picture_url" />
               </div>
               <div class="book-list-item-name">{{ item.name }}</div>
             </div>
@@ -42,7 +42,9 @@
               @current-change="changePage"
             />
             <div>
-              <el-button class="prev-step"><i class="el-icon-back" />课程信息</el-button>
+              <el-button class="prev-step" @click="prevCourseInfo">
+                <i class="el-icon-back" />课程信息
+              </el-button>
               <el-button type="primary" class="next-step" @click="nextStep">
                 下一步<i class="el-icon-right" />
               </el-button>
@@ -96,36 +98,29 @@ export default {
       this.queryBookList();
     },
     addOrRemoveBookToCourse(e, book_id) {
-      let isSelected = false;
-      let classList;
-      if (e.target.classList.contains('book-list-item-img')) {
-        classList = e.target.classList;
-        isSelected = classList.contains('selected');
-      } else {
-        classList = e.target.parentElement.classList;
-        isSelected = classList.contains('selected');
-      }
+      let classList = e.target.parentElement.parentElement.classList;
+      let isSelected = classList.contains('selected');
+
       let data = {
         course_id: this.id,
         book_id
       };
 
       if (isSelected) {
-        RemoveBookFromCourse(data).then(({ status }) => {
-          if (status === 1) {
-            this.$message.success('移除教材成功');
-            classList.remove('selected');
-          }
+        RemoveBookFromCourse(data).then(() => {
+          this.$message.success('移除教材成功');
+          classList.remove('selected');
         });
       } else {
-        AddBookToCourse(data).then(({ status }) => {
-          if (status === 1) {
-            this.$message.success('为课程添加教材成功');
-            classList.add('selected');
-          }
+        AddBookToCourse(data).then(() => {
+          this.$message.success('为课程添加教材成功');
+          classList.add('selected');
         });
       }
     },
+    prevCourseInfo() {
+      this.$router.push(`/create_course_step_table/course_info?id=${this.id}`);
+    },
     nextStep() {
       this.$router.push({ path: `/create_course_step_table/create_task/${this.id}` });
     }
@@ -145,6 +140,7 @@ export default {
     background-color: #fff;
     width: $basicWidth;
     min-width: $basicWidth;
+    min-height: 674px;
     padding: 24px 32px;
     border-radius: 8px;
 
@@ -175,15 +171,16 @@ export default {
       }
 
       .book {
-        height: calc(100vh - #{$header-h} - #{$step-h} - 224px);
+        // height: calc(100vh - #{$header-h} - #{$step-h} - 224px);
         display: flex;
         flex-direction: column;
         justify-content: space-between;
 
         &-list {
           display: flex;
-          justify-content: space-between;
+          justify-content: flex-start;
           flex-wrap: wrap;
+          margin-bottom: 50px;
 
           &-item {
             display: inline-block;
@@ -198,7 +195,7 @@ export default {
               cursor: pointer;
               position: relative;
 
-              img {
+              .el-image {
                 width: 100%;
                 height: 100%;
               }

+ 32 - 0
src/views/teacher/main/CurriculaList.vue

@@ -31,6 +31,20 @@
         <el-table :data="courseList">
           <el-table-column prop="name" label="课程名称" width="240" />
           <el-table-column prop="begin_date" label="课程周期" />
+          <el-table-column fixed="right" width="80">
+            <template slot-scope="scope">
+              <el-dropdown trigger="click">
+                <span class="el-dropdown-link">
+                  <svg-icon icon-class="more"></svg-icon>
+                </span>
+                <el-dropdown-menu slot="dropdown">
+                  <el-dropdown-item @click.native="studentList(scope.row.id)">
+                    <svg-icon icon-class="students" /> Students
+                  </el-dropdown-item>
+                </el-dropdown-menu>
+              </el-dropdown>
+            </template>
+          </el-table-column>
         </el-table>
       </div>
     </div>
@@ -96,6 +110,7 @@ export default {
     queryMyCourseList() {
       const queryCriteria = {
         finish_status: this.finish_status,
+        name: this.search,
         page_capacity: this.page_capacity,
         cur_page: this.cur_page
       };
@@ -103,6 +118,9 @@ export default {
         this.courseList = course_list;
         this.total_count = total_count;
       });
+    },
+    studentList(id) {
+      this.$router.push(`/student_list/index/${id}`);
     }
   }
 };
@@ -167,7 +185,21 @@ export default {
 
     &-list {
       @include list;
+
+      .el-dropdown {
+        cursor: pointer;
+
+        .svg-icon {
+          font-size: 19px;
+        }
+      }
     }
   }
 }
 </style>
+
+<style scope>
+.el-dropdown-menu .svg-icon {
+  margin-right: 8px;
+}
+</style>

+ 9 - 10
src/views/teacher/main/TaskList.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="tasks">
     <div class="tasks-top">
-      <el-calendar v-model="dateTime" />
+      <el-calendar v-model="date" />
       <div class="tasks-top-notification">
         <div class="tasks-top-notification-title">
           <div>
@@ -70,14 +70,13 @@ export default {
     };
   },
   computed: {
-    dateTime: {
-      get: function () {
-        return parseTime(this.date, '{m}-{d}');
-      },
-      set: function (newValue) {
-        this.date = newValue;
-        this.getTaskList();
-      }
+    dateTime: function () {
+      return parseTime(this.date, '{m}-{d}');
+    }
+  },
+  watch: {
+    date: function () {
+      this.getTaskList();
     }
   },
   mounted() {
@@ -120,7 +119,7 @@ export default {
     },
     dateSkip(num) {
       let day = 24 * 60 * 60 * 1000 * num;
-      this.dateTime = new Date(this.date.getTime() + day);
+      this.date = new Date(this.date.getTime() + day);
     },
     getTaskList() {
       GetMyDayTaskList({ date_stamp: formatDate(this.date) }).then(response => {

+ 1 - 1
src/views/teacher/main/index.vue

@@ -28,7 +28,7 @@ export default {
   },
   data() {
     return {
-      currentTab: 'TaskList',
+      currentTab: this.$route.query.tab || 'TaskList',
       menuList: [
         {
           id: 1,

+ 173 - 0
src/views/teacher/student_list/index.vue

@@ -0,0 +1,173 @@
+<template>
+  <div class="student-list">
+    <div class="search">
+      <el-input
+        v-model="student_name"
+        prefix-icon="el-icon-search"
+        @change="queryCourseStudentList"
+      >
+        <el-button slot="append" @click="queryCourseStudentList">搜索</el-button>
+      </el-input>
+    </div>
+    <div class="student-list-container">
+      <div class="tabs">
+        <div class="tabs-left">
+          <span
+            v-for="item in tabList"
+            :key="item.id"
+            :class="['tabs-item', { active: item.id === activeID }]"
+            @click="changeTab(item.id)"
+          >
+            {{ item.name }}
+          </span>
+        </div>
+        <div></div>
+      </div>
+      <div class="student-table">
+        <el-table :data="student_list">
+          <el-table-column prop="student_name" width="240" />
+          <el-table-column prop="age" width="100">
+            <template slot-scope="scope"> {{ scope.row.age }}岁 </template>
+          </el-table-column>
+          <el-table-column prop="org_name" width="180" />
+          <el-table-column prop="country_name" />
+        </el-table>
+      </div>
+    </div>
+    <el-pagination
+      background
+      :page-sizes="[10, 20, 30, 40, 50]"
+      :page-size="page_capacity"
+      layout="prev, pager, next, total, sizes, jumper"
+      :total="total_count"
+      :current-page="cur_page"
+      @prev-click="changePage"
+      @next-click="changePage"
+      @current-change="changePage"
+      @size-change="changePageSize"
+    />
+  </div>
+</template>
+
+<script>
+import { PageQueryCourseStudentList } from '@/api/list';
+
+export default {
+  data() {
+    return {
+      course_id: this.$route.params.id,
+      student_name: '',
+      activeID: 'new',
+      student_list: [],
+      page_capacity: 10,
+      cur_page: 1,
+      total_count: 0,
+      tabList: [
+        {
+          id: 'new',
+          name: '新申请'
+        },
+        {
+          id: 'list',
+          name: '学生列表'
+        }
+      ]
+    };
+  },
+  created() {
+    this.queryCourseStudentList();
+  },
+  methods: {
+    queryCourseStudentList() {
+      let data = {
+        student_name: this.student_name,
+        course_id: this.course_id,
+        page_capacity: this.page_capacity,
+        cur_page: this.cur_page
+      };
+
+      // if (this.activeID === 'new') {
+      //   data['audit_status_list'] = [0];
+      // } else {
+      //   data['audit_status_list'] = [1];
+      // }
+      console.log(data);
+      PageQueryCourseStudentList(data).then(({ student_list, total_count }) => {
+        this.student_list = student_list;
+        this.total_count = total_count;
+      });
+    },
+    changeTab(id) {
+      this.activeID = id;
+      this.queryCourseStudentList();
+    },
+    changePage(newPage) {
+      this.cur_page = newPage;
+      this.queryCourseStudentList();
+    },
+    changePageSize(pageSize) {
+      this.page_capacity = pageSize;
+      this.queryCourseStudentList();
+    }
+  }
+};
+</script>
+
+<style lang="scss">
+@import '~@/styles/mixin.scss';
+
+.student-list {
+  @include container;
+  @include pagination;
+
+  & .search .el-input {
+    width: 528px;
+  }
+
+  &-container {
+    width: 100%;
+    padding: 24px 32px;
+    min-height: calc(100vh - 240px);
+    margin-top: 16px;
+    background-color: #fff;
+    border-radius: 8px;
+
+    // 标签
+    & .tabs {
+      display: flex;
+      border-bottom: 1px solid #d9d9d9;
+
+      &-left {
+        display: flex;
+
+        .tabs-item {
+          cursor: pointer;
+          font-size: 18px;
+          padding-bottom: 16px;
+
+          &.active {
+            font-weight: 600;
+            border-bottom: 2px solid $basicColor;
+          }
+
+          &:not(:first-child) {
+            margin-left: 24px;
+          }
+        }
+      }
+    }
+
+    // 学员列表
+    & .student-table {
+      @include list;
+
+      margin-top: 0;
+      min-height: calc(100vh - 343px);
+
+      .el-table__header {
+        display: none;
+      }
+    }
+  }
+}
+</style>