Browse Source

update 首页样式与功能

dusenyao 3 years ago
parent
commit
493b10d7c4

+ 35 - 24
package-lock.json

@@ -13,6 +13,7 @@
         "axios": "^0.24.0",
         "book-ui": "file:../book-ui-0.1.26.tgz",
         "core-js": "^3.19.1",
+        "dayjs": "^1.10.7",
         "element-ui": "^2.15.6",
         "gcls-book-question-ui": "file:../gcls-book-question-ui-0.1.0.tgz",
         "jquery": "^3.6.0",
@@ -46,8 +47,8 @@
         "eslint-plugin-prettier": "^4.0.0",
         "eslint-plugin-vue": "^7.20.0",
         "html-webpack-plugin": "^5.3.1",
-        "postcss": "^8.3.11",
-        "postcss-html": "^1.2.0",
+        "postcss": "^8.4.1",
+        "postcss-html": "^1.3.0",
         "prettier": "2.4.1",
         "sass": "^1.43.4",
         "sass-loader": "^10.2.0",
@@ -8460,6 +8461,11 @@
         "webidl-conversions": "^4.0.2"
       }
     },
+    "node_modules/dayjs": {
+      "version": "1.10.7",
+      "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.7.tgz",
+      "integrity": "sha512-P6twpd70BcPK34K26uJ1KT3wlhpuOAPoMwJzpsIWUxHZ7wpmbdZL/hQqBDfz7hGurYSa5PhzdhDHtt319hL3ig=="
+    },
     "node_modules/de-indent": {
       "version": "1.0.2",
       "resolved": "https://registry.npm.taobao.org/de-indent/download/de-indent-1.0.2.tgz",
@@ -16638,14 +16644,14 @@
       }
     },
     "node_modules/postcss": {
-      "version": "8.3.11",
-      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.11.tgz",
-      "integrity": "sha512-hCmlUAIlUiav8Xdqw3Io4LcpA1DOt7h3LSTAC4G6JGHFFaWzI6qvFt9oilvl8BmkbBRX1IhM90ZAmpk68zccQA==",
+      "version": "8.4.1",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.1.tgz",
+      "integrity": "sha512-WqLs/TTzXdG+/A4ZOOK9WDZiikrRaiA+eoEb/jz2DT9KUhMNHgP7yKPO8vwi62ZCsb703Gwb7BMZwDzI54Y2Ag==",
       "dev": true,
       "dependencies": {
         "nanoid": "^3.1.30",
         "picocolors": "^1.0.0",
-        "source-map-js": "^0.6.2"
+        "source-map-js": "^1.0.1"
       },
       "engines": {
         "node": "^10 || ^12 || >=14"
@@ -16980,13 +16986,13 @@
       }
     },
     "node_modules/postcss-html": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/postcss-html/-/postcss-html-1.2.0.tgz",
-      "integrity": "sha512-DEuVLHIf8wwqJtLAVGj0ol00PJFB9byPDZF+p56CAC5ktdlF9lFzLdhqbPxBza/jpBYwn17+fGeqvXxYh+h+CQ==",
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/postcss-html/-/postcss-html-1.3.0.tgz",
+      "integrity": "sha512-ewbwd7OGW4dLsErtvZH9HpVMEcXnlhYSzKsr7MepGlOT8imHTIZ/+pdfEruLS+hTYapLTQAWDnoQcJpsYU4uRw==",
       "dev": true,
       "dependencies": {
         "htmlparser2": "^7.1.2",
-        "postcss": "^8.3.11",
+        "postcss": "^8.4.0",
         "postcss-safe-parser": "^6.0.0"
       },
       "engines": {
@@ -20597,9 +20603,9 @@
       }
     },
     "node_modules/source-map-js": {
-      "version": "0.6.2",
-      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-0.6.2.tgz",
-      "integrity": "sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug==",
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.1.tgz",
+      "integrity": "sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
@@ -31652,6 +31658,11 @@
         }
       }
     },
+    "dayjs": {
+      "version": "1.10.7",
+      "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.7.tgz",
+      "integrity": "sha512-P6twpd70BcPK34K26uJ1KT3wlhpuOAPoMwJzpsIWUxHZ7wpmbdZL/hQqBDfz7hGurYSa5PhzdhDHtt319hL3ig=="
+    },
     "de-indent": {
       "version": "1.0.2",
       "resolved": "https://registry.npm.taobao.org/de-indent/download/de-indent-1.0.2.tgz",
@@ -38141,14 +38152,14 @@
       "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs="
     },
     "postcss": {
-      "version": "8.3.11",
-      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.11.tgz",
-      "integrity": "sha512-hCmlUAIlUiav8Xdqw3Io4LcpA1DOt7h3LSTAC4G6JGHFFaWzI6qvFt9oilvl8BmkbBRX1IhM90ZAmpk68zccQA==",
+      "version": "8.4.1",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.1.tgz",
+      "integrity": "sha512-WqLs/TTzXdG+/A4ZOOK9WDZiikrRaiA+eoEb/jz2DT9KUhMNHgP7yKPO8vwi62ZCsb703Gwb7BMZwDzI54Y2Ag==",
       "dev": true,
       "requires": {
         "nanoid": "^3.1.30",
         "picocolors": "^1.0.0",
-        "source-map-js": "^0.6.2"
+        "source-map-js": "^1.0.1"
       }
     },
     "postcss-calc": {
@@ -38402,13 +38413,13 @@
       }
     },
     "postcss-html": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/postcss-html/-/postcss-html-1.2.0.tgz",
-      "integrity": "sha512-DEuVLHIf8wwqJtLAVGj0ol00PJFB9byPDZF+p56CAC5ktdlF9lFzLdhqbPxBza/jpBYwn17+fGeqvXxYh+h+CQ==",
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/postcss-html/-/postcss-html-1.3.0.tgz",
+      "integrity": "sha512-ewbwd7OGW4dLsErtvZH9HpVMEcXnlhYSzKsr7MepGlOT8imHTIZ/+pdfEruLS+hTYapLTQAWDnoQcJpsYU4uRw==",
       "dev": true,
       "requires": {
         "htmlparser2": "^7.1.2",
-        "postcss": "^8.3.11",
+        "postcss": "^8.4.0",
         "postcss-safe-parser": "^6.0.0"
       },
       "dependencies": {
@@ -41223,9 +41234,9 @@
       "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
     },
     "source-map-js": {
-      "version": "0.6.2",
-      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-0.6.2.tgz",
-      "integrity": "sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug==",
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.1.tgz",
+      "integrity": "sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA==",
       "dev": true
     },
     "source-map-resolve": {

+ 4 - 3
package.json

@@ -18,6 +18,7 @@
     "axios": "^0.24.0",
     "book-ui": "file:../book-ui-0.1.26.tgz",
     "core-js": "^3.19.1",
+    "dayjs": "^1.10.7",
     "element-ui": "^2.15.6",
     "gcls-book-question-ui": "file:../gcls-book-question-ui-0.1.0.tgz",
     "jquery": "^3.6.0",
@@ -51,10 +52,10 @@
     "eslint-plugin-prettier": "^4.0.0",
     "eslint-plugin-vue": "^7.20.0",
     "html-webpack-plugin": "^5.3.1",
-    "postcss": "^8.3.11",
-    "postcss-html": "^1.2.0",
+    "postcss": "^8.4.1",
+    "postcss-html": "^1.3.0",
     "prettier": "2.4.1",
-    "sass": "^1.43.4",
+    "sass": "^1.43.5",
     "sass-loader": "^10.2.0",
     "script-ext-html-webpack-plugin": "^2.1.5",
     "stylelint": "^14.0.1",

+ 15 - 0
src/api/list.js

@@ -73,3 +73,18 @@ export function PageQueryCourseStudentList(data) {
     data
   });
 }
