Browse Source

feat: 前后端连接 - 读取幻灯片列表、创建幻灯片、初始化编辑器

ChenYangfan 6 năm trước cách đây
mục cha
commit
025bca2ba8

+ 40 - 0
src/components/ common/SearchBar.vue

@@ -0,0 +1,40 @@
+<template>
+  <div>
+    <input
+      type="text"
+      :value="value"
+      @input="$emit('input', $event.target.value)"
+    />
+  </div>
+</template>
+
+<script>
+export default {
+  model: {
+    prop: 'value',
+    event: 'input'
+  },
+  props: {
+    value: String
+  }
+}
+</script>
+<style lang="scss" scoped>
+$input-background-color: #ebf0f5;
+
+input {
+  box-sizing: border-box;
+  font-size: 16px;
+  font-weight: 500;
+  color: #3a4a5a;
+  background: $input-background-color;
+  border-radius: 24px;
+  border: none;
+  outline: none;
+  width: 100%;
+  height: 48px;
+  line-height: 40px;
+  padding: 0;
+  padding-left: 16px;
+}
+</style>

+ 6 - 1
src/components/editor/Editor.vue

@@ -10,7 +10,7 @@
 <script>
 import { mapState } from 'vuex'
 import EditingPageVue from './EditingPage.vue'
