dusenyao 3 years ago
parent
commit
ebeb2cb867

+ 6 - 6
package-lock.json

@@ -8,7 +8,7 @@
       "name": "gcls_sys_learn_web",
       "version": "0.1.0",
       "dependencies": {
-        "ailp-book-question-ui": "file:../ailp-book-question-ui-0.1.0.tgz",
+        "ailp-book-question-ui": "file:../ailp-book-question-ui-0.1.1.tgz",
         "awe-dnd": "^0.3.4",
         "axios": "^0.21.1",
         "core-js": "^3.10.1",
@@ -4117,9 +4117,9 @@
       }
     },
     "node_modules/ailp-book-question-ui": {
-      "version": "0.1.0",
-      "resolved": "file:../ailp-book-question-ui-0.1.0.tgz",
-      "integrity": "sha512-IsEBARnDEV+51ErizOEp8110yW46L96q+BtjC3CFl8Mxp0DuQRzMU9WVwK9JqaKT0khpBsafdPxXBjfg6anPWg==",
+      "version": "0.1.1",
+      "resolved": "file:../ailp-book-question-ui-0.1.1.tgz",
+      "integrity": "sha512-8snSAD7U2YqlRUWw0NS7smimxC/hL3n1MTgUENFH/Rf0qVV0VTwO+hvqR6q/bGDCDbZZtWztAHnxnwIKruo28w==",
       "dependencies": {
         "awe-dnd": "^0.3.4",
         "axios": "^0.21.1",
@@ -26479,8 +26479,8 @@
       }
     },
     "ailp-book-question-ui": {
-      "version": "file:..\\ailp-book-question-ui-0.1.0.tgz",
-      "integrity": "sha512-IsEBARnDEV+51ErizOEp8110yW46L96q+BtjC3CFl8Mxp0DuQRzMU9WVwK9JqaKT0khpBsafdPxXBjfg6anPWg==",
+      "version": "file:..\\ailp-book-question-ui-0.1.1.tgz",
+      "integrity": "sha512-8snSAD7U2YqlRUWw0NS7smimxC/hL3n1MTgUENFH/Rf0qVV0VTwO+hvqR6q/bGDCDbZZtWztAHnxnwIKruo28w==",
       "requires": {
         "awe-dnd": "^0.3.4",
         "axios": "^0.21.1",

+ 2 - 1
package.json

@@ -6,12 +6,13 @@
     "serve": "vue-cli-service serve",
     "build": "vue-cli-service build",
     "build:stage": "vue-cli-service build --mode staging",
+    "build:report": "vue-cli-service build --report",
     "svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml",
     "test:unit": "jest --clearCache && vue-cli-service test:unit",
     "lint": "eslint --ext .js,.vue src"
   },
   "dependencies": {
-    "ailp-book-question-ui": "file:../ailp-book-question-ui-0.1.0.tgz",
+    "ailp-book-question-ui": "file:../ailp-book-question-ui-0.1.1.tgz",
     "awe-dnd": "^0.3.4",
     "axios": "^0.21.1",
     "core-js": "^3.10.1",

+ 192 - 317
src/views/course_details/index.vue

@@ -53,9 +53,9 @@
 
               <div v-if="!readonly">
                 <span class="price">
-                  ¥ {{ CourseData.price }}
-                  <span class="price_1" v-text="changePrice('1', CourseData.price)"></span>
-                  <span class="price_2" v-text="changePrice('2', CourseData.price)"></span>
+                  ¥
+                  <span class="price_1" v-text="changePrice('1', CourseData.price)" />
+                  <span class="price_2" v-text="changePrice('2', CourseData.price)" />
                 </span>
                 <button class="get" @click="getPurchase">
                   {{ is_buy ? '去学习' : '获取课程' }}
@@ -77,15 +77,11 @@
                 <p>{{ item.book_author }}</p>
                 <div class="operation">
                   <span class="price">
-                    ¥ {{ item.book_price }}
-                    <span class="price_1" v-text="changePrice('1', item.book_price)"></span>
-                    <span class="price_2" v-text="changePrice('2', item.book_price)"></span>
+                    ¥
+                    <span class="price_1" v-text="changePrice('1', item.book_price)" />
+                    <span class="price_2" v-text="changePrice('2', item.book_price)" />
                   </span>
-                  <button
-                    v-if="!readonly"
-                    :class="['get', is_buy ? 'acquired' : '']"
-                    @click="goBook(item.book_id)"
-                  >
+                  <button v-if="!readonly" :class="['get', is_buy ? 'acquired' : '']" @click="goBook(item.book_id)">
                     {{ is_buy ? '已' : '' }}购买
                   </button>
                 </div>
@@ -110,213 +106,83 @@
         </div>
         <div class="course-arrangement">
           <div class="moreTitle">课程安排</div>
-          <div v-for="(item, i) in CourseData.cs_item_list" :key="i" class="angement">
+          <div v-for="(item, i) in CourseData.cs_item_list" :key="i" class="course-list">
             <div class="courseOne">
               <div class="title">
                 <div>
                   <span>{{ i + 1 }}.</span>
                   <span>{{ item.name }}</span>
                 </div>
-                <div style="color: #737373">{{ item.begin_time }} ~ {{ item.end_time }}</div>
+                <div class="courseOne-time">{{ item.begin_time }} ~ {{ item.end_time }}</div>
               </div>
             </div>
             <div class="content" style="width: 670px">
-              <el-collapse @change="handleChange">
+              <el-collapse @change="handleChange(item.id)">
                 <el-collapse-item :name="item.id">
                   <div slot="title" class="Coursetasks">
                     课程任务
                     <img
-                      v-show="openList.indexOf(item.id) !== -1"
-                      class="open1"
-                      src="../../assets/course_details/open1.png"
-                    />
-                    <img
-                      v-show="openList.indexOf(item.id) === -1"
-                      class="open2"
-                      src="../../assets/course_details/open2.png"
+                      class="arrow"
+                      :src="
+                        openList.includes(item.id)
+                          ? require('../../assets/course_details/open1.png')
+                          : require('../../assets/course_details/open2.png')
+                      "
                     />
                   </div>
                   <div class="courseContent">
-                    <div class="tasks">
-                      <div class="title">
-                        <span></span>
-                        课前任务
-                      </div>
-                      <div class="content">
-                        <el-collapse-item
-                          v-for="(it, it_i) in item.pre_task_list"
-                          :key="it_i"
-                          :name="it.id"
-                        >
-                          <div
-                            slot="title"
-                            :class="
-                              openList.indexOf(it.id) !== -1 ? 'contenttitle2' : 'contenttitle'
-                            "
-                          >
-                            <span>{{ it.name }}</span>
-                            <span>
-                              <span class="gray">{{ it.begin_time }} ~ {{ it.end_time }}</span>
-                              <span class="gray">···</span>
-                            </span>
-                          </div>
-                          <div class="detail">
-                            <div>
-                              <span>说明</span>
-                              <p>
-                                {{ it.content }}
-                              </p>
+                    <template v-for="li in courseContentList">
+                      <div v-if="item[li.id].length > 0" :key="li.id" class="tasks">
+                        <div class="title">
+                          <span class="red-circle"></span><span>{{ li.name }}任务</span>
+                        </div>
+                        <div class="content">
+                          <el-collapse-item v-for="(it, it_i) in item[li.id]" :key="it_i" :name="it.id">
+                            <div slot="title" :class="openList.includes(it.id) ? 'contenttitle2' : 'contenttitle'">
+                              <span :title="it.name">{{ it.name }}</span>
+                              <span>
+                                <span class="gray">{{ it.begin_time }} ~ {{ it.end_time }}</span>
+                                <span class="gray">···</span>
+                              </span>
                             </div>
-                            <div v-if="it.courseware_list.length > 0">
-                              <span>课件</span>
+                            <div class="detail">
                               <div>
-                                <div
-                                  v-for="(courseware, courseware_i) in it.courseware_list"
-                                  :key="courseware_i"
-                                  class="btn"
-                                >
-                                  <img src="../../assets/course_details/file.png" alt="" />
-                                  <span> {{ courseware.courseware_name }} </span>
-                                </div>
+                                <span>说明</span>
+                                <p>
+                                  {{ it.content }}
+                                </p>
                               </div>
-                            </div>
-                            <div v-if="it.accessory_list.length > 0">
-                              <span>附件</span>
-                              <div>
-                                <div
-                                  v-for="(accessory, accessory_i) in it.accessory_list"
-                                  :key="accessory_i"
-                                  class="btn"
-                                >
-                                  <img src="../../assets/course_details/fileType1.png" alt="" />
-                                  <span> {{ accessory.file_name }} </span>
-                                </div>
-                              </div>
-                            </div>
-                          </div>
-                        </el-collapse-item>
-                      </div>
-                    </div>
-                    <div class="tasks">
-                      <div class="title">
-                        <span></span>
-                        课中任务
-                      </div>
-                      <div class="content">
-                        <el-collapse-item
-                          v-for="(it, it_i) in item.mid_task_list"
-                          :key="it_i"
-                          :name="it.id"
-                        >
-                          <div
-                            slot="title"
-                            :class="
-                              openList.indexOf(it.id) !== -1 ? 'contenttitle2' : 'contenttitle'
-                            "
-                          >
-                            <span>{{ it.name }}</span>
-                            <span>
-                              <span class="gray">{{ it.begin_time }} ~ {{ it.end_time }}</span>
-                              <span class="gray">···</span>
-                            </span>
-                          </div>
-                          <div class="detail">
-                            <div>
-                              <span>说明</span>
-                              <p>
-                                {{ it.content }}
-                              </p>
-                            </div>
-                            <div v-if="it.courseware_list.length > 0">
-                              <span>课件</span>
-                              <div>
-                                <div
-                                  v-for="(courseware, courseware_i) in it.courseware_list"
-                                  :key="courseware_i"
-                                  class="btn"
-                                >
-                                  <img src="../../assets/course_details/file.png" alt="" />
-                                  <span> {{ courseware.courseware_name }} </span>
+                              <div v-if="it.courseware_list.length > 0">
+                                <span>课件</span>
+                                <div>
+                                  <div
+                                    v-for="(courseware, courseware_i) in it.courseware_list"
+                                    :key="courseware_i"
+                                    class="btn"
+                                  >
+                                    <img src="../../assets/course_details/file.png" alt="" />
+                                    <span> {{ courseware.courseware_name }} </span>
+                                  </div>
                                 </div>
                               </div>
-                            </div>
-                            <div v-if="it.accessory_list.length > 0">
-                              <span>附件</span>
-                              <div>
-                                <div
-                                  v-for="(accessory, accessory_i) in it.accessory_list"
-                                  :key="accessory_i"
-                                  class="btn"
-                                >
-                                  <img src="../../assets/course_details/fileType1.png" alt="" />
-                                  <span> {{ accessory.file_name }} </span>
-                                </div>
-                              </div>
-                            </div>
-                          </div>
-                        </el-collapse-item>
-                      </div>
-                    </div>
-                    <div v-if="item.after_task_list.length > 0" class="tasks">
-                      <div class="title">
-                        <span></span>
-                        课后任务
-                      </div>
-                      <div class="content">
-                        <el-collapse-item
-                          v-for="(it, it_i) in item.after_task_list"
-                          :key="it_i"
-                          :name="it.id"
-                        >
-                          <div
-                            slot="title"
-                            :class="
-                              openList.indexOf(it.id) !== -1 ? 'contenttitle2' : 'contenttitle'
-                            "
-                          >
-                            <span>{{ it.name }}</span>
-                            <span>
-                              <span class="gray">{{ it.begin_time }} ~ {{ it.end_time }}</span>
-                              <span class="gray">···</span>
-                            </span>
-                          </div>
-                          <div class="detail">
-                            <div>
-                              <span>说明</span>
-                              <p>
-                                {{ it.content }}
-                              </p>
-                            </div>
-                            <div v-if="it.courseware_list.length > 0">
-                              <span>课件</span>
-                              <div>
-                                <div
-                                  v-for="(courseware, courseware_i) in it.courseware_list"
-                                  :key="courseware_i"
-                                  class="btn"
-                                >
-                                  <img src="../../assets/course_details/file.png" alt="" />
-                                  <span> {{ courseware.courseware_name }} </span>
-                                </div>
-                              </div>
-                            </div>
-                            <div v-if="it.accessory_list.length > 0">
-                              <span>附件</span>
-                              <div>
-                                <div
-                                  v-for="(accessory, courseware_i) in it.accessory_list"
-                                  :key="courseware_i"
-                                  class="btn"
-                                >
-                                  <img src="../../assets/course_details/fileType1.png" alt="" />
-                                  <span> {{ accessory.file_name }} </span>
+                              <div v-if="it.accessory_list.length > 0">
+                                <span>附件</span>
+                                <div>
+                                  <div
+                                    v-for="(accessory, accessory_i) in it.accessory_list"
+                                    :key="accessory_i"
+                                    class="btn"
+                                  >
+                                    <img src="../../assets/course_details/fileType1.png" alt="" />
+                                    <span> {{ accessory.file_name }} </span>
+                                  </div>
                                 </div>
                               </div>
                             </div>
-                          </div>
-                        </el-collapse-item>
+                          </el-collapse-item>
+                        </div>
                       </div>
-                    </div>
+                    </template>
                   </div>
                 </el-collapse-item>
               </el-collapse>
@@ -335,6 +201,7 @@
         </el-dialog>
       </div>
     </div>
+
     <div v-else-if="!loading" class="non-existent">
       <h1>该课程已下架</h1>
     </div>
@@ -356,8 +223,7 @@ export default {
       goods_id: query.goods_id,
       goods_type: query.goods_type,
       readonly: 'readonly' in query ? query.readonly : false,
-      enshrine: false,
-      SelectShow: '1', // 选择展示课程资源还是下载
+      collection: false,
       openList: [],
       timer: null, // 获取倒计时
       backTime: new Date(),
@@ -365,17 +231,20 @@ export default {
       loading: false,
       is_buy: false,
       CourseData: null,
-      isData: false
+      isData: false,
+      courseContentList: [
+        { id: 'pre_task_list', name: '课前' },
+        { id: 'mid_task_list', name: '课中' },
+        { id: 'after_task_list', name: '课后' }
+      ]
     };
   },
   created() {
     // 获取课程详情
     this.loading = true;
-    CheckMyGoodsBuyStatus({ goods_type: Number(this.goods_type), goods_id: this.goods_id }).then(
-      ({ is_buy }) => {
-        this.is_buy = is_buy === 'true';
-      }
-    );
+    CheckMyGoodsBuyStatus({ goods_type: Number(this.goods_type), goods_id: this.goods_id }).then(({ is_buy }) => {
+      this.is_buy = is_buy === 'true';
+    });
     GetCourseInfoBox({ id: this.goods_id })
       .then(res => {
         this.CourseData = res;
@@ -387,15 +256,15 @@ export default {
         this.loading = false;
       });
   },
+  beforeDestroy() {
+    // 清空定时器
+    clearInterval(this.timer);
+  },
   // 方法集合
   methods: {
     // 课程任务的打开和关闭
     handleChange(val) {
-      this.openList = val;
-    },
-    // 选择课程资源还是下载
-    SelectShowEvent(num) {
-      this.SelectShow = num;
+      this.openList.includes(val) ? this.openList.splice(this.openList.indexOf(val), 1) : this.openList.push(val);
     },
     goBook(book_id) {
       if (!this.is_buy) {
@@ -404,22 +273,20 @@ export default {
     },
     // 处理价格
     changePrice(type, item) {
-      if (item) {
-        let str = String(item);
-        if (str.indexOf('.') !== -1) {
-          if (type === 1) {
-            return str.split('.')[0];
-          } else if (type === 2) {
-            return '.' + str.split('.')[1];
-          }
-        } else if (type === 1) {
-          return str;
+      if (!item) return;
+      let str = String(item);
+      if (str.includes('.')) {
+        if (type === '1') {
+          return str.split('.')[0];
         }
+        return '.' + str.split('.')[1];
+      } else if (type === 1) {
+        return str;
       }
     },
     // 收藏
     enshrineEvent() {
-      this.enshrine = !this.enshrine;
+      this.collection = !this.collection;
     },
     // 购买   需要先加入课程 审核 审核通过之后才能购买课程
     getPurchase() {
@@ -463,11 +330,6 @@ export default {
         seconds
       };
     }
-  },
-  beforeDestory() {
-    // 清空定时器
-    clearInterval(this.timer);
-    this.timer = null;
   }
 };
 </script>
@@ -476,41 +338,40 @@ export default {
 .CourseDetail {
   .main {
     min-height: 100%;
-    padding-top: 52px;
+    padding: 52px 0 20px;
     background: #e5e5e5;
-    padding-bottom: 20px;
 
     .bookDetail {
+      position: relative;
+      display: flex;
       width: 1200px;
       height: 524px;
       padding: 64px;
       margin: 0 auto;
+      overflow: hidden;
       background: url('../../assets/course_details/Rectangle113.png');
       border-radius: 8px;
-      display: flex;
-      position: relative;
-      overflow: hidden;
 
       .rightUp {
+        position: absolute;
+        top: 0;
+        right: 0;
         width: 72px;
         height: 72px;
         background: url('../../assets/course_details/Rectangle903.png');
-        position: absolute;
-        right: 0;
-        top: 0;
 
         span {
-          color: #fff;
-          transform: translateX(4px) translateY(4px) rotateZ(45deg);
           position: absolute;
-          left: 30px;
           top: 10px;
+          left: 30px;
+          color: #fff;
+          transform: translateX(4px) translateY(4px) rotateZ(45deg);
         }
       }
 
       .text {
         width: 1100px;
-        color: white;
+        color: #fff;
 
         .tip:not(.p1) {
           margin-top: 36px;
@@ -521,17 +382,17 @@ export default {
         }
 
         .p1 {
-          font-size: 40px;
           margin-top: 16px;
+          font-size: 40px;
         }
 
         .intro {
-          height: 36px;
           display: -webkit-box;
+          height: 36px;
           -webkit-box-orient: vertical;
           -webkit-line-clamp: 2;
-          text-overflow: ellipsis;
           overflow: hidden;
+          text-overflow: ellipsis;
         }
 
         > :not(.p1) {
@@ -570,8 +431,8 @@ export default {
               }
 
               &-name {
-                font-size: 24px;
                 margin-top: 12px;
+                font-size: 24px;
               }
             }
           }
@@ -580,30 +441,30 @@ export default {
         .get {
           width: 200px;
           height: 56px;
+          margin-left: 30px;
+          font-size: 20px;
+          color: #fff;
+          cursor: pointer;
           background: $basicColor;
+          border-style: none;
           border-radius: 4px;
-          border: none;
           outline: none;
-          color: #fff;
-          font-size: 20px;
-          margin-left: 30px;
-          cursor: pointer;
         }
 
         .acquired {
           width: 120px;
           height: 40px;
+          margin-left: 30px;
+          font-size: 16px;
+          color: #fff;
+          cursor: pointer;
           background: #d5d5d5;
+          border-style: none;
           border-radius: 4px;
-          border: none;
           outline: none;
-          color: white;
-          font-size: 16px;
-          margin-left: 30px;
-          cursor: pointer;
         }
 
-        .enshrine {
+        .collection {
           margin-left: 30px;
 
           img {
@@ -620,36 +481,36 @@ export default {
       margin-top: 30px;
 
       .moreTitle {
-        font-weight: 600;
         font-size: 20px;
+        font-weight: 600;
         color: #000;
       }
 
       .moreTitle::before {
+        margin-right: 16px;
+        color: $basicColor;
         content: '|';
         background: $basicColor;
-        color: $basicColor;
-        margin-right: 16px;
       }
 
       .moreList {
-        width: 1300px;
-        margin: 0 auto;
         display: flex;
         flex-wrap: wrap;
+        width: 1300px;
+        margin: 0 auto;
 
         .moreOne {
-          margin-right: 20px;
-          margin-top: 20px;
+          display: flex;
           width: 598px;
           height: 236px;
+          margin-top: 20px;
+          margin-right: 20px;
           background: #fff;
           border-radius: 8px;
-          display: flex;
 
           > div {
-            margin-left: 32px;
             margin-top: 32px;
+            margin-left: 32px;
 
             img {
               width: 120px;
@@ -662,15 +523,15 @@ export default {
             margin-right: 23px;
 
             > p:not(.p1) {
+              margin-top: 10px;
               font-size: 16px;
               color: #2c2c2c;
               opacity: 0.7;
-              margin-top: 10px;
             }
 
             .p1 {
-              font-weight: 600;
               font-size: 20px;
+              font-weight: 600;
               color: #2c2c2c;
             }
 
@@ -682,14 +543,14 @@ export default {
             .get {
               width: 120px;
               height: 40px;
+              margin-left: 30px;
+              font-size: 20px;
+              color: #fff;
+              cursor: pointer;
               background: $basicColor;
+              border-style: none;
               border-radius: 4px;
-              border: none;
               outline: none;
-              color: white;
-              font-size: 20px;
-              margin-left: 30px;
-              cursor: pointer;
             }
 
             .acquired {
@@ -728,24 +589,24 @@ export default {
       margin-top: 30px;
 
       .moreTitle {
-        font-weight: 600;
         font-size: 20px;
+        font-weight: 600;
         color: #000;
       }
 
       .moreTitle::before {
+        margin-right: 16px;
+        color: $basicColor;
         content: '|';
         background: $basicColor;
-        color: $basicColor;
-        margin-right: 16px;
       }
 
-      .angement {
-        margin-top: 30px;
+      .course-list {
         width: 1200px;
-        background: #fff;
         padding: 40px 68px 40px 40px;
+        margin-top: 30px;
         font-size: 18px;
+        background: #fff;
 
         > :not(.courseOne) {
           padding-left: 40px;
@@ -766,15 +627,19 @@ export default {
               }
             }
           }
+
+          &-time {
+            color: #737373;
+          }
         }
 
         .Coursetasks {
-          cursor: pointer;
           display: flex;
           align-items: center;
           font-size: 16px;
+          cursor: pointer;
 
-          img {
+          .arrow {
             width: 24px;
             margin-left: 8px;
           }
@@ -788,35 +653,35 @@ export default {
               font-size: 16px;
               color: #2c2c2c;
 
-              span {
+              .red-circle {
+                position: relative;
+                right: 3px;
                 display: inline-block;
                 width: 8px;
                 height: 8px;
+                margin-right: 16px;
                 background: #fe6d68;
                 border-radius: 50%;
-                position: relative;
-                right: 3px;
-                margin-right: 16px;
               }
             }
 
             .content {
-              border-left: 1px solid #fe6d68;
+              padding-bottom: 10px;
               padding-left: 20px;
               margin-top: 16px;
-              padding-bottom: 10px;
+              border-left: 1px solid #fe6d68;
 
               .contenttitle {
-                padding: 0 10px;
-                width: 670px;
-                background: #fff;
-                border: 1px solid #e6e6e6;
-                border-radius: 8px;
                 display: flex;
-                justify-content: space-between;
                 align-items: center;
+                justify-content: space-between;
+                width: 670px;
+                padding: 0 10px;
                 font-size: 16px;
                 cursor: pointer;
+                background: #fff;
+                border: 1px solid #e6e6e6;
+                border-radius: 8px;
 
                 img {
                   width: 16px;
@@ -827,6 +692,13 @@ export default {
                   margin-left: 16px;
                 }
 
+                > span:first-child {
+                  width: 180px;
+                  overflow: hidden;
+                  text-overflow: ellipsis;
+                  white-space: nowrap;
+                }
+
                 .gray {
                   opacity: 0.5;
                 }
@@ -836,30 +708,30 @@ export default {
                 @extend .contenttitle;
 
                 background: #f9f9f9;
-                border-bottom-left-radius: 0;
                 border-bottom-right-radius: 0;
+                border-bottom-left-radius: 0;
               }
 
               .detail {
                 width: 599px;
+                padding-bottom: 24px;
                 background: #fff;
                 border: 1px solid #e7e7e7;
-                border-bottom-left-radius: 8px;
                 border-bottom-right-radius: 8px;
+                border-bottom-left-radius: 8px;
                 box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
-                padding-bottom: 24px;
 
                 > div {
-                  margin-top: 24px;
                   display: flex;
                   align-items: center;
+                  margin-top: 24px;
 
                   > :nth-child(1) {
                     width: 78px;
                     min-width: 78px;
+                    margin-left: 24px;
                     font-size: 16px;
                     color: #000;
-                    margin-left: 24px;
                   }
 
                   > :nth-child(2) {
@@ -870,18 +742,18 @@ export default {
                     }
 
                     .btn {
+                      display: flex;
+                      align-items: center;
                       width: 270px;
                       height: 40px;
+                      cursor: pointer;
                       background: #fff;
                       border: 1px solid #dbdbdb;
                       border-radius: 4px;
-                      display: flex;
-                      align-items: center;
-                      cursor: pointer;
 
                       img {
-                        margin-left: 16px;
                         margin-right: 8px;
+                        margin-left: 16px;
                       }
                     }
 
@@ -903,38 +775,38 @@ export default {
       margin-top: 24px;
 
       .sele {
+        display: flex;
+        align-items: center;
         width: 318px;
         height: 48px;
+        font-size: 20px;
+        color: #9f9f9f;
         background: #ebebeb;
         border-radius: 30px;
-        color: #9f9f9f;
-        font-size: 20px;
-        display: flex;
-        align-items: center;
 
         > div {
           width: 158px;
           height: 48px;
-          border-radius: 30px;
           line-height: 48px;
           text-align: center;
           cursor: pointer;
+          border-radius: 30px;
         }
 
         .select {
+          color: #fff;
           background: $basicColor;
-          color: white;
           box-shadow: 0 2px 8px rgba(255, 153, 0, 0.15);
         }
       }
     }
 
     .Catalogue {
-      margin: 24px auto;
+      display: flex;
       width: 1200px;
       height: 710px;
+      margin: 24px auto;
       background: #fff;
-      display: flex;
 
       .left {
         width: 340px;
@@ -944,8 +816,8 @@ export default {
         .title {
           width: 80%;
           margin: 29px auto;
-          font-weight: 600;
           font-size: 24px;
+          font-weight: 600;
           color: #000;
         }
       }
@@ -957,23 +829,22 @@ export default {
     }
 
     .Resources {
-      margin: 24px auto;
+      display: flex;
       width: 1200px;
       height: 710px;
+      margin: 24px auto;
       background: #fff;
-      display: flex;
 
       div {
+        display: flex;
+        align-items: center;
+        justify-content: center;
         height: 40px;
+        padding: 0 10px;
         margin: 10px;
+        cursor: pointer;
         border: 1px solid rgba(44, 44, 44, 0.15);
         border-radius: 4px;
-        padding: 0 10px;
-        margin-left: 10px;
-        display: flex;
-        justify-content: center;
-        align-items: center;
-        cursor: pointer;
 
         img {
           width: 24px;
@@ -992,17 +863,21 @@ export default {
 }
 
 .non-existent {
-  text-align: center;
   margin-top: 15vh;
+  text-align: center;
 }
 </style>
 
 <style lang="scss">
 .el-collapse {
-  border: none;
+  border-style: none;
+
+  &-item + &-item {
+    margin-top: 12px;
+  }
 
   .el-collapse-item__header {
-    border: none;
+    border-style: none;
 
     .l-collapse-item__arrow,
     .el-icon-arrow-right {
@@ -1011,7 +886,7 @@ export default {
   }
 
   .el-collapse-item__wrap {
-    border: none;
+    border-style: none;
   }
 
   .el-collapse-item__content {
@@ -1024,14 +899,14 @@ export default {
     padding: 32px 20px 24px 32px;
 
     .el-dialog__title {
-      line-height: 150%;
       font-size: 20px;
+      line-height: 150%;
       color: #000;
     }
   }
 
   .el-dialog__body {
-    padding: 0 32px 32px 32px;
+    padding: 0 32px 32px;
   }
 }
 </style>

+ 1 - 4
src/views/live/common.js

@@ -75,10 +75,7 @@ export function publishStream(streamName) {
  */
 export function createData() {
   let device = store.state.app.liveDevice;
-  let video =
-    device.video.length > 0
-      ? { device: 'camera', resolution: 'sif', deviceId: device.video }
-      : false;
+  let video = device.video.length > 0 ? { device: 'camera', resolution: 'sif', deviceId: device.video } : false;
   let audio = device.audio.length > 0 ? { deviceId: device.audio } : false;
 
   return {

+ 14 - 9
src/views/live/student/group.js

@@ -1,5 +1,5 @@
 import { Message } from 'element-ui';
-import { rtc, publishStream, closeVideo, createData } from '@/views/live/common';
+import { rtc, publishStream, closeVideo, createData, getHistory } from '@/views/live/common';
 export {
   initSDK,
   sendMsg,
@@ -78,6 +78,19 @@ export function initListener(vue) {
   // 教师 必须在加入房间成功的事件回调里创建本地流
   rtc.on('conference_join', () => {
     console.log('加入房间成功');
+
+    getHistory({
+      success(data) {
+        let chatLog = data.datas.meta.chatLog.map(({ content, userName }) => {
+          return { msg: content, username: userName };
+        });
+        vue.chatList = chatLog;
+      },
+      fail(str) {
+        console.log(str);
+      }
+    });
+
     if (vue.studentSelf.is_teacher_role_in_room === 'false') {
       rtc.handsUp({
         success: str => {
@@ -242,14 +255,6 @@ export function initListener(vue) {
     vue.chatList.push(dat);
   });
 
-  rtc.on('allowChatChange', function (data) {
-    let msg = data.settings.allow_chat ? '开言' : '禁言';
-    Message({
-      type: 'success',
-      message: `全体${msg}成功`
-    });
-  });
-
   // 接收自定义消息
   rtc.on('publish_message', data => {});
 }

+ 27 - 26
src/views/live/student/group.vue

@@ -373,7 +373,7 @@ export default {
 
             if (is_has_group_message === 'true') {
               this.$alert(group_message_text, '群消息', {
-                confirmButtonText: '关闭'
+                confirmButtonText: '确定'
               });
             }
           }
@@ -421,7 +421,7 @@ export default {
 </script>
 
 <style lang="scss" scoped>
-@import '~@/styles/mixin.scss';
+@import '~@/styles/mixin';
 $live-bc: #3d3938;
 
 .group {
@@ -429,8 +429,8 @@ $live-bc: #3d3938;
 
   // 顶部
   &-top {
-    background-color: #fff;
     padding: 24px 32px;
+    background-color: #fff;
     border-top-left-radius: 8px;
     border-top-right-radius: 8px;
 
@@ -443,15 +443,15 @@ $live-bc: #3d3938;
       }
 
       .el-button {
-        border-radius: 4px;
         padding: 7px 12px;
+        border-radius: 4px;
       }
     }
 
     .live-course-name {
       font-size: 14px;
-      color: #737373;
       line-height: 30px;
+      color: #737373;
     }
 
     .live-teacher {
@@ -479,13 +479,13 @@ $live-bc: #3d3938;
 
       // 分组讨论
       .group-discussion {
+        position: relative;
         display: flex;
         flex-wrap: wrap;
         width: 100%;
         height: 468px;
-        position: relative;
-        background-color: $live-bc;
         overflow: auto;
+        background-color: $live-bc;
 
         .group-box {
           width: 254px;
@@ -513,17 +513,18 @@ $live-bc: #3d3938;
         .group-wrapper {
           position: relative;
 
+          %live-wrapper-stream,
           .live-wrapper-stream {
             position: absolute;
             top: 120px;
-            height: 32px;
             width: calc(100% - 16px);
-            background-color: rgba(0, 0, 0, 0.7);
-            color: #fff;
+            height: 32px;
+            padding: 0 15px;
+            margin: 0 8px;
             line-height: 32px;
+            color: #fff;
             text-align: center;
-            margin: 0 8px;
-            padding: 0 15px;
+            background-color: rgba(0, 0, 0, 0.7);
             transition: all 300ms ease-in 0s;
 
             > .svg-icon {
@@ -532,7 +533,7 @@ $live-bc: #3d3938;
           }
 
           .local-stream {
-            @extend .live-wrapper-stream;
+            @extend %live-wrapper-stream;
 
             display: flex;
 
@@ -545,8 +546,8 @@ $live-bc: #3d3938;
               text-align: right;
 
               .svg-icon {
-                cursor: pointer;
                 margin-right: 18px;
+                cursor: pointer;
               }
             }
           }
@@ -557,8 +558,8 @@ $live-bc: #3d3938;
         display: flex;
         justify-content: space-between;
         height: 48px;
-        background-color: #4d4d4d;
         padding: 0 15px;
+        background-color: #4d4d4d;
         border-bottom-left-radius: 5px;
 
         .svg-icon {
@@ -582,19 +583,19 @@ $live-bc: #3d3938;
 
       // 聊天窗口
       &-chat {
-        height: 278px;
-        border: 1px solid #ccc;
-        border-bottom-left-radius: 8px;
         display: flex;
         flex-direction: column;
         justify-content: space-between;
+        height: 278px;
+        border: 1px solid #ccc;
+        border-bottom-left-radius: 8px;
 
         .chat-top {
           display: flex;
           justify-content: space-between;
           padding: 15px 15px 10px;
-          border-bottom: 1px solid #e6e6e6;
           color: #959595;
+          border-bottom: 1px solid #e6e6e6;
 
           label {
             cursor: pointer;
@@ -659,24 +660,24 @@ $live-bc: #3d3938;
 
         .live-wrapper {
           position: absolute;
-          height: 40px;
           width: 100%;
-          background-color: rgba(0, 0, 0, 0.7);
-          color: #fff;
-          line-height: 40px;
+          height: 40px;
           padding: 0 16px;
+          line-height: 40px;
+          color: #fff;
+          background-color: rgba(0, 0, 0, 0.7);
           transition: all 300ms ease-in 0s;
         }
       }
 
       .student-list {
         width: 100%;
+        height: calc(100% - 200px);
         padding: 24px 16px;
         margin-top: 2px;
-        height: calc(100% - 200px);
-        background-color: #2c2c2c;
         font-size: 14px;
         color: #fff;
+        background-color: #2c2c2c;
 
         &-title {
           margin-bottom: 16px;
@@ -693,8 +694,8 @@ $live-bc: #3d3938;
 
           .student-list-left {
             .name {
-              vertical-align: super;
               margin-left: 8px;
+              vertical-align: super;
             }
           }
         }

+ 44 - 38
src/views/live/student/index.vue

@@ -21,10 +21,10 @@
             <el-avatar icon="el-icon-user" :src="roomInfo.teacher_image_url" />
             <p class="loading-title">{{ roomInfo.teacher_name }}邀请您连线中</p>
             <div>
-              <el-button type="success" icon="el-icon-phone-outline" circle @click="inviteAccept" />
               <el-button type="danger" circle @click="handsDown">
                 <svg-icon icon-class="hang-up" />
               </el-button>
+              <el-button type="success" icon="el-icon-phone-outline" circle @click="inviteAccept" />
             </div>
           </div>
         </div>
@@ -91,8 +91,14 @@
             </ul>
           </div>
           <div class="chat-speak">
-            <el-input v-model="msg" placeholder="输入发言" maxlength="400" @keydown.enter.native="sendMsg">
-              <el-button slot="append" @click="sendMsg">发送</el-button>
+            <el-input
+              v-model="msg"
+              :disabled="!roomData.allow_chat"
+              :placeholder="roomData.allow_chat ? '输入发言' : '已全体禁言'"
+              maxlength="400"
+              @keydown.enter.native="sendMsg"
+            >
+              <el-button slot="append" :disabled="!roomData.allow_chat" @click="sendMsg">发送</el-button>
             </el-input>
           </div>
         </div>
@@ -516,15 +522,15 @@ export default {
 </script>
 
 <style lang="scss" scoped>
-@import '~@/styles/mixin.scss';
+@import '~@/styles/mixin';
 $live-bc: #3d3938;
 $draw-h: 520px;
 
 .live {
   @include dialog;
 
-  margin-bottom: 24px;
   min-width: 1440px;
+  margin-bottom: 24px;
 
   .dialog-group .el-dialog__body {
     height: 65px;
@@ -532,11 +538,11 @@ $draw-h: 520px;
 
   // 顶部
   &-top {
-    background-color: #fff;
     padding: 24px 32px;
+    background-color: #fff;
+    border-bottom: 1px solid #ccc;
     border-top-left-radius: 8px;
     border-top-right-radius: 8px;
-    border-bottom: 1px solid #ccc;
     box-shadow: 0 1px 1px #ccc;
 
     .live-title {
@@ -548,8 +554,8 @@ $draw-h: 520px;
       }
 
       .el-button {
-        border-radius: 4px;
         padding: 7px 12px;
+        border-radius: 4px;
       }
     }
   }
@@ -565,13 +571,13 @@ $draw-h: 520px;
 
       .loading {
         position: relative;
+        display: flex;
+        align-items: center;
+        justify-content: center;
         width: 100%;
         height: $draw-h;
         color: #fff;
         background-color: #646464;
-        display: flex;
-        justify-content: center;
-        align-items: center;
 
         &-wrapper {
           text-align: center;
@@ -579,8 +585,8 @@ $draw-h: 520px;
           > .el-avatar {
             width: 96px;
             height: 96px;
-            line-height: 96px;
             margin-bottom: 24px;
+            line-height: 96px;
 
             > &--icon {
               font-size: 36px;
@@ -599,9 +605,9 @@ $draw-h: 520px;
         height: $draw-h;
 
         #student {
+          position: relative;
           width: 100%;
           height: $draw-h;
-          position: relative;
           background-color: $live-bc;
         }
 
@@ -612,17 +618,17 @@ $draw-h: 520px;
         }
 
         .student-audio {
-          width: 100%;
-          height: 100%;
-          background-color: #646464;
           display: flex;
           flex-direction: column;
-          justify-content: center;
           align-items: center;
+          justify-content: center;
+          width: 100%;
+          height: 100%;
+          background-color: #646464;
 
           .connect-name {
-            color: #fff;
             margin: 24px 0;
+            color: #fff;
           }
 
           > .el-avatar {
@@ -639,19 +645,19 @@ $draw-h: 520px;
 
       // 画板
       #draw-parent {
-        height: $draw-h;
-        width: 100%;
         position: relative;
-        background-color: $live-bc;
+        width: 100%;
+        height: $draw-h;
         overflow: hidden;
+        background-color: $live-bc;
       }
 
       .button-group {
         display: flex;
         justify-content: space-between;
         height: 48px;
-        background-color: #4d4d4d;
         padding: 0 15px;
+        background-color: #4d4d4d;
         border-bottom-left-radius: 5px;
 
         .svg-icon {
@@ -680,13 +686,13 @@ $draw-h: 520px;
     }
 
     &-right {
-      height: 568px;
       width: 485px;
+      height: 568px;
       background-color: #fff;
 
       .live-teacher-lens {
-        display: flex;
         position: relative;
+        display: flex;
         overflow: hidden;
 
         #live {
@@ -696,14 +702,14 @@ $draw-h: 520px;
         }
 
         .live-wrapper {
-          display: flex;
           position: absolute;
-          height: 40px;
+          display: flex;
           width: 272px;
-          background-color: rgba(0, 0, 0, 0.7);
-          color: #fff;
-          line-height: 40px;
+          height: 40px;
           padding: 0 16px;
+          line-height: 40px;
+          color: #fff;
+          background-color: rgba(0, 0, 0, 0.7);
           transition: all 300ms ease-in 0s;
 
           > div:first-child {
@@ -715,18 +721,18 @@ $draw-h: 520px;
             text-align: right;
 
             .svg-icon {
-              cursor: pointer;
               margin-right: 18px;
+              cursor: pointer;
             }
           }
         }
 
         .live-operate {
-          flex: 1;
           display: flex;
+          flex: 1;
           flex-direction: column;
-          justify-content: center;
           align-items: center;
+          justify-content: center;
 
           &-icon {
             display: flex;
@@ -741,18 +747,18 @@ $draw-h: 520px;
 
       // 聊天窗口
       &-chat {
-        height: 417px;
-        border: 1px solid #ccc;
         display: flex;
         flex-direction: column;
         justify-content: space-between;
+        height: 417px;
+        border: 1px solid #ccc;
 
         .chat-top {
           display: flex;
           justify-content: space-between;
           padding: 15px 15px 10px;
-          border-bottom: 1px solid #e6e6e6;
           color: #959595;
+          border-bottom: 1px solid #e6e6e6;
 
           label {
             cursor: pointer;
@@ -814,15 +820,15 @@ $draw-h: 520px;
           align-items: center;
           width: 120px;
           height: 112px;
-          background-color: #fff;
           margin: 0 8px 8px 0;
+          background-color: #fff;
 
           .li-top {
             position: relative;
             width: 100%;
-            background-color: #000;
             height: 72px;
             text-align: center;
+            background-color: #000;
 
             .svg-icon {
               position: absolute;
@@ -843,9 +849,9 @@ $draw-h: 520px;
               padding: 0 24px;
 
               .svg-icon {
+                margin: 8px 4px 0;
                 font-size: 18px;
                 cursor: pointer;
-                margin: 8px 4px 0;
               }
             }
           }

+ 23 - 22
src/views/live/student/live.js

@@ -1,7 +1,7 @@
 import { Message } from 'element-ui';
 import store from '@/store';
 import { GetLiveRoomInfo } from '@/api/live';
-import { rtc, publishStream, closeVideo, getDevice } from '@/views/live/common';
+import { rtc, publishStream, closeVideo, getDevice, getHistory } from '@/views/live/common';
 export {
   initSDK,
   sendMsg,
@@ -14,14 +14,6 @@ export {
   sendPublishMessage
 } from '@/views/live/common';
 
-// 分组讨论
-
-let r;
-export function init(data) {
-  r = new Rtc(data);
-  return r;
-}
-
 // 连麦
 
 /**
@@ -65,15 +57,13 @@ export function initListener(vue) {
       type: 'success'
     });
     vue.roomData = data;
-    // 初始化画板需要的数据
-    let canvasInitData = {
+    // 初始化画板
+    rtc.canvasInit({
       allowDraw: false, // 是否具有书写画笔权限(讲师权限) true / false
       id: 'draw-parent',
       pptDisplay: 1, // 文档展示方式。默认0,按窗口  1,按宽度
       liveId: data.live.status === 1 ? data.live.id : '' // 如果直播已经开始,需将直播 id 传入 sdk 中
-    };
-    // 初始化画板
-    rtc.canvasInit(canvasInitData);
+    });
   });
 
   rtc.on('login_failed', data => {
@@ -88,6 +78,18 @@ export function initListener(vue) {
   rtc.on('conference_join', () => {
     console.log('加入房间成功');
 
+    getHistory({
+      success(data) {
+        let chatLog = data.datas.meta.chatLog.map(({ content, userName }) => {
+          return { msg: content, username: userName };
+        });
+        vue.chatList = chatLog;
+      },
+      fail(str) {
+        console.log(str);
+      }
+    });
+
     getDevice({
       success(data) {
         console.log('获取音视频设备成功', data);
@@ -198,6 +200,10 @@ export function initListener(vue) {
 
   rtc.on('switch_settings', data => {
     console.log('房间设置事件', JSON.parse(data)); // 房间设置事件
+    let { changed, settings } = JSON.parse(data);
+    if (changed.includes('allow_chat')) {
+      vue.roomData.allow_chat = settings.allow_chat;
+    }
   });
 
   rtc.on('publishStreamErr', data => {
@@ -272,10 +278,7 @@ export function initListener(vue) {
       console.log('创建本地流推流');
       vue.roomInfo.video_mode = video_mode;
       let device = store.state.app.liveDevice;
-      let video =
-        device.video.length > 0
-          ? { device: 'camera', resolution: 'sif', deviceId: device.video }
-          : false;
+      let video = device.video.length > 0 ? { device: 'camera', resolution: 'sif', deviceId: device.video } : false;
       let audio = device.audio.length > 0 ? { deviceId: device.audio } : false;
 
       const createData = {
@@ -311,7 +314,6 @@ export function initListener(vue) {
    */
   rtc.on('chat_message', data => {
     let dat = JSON.parse(data);
-    console.log(dat);
     // 敏感词过滤:如果发送的聊天消息被系统判定包含敏感词,则只有发送者能收到本条消息,房间内其他人都不会收到这条聊天消息。
     // 如果返回消息中有 isFilterChat 字段(消息不包含敏感词返回数据中无isFilterChat字段),且isFilterChat的值为1,则说明该消息包含敏感字,除发送者外其他人不会收到这条消息。
     if (dat.isFilterChat && dat.isFilterChat === 1) {
@@ -320,11 +322,10 @@ export function initListener(vue) {
     vue.chatList.push(dat);
   });
 
-  rtc.on('allowChatChange', function (data) {
-    let msg = data.settings.allow_chat ? '开言' : '禁言';
+  rtc.on('allowChatChange', ({ settings }) => {
     Message({
       type: 'success',
-      message: `全体${msg}成功`
+      message: `已${settings.allow_chat ? '取消' : '开启'}全体禁言`
     });
   });
 

+ 0 - 8
src/views/live/teacher/group.js

@@ -225,14 +225,6 @@ export function initListener(vue) {
       vue.chatList.push(dat);
     }
   });
-
-  rtc.on('allowChatChange', function (data) {
-    let msg = data.settings.allow_chat ? '开言' : '禁言';
-    Message({
-      type: 'success',
-      message: `全体${msg}成功`
-    });
-  });
 }
 
 // 加载直播所需 SDK,加载完成后才能初始化

+ 66 - 62
src/views/live/teacher/index.vue

@@ -117,10 +117,10 @@
         <div class="live-container-right-chat">
           <div class="chat-top">
             <span>聊天</span>
-            <label @click="chatBans">
-              <input v-model="roomData.allow_chat" type="checkbox" class="allow-chat" />
+            <span class="chat-bans" @click="chatBans">
+              <input type="checkbox" :checked="isAllowChat" class="allow-chat" />
               <span>禁言</span>
-            </label>
+            </span>
           </div>
           <div class="chat-window">
             <ul ref="chat" class="chat-window-ul">
@@ -326,6 +326,9 @@ export default {
     isDraw() {
       return !this.connect && !this.callLoading;
     },
+    isAllowChat() {
+      return !this.roomData.allow_chat;
+    },
     netStatusColor() {
       if (this.netStatus >= 1000) {
         return '#f00';
@@ -663,7 +666,8 @@ export default {
     chatBans() {
       common.roomUpdate({
         allow_chat: !this.roomData.allow_chat,
-        roomUpdateSuccess(data) {
+        roomUpdateSuccess: data => {
+          this.roomData.allow_chat = !this.roomData.allow_chat;
           console.log(data, '房间模板配置更新请求成功!');
         },
         roomUpdateFailed(data) {
@@ -787,15 +791,15 @@ export default {
 </script>
 
 <style lang="scss" scoped>
-@import '~@/styles/mixin.scss';
+@import '~@/styles/mixin';
 $live-bc: #3d3938;
 $draw-h: 520px;
 
 .live {
   @include dialog;
 
-  margin-bottom: 24px;
   min-width: 1440px;
+  margin-bottom: 24px;
 
   .dialog-group .el-dialog__body {
     height: 65px;
@@ -803,11 +807,11 @@ $draw-h: 520px;
 
   // 顶部
   &-top {
-    background-color: #fff;
     padding: 24px 32px;
+    background-color: #fff;
+    border-bottom: 1px solid #ccc;
     border-top-left-radius: 8px;
     border-top-right-radius: 8px;
-    border-bottom: 1px solid #ccc;
     box-shadow: 0 1px 1px #ccc;
 
     .live-title {
@@ -819,8 +823,8 @@ $draw-h: 520px;
       }
 
       .el-button {
-        border-radius: 4px;
         padding: 7px 12px;
+        border-radius: 4px;
       }
     }
   }
@@ -836,13 +840,13 @@ $draw-h: 520px;
 
       .loading {
         position: relative;
+        display: flex;
+        align-items: center;
+        justify-content: center;
         width: 100%;
         height: $draw-h;
         color: #fff;
         background-color: #646464;
-        display: flex;
-        justify-content: center;
-        align-items: center;
 
         &-wrapper {
           text-align: center;
@@ -850,8 +854,8 @@ $draw-h: 520px;
           > .el-avatar {
             width: 96px;
             height: 96px;
-            line-height: 96px;
             margin-bottom: 24px;
+            line-height: 96px;
 
             > &--icon {
               font-size: 36px;
@@ -870,9 +874,9 @@ $draw-h: 520px;
         height: $draw-h;
 
         #student {
+          position: relative;
           width: 100%;
           height: $draw-h;
-          position: relative;
           background-color: $live-bc;
         }
 
@@ -883,17 +887,17 @@ $draw-h: 520px;
         }
 
         .student-audio {
-          width: 100%;
-          height: 100%;
-          background-color: #646464;
           display: flex;
           flex-direction: column;
-          justify-content: center;
           align-items: center;
+          justify-content: center;
+          width: 100%;
+          height: 100%;
+          background-color: #646464;
 
           .connect-name {
-            color: #fff;
             margin: 24px 0;
+            color: #fff;
           }
 
           > .el-avatar {
@@ -910,11 +914,11 @@ $draw-h: 520px;
 
       // 画板
       #draw-parent {
-        height: $draw-h;
-        width: 100%;
         position: relative;
-        background-color: $live-bc;
+        width: 100%;
+        height: $draw-h;
         overflow: hidden;
+        background-color: $live-bc;
 
         // 设置屏幕画笔
         .draw-setting {
@@ -922,72 +926,72 @@ $draw-h: 520px;
           bottom: 13px;
           left: 22px;
           z-index: 9999;
-          background-color: #a0a0a0;
-          padding: 6px;
-          border-radius: 40px;
           height: 40px;
+          padding: 6px;
           line-height: 28px;
+          background-color: #a0a0a0;
+          border-radius: 40px;
 
-          & > span {
+          > span {
             display: inline-block;
-            text-align: center;
             margin-right: 10px;
+            text-align: center;
           }
 
           & > span.brush-shape {
             width: 28px;
             height: 28px;
-            border-radius: 50%;
-            background-color: #fff;
             cursor: pointer;
+            background-color: #fff;
+            border-radius: 50%;
           }
 
           .draw-color {
             position: relative;
             top: 5px;
-            height: 18px;
             width: 18px;
-            border-radius: 50%;
+            height: 18px;
             cursor: pointer;
+            border-radius: 50%;
           }
 
           .current::after {
-            content: '';
             position: absolute;
             bottom: -7px;
             left: 7px;
             width: 4px;
             height: 4px;
-            border-radius: 50%;
+            content: '';
             background-color: #292929;
+            border-radius: 50%;
           }
 
           .draw-thickness {
-            height: 18px;
-            width: 18px;
-            cursor: pointer;
             display: inline-flex;
             flex-direction: column;
+            align-items: center;
             justify-content: center;
+            width: 18px;
+            height: 18px;
             vertical-align: middle;
-            align-items: center;
+            cursor: pointer;
 
             span {
-              border-radius: 50%;
               background-color: #000;
+              border-radius: 50%;
             }
           }
 
-          & > .brush-clear {
+          > .brush-clear {
             width: 28px;
             height: 28px;
-            border-radius: 50%;
-            background-color: #666;
-            cursor: pointer;
             margin-right: 0;
+            cursor: pointer;
+            background-color: #666;
+            border-radius: 50%;
           }
 
-          & > .eraser {
+          > .eraser {
             @extend .brush-clear;
 
             margin-right: 12px;
@@ -999,8 +1003,8 @@ $draw-h: 520px;
         display: flex;
         justify-content: space-between;
         height: 48px;
-        background-color: #4d4d4d;
         padding: 0 15px;
+        background-color: #4d4d4d;
         border-bottom-left-radius: 5px;
 
         .svg-icon {
@@ -1028,13 +1032,13 @@ $draw-h: 520px;
     }
 
     &-right {
-      height: 568px;
       width: 485px;
+      height: 568px;
       background-color: #fff;
 
       .live-teacher-lens {
-        display: flex;
         position: relative;
+        display: flex;
         overflow: hidden;
 
         #live {
@@ -1044,14 +1048,14 @@ $draw-h: 520px;
         }
 
         .live-wrapper {
-          display: flex;
           position: absolute;
-          height: 40px;
+          display: flex;
           width: 272px;
-          background-color: rgba(0, 0, 0, 0.7);
-          color: #fff;
-          line-height: 40px;
+          height: 40px;
           padding: 0 16px;
+          line-height: 40px;
+          color: #fff;
+          background-color: rgba(0, 0, 0, 0.7);
           transition: all 300ms ease-in 0s;
 
           > div:first-child {
@@ -1063,26 +1067,26 @@ $draw-h: 520px;
             text-align: right;
 
             .svg-icon {
-              cursor: pointer;
               margin-right: 18px;
+              cursor: pointer;
             }
           }
         }
 
         .live-operate {
-          flex: 1;
           display: flex;
+          flex: 1;
           flex-direction: column;
-          justify-content: center;
           align-items: center;
+          justify-content: center;
 
           &-icon {
             display: flex;
             padding-top: 18px;
 
             > .svg-icon {
-              cursor: pointer;
               margin-left: 24px;
+              cursor: pointer;
             }
           }
         }
@@ -1090,20 +1094,20 @@ $draw-h: 520px;
 
       // 聊天窗口
       &-chat {
-        height: 417px;
-        border: 1px solid #ccc;
         display: flex;
         flex-direction: column;
         justify-content: space-between;
+        height: 417px;
+        border: 1px solid #ccc;
 
         .chat-top {
           display: flex;
           justify-content: space-between;
           padding: 15px 15px 10px;
-          border-bottom: 1px solid #e6e6e6;
           color: #959595;
+          border-bottom: 1px solid #e6e6e6;
 
-          label {
+          .chat-bans {
             cursor: pointer;
           }
 
@@ -1163,16 +1167,16 @@ $draw-h: 520px;
           align-items: center;
           width: 120px;
           height: 144px;
-          background-color: #fff;
           margin: 0 8px 8px 0;
+          background-color: #fff;
 
           .li-top {
             position: relative;
             flex: 1;
             width: 100%;
-            background-color: #000;
             min-height: 72px;
             text-align: center;
+            background-color: #000;
 
             .svg-icon {
               position: absolute;
@@ -1194,9 +1198,9 @@ $draw-h: 520px;
               padding: 0 24px;
 
               .svg-icon {
+                margin: 8px 4px 0;
                 font-size: 18px;
                 cursor: pointer;
-                margin: 8px 4px 0;
               }
             }
           }

+ 15 - 4
src/views/live/teacher/live.js

@@ -1,6 +1,6 @@
 import { Message } from 'element-ui';
 import store from '@/store';
-import { rtc, updateMcResult, getDevice, createData } from '@/views/live/common';
+import { rtc, updateMcResult, getDevice, createData, getHistory } from '@/views/live/common';
 export {
   initSDK,
   downloadWebSDK,
@@ -108,6 +108,18 @@ export function initListener(vue) {
   // 教师 必须在加入房间成功的事件回调里创建本地流
   rtc.on('conference_join', () => {
     console.log('加入房间成功');
+    getHistory({
+      success(data) {
+        let chatLog = data.datas.meta.chatLog.map(({ content, userName }) => {
+          return { msg: content, username: userName };
+        });
+        vue.chatList = chatLog;
+      },
+      fail(str) {
+        console.log(str);
+      }
+    });
+
     getDevice({
       success(data) {
         console.log('获取音视频设备成功', data);
@@ -317,11 +329,10 @@ export function initListener(vue) {
     vue.chatList.push(dat);
   });
 
-  rtc.on('allowChatChange', function (data) {
-    let msg = data.settings.allow_chat ? '开言' : '禁言';
+  rtc.on('allowChatChange', ({ settings }) => {
     Message({
       type: 'success',
-      message: `全体${msg}成功`
+      message: `已${settings.allow_chat ? '取消' : '开启'}全体禁言`
     });
   });
 

+ 24 - 37
src/views/main/TaskList.vue

@@ -14,11 +14,7 @@
         </div>
         <div class="tasks-top-notification-container">
           <ul>
-            <li
-              v-for="item in message_list"
-              :key="item.id"
-              @click="readMyMessage(item.id, item.source_entity_id)"
-            >
+            <li v-for="item in message_list" :key="item.id" @click="readMyMessage(item.id, item.source_entity_id)">
               <span class="send_time">{{ item.send_time }}</span>
               <span class="content">{{ item.content }}</span>
             </li>
@@ -48,20 +44,12 @@
           <div class="tasks-group-list">
             <div v-for="list in item.task_list" :key="list.id" class="tasks-group-list-info">
               <div class="tasks-group-list-info-name">
-                <span @click="taskLink_outside(list.id)">
-                  {{ timeType(list.time_type) }}任务:{{ list.name }}
-                </span>
-                <el-link
-                  class="task-link"
-                  :underline="false"
-                  @click.stop="taskLink(list.teaching_type, list.id)"
-                >
+                <span @click="taskLink_outside(list.id)"> {{ timeType(list.time_type) }}任务:{{ list.name }} </span>
+                <el-link class="task-link" :underline="false" @click.stop="taskLink(list.teaching_type, list.id)">
                   {{ teachingType(list.teaching_type) }}
                 </el-link>
               </div>
-              <div class="tasks-group-list-info-item-name">
-                {{ list.course_name }} - {{ list.cs_item_name }}
-              </div>
+              <div class="tasks-group-list-info-item-name">{{ list.course_name }} - {{ list.cs_item_name }}</div>
               <div class="tasks-group-list-info-time">{{ list.time_space_view_txt }}</div>
               <div></div>
             </div>
@@ -146,17 +134,13 @@ export default {
           });
         });
       } else {
-        this.$router.push(
-          `/task_detail/${userType === 'STUDENT' ? 'student' : 'teacher'}/${task_id}`
-        );
+        this.$router.push(`/task_detail/${userType === 'STUDENT' ? 'student' : 'teacher'}/${task_id}`);
       }
     },
 
     taskLink_outside(task_id) {
       this.$router.push(
-        `/task_detail/${
-          this.$store.state.user.user_type === 'STUDENT' ? 'student' : 'teacher'
-        }/${task_id}`
+        `/task_detail/${this.$store.state.user.user_type === 'STUDENT' ? 'student' : 'teacher'}/${task_id}`
       );
     },
 
@@ -204,19 +188,19 @@ export default {
 
       &__body {
         thead th {
-          padding: 0 0 4px 0;
+          padding: 0 0 4px;
         }
       }
     }
 
     // 任务通知
     &-notification {
-      background-color: #fff;
       flex: 1;
       height: 300px;
-      margin-left: 16px;
       padding: 20px 24px;
+      margin-left: 16px;
       overflow: hidden;
+      background-color: #fff;
 
       &-title {
         display: flex;
@@ -224,26 +208,30 @@ export default {
         font-size: 20px;
         font-weight: 700;
 
-        & .title {
+        .title {
           display: inline-block;
           margin-left: 10px;
         }
 
-        & .el-icon-arrow-right {
+        .el-icon-arrow-right {
           cursor: pointer;
         }
       }
 
       &-container {
+        height: 210px;
         margin-top: 24px;
+        overflow-y: auto;
 
         ul {
           li {
-            font-size: 14px;
             display: flex;
+            font-size: 14px;
+            line-height: 1.3;
 
             .send_time {
               width: 150px;
+              min-width: 150px;
               color: #767676;
             }
 
@@ -262,11 +250,11 @@ export default {
   }
 
   &-container {
-    margin-top: 16px;
-    border-radius: 8px;
     width: 100%;
     min-height: calc(100vh - 522px);
+    margin-top: 16px;
     background-color: #fff;
+    border-radius: 8px;
 
     &-title {
       display: flex;
@@ -291,9 +279,8 @@ export default {
         }
 
         .el-icon-arrow-left {
-          @extend .el-icon-arrow-right;
-
           margin: 0 26px 0 33px;
+          cursor: pointer;
         }
       }
     }
@@ -306,8 +293,8 @@ export default {
 
         &-top {
           display: flex;
-          justify-content: space-between;
           align-items: center;
+          justify-content: space-between;
 
           &-time {
             color: #808080;
@@ -326,10 +313,10 @@ export default {
           &-info {
             display: inline-block;
             padding: 16px 24px;
-            border: 1px solid #ccc;
-            border-radius: 8px;
             margin: 10px 15px 10px 0;
             background-color: #fff4e3;
+            border: 1px solid #ccc;
+            border-radius: 8px;
 
             > div {
               margin: 8px 0;
@@ -341,10 +328,10 @@ export default {
               }
 
               .task-link {
-                font-size: 16px;
-                vertical-align: top;
                 margin-left: 8px;
+                font-size: 16px;
                 color: $basicColor;
+                vertical-align: top;
               }
             }
 

+ 5 - 8
src/views/task_details/ShowCourseware.vue

@@ -2,9 +2,7 @@
   <div class="show-courseware">
     <div id="AILPcontent">
       <div class="full">
-        <el-button type="primary" class="full-screen" @click="fullScreen">
-          <el-image :src="fullImage" />
-        </el-button>
+        <el-image class="full-screen" :src="require('../../assets/common/fullScreen.png')" @click="fullScreen" />
       </div>
       <template v-if="sys_type === 'GCLS'">
         <bookquestion :context="context" :book-client-width="1200" />
@@ -28,7 +26,6 @@ import { GetCoursewareContent_View } from '@/api/course';
 export default {
   data() {
     return {
-      fullImage: require('../../assets/common/fullScreen.png'),
       coursewareId: this.$route.params.coursewareId,
       context: null,
       ui_type: '',
@@ -130,10 +127,10 @@ export default {
       top: 30px;
       left: 90%;
       z-index: 2;
-
-      .el-image {
-        width: 70px;
-      }
+      display: block;
+      width: 70px;
+      max-height: 42px;
+      cursor: pointer;
     }
   }
 }

+ 4 - 4
src/views/task_details/TaskTop.vue

@@ -71,8 +71,8 @@ export default {
 
   .title {
     display: flex;
-    justify-content: space-between;
     align-items: center;
+    justify-content: space-between;
 
     &-name {
       font-size: 24px;
@@ -92,8 +92,8 @@ export default {
     margin-bottom: 16px;
 
     &-title {
-      font-size: 18px;
       margin-bottom: 16px;
+      font-size: 18px;
     }
   }
 
@@ -103,8 +103,8 @@ export default {
     border-top: 1px solid #d9d9d9;
 
     &-title {
-      font-size: 18px;
       margin-bottom: 16px;
+      font-size: 18px;
     }
 
     .el-tag {
@@ -114,8 +114,8 @@ export default {
         overflow: hidden;
 
         .svg-icon {
-          font-size: 18px;
           margin-right: 12px;
+          font-size: 18px;
         }
 
         &_name {

+ 38 - 61
src/views/task_details/student/index.vue

@@ -17,23 +17,14 @@
             @click="finishTask(item.courseware_id, item.is_finished)"
           >
             <svg-icon icon-class="courseware" /> <span>{{ item.courseware_name }}</span>
-            <svg-icon
-              v-if="item.is_finished === 'true'"
-              class="check-mark"
-              icon-class="check-mark"
-            />
+            <svg-icon v-if="item.is_finished === 'true'" class="check-mark" icon-class="check-mark" />
           </el-tag>
         </div>
       </div>
       <div class="accessory-list">
         <span class="label">文档列表</span>
         <div>
-          <el-tag
-            v-for="item in accessory_list"
-            :key="item.file_id"
-            color="#fff"
-            :title="item.file_name"
-          >
+          <el-tag v-for="item in accessory_list" :key="item.file_id" color="#fff" :title="item.file_name">
             <span @click="viewFile(item.file_name, item.file_id)">{{ item.file_name }}</span>
           </el-tag>
         </div>
@@ -41,7 +32,7 @@
       <!-- 完成评价 -->
       <template v-if="my_execute_info.is_finished === 'true'">
         <div class="teacher-commenting">
-          <div>
+          <div class="single-line">
             <span class="label">作业</span>
             <div>
               <el-tag
@@ -54,31 +45,19 @@
               </el-tag>
             </div>
           </div>
-          <div v-if="teaching_type === 10">
+          <div v-if="teaching_type === 10" class="single-line">
             <span class="label">学员课后评价</span>
-            <el-input
-              v-model="my_execute_info.student_remark"
-              disabled
-              type="textarea"
-              resize="none"
-              :rows="6"
-            />
+            <el-input v-model="my_execute_info.student_remark" disabled type="textarea" resize="none" :rows="6" />
           </div>
-          <div v-if="teaching_type === 10">
+          <div v-if="teaching_type === 10" class="single-line">
             <span class="label">学员课后评分</span>
             <el-rate v-model="my_execute_info.student_score" disabled />
           </div>
-          <div>
+          <div class="single-line">
             <span class="label">给教师留言</span>
-            <el-input
-              v-model="my_execute_info.student_message"
-              disabled
-              type="textarea"
-              resize="none"
-              :rows="6"
-            />
+            <el-input v-model="my_execute_info.student_message" disabled type="textarea" resize="none" :rows="6" />
           </div>
-          <div>
+          <div class="single-line">
             <span class="label">教师点评</span>
             <el-rate v-model="my_execute_info.teacher_score" disabled />
             <span class="teacher_remark">{{ my_execute_info.teacher_remark }}</span>
@@ -88,20 +67,18 @@
       <!-- 直播评价 -->
       <template v-else-if="teaching_type === 10">
         <div class="live-info">
-          <div>
-            <span class="enter-live" @click="enterLive">
-              <svg-icon icon-class="video-red" /> 点击进入直播间
-            </span>
+          <div class="single-line">
+            <span class="enter-live" @click="enterLive"><svg-icon icon-class="video-red" /> 点击进入直播间</span>
           </div>
-          <div>
+          <div class="single-line">
             <span class="label">学员课后评价</span>
             <el-input v-model="student_remark" type="textarea" resize="none" :rows="6" />
           </div>
-          <div>
+          <div class="single-line">
             <span class="label">学员课后评分</span>
             <el-rate v-model="student_score" />
           </div>
-          <div class="confirm">
+          <div class="confirm single-line">
             <el-button type="primary" @click="fillTaskExecuteInfo_Student_live">提交</el-button>
           </div>
         </div>
@@ -370,21 +347,21 @@ export default {
 </script>
 
 <style lang="scss">
-@import '~@/styles/mixin.scss';
+@import '~@/styles/mixin';
 $bor-color: #d9d9d9;
 
 .task-detail {
   @include container;
 
-  margin-top: 56px;
   min-height: calc(100vh - 130px);
+  margin-top: 56px;
 
   .el-tag {
     @include el-tag;
 
-    border-radius: 4px;
     margin: 0 8px 6px 0;
     border-color: $bor-color;
+    border-radius: 4px;
 
     > span {
       cursor: pointer;
@@ -392,10 +369,10 @@ $bor-color: #d9d9d9;
   }
 
   &-main {
+    padding: 24px 32px;
+    margin-top: 16px;
     background-color: #fff;
     border-radius: 8px;
-    margin-top: 16px;
-    padding: 24px 32px;
 
     .time-type {
       font-size: 20px;
@@ -403,27 +380,29 @@ $bor-color: #d9d9d9;
     }
 
     .time-interval {
-      color: #737373;
       padding: 16px 0;
+      color: #737373;
     }
 
+    %submit-homework,
     .submit-homework {
-      border-top: 1px solid $bor-color;
-      padding-top: 24px;
       display: flex;
       align-items: center;
+      padding-top: 24px;
+      border-top: 1px solid $bor-color;
     }
 
+    %teacher-commenting,
     .teacher-commenting {
-      @extend .submit-homework;
+      @extend %submit-homework;
 
       flex-direction: column;
 
-      > div {
+      > .single-line {
         display: flex;
         width: 100%;
 
-        & + div {
+        + div {
           margin-top: 24px;
         }
 
@@ -434,18 +413,18 @@ $bor-color: #d9d9d9;
     }
 
     .live-info {
-      @extend .teacher-commenting;
+      @extend %teacher-commenting;
 
       .enter-live {
-        cursor: pointer;
         padding: 8px 26px;
         color: #ff6868;
+        cursor: pointer;
         border: 1px solid #ff6868;
         border-radius: 20px;
       }
 
       .confirm {
-        padding-left: 105px;
+        padding-left: 120px;
       }
     }
 
@@ -454,8 +433,8 @@ $bor-color: #d9d9d9;
       margin-bottom: 16px;
 
       > .el-tag {
-        color: #409eff;
         padding: 0 10px;
+        color: #409eff;
         border-color: #d9ecff;
       }
     }
@@ -467,25 +446,21 @@ $bor-color: #d9d9d9;
       .label {
         margin-top: 8px;
       }
-
-      .el-textarea {
-        width: 1010px;
-      }
     }
 
     .task-courseware .el-tag {
       cursor: pointer;
 
       .svg-icon {
-        font-size: 18px;
         margin-right: 8px;
+        font-size: 18px;
       }
 
       .check-mark {
-        margin-left: 12px;
+        position: relative;
         top: 2px;
         right: -20px;
-        position: relative;
+        margin-left: 12px;
       }
     }
 
@@ -493,7 +468,9 @@ $bor-color: #d9d9d9;
     .task-courseware,
     .accessory-list,
     .submit-homework,
-    .leave-message {
+    .leave-message,
+    .live-info,
+    .teacher-commenting {
       display: flex;
       margin-bottom: 16px;
 
@@ -505,7 +482,7 @@ $bor-color: #d9d9d9;
     }
 
     .submit-button {
-      padding-left: 105px;
+      padding-left: 120px;
     }
   }
 }

+ 5 - 17
src/views/task_details/teacher/index.vue

@@ -22,11 +22,7 @@
       <div class="finish-detail">
         <div class="student-info">
           <div>
-            <el-avatar
-              :src="curFinishDetail.student_image_url"
-              :size="32"
-              icon="el-icon-user-solid"
-            />
+            <el-avatar :src="curFinishDetail.student_image_url" :size="32" icon="el-icon-user-solid" />
             <span class="student-info-name">{{ curFinishDetail.student_name }}</span>
           </div>
           <span class="finish-time">{{ curFinishDetail.finish_time_view_txt }}</span>
@@ -44,11 +40,7 @@
               <div class="courseware">
                 <svg-icon icon-class="courseware" />
                 <span class="courseware_name">{{ item.courseware_name }}</span>
-                <svg-icon
-                  v-if="item.is_finished === 'true'"
-                  class="check-mark"
-                  icon-class="check-mark-circle"
-                />
+                <svg-icon v-if="item.is_finished === 'true'" class="check-mark" icon-class="check-mark-circle" />
               </div>
             </el-tag>
           </div>
@@ -81,10 +73,10 @@
           </template>
           <div class="title">
             <span>教师点评</span>
-            <el-rate v-model="teacher_score"></el-rate>
+            <el-rate v-model="teacher_score" />
           </div>
           <div>
-            <el-input v-model="teacher_remark" type="textarea" resize="none" :rows="6"></el-input>
+            <el-input v-model="teacher_remark" type="textarea" resize="none" :rows="6" />
           </div>
           <div class="confirm">
             <el-button type="primary" @click="remarkTaskStudentExecuteInfo_Teacher">提交</el-button>
@@ -117,11 +109,7 @@
 import CompletionView from '@/components/course/CompletionView.vue';
 import ShowFile from '@/common/show_file';
 import TaskTop from '../TaskTop.vue';
-import {
-  GetTaskInfo,
-  GetTaskStudentExecuteInfo,
-  RemarkTaskStudentExecuteInfo_Teacher
-} from '@/api/course';
+import { GetTaskInfo, GetTaskStudentExecuteInfo, RemarkTaskStudentExecuteInfo_Teacher } from '@/api/course';
 
 export default {
   components: { CompletionView, TaskTop, ShowFile },