+
+/**
+ * 得到我的任务所属课程列表(用于主页显示)
+ * @param {Object} data
+ */
+export function GetMyCourseList_TaskBelong(data) {
+  let params = getRequestParams('cominfo_query-task_query-GetMyCourseList_TaskBelong');
+
+  return request({
+    method: 'post',
+    url: process.env.VUE_APP_LearnWebSI,
+    params,
+    data
+  });
+}

+ 1 - 0
src/icons/svg/arrival.svg

@@ -0,0 +1 @@
+<svg width="24" height="24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M17.207 9.707a1 1 0 0 0-1.414-1.414L10.5 13.586l-2.293-2.293a1 1 0 0 0-1.414 1.414l3 3a1 1 0 0 0 1.414 0l6-6Z" fill="currentColor" /><path fill-rule="evenodd" clip-rule="evenodd" d="M3 2a1 1 0 0 0-1 1v18a1 1 0 0 0 1 1h18a1 1 0 0 0 1-1V3a1 1 0 0 0-1-1h-6a1 1 0 0 0-.922.613c-.287.685-.615 1.119-.944 1.379-.315.248-.678.377-1.134.377-.456 0-.82-.129-1.134-.377-.329-.26-.657-.694-.944-1.379A1 1 0 0 0 9 2H3Zm1 18V4h4.368c.334.626.748 1.158 1.259 1.561A3.746 3.746 0 0 0 12 6.37c.882 0 1.687-.266 2.373-.808.511-.403.925-.935 1.259-1.561H20v16H4Z" fill="currentColor" /></svg>

+ 1 - 0
src/icons/svg/calendar.svg

@@ -0,0 +1 @@
+<svg width="24" height="24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M8 1a1 1 0 0 1 1 1v.5h6V2a1 1 0 1 1 2 0v.5h3.5a2 2 0 0 1 2 2V20a2 2 0 0 1-2 2h-17a2 2 0 0 1-2-2V4.5a2 2 0 0 1 2-2H7V2a1 1 0 0 1 1-1ZM7 4.5H3.5v4h17v-4H17V6a1 1 0 1 1-2 0V4.5H9V6a1 1 0 0 1-2 0V4.5Zm13.5 6h-17V20h17v-9.5ZM6 13a1 1 0 0 1 1-1h3a1 1 0 1 1 0 2H7a1 1 0 0 1-1-1Zm7 0a1 1 0 0 1 1-1h3a1 1 0 1 1 0 2h-3a1 1 0 0 1-1-1Zm-7 4a1 1 0 0 1 1-1h3a1 1 0 1 1 0 2H7a1 1 0 0 1-1-1Zm7 0a1 1 0 0 1 1-1h3a1 1 0 1 1 0 2h-3a1 1 0 0 1-1-1Z" fill="#000" fill-opacity=".85"/></svg>

+ 1 - 0
src/icons/svg/schedule.svg

@@ -0,0 +1 @@
+<svg width="24" height="24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M7 10.5a1 1 0 1 0 0 2h5.5a1 1 0 1 0 0-2H7Zm-1 5a1 1 0 0 1 1-1h10a1 1 0 1 1 0 2H7a1 1 0 0 1-1-1Z" fill="#000" fill-opacity=".25"/><path fill-rule="evenodd" clip-rule="evenodd" d="M7 2a1 1 0 0 1 1 1v1h8V3a1 1 0 1 1 2 0v1h3a2 2 0 0 1 2 2v13a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h3V3a1 1 0 0 1 1-1Zm9 4v1a1 1 0 1 0 2 0V6h3v13H3V6h3v1a1 1 0 0 0 2 0V6h8Z" fill="#000" fill-opacity=".25"/></svg>

+ 1 - 0
src/icons/svg/task.svg

@@ -0,0 +1 @@
+<svg width="24" height="24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M17.207 9.707a1 1 0 0 0-1.414-1.414L10.5 13.586l-2.293-2.293a1 1 0 0 0-1.414 1.414l3 3a1 1 0 0 0 1.414 0l6-6Z" fill="#3479FF"/><path fill-rule="evenodd" clip-rule="evenodd" d="M3 2a1 1 0 0 0-1 1v18a1 1 0 0 0 1 1h18a1 1 0 0 0 1-1V3a1 1 0 0 0-1-1h-6a1 1 0 0 0-.922.613c-.287.685-.615 1.119-.944 1.379-.315.248-.678.377-1.134.377-.456 0-.82-.129-1.134-.377-.329-.26-.657-.694-.944-1.379A1 1 0 0 0 9 2H3Zm1 18V4h4.368c.334.626.748 1.158 1.259 1.561A3.746 3.746 0 0 0 12 6.37c.882 0 1.687-.266 2.373-.808.511-.403.925-.935 1.259-1.561H20v16H4Z" fill="#3479FF"/></svg>

+ 5 - 0
src/styles/common.scss

@@ -12,3 +12,8 @@
 .tip {
   color: #aaa;
 }
+
+svg.svg-normal.svg-icon {
+  width: 24px;
+  height: 24px;
+}

+ 0 - 0
src/styles/fonts.scss


BIN
src/styles/fonts/D-DIN-Bold.ttf


BIN
src/styles/fonts/D-DIN-Italic.ttf


BIN
src/styles/fonts/D-DIN.ttf


BIN
src/styles/fonts/D-DINCondensed-Bold.ttf


BIN
src/styles/fonts/D-DINCondensed.ttf


BIN
src/styles/fonts/D-DINExp-Bold.ttf


BIN
src/styles/fonts/D-DINExp-Italic.ttf


BIN
src/styles/fonts/D-DINExp.ttf