-import { USE_FOCUS } from '../../store/types/editor-types'
+import { USE_FOCUS, INIT_BY_DEFAULT } from '../../store/types/editor-types'
 export default {
   name: 'editor',
   components: {
@@ -22,6 +22,11 @@ export default {
     }),
     pages() {
       const items = this.$store.state.editor.items
+      if (items.length === 0) {
+        this.$nextTick(() => {
+          this.$store.commit(INIT_BY_DEFAULT)
+        })
+      }
       const pages = []
       let lastIndex = 0
       let times = 0

+ 34 - 6
src/components/teacher/SlideListItem.vue

@@ -1,20 +1,39 @@
 <template>
-  <div class="slide-list-item-container">
+  <div class="slide-list-item-container" @click="handleClick">
     <div class="content">
-      <div class="title">编程基础 I - 基础与抽象讲解</div>
-      <div>最后编辑时间:2020.01.03 14:22</div>
-      <div>所属课程:软件工程与计算 I</div>
+      <div class="title">
+        {{ slide.name }}
+        <span class="tag">{{ stateChinese }} </span>
+      </div>
+      <div>修改时间:{{ slide.updateTime }}</div>
+      <div>所属课程:{{ slide.courseName }}</div>
     </div>
   </div>
 </template>
 
 <script>
-export default {}
+import stateMap from '@/utils/state-chinese-map'
+import { INIT_BY_STATE } from '../../store/types/editor-types'
+export default {
+  props: ['slide'],
+  data() {
+    return {
+      stateChinese: stateMap[this.slide.state]
+    }
+  },
+  methods: {
+    handleClick() {
+      this.$store.commit(INIT_BY_STATE, this.slide)
+      this.$router.push('/editor')
+    }
+  }
+}
 </script>
 
 <style lang="scss" scoped>
 .slide-list-item-container {
-  margin: 16px 0 32px 0;
+  margin: 24px 0 0 0;
+  padding-bottom: 8px;
   cursor: pointer;
 }
 .content > div {
@@ -28,4 +47,13 @@ export default {}
 
   color: #555;
 }
+.tag {
+  font-size: 12px;
+  display: inline-block;
+  background: #fcecb8;
+  color: #a88100;
+  border-radius: 6px;
+  padding: 2px 8px;
+  transform: translateY(-2px);
+}
 </style>

+ 4 - 4
src/config/server-info.js

@@ -1,13 +1,13 @@
 // const host = 'http://106.14.178.184:8080/seec_helper'
 const host = 'http://localhost:18080/'
 
-const slideUrl = host + '/api/slide/'
+const slideUrl = host + '/api/slide'
 
-const useSlideServer = postfix => postfix ? slideUrl + postfix : slideUrl
+const useSlideServer = postfix => postfix ? slideUrl + '/' + postfix : slideUrl
 
-const courseUrl = host + '/api/course/'
+const courseUrl = host + '/api/course'
 
-const useCourseServer = postfix => postfix ? courseUrl + postfix : courseUrl
+const useCourseServer = postfix => postfix ? courseUrl + '/' + postfix : courseUrl
 
 export {
   useSlideServer,

+ 12 - 0
src/server/slide.js

@@ -7,6 +7,18 @@ export function getSlide(id) {
   return axios.get(useSlideServer(id))
 }
 
+export function getRecentSlides() {
+  return axios.get(useSlideServer(), {
+    params: {
+      sort: 'updateTime,desc'
+    }
+  }).then(res => {
+    if (res.data.code === 200) {
+      return res.data.data
+    }
+  })
+}
+
 export function createSlide(courseId, name) {
   const data = {
     courseId,

+ 16 - 4
src/store/modules/editor.js

@@ -9,13 +9,15 @@ import {
   SET_FOCUS_AFTER,
   USE_FOCUS,
   GET_SLIDE,
-  CREATE_SLIDE
+  CREATE_SLIDE,
+  SAVE
 } from '../types/editor-types'
 
 import uuid from 'uuid'
 import {
   getSlide,
-  createSlide
+  createSlide,
+  updateSlide
 } from '@/server/slide'
 
 export default {
@@ -26,12 +28,19 @@ export default {
   },
 
   mutations: {
-    [INIT_BY_STATE](state, payload) {},
+    [INIT_BY_STATE](state, payload) {
+      console.log(payload)
+      state.items = payload.items
+      state.slideInfo = {
+        ...payload,
+        items: undefined
+      }
+    },
     [INIT_BY_DEFAULT](state, payload) {
       const newItemId = uuid.v4()
       state.items = [{
         id: newItemId,
-        placeholder: '未编辑文档标题',
+        placeholder: '标题',
         content: '# '
       }]
       state.focus = {
@@ -126,6 +135,9 @@ export default {
     }
   },
   actions: {
+    [SAVE](state, payload) {
+      updateSlide.then(state.items.map(item => {}))
+    },
     [CREATE_SLIDE](state, payload) {
       createSlide({
         courseId: payload.courseId,

+ 2 - 0
src/store/types/editor-types.js

@@ -11,3 +11,5 @@ export const USE_FOCUS = 'useFocus'
 export const GET_SLIDE = 'getSlide'
 export const CREATE_SLIDE = 'createSlide'
 export const UPDATE_SLIDE = 'updateSlide'
+
+export const SAVE = 'save'

+ 3 - 0
src/utils/state-chinese-map.js

@@ -0,0 +1,3 @@
+export default {
+  DRAFT: '草稿'
+}

+ 3 - 28
src/views/teacher/tabs/AddTab.vue

@@ -16,7 +16,7 @@
       v-model="userInput"
       placeholder="请勿与同课程幻灯片重名"
     />
-    <button class="submit-button" @click.prevent="handleSubmit">
+    <button class="my-button" @click.prevent="handleSubmit">
       添加
     </button>
   </div>
@@ -52,32 +52,11 @@ export default {
 <style lang="scss" scoped>
 @import './tab-common.scss';
 $input-background-color: #ebf0f5;
-$submit-button-color: #5485e5;
 
 .title {
   margin-bottom: 32px;
 }
 
-.submit-button {
-  display: block;
-  width: 120px;
-  height: 40px;
-  margin-top: 36px;
-  background: $submit-button-color;
-  color: white;
-  border-radius: 8px;
-  border: none;
-  outline: none;
-  font-size: 14px;
-  font-weight: 500;
-  &:hover {
-    background: darken($submit-button-color, 5);
-  }
-
-  &:active {
-    background: darken($submit-button-color, 10);
-  }
-}
 .select-wrapper {
   width: 100%;
   height: 40px;
@@ -109,11 +88,7 @@ select {
   //通过padding-left的值让文字居中
 }
 
-input {
-  border: none;
-  border-radius: 8px;
-
-  outline: none;
-  background: $input-background-color;
+.my-button {
+  margin-top: 36px;
 }
 </style>

+ 43 - 9
src/views/teacher/tabs/HomeTab.vue

@@ -1,22 +1,43 @@
 <template>
   <div class="tab-wrapper">
     <section class="slide-section">
-      <div class="title">准备上课?</div>
-      <slide-list-item-vue></slide-list-item-vue>
-    </section>
-    <section class="slide-section">
-      <div class="title">编辑历史</div>
-      <slide-list-item-vue></slide-list-item-vue>
-      <slide-list-item-vue></slide-list-item-vue>
-      <slide-list-item-vue></slide-list-item-vue>
+      <div class="title">最近修改</div>
+      <section class="recent-slides-section">
+        <div v-if="recentSlides && recentSlides.length === 0">
+          <div class="no-slide-warning">
+            您还没有创建过幻灯片 (´・ω・`)
+          </div>
+          <router-link to="/teacher/teacher-add">
+            <button class="my-button">新建幻灯片</button>
+          </router-link>
+        </div>
+        <div v-else>
+          <slide-list-item-vue
+            v-for="slide of recentSlides"
+            :key="slide.id"
+            :slide="slide"
+          ></slide-list-item-vue>
+        </div>
+      </section>
     </section>
   </div>
 </template>
 
 <script>
-import SlideListItemVue from '../../../components/teacher/SlideListItem.vue'
+import SlideListItemVue from '@/components/teacher/SlideListItem.vue'
+import { getRecentSlides } from '../../../server/slide'
 
 export default {
+  data() {
+    return {
+      recentSlides: []
+    }
+  },
+  mounted() {
+    getRecentSlides().then(res => {
+      this.recentSlides = res
+    })
+  },
   components: { SlideListItemVue }
 }
 </script>
@@ -26,4 +47,17 @@ export default {
   max-height: 80vh;
   overflow: auto;
 }
+.recent-slides-section {
+  max-height: 50vh;
+  overflow: auto;
+
+  .no-slide-warning {
+    color: #aabaca;
+    font-size: 20px;
+    font-weight: bold;
+    display: flex;
+    align-items: center;
+    padding: 50px 0;
+  }
+}
 </style>

+ 28 - 3
src/views/teacher/tabs/tab-common.scss

@@ -8,7 +8,7 @@
 .title {
   font-size: 28px;
   font-weight: 500;
-  margin-bottom: 24px;
+  margin-bottom: 12px;
 }
 
 .sub-title {
@@ -17,6 +17,31 @@
   margin-bottom: 16px;
 }
 
-.slide-section {
-  margin-bottom: 36px;
+$submit-button-color: #5485e5;
+
+.my-button {
+  display: block;
+  width: 120px;
+  height: 40px;
+  background: $submit-button-color;
+  color: white;
+  border-radius: 8px;
+  border: none;
+  outline: none;
+  font-size: 14px;
+  font-weight: 500;
+
+  &:hover {
+    background: darken($submit-button-color, 5);
+  }
+
+  &:active {
+    background: darken($submit-button-color, 10);
+  }
+}
+
+a {
+  outline: none;
+  text-decoration: none;
+  color: black;
 }