瀏覽代碼

1. 添加 用户更换语言类型接口,优化国际化
2. 添加 新建课程页
3. 使用 eslint vue插件 规范 Vue 格式

dusenyao 4 年之前
父節點
當前提交
d53ba742cb

+ 7 - 1
.eslintrc.js

@@ -17,7 +17,13 @@ module.exports = {
     Rtc: true
   },
 
-  extends: ['plugin:vue/strongly-recommended', 'eslint:recommended', '@vue/prettier'],
+  extends: [
+    'plugin:vue/essential',
+    'plugin:vue/strongly-recommended',
+    'plugin:vue/recommended',
+    'eslint:recommended',
+    '@vue/prettier'
+  ],
 
   rules: {
     'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',

+ 14 - 1
src/api/user.js

@@ -1,4 +1,4 @@
-import { request } from '@/utils/request';
+import { request, getRequestParameter } from '@/utils/request';
 
 /**
  * @description 登录
@@ -14,3 +14,16 @@ export function login(Parameter) {
     }
   });
 }
+
+/**
+ * @description 用户更换语言类型
+ * @param {Object} Parameter { language_type 语言类型 }
+ */
+export function updateLanguageType(Parameter) {
+  let params = getRequestParameter('login_control-UpdateLanguageType', Parameter);
+  return request({
+    method: 'post',
+    url: process.env.VUE_APP_WEB_SI,
+    params
+  });
+}

+ 3 - 3
src/common/CircleProgress/index.vue

@@ -9,6 +9,9 @@ import CircleProgressSvg from './CircleProgressSvg';
 
 export default {
   name: 'CircleProgress',
+  components: {
+    CircleProgressSvg
+  },
   props: {
     totalCount: {
       type: Number,
@@ -19,9 +22,6 @@ export default {
       default: 0
     }
   },
-  components: {
-    CircleProgressSvg
-  },
   computed: {
     percentage() {
       const per = this.finishCount / this.totalCount;

+ 3 - 2
src/layouts/components/Header.vue

@@ -56,8 +56,9 @@ export default {
       await this.$store.dispatch('user/signOut');
       this.$router.push(`/login?redirect=${this.$route.fullPath}`);
     },
-    setI18nLang(lang) {
-      setI18nLang(lang);
+    async setI18nLang(lang) {
+      await setI18nLang(lang);
+      // 为了触发 created 生命周期的获取单词列表事件
       this.$router.go(0);
     }
   }

+ 12 - 0
src/router/index.js

@@ -40,6 +40,18 @@ const routes = [
     ]
   },
   {
+    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,
     redirect: '/live/teacher',

+ 2 - 1
src/store/getters.js

@@ -1,5 +1,6 @@
 const getters = {
-  state: state => state.user.state
+  state: state => state.user.state,
+  language_type: state => state.user.language_type
 };
 
 export default getters;

+ 2 - 1
src/store/index.js

@@ -14,5 +14,6 @@ export default new Vuex.Store({
     user,
     app
   },
-  getters
+  getters,
+  strict: process.env.NODE_ENV === 'development'
 });

+ 26 - 6
src/store/modules/user.js

@@ -1,14 +1,15 @@
 import { getSessionID, removeSessionID, setSessionID } from '@/utils/auth';
 import { user } from '@/store/mutation-types';
 import { resetRouter } from '@/router';
-import { login } from '@/api/user';
+import { login, updateLanguageType } from '@/api/user';
 
 const getDefaultSate = () => {
   return {
     session_id: getSessionID(),
     user_code: '',
     user_real_name: '',
-    user_type: ''
+    user_type: '',
+    language_type: localStorage.getItem('language_type') || 'ZH'
   };
 };
 
@@ -21,10 +22,15 @@ const mutations = {
   [user.SET_SESSION_ID]: (state, session_id) => {
     state.session_id = session_id;
   },
-  [user.SET_USER_INFO]: (state, { user_code, user_real_name, user_type }) => {
+  [user.SET_USER_INFO]: (state, { user_code, user_real_name, user_type, language_type }) => {
     state.user_code = user_code;
     state.user_real_name = user_real_name;
     state.user_type = user_type;
+    state.language_type = language_type;
+  },
+  [user.UPDATE_LANGUAGE_TYPE]: (state, language_type) => {
+    localStorage.setItem('language_type', language_type);
+    state.language_type = language_type;
   }
 };
 
@@ -35,9 +41,9 @@ const actions = {
     return new Promise((reslove, reject) => {
       login(loginForm)
         .then(response => {
-          let { user_code, user_real_name, user_type, session_id } = response;
-          setSessionID(response.session_id);
-          commit(user.SET_USER_INFO, { user_code, user_real_name, user_type });
+          let { session_id } = response;
+          setSessionID(session_id);
+          commit(user.SET_USER_INFO, response);
           commit(user.SET_SESSION_ID, session_id);
           reslove();
         })
@@ -57,6 +63,20 @@ const actions = {
     });
   },
 
+  // 用户更换语言类型
+  updateLanguageType({ commit }, language_type) {
+    return new Promise((reslove, reject) => {
+      updateLanguageType({ language_type })
+        .then(() => {
+          commit(user.UPDATE_LANGUAGE_TYPE, language_type);
+          reslove();
+        })
+        .catch(error => {
+          reject(error);
+        });
+    });
+  },
+
   resetSessionID({ commit }) {
     return new Promise(reslove => {
       removeSessionID();

+ 2 - 1
src/store/mutation-types.js

@@ -1,7 +1,8 @@
 const user = {
   RESET_STATE: 'RESET_STATE',
   SET_SESSION_ID: 'SET_SESSION_ID',
-  SET_USER_INFO: 'SET_USER_INFO'
+  SET_USER_INFO: 'SET_USER_INFO',
+  UPDATE_LANGUAGE_TYPE: 'UPDATE_LANGUAGE_TYPE'
 };
 
 const app = {};

+ 5 - 12
src/utils/i18n.js

@@ -1,5 +1,6 @@
 import Vue from 'vue';
 import VueI18n from 'vue-i18n';
+import store from '@/store';
 import { GetWordPack } from '@/api/app';
 import ElementLocale from 'element-ui/lib/locale';
 import zhLocal from 'element-ui/lib/locale/lang/zh-CN';
@@ -11,16 +12,8 @@ import ruLocal from 'element-ui/lib/locale/lang/ru-RU';
 
 Vue.use(VueI18n);
 
-// function getBasicI18nMessage() {
-//   let lang = getI18nLang();
-//   GetWordPack({
-//     language_type: lang,
-//     word_key_list: {}
-//   });
-// }
-
 const i18n = new VueI18n({
-  locale: localStorage.getItem('lang') || 'ZH',
+  locale: store.getters.language_type,
   messages: {
     ZH: {
       ...zhLocal
@@ -46,9 +39,8 @@ const i18n = new VueI18n({
 
 ElementLocale.i18n((key, value) => i18n.t(key, value));
 
-export function setI18nLang(lang) {
-  localStorage.setItem('lang', lang);
-  i18n.locale = lang;
+export async function setI18nLang(language_type) {
+  await store.dispatch('user/updateLanguageType', language_type);
 }
 
 /**
@@ -65,6 +57,7 @@ export function updateWordPack(Parameter) {
     }
     let wordPack = Object.assign(localWord, data.word_pack);
     i18n.setLocaleMessage(data.language_type, wordPack);
+    // localStorage.setItem('i18n-message', JSON.stringify(i18n.messages));
   });
 }
 

+ 3 - 3
src/views/live/index.vue

@@ -29,9 +29,6 @@ export default {
       loadedNumber: 0
     };
   },
-  created() {
-    this.downloadWebSDK();
-  },
   watch: {
     loadedNumber(newValue) {
       if (newValue === 2) {
@@ -39,6 +36,9 @@ export default {
       }
     }
   },
+  created() {
+    this.downloadWebSDK();
+  },
   methods: {
     downloadWebSDK() {
       let script = this.createScript('https://class.csslcloud.net/static/dist/js/websdk_4.0.js');

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

@@ -14,9 +14,9 @@
 
       <el-form-item prop="user_name">
         <el-input
-          type="text"
-          v-model="loginForm.user_name"
           ref="user_name"
+          v-model="loginForm.user_name"
+          type="text"
           name="user_name"
           auto-complete="on"
           :placeholder="$t('username')"
@@ -25,9 +25,9 @@
 
       <el-form-item prop="password">
         <el-input
-          type="password"
-          v-model="loginForm.password"
           ref="password"
+          v-model="loginForm.password"
+          type="password"
           name="password"
           :placeholder="$t('password')"
           auto-complete="on"

+ 35 - 0
src/views/teacher/add_course/index.vue

@@ -0,0 +1,35 @@
+<template>
+  <div class="course">
+    <keep-alive>
+      <component :is="curComponent" @next-step="step" />
+    </keep-alive>
+  </div>
+</template>
+
+<script>
+import courseInformation from './step/step_course_information';
+
+export default {
+  components: {
+    courseInformation
+  },
+  data() {
+    return {
+      curComponent: 'courseInformation'
+    };
+  },
+  methods: {
+    step(s) {
+      console.log(s);
+    }
+  }
+};
+</script>
+
+<style lang="scss">
+@import '~@/styles/mixin.scss';
+
+.course {
+  @include container;
+}
+</style>

+ 168 - 0
src/views/teacher/add_course/step/step_course_information.vue

@@ -0,0 +1,168 @@
+<template>
+  <div class="information">
+    <div class="information-title">{{ $t('Learn_New_Courses') }}</div>
+    <el-form
+      ref="form"
+      :model="form"
+      :rules="formRules"
+      label-width="130px"
+      label-position="left"
+      hide-required-asterisk
+    >
+      <el-form-item :label="$t('Learn_Course_Cover')" class="information-cover">
+        <el-upload action="http" class="avatar-uploader" :show-file-list="false">
+          <img v-if="form.imageUrl" :v-model="form.imageUrl" :src="form.imageUrl" class="avatar" />
+          <i v-else class="el-icon-plus avatar-uploader-icon"></i>
+        </el-upload>
+        <span class="line-middle auto"><a @click="automatically">自动生成功能</a></span>
+      </el-form-item>
+      <el-form-item :label="$t('Learn_Course_Name')" prop="name">
+        <el-input v-model="form.name" type="text" class="name-input"></el-input>
+      </el-form-item>
+      <el-form-item label="课程介绍">
+        <el-input
+          v-model="form.introduce"
+          type="textarea"
+          class="introduce-textarea"
+          resize="none"
+          rows="6"
+        ></el-input>
+      </el-form-item>
+      <el-form-item label="授课教师">
+        <el-button>添加教师</el-button>
+      </el-form-item>
+      <el-form-item label="时间">
+        <el-date-picker v-model="form.beginDate" type="date" placeholder="添加开始日期" />
+        <span class="horizontal-bar">-</span>
+        <el-date-picker v-model="form.endDate" type="date" placeholder="添加截止日期" />
+      </el-form-item>
+      <el-form-item label="学员人数">
+        <el-input v-model="form.studentNumber" type="input" class="people-input"></el-input>
+        <el-checkbox v-model="form.checked" class="student-checkbox"> 人数满足自动封班</el-checkbox>
+      </el-form-item>
+      <el-form-item label="类型">
+        <el-checkbox-group v-model="form.typeList">
+          <el-checkbox label="a">公开课</el-checkbox>
+          <el-checkbox label="b">需申请</el-checkbox>
+        </el-checkbox-group>
+      </el-form-item>
+      <el-form-item>
+        <el-button @click="cancel">取消</el-button>
+        <el-button type="primary" @click="nextStep">下一步</el-button>
+      </el-form-item>
+    </el-form>
+  </div>
+</template>
+
+<script>
+import { updateWordPack } from '@/utils/i18n';
+
+export default {
+  data() {
+    return {
+      form: {
+        imageUrl: '',
+        name: '',
+        introduce: '',
+        teacher: '',
+        beginDate: '',
+        endDate: '',
+        studentNumber: '',
+        checked: false,
+        typeList: []
+      },
+      formRules: {
+        name: { required: true, message: '课程名称不能为空', trigger: 'blur' }
+      }
+    };
+  },
+  created() {
+    updateWordPack({
+      word_key_list: ['Learn_New_Courses', 'Learn_Course_Cover', 'Learn_Course_Name']
+    });
+  },
+  methods: {
+    cancel() {
+      this.$router.go(-1);
+    },
+    nextStep() {
+      this.$emit('next-step', 'course');
+    },
+    // 自动生成功能
+    automatically() {}
+  }
+};
+</script>
+
+<style lang="scss">
+.information {
+  &-title {
+    margin-bottom: 15px;
+    font-weight: 700;
+  }
+  &-cover {
+    .el-form-item__label {
+      @extend .line-middle;
+    }
+  }
+  .el-form-item__label {
+    font-size: 16px;
+  }
+  .name-input,
+  .introduce-textarea {
+    width: 530px;
+  }
+  .people-input {
+    width: 185px;
+  }
+  .student-checkbox {
+    margin-left: 28px;
+  }
+  .horizontal-bar {
+    margin: 0 24px;
+  }
+  .el-button {
+    width: 140px;
+    height: 40px;
+  }
+}
+
+.line-middle {
+  line-height: 90px;
+}
+
+.auto {
+  display: inline-block;
+  vertical-align: text-bottom;
+  margin-left: 38px;
+}
+
+.avatar-uploader {
+  display: inline-block;
+  & .el-upload {
+    border: 1px dashed #d9d9d9;
+    border-radius: 6px;
+    cursor: pointer;
+    position: relative;
+    overflow: hidden;
+    &:hover {
+      border-color: #409eff;
+    }
+  }
+
+  &-icon {
+    font-size: 28px;
+    color: #8c939d;
+    width: 90px;
+    height: 90px;
+    line-height: 90px;
+    text-align: center;
+  }
+
+  & .avatar {
+    width: 90px;
+    height: 90px;
+    display: block;
+  }
+}
+</style>

+ 9 - 9
src/views/teacher/cs_item_detail/ClassroomTask.vue

@@ -28,9 +28,9 @@
                   <span>{{ $t('Learn_Courseware') }}:</span>
                   <span>
                     <el-tag
-                      class="courseware-tag"
                       v-for="courseware in list.courseware_list"
                       :key="courseware.id"
+                      class="courseware-tag"
                       type="info"
                       >{{ courseware.name }}</el-tag
                     >
@@ -41,9 +41,9 @@
                   <span>{{ $t('Learn_Enclosure') }}:</span>
                   <span>
                     <el-tag
-                      class="accessory-tag"
                       v-for="(accessory, j) in list.accessory_list"
                       :key="j"
+                      class="accessory-tag"
                       type="info"
                     >
                       <a :href="accessory.file_url" target="_blank">{{ accessory.file_name }}</a>
@@ -93,9 +93,9 @@
                   <span>{{ $t('Learn_Courseware') }}:</span>
                   <span>
                     <el-tag
-                      class="courseware-tag"
                       v-for="courseware in list.courseware_list"
                       :key="courseware.id"
+                      class="courseware-tag"
                       type="info"
                       >{{ courseware.name }}</el-tag
                     >
@@ -106,9 +106,9 @@
                   <span>{{ $t('Learn_Enclosure') }}:</span>
                   <span>
                     <el-tag
-                      class="accessory-tag"
                       v-for="(accessory, j) in list.accessory_list"
                       :key="j"
+                      class="accessory-tag"
                       type="info"
                     >
                       <a :href="accessory.file_url" target="_blank">{{ accessory.file_name }}</a>
@@ -161,9 +161,9 @@
                   <span>{{ $t('Learn_Courseware') }}:</span>
                   <span>
                     <el-tag
-                      class="courseware-tag"
                       v-for="courseware in list.courseware_list"
                       :key="courseware.id"
+                      class="courseware-tag"
                       type="info"
                       >{{ courseware.name }}</el-tag
                     >
@@ -174,9 +174,9 @@
                   <span>{{ $t('Learn_Enclosure') }}:</span>
                   <span>
                     <el-tag
-                      class="accessory-tag"
                       v-for="(accessory, j) in list.accessory_list"
                       :key="j"
+                      class="accessory-tag"
                       type="info"
                     >
                       <a :href="accessory.file_url" target="_blank">{{ accessory.file_name }}</a>
@@ -226,6 +226,9 @@ import CircleProgress from '@/common/CircleProgress';
 
 export default {
   name: 'ClassroomTask',
+  components: {
+    CircleProgress
+  },
   props: {
     preTaskList: {
       type: Array,
@@ -250,9 +253,6 @@ export default {
     return {
       dashoffset: 0
     };
-  },
-  components: {
-    CircleProgress
   }
 };
 </script>

+ 4 - 4
src/views/teacher/cs_item_detail/index.vue

@@ -45,9 +45,9 @@
           </el-col>
         </el-row>
         <el-tag
-          class="learning-material-tag"
           v-for="(list, i) in CSItemInfoBox.learning_material_list"
           :key="i"
+          class="learning-material-tag"
           type="info"
         >
           <a :href="list.file_url" target="_blank">{{ list.file_url }}</a>
@@ -64,6 +64,9 @@ import ClassroomTask from './ClassroomTask';
 import { updateWordPack } from '@/utils/i18n';
 
 export default {
+  components: {
+    ClassroomTask
+  },
   data() {
     return {
       id: this.$route.params.id,
@@ -80,9 +83,6 @@ export default {
       }
     };
   },
-  components: {
-    ClassroomTask
-  },
   created() {
     updateWordPack({
       word_key_list: [

+ 42 - 32
src/views/teacher/main/CurriculaManager.vue

@@ -6,23 +6,23 @@
     <div class="curricula-manager-body">
       <div class="curricula-manager-body-button">
         <el-button
-          @click="click(item.status, index)"
-          :class="['bg-color', { active: background == index }]"
           v-for="(item, index) in statusList"
           :key="index"
+          :class="['bg-color', { active: background == index }]"
+          @click="click(item.status, index)"
         >
           {{ item.val }}
         </el-button>
       </div>
-      <div class="sort">
-        <span>排序:</span>
-        <span class="sort-body" v-for="item in sortList" :key="item.id">
-          {{ item.name }}
-          <i class="el-icon-sort"></i>
-        </span>
-      </div>
-      <div class="curricula-manager-body-add">
-        <el-button class="bg-color" @click="add()">新建课程</el-button>
+      <div class="curricula-manager-body-sort">
+        <div>
+          <span>排序:</span>
+          <span v-for="item in sortList" :key="item.id" class="sort-body">
+            {{ item.name }}
+            <i class="el-icon-sort"></i>
+          </span>
+        </div>
+        <el-button class="bg-color" @click="addCourse()">{{ $t('Learn_New_Courses') }}</el-button>
       </div>
     </div>
     <div class="curricula-manager-foot">
@@ -44,6 +44,8 @@
 </template>
 
 <script>
+import { updateWordPack } from '@/utils/i18n';
+
 export default {
   name: 'CurriculaManager',
   data() {
@@ -153,33 +155,40 @@ export default {
       ]
     };
   },
+  created() {
+    updateWordPack({
+      word_key_list: ['Learn_New_Courses']
+    });
+  },
   methods: {
     click(status, index) {
       this.isStatus = status;
       this.background = index;
-      console.log(status);
-      console.log(index);
     },
-    add() {
-      console.log(123);
+    addCourse() {
+      this.$router.push('/add_course');
     }
   }
 };
 </script>
 
 <style lang="scss">
+$main-w: 953px;
+
 .curricula-manager {
   &-header .el-input {
     width: 244px;
     height: 40px;
-    margin: 37px auto 0 auto;
+    margin: 37px auto 0;
     display: block;
   }
+
   &-body-button {
     display: flex;
     justify-content: center;
     margin-top: 35px;
     font-size: 16px;
+
     .el-button {
       width: 97px;
       height: 52px;
@@ -189,46 +198,47 @@ export default {
     }
   }
 
+  &-body-sort {
+    display: flex;
+    justify-content: space-between;
+    width: $main-w;
+    line-height: 40px;
+    margin: 25px auto 15px;
+  }
+
   .bg-color {
     background: #c4c4c4;
     border: 1px solid #c4c4c4;
     border-radius: 0;
-    color: #0c0c0c;
+    color: #000;
+
     &.active {
-      background: #e5e5e5;
-      border: 1px solid #0c0c0c;
-      border-radius: 0;
-      color: #0c0c0c;
+      background: #e6e6e6;
+      border-color: #0c0c0c;
     }
   }
 
   .sort {
-    margin-top: 25px;
+    margin-top: 30px;
     &-body {
       margin-left: 20px;
     }
   }
-  &-body {
-    &-add {
-      margin-top: 5px;
-      margin-left: 855px;
-    }
-  }
 
   &-foot {
     .circulation {
-      margin: 0 0 15px 0;
-      width: 953px;
+      margin: 0 auto 15px;
+      width: $main-w;
       height: 92px;
       background-color: #eee;
-      padding: 20px 20px 0 20px;
+      padding: 20px 20px 0;
     }
     &-value {
       display: flex;
       justify-content: space-between;
     }
     &-create {
-      padding: 20px 0 0 0;
+      padding: 20px 0 0;
     }
     &-on-class {
       margin-left: 20px;

+ 4 - 4
src/views/teacher/main/TaskKanban.vue

@@ -32,8 +32,8 @@
     <div class="right-container">
       <div
         v-for="item in cs_item_list"
-        class="cs-item"
         :key="item.id"
+        class="cs-item"
         :style="{
           'background-color':
             item.finish_status === 0 ? '#E7F8E1' : item.finish_status === 1 ? '#FFFBD8' : '#F7DFDF'
@@ -75,9 +75,6 @@ export default {
       cs_item_list: {}
     };
   },
-  mounted() {
-    this.getCSItemList();
-  },
   computed: {
     dateTime: {
       get: function () {
@@ -89,6 +86,9 @@ export default {
       }
     }
   },
+  mounted() {
+    this.getCSItemList();
+  },
   methods: {
     getCSItemList() {
       getMyCsItemsDateTeacher({ date_stamp: formatDate(this.date) }).then(response => {

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

@@ -4,13 +4,13 @@
       <span
         v-for="item in menu"
         :key="item.id"
+        v-t="item.name"
         :class="['tab-menu', { active: currentTab === item.tab }]"
         @click="currentTab = item.tab"
-        v-t="item.name"
       ></span>
     </div>
     <keep-alive>
-      <component :is="currentTabComponent"></component>
+      <component :is="currentTabComponent" />
     </keep-alive>
   </div>
 </template>
@@ -22,6 +22,10 @@ import { updateWordPack } from '@/utils/i18n';
 
 export default {
   name: 'Main',
+  components: {
+    TaskKanban,
+    CurriculaManager
+  },
   data() {
     return {
       currentTab: 'TaskKanban',
@@ -39,9 +43,10 @@ export default {
       ]
     };
   },
-  components: {
-    TaskKanban,
-    CurriculaManager
+  computed: {
+    currentTabComponent: function () {
+      return this.currentTab;
+    }
   },
   created() {
     updateWordPack({
@@ -53,11 +58,6 @@ export default {
         'Learn_Task_Over'
       ]
     });
-  },
-  computed: {
-    currentTabComponent: function () {
-      return this.currentTab;
-    }
   }
 };
 </script>