+ 1 - 1
src/views/login/index.vue

@@ -148,7 +148,7 @@ export default {
   width: 100%;
   min-height: 100%;
   overflow: hidden;
-  background-color: #f5f5f5;
+  background-color: $bac-color;
 
   .title-container {
     position: relative;

+ 216 - 64
src/views/main/TaskList.vue

@@ -3,110 +3,201 @@
     <div class="tasks-left">
       <!-- 菜单 -->
       <div class="menu">
-        <span v-for="{ tab, name } in menuList" :key="tab" :class="['menu-item', tab === 'TaskList' ? 'active' : '']">
-          {{ name }}
-        </span>
+        <template v-for="{ tab, name, isShow } in menuList">
+          <span
+            v-if="isShow"
+            :key="tab"
+            :class="['menu-item', tab === 'TaskList' ? 'active' : '']"
+            @click="changeTab(tab)"
+          >
+            {{ name }}
+          </span>
+        </template>
       </div>
       <!-- 日历 -->
-      <div class="calendar" />
+      <monthly-calendar ref="calendar" @changeTimeUnit="changeTimeUnit" @changeDate="changeDate" />
       <!-- 通知 -->
       <div class="notice">
         <div class="notice-title">
-          <svg-icon icon-class="task-notification" />
+          <svg-icon icon-class="task-notification" class-name="svg-normal" />
           <span>通知</span>
-          <span class="notice-title-link">全部 <i class="el-icon-arrow-right" /></span>
+          <span class="notice-title-link" @click="goPersonal">全部 <i class="el-icon-arrow-right" /></span>
+        </div>
+        <!-- 通知列表 -->
+        <div class="notice-container">
+          <ul>
+            <li v-for="{ id, is_read, content, send_time, source_entity_id } in message_list" :key="id">
+              <span class="is-read" v-text="is_read === 'false' ? 'new' : ''" />
+              <span
+                class="notice-content"
+                :style="{ color: is_read === 'true' ? '#8c8c8c' : '#000' }"
+                @click="readMyMessage(id, source_entity_id)"
+              >
+                {{ content }}
+              </span>
+              <span class="send-time">{{ send_time }}</span>
+            </li>
+          </ul>
         </div>
-        <div class="notice-container" />
       </div>
     </div>
+
     <div class="tasks-right">
       <div class="task-title">
-        <svg-icon icon-class="task-list" /><span class="task-title-name">任务列表</span>
+        <svg-icon icon-class="task-list" class-name="svg-normal" /><span class="task-title-name">任务列表</span>
         <div class="curricula-type">
           <span
             v-for="{ constant, name } in taskTimeList"
             :key="constant"
-            :class="['curricula-type-item', curTaskTime === constant ? 'active' : '']"
+            :class="['curricula-type-item', timeType === constant ? 'active' : '']"
+            @click="changeTaskTime(constant)"
           >
             {{ name }}
           </span>
         </div>
-        <el-select />
+        <span class="select-prefix">
+          <svg-icon icon-class="schedule" class-name="svg-normal" />
+        </span>
+        <el-select v-model="course_id" @change="changeCourse">
+          <el-option v-for="{ id, name } in course_list" :key="id" :label="name" :value="id" />
+        </el-select>
+      </div>
+
+      <div class="task-container">
+        <ul v-for="({ task_list }, i) in task_group_list" :key="i" class="task-list">
+          <li
+            v-for="({ id, cs_item_name, time_type, course_name, teaching_type }, j) in task_list"
+            :key="id"
+            class="task-item"
+            :style="{
+              'background-color': colorMatching[i % 6].background,
+              color: colorMatching[i % 6].main,
+              border: `1px solid ${colorMatching[i % 6].border}`
+            }"
+            @click="taskLink_outside(id)"
+          >
+            <div class="task-item-top">
+              <svg-icon icon-class="arrival" :style="{ color: colorMatching[i % 6].main }" />
+              <span class="cs-item-name">{{ cs_item_name }}</span>
+              <span
+                class="task-button"
+                :style="{ 'background-color': buttonColorList[j % 2] }"
+                @click.stop="taskLink(teaching_type, id)"
+              >
+                {{ getTimeTypeName(time_type) }}任务
+              </span>
+            </div>
+            <div class="task-item-bottom">
+              <span>{{ course_name }}</span>
+            </div>
+          </li>
+        </ul>
       </div>
-      <div />
     </div>
   </div>
 </template>
 
 <script>
-import { GetMyDayTaskList, PageQueryMyMessageList, GetMyTaskList } from '@/api/table';
+import { PageQueryMyMessageList, GetMyTaskList } from '@/api/table';
 import { CreateEnterLiveRoomSession } from '@/api/live';
-import { parseTime, formatDate } from '@/utils';
 import { ReadMyMessage } from '@/api/user';
-import { colorMatching, getMenuList } from './data';
+import { colorMatching, getMenuList, buttonColorList } from './data';
 import { taskTimeList } from '@/common/data';
+import { GetMyCourseList_TaskBelong } from '@/api/list';
+import MonthlyCalendar from './components/MonthlyCalendar';
 
 export default {
   name: 'TaskList',
+  components: {
+    MonthlyCalendar
+  },
   data() {
     return {
       colorMatching,
+      buttonColorList,
       taskTimeList,
-      date: new Date(),
+      course_id: '',
       selected: '',
-      curTaskTime: -1,
+      timeType: -1,
       menuList: getMenuList(),
       task_group_list: [],
-      message_list: []
+      message_list: [],
+      course_list: []
     };
   },
   computed: {
-    dateTime() {
-      return parseTime(this.date, '{m}-{d}');
-    }
-  },
-  watch: {
-    date() {
-      this.getTaskList();
+    time_unit() {
+      return this.$refs.calendar.time_unit;
     }
   },
   created() {
     PageQueryMyMessageList({
       read_status: -1,
       message_type: -1,
-      page_capacity: 5,
+      page_capacity: 4,
       cur_page: 1
     }).then(({ message_list }) => {
       this.message_list = message_list;
     });
-    GetMyTaskList({
-      time_type: this.time_type
-    });
   },
   mounted() {
-    this.getTaskList();
+    this.init();
   },
   methods: {
-    timeType(type) {
-      switch (type) {
-        case 0:
-          return '课前';
-        case 1:
-          return '课中';
-        case 2:
-          return '课后';
-        default:
-          return '';
-      }
+    getTimeTypeName(type) {
+      if (type === 0) return '课前';
+      if (type === 1) return '课中';
+      if (type === 2) return '课后';
+      return '';
     },
 
-    teachingType(type) {
-      switch (type) {
-        case 10:
-          return '进入直播间';
-        default:
-          return '查看';
-      }
+    getMyCourseList_TaskBelong() {
+      let { curYear, curMonth, focusDate } = this.$refs.calendar;
+      GetMyCourseList_TaskBelong({
+        time_unit: this.time_unit,
+        date_stamp: `${curYear}-${curMonth}-${focusDate}`,
+        month_stamp: `${curYear}-${curMonth}`
+      }).then(({ course_list }) => {
+        this.course_list = course_list;
+      });
+    },
+
+    getMyTaskList() {
+      let { curYear, curMonth, focusDate } = this.$refs.calendar;
+      GetMyTaskList({
+        time_unit: this.time_unit,
+        date_stamp: `${curYear}-${curMonth}-${focusDate}`,
+        month_stamp: `${curYear}-${curMonth}`,
+        time_type: this.timeType,
+        course_id: this.course_id
+      }).then(({ task_group_list }) => {
+        this.task_group_list = task_group_list;
+      });
+    },
+
+    // 改变任务时间类型
+    changeTaskTime(constant) {
+      this.timeType = constant;
+      this.getMyTaskList();
+    },
+
+    changeTimeUnit() {
+      this.init();
+    },
+
+    changeDate() {
+      this.init();
+    },
+
+    init() {
+      this.course_id = '';
+      this.getMyTaskList();
+      this.getMyCourseList_TaskBelong();
+    },
+
+    changeCourse(val) {
+      if (val.length <= 0) return;
+      this.getMyTaskList();
     },
 
     taskLink(type, task_id) {
@@ -131,11 +222,6 @@ export default {
       );
     },
 
-    dateSkip(num) {
-      let day = 24 * 60 * 60 * 1000 * num;
-      this.date = new Date(this.date.getTime() + day);
-    },
-
     readMyMessage(id, source_entity_id) {
       ReadMyMessage({ id }).then(() => {
         this.taskLink_outside(source_entity_id);
@@ -146,10 +232,8 @@ export default {
       window.location.href = `/GCLS-Personal/#/EnterSys`;
     },
 
-    getTaskList() {
-      GetMyDayTaskList({ date_stamp: formatDate(this.date) }).then(response => {
-        this.task_group_list = response.task_group_list;
-      });
+    changeTab(tab) {
+      this.$emit('changeTab', tab);
     }
   }
 };
@@ -188,7 +272,8 @@ export default {
       }
     }
 
-    .calendar {
+    // 日历
+    .monthly-calendar {
       height: 498px;
       padding: 32px;
       margin: 16px 0;
@@ -207,11 +292,6 @@ export default {
         align-items: center;
         justify-content: space-between;
 
-        .svg-icon {
-          width: 24px;
-          height: 24px;
-        }
-
         > span:first-of-type {
           flex: 1;
           padding-left: 16px;
@@ -221,11 +301,42 @@ export default {
           color: #bababa;
         }
       }
+
+      &-container {
+        height: 100%;
+        overflow: auto;
+
+        ul {
+          margin-top: 16px;
+
+          li {
+            display: flex;
+            padding: 8px 0;
+            border-bottom: 1px solid $border-color;
+
+            .is-read {
+              width: 80px;
+              color: $basic-color;
+            }
+
+            .notice-content {
+              width: 230px;
+              margin-right: 16px;
+              cursor: pointer;
+            }
+
+            .send-time {
+              color: #8c8c8c;
+            }
+          }
+        }
+      }
     }
   }
 
   &-right {
     width: 802px;
+    height: calc(100vh - 119px);
     padding: 16px 24px;
     background-color: #fff;
     border-radius: 8px;
@@ -247,7 +358,7 @@ export default {
         height: 40px;
         margin: 0 16px;
         color: #8c8c8c;
-        background-color: #f5f5f5;
+        background-color: $bac-color;
         border: 1px solid $border-color;
         border-radius: 8px;
 
@@ -266,10 +377,51 @@ export default {
         }
       }
 
-      .el-select {}
+      .select-prefix {
+        padding: 6px;
+        margin-right: -1px;
+        border: 1px solid $border-color;
+        border-radius: 8px 0 0 8px;
+      }
+
+      .el-select {
+        width: calc(100% - 360px);
+      }
     }
 
     .task-container {
+      height: calc(100% - 50px);
+      overflow: auto;
+
+      .task-list {
+        .task-item {
+          padding: 16px 24px;
+          margin-top: 16px;
+          cursor: pointer;
+          border-radius: 8px;
+
+          &-top {
+            display: flex;
+            margin-bottom: 8px;
+
+            .cs-item-name {
+              flex: 1;
+              margin-left: 10px;
+            }
+
+            .task-button {
+              padding: 4px 8px;
+              color: #fff;
+              border-radius: 8px;
+            }
+          }
+
+          &-bottom {
+            font-size: 14px;
+            color: #808080;
+          }
+        }
+      }
     }
   }
 }

+ 41 - 19
src/views/main/TemplateList.vue

@@ -3,7 +3,7 @@
     <!-- 查询条件 -->
     <div class="template-search">
       <div>
-        <el-input v-model="name" class="search-name" prefix-icon="el-icon-search" @change="queryCourseList">
+        <el-input v-model="template_name" class="search-name" prefix-icon="el-icon-search" @change="queryCourseList">
           <el-button slot="append" @click="queryCourseList">搜索</el-button>
         </el-input>
       </div>
@@ -17,7 +17,18 @@
     <!-- 模板列表 -->
     <div class="template-container">
       <div class="template-container-title">
-        <span>模板库</span>
+        <span class="menu-list">
+          <template v-for="{ name, tab, isShow } in menuList">
+            <span
+              v-if="isShow"
+              :key="tab"
+              :class="[tab === 'CurriculaList' ? 'active' : '', 'menu-list-item']"
+              @click="changeTab(tab)"
+            >
+              {{ name }}
+            </span>
+          </template>
+        </span>
         <el-button class="create" @click="$router.push('/create_course_step_table/course_info?is_template=true')">
           <div><svg-icon icon-class="create" /><span>创建模板</span></div>
         </el-button>
@@ -38,22 +49,20 @@
           <el-table-column label="所属机构" prop="org_name" />
 
           <el-table-column fixed="right" width="80">
-            <template slot-scope="{ row }">
+            <template slot-scope="{ row: { id, is_release } }">
               <el-dropdown trigger="click">
                 <span class="el-dropdown-link">
                   <svg-icon icon-class="more" />
                 </span>
                 <el-dropdown-menu slot="dropdown">
-                  <el-dropdown-item @click.native="edit(row.id)">
-                    <svg-icon icon-class="edit" /> 编辑
-                  </el-dropdown-item>
-                  <el-dropdown-item v-if="row.is_release === 'false'" @click.native="releaseCourse(row.id, true)">
+                  <el-dropdown-item @click.native="edit(id)"> <svg-icon icon-class="edit" /> 编辑 </el-dropdown-item>
+                  <el-dropdown-item v-if="is_release === 'false'" @click.native="releaseCourse(id, true)">
                     <svg-icon icon-class="publish" /> 发布
                   </el-dropdown-item>
-                  <el-dropdown-item v-else @click.native="releaseCourse(row.id, false)">
+                  <el-dropdown-item v-else @click.native="releaseCourse(id, false)">
                     <svg-icon icon-class="undo" /> 取消发布
                   </el-dropdown-item>
-                  <el-dropdown-item @click.native="deleteCourse(row.id)">
+                  <el-dropdown-item @click.native="deleteCourse(id)">
                     <svg-icon icon-class="delete" /> 删除
                   </el-dropdown-item>
                 </el-dropdown-menu>
@@ -63,6 +72,7 @@
         </el-table>
       </div>
     </div>
+
     <el-pagination
       background
       :page-sizes="[10, 20, 30, 40, 50]"
@@ -79,6 +89,7 @@
 </template>
 
 <script>
+import { getMenuList } from './data';
 import { PageQueryCourseList } from '@/api/table';
 import { ReleaseCourse, DeleteCourse, IsHasEditDestCoursePopedom } from '@/api/course';
 
@@ -86,11 +97,12 @@ export default {
   data() {
     return {
       // 查询条件
-      name: '',
+      template_name: '',
       page_capacity: 10,
       cur_page: 0,
       total_count: 0,
       release_status: -1,
+      menuList: getMenuList(),
       releaseStatusList: [
         {
           name: '全部',
@@ -122,38 +134,43 @@ export default {
       this.queryCourseList();
     },
     queryCourseList() {
-      const queryCriteria = {
+      PageQueryCourseList({
         is_template: true,
-        name: this.name,
+        name: this.template_name,
         page_capacity: this.page_capacity,
         cur_page: this.cur_page,
         release_status: this.release_status
-      };
-      PageQueryCourseList(queryCriteria).then(({ course_list, total_count }) => {
+      }).then(({ course_list, total_count }) => {
         this.courseList = course_list;
         this.total_count = total_count;
       });
     },
+
     edit(id) {
       IsHasEditDestCoursePopedom({ id }).then(({ is_has_popedom }) => {
         if (is_has_popedom === 'true') {
-          this.$router.push(`/create_course_step_table/course_info?id=${id}&is_template=true`);
-        } else {
-          this.$message.warning('您没有编辑该模板的权限');
+          return this.$router.push(`/create_course_step_table/course_info?id=${id}&is_template=true`);
         }
+        this.$message.warning('您没有编辑该模板的权限');
       });
     },
+
     releaseCourse(course_id, is_release) {
       ReleaseCourse({ course_id, is_release }).then(() => {
         this.queryCourseList();
         this.$message.success(`${is_release ? '' : '取消'}发布课程成功`);
       });
     },
+
     deleteCourse(id) {
       DeleteCourse({ id }).then(() => {
         this.queryCourseList();
         this.$message.success('删除课程成功');
       });
+    },
+
+    changeTab(tab) {
+      this.$emit('changeTab', tab);
     }
   }
 };
@@ -161,6 +178,7 @@ export default {
 
 <style lang="scss">
 @import '~@/styles/mixin';
+@import './common';
 
 .template {
   @include pagination;
@@ -181,7 +199,7 @@ export default {
 
   &-container {
     width: 100%;
-    min-height: calc(100vh - 325px);
+    min-height: calc(100vh - 235px);
     margin-top: 16px;
     background-color: #fff;
     border-radius: 8px;
@@ -190,10 +208,14 @@ export default {
       display: flex;
       align-items: center;
       justify-content: space-between;
-      padding: 32px;
+      padding: 24px 32px;
       font-size: 20px;
       font-weight: bold;
 
+      .menu-list {
+        @include menu-list;
+      }
+
       .create {
         width: 138px;
 

+ 22 - 0
src/views/main/common.scss

@@ -0,0 +1,22 @@
+@mixin menu-list {
+  font-size: 16px;
+  font-weight: normal;
+  color: #8c8c8c;
+  text-align: center;
+  background-color: #ebebeb;
+  border: 1px solid $border-color;
+  border-radius: 8px;
+
+  &-item {
+    display: inline-block;
+    padding: 8px 12px;
+    cursor: pointer;
+
+    &.active {
+      color: #000;
+      background-color: #fff;
+      border-radius: 8px;
+      box-shadow: 0 2px 4px $border-color;
+    }
+  }
+}

+ 355 - 0
src/views/main/components/MonthlyCalendar.vue

@@ -0,0 +1,355 @@
+<template>
+  <div class="monthly-calendar">
+    <div class="monthly-calendar-top">
+      <svg-icon icon-class="calendar" class-name="svg-normal" />
+      <span class="date">{{ curYear }}{{ time_unit === DAY ? `-${curMonth}` : '' }}</span>
+      <i class="el-icon-arrow-left" @click="changeDate('pre')" />
+      <span class="today-dot" @click="backToday" />
+      <i class="el-icon-arrow-right" @click="changeDate('next')" />
+    </div>
+    <!-- 日历主内容 -->
+    <div class="monthly-calendar-container" :style="{ 'grid-template': calendarStyle }">
+      <template v-if="time_unit === DAY">
+        <div
+          v-for="{ name, label } in weekList"
+          :key="label"
+          :style="{ color: ['Sun', 'Sat'].includes(label) ? '#f90' : '', 'font-size': '14px' }"
+          class="week"
+        >
+          {{ name }}
+        </div>
+        <div
+          v-for="{ day, isCurMonth, key, isToday } in dateArr"
+          :key="key"
+          :style="{ color: isCurMonth ? '' : '#A5A5A5' }"
+          class="date"
+        >
+          <div
+            :class="['date-wrapper', isToday ? 'today' : '', isCurMonth && focusDate === day ? 'active' : '']"
+            @click="selectDate(day, isCurMonth)"
+          >
+            {{ day }}
+          </div>
+        </div>
+      </template>
+      <template v-if="time_unit === MONTH">
+        <div v-for="({ name, label }, i) in monthList" :key="label" class="month">
+          <div
+            :class="[
+              'month-wrapper',
+              focusMonth === i ? 'active' : '',
+              curYear === new Date().getFullYear() && new Date().getMonth() === i ? 'this-month' : ''
+            ]"
+            @click="selectMonth(i)"
+          >
+            {{ name }}
+          </div>
+        </div>
+      </template>
+    </div>
+    <!-- 日历模式 -->
+    <div class="monthly-calendar-mode">
+      <span
+        v-for="{ type, name } in modeList"
+        :key="type"
+        :class="['item', type === time_unit ? 'active' : '']"
+        @click="changeMenu(type)"
+      >
+        {{ name }}
+      </span>
+    </div>
+  </div>
+</template>
+
+<script>
+import dayjs from 'dayjs';
+import { weekList, modeList, monthList } from './calendarData';
+
+export default {
+  data() {
+    return {
+      focusDate: 0,
+      focusMonth: 0,
+      dateArr: [],
+      weekList,
+      monthList,
+      date: '',
+      curYear: new Date().getFullYear(),
+      curMonth: new Date().getMonth() + 1,
+      time_unit: modeList[0].type,
+      DAY: modeList[0].type,
+      MONTH: modeList[1].type,
+      modeList,
+      calendarStyle: ''
+    };
+  },
+  watch: {
+    time_unit(newVal) {
+      if (newVal === this.DAY) {
+        return (this.calendarStyle = `40px repeat(${this.dateArr.length > 35 ? 6 : 5}, 1fr) / repeat(7, 1fr)`);
+      }
+      if (newVal === this.MONTH) return (this.calendarStyle = `repeat(4, 1fr) / repeat(3, 1fr)`);
+    },
+    dateArr(newVal) {
+      if (this.time_unit === this.DAY) {
+        this.calendarStyle = `40px repeat(${newVal.length > 35 ? 6 : 5}, 1fr) / repeat(7, 1fr)`;
+      }
+    },
+    date(newVal) {
+      let arr = newVal.split('-').map(item => Number(item));
+      this.curYear = arr[0];
+      this.curMonth = arr[1];
+      this.focusMonth = arr[1] - 1;
+    }
+  },
+  created() {
+    this.date = `${new Date().getFullYear()}-${new Date().getMonth() + 1}`;
+    this.getDateArr();
+    this.focusDate = new Date().getDate();
+  },
+  methods: {
+    backToday() {
+      this.date = `${new Date().getFullYear()}-${new Date().getMonth() + 1}`;
+      this.focusDate = new Date().getDate();
+      this.focusMonth = new Date().getMonth();
+      this.$emit('changeDate');
+      this.getDateArr();
+    },
+
+    changeDate(type) {
+      const curMonth = dayjs(this.date).month();
+      const curYear = dayjs(this.date).year();
+      if (type === 'pre' && this.time_unit === this.DAY) {
+        this.date = curMonth === 0 ? `${curYear - 1}-12` : `${curYear}-${curMonth}`;
+      }
+      if (type === 'pre' && this.time_unit === this.MONTH) {
+        this.date = `${curYear - 1}-${curMonth + 1}`;
+      }
+
+      if (type === 'next' && this.time_unit === this.DAY) {
+        this.date = curMonth === 11 ? `${curYear + 1}-1` : `${curYear}-${curMonth + 2}`;
+      }
+      if (type === 'next' && this.time_unit === this.MONTH) {
+        this.date = `${curYear + 1}-${curMonth + 1}`;
+      }
+      this.$emit('changeDate');
+      this.getDateArr();
+    },
+
+    changeMenu(type) {
+      this.time_unit = type;
+      this.$emit('changeTimeUnit');
+    },
+
+    selectDate(number, isCurMonth) {
+      if (this.time_unit === this.DAY) {
+        this.focusDate = number;
+      }
+      if (!isCurMonth) {
+        this.changeDate(number < 7 ? 'next' : 'pre');
+      }
+      this.$emit('changeDate');
+    },
+    selectMonth(number) {
+      this.date = `${this.curYear}-${number + 1}`;
+      this.focusMonth = number;
+      this.$nextTick(() => {
+        this.$emit('changeDate');
+      });
+    },
+
+    // 得到日历所需数组
+    getDateArr() {
+      const curDate = new Date().getDate();
+      const daysInMonth = dayjs(this.date).daysInMonth();
+      const dayOfWeek = dayjs(`${this.date}-1`).day();
+      const curMonth = dayjs(this.date).month();
+      const curYear = dayjs(this.date).year();
+      let lastDays = dayjs(curMonth === 0 ? `${curYear - 1}-12` : `${curYear}-${curMonth}`).daysInMonth();
+      const isThisMonth = curMonth === new Date().getMonth() && curYear === new Date().getFullYear();
+
+      let arr = [];
+      // 是否有上个月
+      for (let i = 0; i < dayOfWeek; i++) {
+        arr[i] = {
+          key: `last-${i}`,
+          day: lastDays - dayOfWeek + i + 1,
+          isCurMonth: false,
+          isToday: false
+        };
+      }
+      // 本月
+      for (let j = 1; j <= daysInMonth; j++) {
+        arr[j + dayOfWeek - 1] = {
+          key: `cur-${j}`,
+          day: j,
+          isCurMonth: true,
+          isToday: j === curDate && isThisMonth
+        };
+      }
+      if (arr.length === 35) {
+        this.dateArr = arr;
+        return;
+      }
+      // 下月
+      if (arr.length < 35) {
+        for (let k = 1; k <= 35 - (dayOfWeek + daysInMonth); k++) {
+          arr.push({
+            key: `next-${k}`,
+            day: k,
+            isCurMonth: false,
+            isToday: false
+          });
+        }
+        this.dateArr = arr;
+        return;
+      }
+      if (arr.length > 35) {
+        for (let k = 1; k <= 42 - (dayOfWeek + daysInMonth); k++) {
+          arr.push({
+            key: `next-${k}`,
+            day: k,
+            isCurMonth: false
+          });
+        }
+        this.dateArr = arr;
+        return;
+      }
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+.monthly-calendar {
+  display: flex;
+  flex-direction: column;
+
+  &-top {
+    display: flex;
+    align-items: center;
+    margin-bottom: 24px;
+
+    .date {
+      flex: 1;
+      margin-left: 9px;
+      font-weight: 700;
+    }
+
+    .today-dot {
+      display: inline-block;
+      width: 4px;
+      height: 4px;
+      margin: 0 16px;
+      background-color: #595959;
+      border-radius: 50%;
+    }
+
+    .el-icon-arrow-left,
+    .el-icon-arrow-right,
+    .today-dot {
+      cursor: pointer;
+    }
+  }
+
+  &-container {
+    --basic-color: #fff4e4;
+
+    display: grid;
+    flex: 1;
+
+    .week,
+    .date {
+      text-align: center;
+    }
+
+    .date {
+      cursor: pointer;
+
+      &-wrapper {
+        width: 40px;
+        min-height: 40px;
+        margin: 0 auto;
+        line-height: 40px;
+        border-radius: 40px;
+
+        &.today {
+          color: $basic-color;
+          background-color: var(--basic-color);
+          border: 1px solid $basic-color;
+        }
+
+        &:hover {
+          background-color: var(--basic-color);
+        }
+
+        &.active {
+          color: #fff;
+          background-color: $basic-color;
+        }
+      }
+    }
+
+    .month {
+      text-align: center;
+
+      &:nth-child(n + 4) {
+        margin-top: 10px;
+      }
+
+      &:nth-child(n + 7) {
+        margin-top: 20px;
+      }
+
+      &:nth-child(n + 10) {
+        margin-top: 30px;
+      }
+
+      &-wrapper {
+        width: 80px;
+        height: 36px;
+        margin: 0 auto;
+        line-height: 36px;
+        cursor: pointer;
+        border-radius: 40px;
+
+        &:hover {
+          background-color: var(--basic-color);
+        }
+
+        &.this-month {
+          color: $basic-color;
+          background-color: var(--basic-color);
+        }
+
+        &.active {
+          color: #fff;
+          background-color: $basic-color;
+        }
+      }
+    }
+  }
+
+  &-mode {
+    display: flex;
+    height: 40px;
+    line-height: 40px;
+    color: #878787;
+    cursor: pointer;
+    background-color: $bac-color;
+    border-radius: 8px;
+
+    .item {
+      flex: 1;
+      text-align: center;
+
+      &.active {
+        color: #000;
+        background-color: #fff;
+        border-radius: 8px;
+        box-shadow: 0 2px 4px $border-color;
+      }
+    }
+  }
+}
+</style>

+ 94 - 0
src/views/main/components/calendarData.js

@@ -0,0 +1,94 @@
+const weekList = [
+  {
+    name: '日',
+    label: 'Sun'
+  },
+  {
+    name: '一',
+    label: 'Mon'
+  },
+  {
+    name: '二',
+    label: 'Tue'
+  },
+  {
+    name: '三',
+    label: 'Wed'
+  },
+  {
+    name: '四',
+    label: 'Thu'
+  },
+  {
+    name: '五',
+    label: 'Fri'
+  },
+  {
+    name: '六',
+    label: 'Sat'
+  }
+];
+
+const monthList = [
+  {
+    name: '01月',
+    label: 'Jan'
+  },
+  {
+    name: '02月',
+    label: 'Feb'
+  },
+  {
+    name: '03月',
+    label: 'Mar'
+  },
+  {
+    name: '04月',
+    label: 'Apr'
+  },
+  {
+    name: '05月',
+    label: 'May'
+  },
+  {
+    name: '06月',
+    label: 'Jun'
+  },
+  {
+    name: '07月',
+    label: 'Jul'
+  },
+  {
+    name: '08月',
+    label: 'Aug'
+  },
+  {
+    name: '09月',
+    label: 'Sep'
+  },
+  {
+    name: '10月',
+    label: 'Oct'
+  },
+  {
+    name: '11月',
+    label: 'Nov'
+  },
+  {
+    name: '12月',
+    label: 'Dec'
+  }
+];
+
+const modeList = [
+  {
+    type: 'DAY',
+    name: '日'
+  },
+  {
+    type: 'MONTH',
+    name: '月'
+  }
+];
+
+export { weekList, modeList, monthList };

+ 40 - 25
src/views/main/curricula_list/student.vue

@@ -28,12 +28,7 @@
         </el-select>
         <el-select v-model="buy_status">
           <el-option label="-请选择-" :value="-1" />
-          <el-option
-            v-for="item in buy_status_list"
-            :key="item.status"
-            :label="item.name"
-            :value="item.status"
-          />
+          <el-option v-for="item in buy_status_list" :key="item.status" :label="item.name" :value="item.status" />
         </el-select>
         <el-button type="primary" @click="queryMyCourseList">查询</el-button>
       </div>
@@ -42,7 +37,18 @@
     <div class="curricula-student-container">
       <div class="curricula-student-container-title">
         <div>
-          <span class="title">课程列表</span>
+          <span class="menu-list">
+            <template v-for="{ name, tab, isShow } in menuList">
+              <span
+                v-if="isShow"
+                :key="tab"
+                :class="[tab === 'CurriculaList' ? 'active' : '', 'menu-list-item']"
+                @click="changeTab(tab)"
+              >
+                {{ name }}
+              </span>
+            </template>
+          </span>
           <span class="tip"> 你也可以去 <a @click="goLearningCenter">学习中心</a> 选择更多的课程。 </span>
         </div>
       </div>
@@ -92,6 +98,7 @@ import {
   GetMyJoinCourseTeacherList_Student,
   GetStudentCourseBuyStatusList
 } from '@/api/select';
+import { getMenuList } from '../data';
 
 export default {
   data() {
@@ -108,15 +115,12 @@ export default {
       page_capacity: 10,
       cur_page: 1,
       total_count: 0,
-      courseList: []
+      courseList: [],
+      menuList: getMenuList()
     };
   },
   created() {
-    this.queryMyCourseList();
     this.initData();
-    updateWordPack({
-      word_key_list: ['Learn_New_Courses']
-    });
   },
   methods: {
     initData() {
@@ -129,6 +133,10 @@ export default {
       GetMyJoinCourseTeacherList_Student().then(({ teacher_list }) => {
         this.teacher_list = teacher_list;
       });
+      this.queryMyCourseList();
+      updateWordPack({
+        word_key_list: ['Learn_New_Courses']
+      });
     },
     changePage(newPage) {
       this.cur_page = newPage;
@@ -138,33 +146,33 @@ export default {
       this.page_capacity = pageSize;
       this.queryMyCourseList();
     },
+
     queryMyCourseList() {
-      let data = {
+      PageQueryMyJoinCourseList_Student({
         teacher_id: this.teacher_id,
         finish_status: this.finish_status,
         course_name: this.search,
         page_capacity: this.page_capacity,
         cur_page: this.cur_page,
         buy_status: this.buy_status
-      };
-      PageQueryMyJoinCourseList_Student(data).then(({ course_list, total_count }) => {
+      }).then(({ course_list, total_count }) => {
         this.courseList = course_list;
         this.total_count = total_count;
       });
     },
+
     statusColor(val) {
-      if (val === 50) {
-        return '#FF5050';
-      }
-      if (val === 51) {
-        return '#2ECE5B';
-      }
-      if (val === 52) {
-        return '#68CEFA';
-      }
+      if (val === 50) return '#FF5050';
+      if (val === 51) return '#2ECE5B';
+      if (val === 52) return '#68CEFA';
     },
+
     goLearningCenter() {
       window.location.href = `/GCLS-LC/#/EnterSys`;
+    },
+
+    changeTab(tab) {
+      this.$emit('changeTab', tab);
     }
   }
 };
@@ -172,6 +180,7 @@ export default {
 
 <style lang="scss">
 @import '~@/styles/mixin';
+@import '../common';
 
 .curricula-student {
   @include pagination;
@@ -200,7 +209,7 @@ export default {
 
   &-container {
     width: 100%;
-    min-height: calc(100vh - 325px);
+    min-height: calc(100vh - 235px);
     margin-top: 16px;
     background-color: #fff;
     border-radius: 8px;
@@ -212,6 +221,12 @@ export default {
       height: 88px;
       padding: 24px 32px;
 
+      .menu-list {
+        @include menu-list;
+
+        display: inline-block;
+      }
+
       .title {
         margin-right: 36px;
         font: {

+ 34 - 20
src/views/main/curricula_list/teacher.vue

@@ -23,9 +23,18 @@
     <!-- 课程列表 -->
     <div class="curricula-teacher-container">
       <div class="curricula-teacher-container-title">
-        <div>
-          <span class="title">课程列表</span>
-        </div>
+        <span class="menu-list">
+          <template v-for="{ name, tab, isShow } in menuList">
+            <span
+              v-if="isShow"
+              :key="tab"
+              :class="[tab === 'CurriculaList' ? 'active' : '', 'menu-list-item']"
+              @click="changeTab(tab)"
+            >
+              {{ name }}
+            </span>
+          </template>
+        </span>
         <div>
           <el-button class="create" @click="$router.push('/create_course')">
             <div><svg-icon icon-class="create" /><span>创建课程</span></div>
@@ -99,6 +108,7 @@ import { updateWordPack } from '@/utils/i18n';
 import { PageQueryMyCourseList } from '@/api/table';
 import { GetFinishStatusList_Course } from '@/api/select';
 import { ReleaseCourse, DeleteCourse } from '@/api/course';
+import { getMenuList } from '../data';
 
 export default {
   data() {
@@ -110,7 +120,8 @@ export default {
       page_capacity: 10,
       cur_page: 1,
       total_count: 0,
-      courseList: []
+      courseList: [],
+      menuList: getMenuList()
     };
   },
   created() {
@@ -135,30 +146,22 @@ export default {
       this.queryMyCourseList();
     },
     queryMyCourseList() {
-      const queryCriteria = {
+      PageQueryMyCourseList({
         finish_status: this.finish_status,
         name: this.search,
         page_capacity: this.page_capacity,
         cur_page: this.cur_page
-      };
-      PageQueryMyCourseList(queryCriteria).then(({ course_list, total_count }) => {
+      }).then(({ course_list, total_count }) => {
         this.courseList = course_list;
         this.total_count = total_count;
       });
     },
+
     statusColor(val) {
-      if (val === 0) {
-        return '#68CEFA';
-      }
-      if (val === 1) {
-        return '#2ECE5B';
-      }
-      if (val === 3) {
-        return '#f90';
-      }
-      if (val === 4) {
-        return '#4F8EEC';
-      }
+      if (val === 0) return '#68CEFA';
+      if (val === 1) return '#2ECE5B';
+      if (val === 3) return '#f90';
+      if (val === 4) return '#4F8EEC';
     },
 
     studentList(id) {
@@ -170,12 +173,14 @@ export default {
     view(id) {
       this.$router.push(`/GoodsDetail?goods_id=${id}&goods_type=201&readonly=true`);
     },
+
     releaseCourse(course_id, is_release) {
       ReleaseCourse({ course_id, is_release }).then(() => {
         this.queryMyCourseList();
         this.$message.success(`${is_release ? '' : '取消'}发布课程成功`);
       });
     },
+
     deleteCourse(id) {
       this.$confirm('您确定要删除该课程吗?', '提示', {
         confirmButtonText: '确定',
@@ -187,6 +192,10 @@ export default {
           this.queryMyCourseList();
         });
       });
+    },
+
+    changeTab(tab) {
+      this.$emit('changeTab', tab);
     }
   }
 };
@@ -194,6 +203,7 @@ export default {
 
 <style lang="scss">
 @import '~@/styles/mixin';
+@import '../common';
 
 .curricula-teacher {
   @include pagination;
@@ -222,7 +232,7 @@ export default {
 
   &-container {
     width: 100%;
-    min-height: calc(100vh - 325px);
+    min-height: calc(100vh - 235px);
     margin-top: 16px;
     background-color: #fff;
     border-radius: 8px;
@@ -234,6 +244,10 @@ export default {
       height: 88px;
       padding: 24px 32px;
 
+      .menu-list {
+        @include menu-list;
+      }
+
       .title {
         margin-right: 36px;
         font-size: 20px;

+ 4 - 2
src/views/main/data.js

@@ -1,6 +1,6 @@
 import store from '@/store';
 
-let colorMatching = [
+const colorMatching = [
   {
     main: '#3479FF',
     background: 'rgba(52, 121, 255, 0.05)',
@@ -38,6 +38,8 @@ let colorMatching = [
   }
 ];
 
+const buttonColorList = ['#f90', '#00CD8F', '#63A1FF'];
+
 function getMenuList() {
   let popedom_code_list = store.state.user.popedom_code_list;
   let isStudent = store.state.user.user_type === 'STUDENT';
@@ -61,4 +63,4 @@ function getMenuList() {
   ];
 }
 
-export { colorMatching, getMenuList };
+export { colorMatching, getMenuList, buttonColorList };

+ 14 - 10
src/views/main/index.vue

@@ -1,20 +1,24 @@
 <template>
-  <div class="main-container">
+  <main class="main-container">
     <keep-alive>
-      <component :is="currentTabComponent" />
+      <component :is="currentTabComponent" @changeTab="changeTab" />
     </keep-alive>
-  </div>
+  </main>
 </template>
 
 <script>
 import TaskList from './TaskList.vue';
 import TemplateList from './TemplateList.vue';
+import CurriculaListStudent from './curricula_list/student.vue';
+import CurriculaListTeacher from './curricula_list/teacher.vue';
 
 export default {
   name: 'Main',
   components: {
     TaskList,
-    TemplateList
+    TemplateList,
+    CurriculaListStudent,
+    CurriculaListTeacher
   },
   data() {
     const state = this.$store.state;
@@ -31,14 +35,14 @@ export default {
   },
   computed: {
     currentTabComponent() {
-      if (['TemplateList', 'TaskList'].includes(this.currentTab)) {
-        return this.currentTab;
-      }
-      return this.currentTab + this.$store.state.user.user_type === 'TEACHER' ? 'Teacher' : 'Student';
+      if (['TemplateList', 'TaskList'].includes(this.currentTab)) return this.currentTab;
+      return `${this.currentTab}${this.$store.state.user.user_type === 'TEACHER' ? 'Teacher' : 'Student'}`;
     }
   },
-  created() {
-
+  methods: {
+    changeTab(tab) {
+      this.currentTab = tab;
+    }
   }
 };
 </script>