Browse Source

Merge branch 'master' of http://gcls-git.helxsoft.cn/GCLS/eep_page

zq 1 day ago
parent
commit
1442621a51

+ 9 - 1
main.js

@@ -1,4 +1,4 @@
-const { app, BrowserWindow } = require('electron');
+const { app, BrowserWindow, shell } = require('electron');
 const path = require('path');
 const url = require('url');
 
@@ -32,6 +32,14 @@ const createWindow = () => {
     win.maximize();
     win.show();
   });
+
+  // 拦截当前窗口的导航,防止外部链接在应用内打开
+  win.webContents.on('will-navigate', (event, url) => {
+    if (url.startsWith('http://') || url.startsWith('https://')) {
+      event.preventDefault();
+      shell.openExternal(url);
+    }
+  });
 };
 
 // 当 Electron 完成初始化并准备创建浏览器窗口时调用此方法

+ 15 - 6
src/views/book/courseware/create/components/CreateCanvas.vue

@@ -504,19 +504,20 @@ export default {
       // 高度为 auto 时
       if (grid.height === 'auto') {
         const gridHeight = document.querySelector(`.${id}`).offsetHeight;
-        const height = gridHeight + offsetY;
+        let height = gridHeight + offsetY;
+        // 当高度小于最小高度时,设置为最小高度
         if (height < min_height) {
-          return;
+          height = min_height;
         }
-        grid.height = `${gridHeight + offsetY}px`;
+        grid.height = `${height}px`;
         col.grid_template_rows = `0 ${col.grid_list.map(({ height }) => height).join(' 6px ')} 0`;
         return;
       }
       // 高度为数字时
       const height = Number(grid.height.replace('px', ''));
-      const _h = height + offsetY;
+      let _h = height + offsetY;
       if (_h < min_height) {
-        return;
+        _h = min_height;
       }
       if (_h >= 50) {
         grid.height = `${_h}px`;
@@ -1175,6 +1176,12 @@ export default {
       left: 6px;
     }
 
+    .drag-vertical-line.grid-line-right,
+    .drag-vertical-line.grid-line-left {
+      top: 25%;
+      height: 50%;
+    }
+
     .drag-vertical-line.col-start {
       left: -12px;
     }
@@ -1210,6 +1217,8 @@ export default {
     opacity: 0;
 
     &.drag-row {
+      width: 50%;
+      margin-left: 25%;
       background-color: $right-color;
     }
 
@@ -1228,7 +1237,7 @@ export default {
     z-index: 2;
     width: 4px;
     height: 100%;
-    background-color: #379fff;
+    background-color: #f43;
     border-radius: 4px;
     opacity: 0;
 

+ 1 - 1
src/views/book/courseware/create/components/base/common/UploadFile.vue

@@ -46,7 +46,7 @@
             v-if="file.progress > 0 && file.progress < 100"
             type="circle"
             :percentage="file.progress"
-            width="20"
+            :width="20"
             color="#2A5AF6"
             stroke-linecap="butt"
             :show-text="false"

+ 2 - 0
src/views/book/courseware/data/fill.js

@@ -32,6 +32,8 @@ export const audioGenerationMethodList = [
 
 // 填空方式
 export const fillTypeList = [
+  { value: 'input', label: '输入' },
+  { value: 'select', label: '选词' },
   { value: 'handwriting', label: '手写' },
   { value: 'voice', label: '语音' },
 ];

+ 0 - 1
src/views/book/courseware/preview/components/article/components/Strockplay.vue

@@ -78,7 +78,6 @@ export default {
 };
 </script>
 <style lang="scss" scoped>
-//@import url(); 引入公共css类
 .strockplayInner {
   position: relative;
   width: 100%; //444px

+ 41 - 8
src/views/book/courseware/preview/components/fill/FillPreview.vue

@@ -10,13 +10,38 @@
           <template v-for="(li, j) in item">
             <span v-if="li.type === 'text'" :key="j" v-html="sanitizeHTML(li.content)"></span>
             <template v-if="li.type === 'input'">
-              <el-input
-                :key="j"
-                v-model="li.content"
-                :disabled="disabled"
-                :class="[data.property.fill_font, ...computedAnswerClass(li.mark)]"
-                :style="[{ width: Math.max(80, li.content.length * 21.3) + 'px' }]"
-              />
+              <template v-if="data.property.fill_type === fillTypeList[0].value">
+                <el-input
+                  :key="j"
+                  v-model="li.content"
+                  :disabled="disabled"
+                  :class="[data.property.fill_font, ...computedAnswerClass(li.mark)]"
+                  :style="[{ width: Math.max(80, li.content.length * 21.3) + 'px' }]"
+                />
+              </template>
+
+              <template v-else-if="data.property.fill_type === fillTypeList[1].value">
+                <el-popover
+                  :key="j"
+                  placement="top"
+                  trigger="click"
+                  content="这是一段内容,这是一段内容,这是一段内容,这是一段内容。"
+                >
+                  <el-input
+                    v-model="li.content"
+                    :disabled="true"
+                    :class="[data.property.fill_font, ...computedAnswerClass(li.mark)]"
+                    class="pinyin"
+                    :style="[{ width: Math.max(80, li.content.length * 21.3) + 'px' }]"
+                  />
+                </el-popover>
+              </template>
+
+              <template v-else-if="data.property.fill_type === fillTypeList[2].value"></template>
+
+              <template v-else-if="data.property.fill_type === fillTypeList[3].value">
+                <SoundRecord :key="j" :wav-blob.sync="li.audio_file_id" />
+              </template>
               <span v-show="computedAnswerText(li.mark).length > 0" :key="`answer-${j}`" class="right-answer">
                 {{ computedAnswerText(li.mark) }}
               </span>
@@ -38,7 +63,13 @@
 </template>
 
 <script>
-import { getFillData, fillFontList, arrangeTypeList, audioPositionList } from '@/views/book/courseware/data/fill';
+import {
+  getFillData,
+  fillFontList,
+  fillTypeList,
+  arrangeTypeList,
+  audioPositionList,
+} from '@/views/book/courseware/data/fill';
 
 import PreviewMixin from '../common/PreviewMixin';
 import AudioFill from './components/AudioFillPlay.vue';
@@ -54,6 +85,7 @@ export default {
   data() {
     return {
       data: getFillData(),
+      fillTypeList,
     };
   },
   computed: {
@@ -71,6 +103,7 @@ export default {
                 if (type === 'input') {
                   return {
                     value: content,
+                    audio_file_id: '',
                     mark,
                   };
                 }

+ 9 - 9
src/views/book/courseware/preview/components/new_word/NewWordPreview.vue

@@ -33,11 +33,11 @@
                 />
               </div>
               <ul
+                v-if="isEnable(data.property.auto_wrap)"
                 class="NPC-word-table"
                 cellspacing="0"
                 border="0"
                 cellpadding="0"
-                v-if="isEnable(data.property.auto_wrap)"
               >
                 <li
                   v-for="(item, index) in data.option_list"
@@ -87,8 +87,8 @@
                         <span
                           v-if="data.property.pinyin_position == 'top'"
                           class="NPC-word-tab-common NPC-word-tab-pinyin"
-                          v-html="sItem.pinyin"
                           :style="{ width: data.col_width[0].value + 'px' }"
+                          v-html="sItem.pinyin"
                         >
                         </span>
                         <span
@@ -100,29 +100,29 @@
                         <span
                           v-if="data.property.pinyin_position == 'bottom'"
                           class="NPC-word-tab-common NPC-word-tab-pinyin"
-                          v-html="sItem.pinyin"
                           :style="{ width: data.col_width[0].value + 'px' }"
+                          v-html="sItem.pinyin"
                         >
                         </span>
                       </div>
                       <span
                         class="NPC-word-tab-common NPC-word-tab-cixing"
                         :class="[/[\u4E00-\u9FA5\uF900-\uFA2D]/.test(sItem.cixing) ? 'hasCn' : '']"
-                        v-html="sItem.cixing"
                         :style="{ width: data.col_width[2].value + 'px' }"
+                        v-html="sItem.cixing"
                       ></span>
                       <span
                         class="NPC-word-tab-common NPC-word-tab-def"
-                        v-html="sItem.def_str"
                         :style="{ width: data.col_width[3].value + 'px' }"
+                        v-html="sItem.def_str"
                       ></span>
                     </template>
                     <template v-else>
                       <span
                         v-if="!data.property.pinyin_position || data.property.pinyin_position == 'front'"
                         class="NPC-word-tab-common NPC-word-tab-pinyin"
-                        v-html="sItem.pinyin"
                         :style="{ width: data.col_width[1].value + 'px' }"
+                        v-html="sItem.pinyin"
                       >
                       </span>
                       <span
@@ -134,20 +134,20 @@
                       <span
                         v-if="data.property.pinyin_position == 'back'"
                         class="NPC-word-tab-common NPC-word-tab-pinyin"
-                        v-html="sItem.pinyin"
                         :style="{ width: data.col_width[1].value + 'px' }"
+                        v-html="sItem.pinyin"
                       >
                       </span>
                       <span
                         class="NPC-word-tab-common NPC-word-tab-cixing"
                         :class="[/[\u4E00-\u9FA5\uF900-\uFA2D]/.test(sItem.cixing) ? 'hasCn' : '']"
-                        v-html="sItem.cixing"
                         :style="{ width: data.col_width[2].value + 'px' }"
+                        v-html="sItem.cixing"
                       ></span>
                       <span
                         class="NPC-word-tab-common NPC-word-tab-def"
-                        v-html="sItem.def_str"
                         :style="{ width: data.col_width[3].value + 'px' }"
+                        v-html="sItem.def_str"
                       ></span>
                     </template>
                     <div class="right-box">

+ 12 - 29
src/views/book/courseware/preview/components/new_word/components/Strockplay.vue

@@ -1,4 +1,3 @@
-<!--  -->
 <template>
   <div class="strockplayInner" :class="className">
     <div v-if="playStorkes" class="strock-play-box" :style="{ width: palyWidth, height: palyWidth }" @click="playHanzi">
@@ -43,9 +42,8 @@ export default {
     targetDiv: {
       handler(val, oldVal) {
         if (val !== oldVal) {
-          let _this = this;
-          _this.$nextTick(() => {
-            _this.initHanziwrite();
+          this.$nextTick(() => {
+            this.initHanziwrite();
           });
         }
       },
@@ -55,9 +53,8 @@ export default {
     strokeColor: {
       handler(val, oldVal) {
         if (val !== oldVal) {
-          let _this = this;
-          _this.$nextTick(() => {
-            _this.initHanziwrite();
+          this.$nextTick(() => {
+            this.initHanziwrite();
           });
         }
       },
@@ -65,44 +62,31 @@ export default {
       deep: true,
     },
   },
-  // 生命周期 - 创建完成(可以访问当前this实例)
-  created() {},
-  // 生命周期 - 挂载完成(可以访问DOM元素)
   mounted() {
-    let _this = this;
-    _this.$nextTick(() => {
-      _this.initHanziwrite();
+    this.$nextTick(() => {
+      this.initHanziwrite();
     });
   },
-  beforeCreate() {}, // 生命周期 - 创建之前
-  beforeMount() {}, // 生命周期 - 挂载之前
-  beforeUpdate() {}, // 生命周期 - 更新之前
-  updated() {}, // 生命周期 - 更新之后
-  beforeDestroy() {}, // 生命周期 - 销毁之前
-  destroyed() {}, // 生命周期 - 销毁完成
-  activated() {},
   // 方法集合
   methods: {
     initHanziwrite() {
-      let _this = this;
-      let node = document.getElementById(`${_this.targetDiv}`);
+      let node = document.getElementById(`${this.targetDiv}`);
       if (node.children.length > 1) {
         node.removeChild(node.children[1]);
       }
       // var ren = require("hanzi-writer-data/国");
-      _this.writer = HanziWriter.default.create(_this.targetDiv, _this.Book_text, {
+      this.writer = HanziWriter.default.create(this.targetDiv, this.Book_text, {
         charDataLoader(char, onComplete) {
-          let charData = _this.handleData();
+          let charData = this.handleData();
           onComplete(charData);
         },
         padding: 5,
         showOutline: true,
-        strokeColor: _this.strokeColor ? _this.strokeColor : '#333',
+        strokeColor: this.strokeColor ? this.strokeColor : '#333',
       });
     },
     playHanzi() {
-      let _this = this;
-      _this.writer.animateCharacter();
+      this.writer.animateCharacter();
     },
     handleData() {
       if (this.curItem) {
@@ -110,11 +94,10 @@ export default {
         return charData;
       }
     },
-  }, // 如果页面有keep-alive缓存功能,这个函数会触发
+  },
 };
 </script>
 <style lang="scss" scoped>
-//@import url(); 引入公共css类
 .strockplayInner {
   position: relative;
   width: 100%; //444px