2 Commits 7eb8e67db7 ... 8494d488bd

Author SHA1 Message Date
  dsy 8494d488bd Merge branch 'master' of http://60.205.254.193:3000/GCLS/eep_page 1 month ago
  dsy 0e083e7434 输入框与富文本多语言,将多言语变为公用,并优化 1 month ago

+ 6 - 0
src/icons/svg/multilingual.svg

@@ -0,0 +1,6 @@
+<svg t="1755036112589" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4003"
+  width="200" height="200">
+  <path
+    d="M710.8608 389.12c3.8912 39.3728 5.9392 80.5376 5.9392 122.88s-2.048 83.5072-5.9392 122.88h213.4016c11.5712-38.912 17.8176-80.1792 17.8176-122.88 0-42.7008-6.2464-83.968-17.8176-122.88h-213.4016z m-82.5344 0H395.6736a1147.392 1147.392 0 0 0 0 245.76h232.6528a1147.392 1147.392 0 0 0 0-245.76z m-315.1872 0H99.7376A430.1312 430.1312 0 0 0 81.92 512c0 42.7008 6.2464 83.968 17.8176 122.88h213.4016A1255.7312 1255.7312 0 0 1 307.2 512c0-42.3424 2.048-83.5072 5.9392-122.88z m320.0512 535.6544A431.2064 431.2064 0 0 0 890.2656 716.8h-190.464c-14.592 83.2-37.6832 154.8288-66.56 207.9744z m-242.3808 0c-28.928-53.1456-52.0192-124.7744-66.56-207.9744H133.7344a431.2064 431.2064 0 0 0 257.024 207.9744zM407.7056 716.8c25.4464 135.168 71.5776 225.28 104.2944 225.28s78.848-90.112 104.2432-225.28H407.7568z m225.4848-617.5744c28.928 53.1456 52.0192 124.7744 66.56 207.9744h190.5152a431.2064 431.2064 0 0 0-257.024-207.9744z m-242.3808 0A431.2064 431.2064 0 0 0 133.7344 307.2h190.464c14.592-83.2 37.6832-154.8288 66.56-207.9744zM407.7056 307.2h208.5376C590.848 172.032 544.768 81.92 512 81.92S433.152 172.032 407.7568 307.2zM512 1024C229.2224 1024 0 794.7776 0 512S229.2224 0 512 0s512 229.2224 512 512-229.2224 512-512 512z"
+    fill="currentColor" p-id="4004"></path>
+</svg>

+ 4 - 0
src/styles/mixin.scss

@@ -64,6 +64,10 @@
   .main {
   .main {
     grid-area: main;
     grid-area: main;
     width: 100%;
     width: 100%;
+
+    .lang {
+      grid-area: lang;
+    }
   }
   }
 }
 }
 
 

+ 10 - 0
src/views/book/components/MultilingualFill.vue

@@ -116,6 +116,16 @@ export default {
       },
       },
       immediate: true,
       immediate: true,
     },
     },
+    visible: {
+      handler(newVal) {
+        if (!newVal && this.selectedLangList.length > 0) {
+          this.selectedLangList = this.selectedLangList.map((item) => ({
+            code: item.code,
+            translation: '',
+          }));
+        }
+      },
+    },
   },
   },
   methods: {
   methods: {
     closeDialog() {
     closeDialog() {

+ 15 - 1
src/views/book/courseware/create/components/base/rich_text/RichText.vue

@@ -15,6 +15,14 @@
           @compareAnnotationAndSave="compareAnnotationAndSave"
           @compareAnnotationAndSave="compareAnnotationAndSave"
         />
         />
         <el-divider v-if="isEnable(data.property.view_pinyin)" content-position="left">拼音效果</el-divider>
         <el-divider v-if="isEnable(data.property.view_pinyin)" content-position="left">拼音效果</el-divider>
+
+        <el-button class="btn" @click="openMultilingual">多语言</el-button>
+        <MultilingualFill
+          :visible.sync="multilingualVisible"
+          :text="data.content"
+          :translations="data.multilingual"
+          @SubmitTranslation="handleMultilingualTranslation"
+        />
         <PinyinText
         <PinyinText
           v-if="isEnable(data.property.view_pinyin)"
           v-if="isEnable(data.property.view_pinyin)"
           :id="richId + '_pinyin_text'"
           :id="richId + '_pinyin_text'"
@@ -27,7 +35,7 @@
       <ExplanatoryNoteDialog
       <ExplanatoryNoteDialog
         ref="explanatoryNote"
         ref="explanatoryNote"
         :open.sync="isViewExplanatoryNoteDialog"
         :open.sync="isViewExplanatoryNoteDialog"
-        :initData="oldRichData"
+        :init-data="oldRichData"
         @confirm="confirmExplanatoryNote"
         @confirm="confirmExplanatoryNote"
         @cancel="cancelExplanatoryNote"
         @cancel="cancelExplanatoryNote"
       />
       />
@@ -185,3 +193,9 @@ export default {
   },
   },
 };
 };
 </script>
 </script>
+
+<style lang="scss" scoped>
+.btn {
+  margin-top: 12px;
+}
+</style>

+ 13 - 0
src/views/book/courseware/create/components/common/ModuleMixin.js

@@ -2,6 +2,7 @@
 import Vue from 'vue';
 import Vue from 'vue';
 import ModuleBase from './ModuleBase.vue';
 import ModuleBase from './ModuleBase.vue';
 import RichText from '@/components/RichText.vue';
 import RichText from '@/components/RichText.vue';
+import MultilingualFill from '@/views/book/components/MultilingualFill.vue';
 
 
 import { displayList, viewMethodList, isEnable } from '@/views/book/courseware/data/common';
 import { displayList, viewMethodList, isEnable } from '@/views/book/courseware/data/common';
 import { ContentSaveCoursewareComponentContent, ContentGetCoursewareComponentContent } from '@/api/book';
 import { ContentSaveCoursewareComponentContent, ContentGetCoursewareComponentContent } from '@/api/book';
@@ -16,6 +17,7 @@ const mixin = {
         isGetContent: false, // 是否已获取内容
         isGetContent: false, // 是否已获取内容
       },
       },
       borderColorObj: Vue.observable({ value: this.borderColor }), // 边框颜色
       borderColorObj: Vue.observable({ value: this.borderColor }), // 边框颜色
+      multilingualVisible: false, // 多语言弹窗
     };
     };
   },
   },
   props: {
   props: {
@@ -39,6 +41,7 @@ const mixin = {
   components: {
   components: {
     ModuleBase,
     ModuleBase,
     RichText,
     RichText,
+    MultilingualFill,
   },
   },
   provide() {
   provide() {
     return {
     return {
@@ -124,6 +127,16 @@ const mixin = {
       }
       }
       return null;
       return null;
     },
     },
+    openMultilingual() {
+      this.multilingualVisible = true;
+    },
+    /**
+     * @description 提交多语言翻译
+     * @param {Array} multilingual
+     */
+    handleMultilingualTranslation(multilingual) {
+      this.data.multilingual = multilingual;
+    },
   },
   },
 };
 };
 
 

+ 1 - 11
src/views/book/courseware/create/components/question/fill/Fill.vue

@@ -42,7 +42,7 @@
 
 
         <div>
         <div>
           <el-button @click="identifyText">识别</el-button>
           <el-button @click="identifyText">识别</el-button>
-          <el-button @click="multilingualVisible = true">多语言</el-button>
+          <el-button @click="openMultilingual">多语言</el-button>
         </div>
         </div>
 
 
         <div class="correct-answer">
         <div class="correct-answer">
@@ -71,7 +71,6 @@
 import ModuleMixin from '../../common/ModuleMixin';
 import ModuleMixin from '../../common/ModuleMixin';
 import SoundRecord from '@/views/book/courseware/create/components/question/fill/components/SoundRecord.vue';
 import SoundRecord from '@/views/book/courseware/create/components/question/fill/components/SoundRecord.vue';
 import UploadAudio from '@/views/book/courseware/create/components/question/fill/components/UploadAudio.vue';
 import UploadAudio from '@/views/book/courseware/create/components/question/fill/components/UploadAudio.vue';
-import MultilingualFill from '@/views/book/components/MultilingualFill.vue';
 
 
 import { getFillData, arrangeTypeList, fillFontList, fillTypeList } from '@/views/book/courseware/data/fill';
 import { getFillData, arrangeTypeList, fillFontList, fillTypeList } from '@/views/book/courseware/data/fill';
 import { addTone, handleToneValue } from '@/views/book/courseware/data/common';
 import { addTone, handleToneValue } from '@/views/book/courseware/data/common';
@@ -83,14 +82,12 @@ export default {
   components: {
   components: {
     SoundRecord,
     SoundRecord,
     UploadAudio,
     UploadAudio,
-    MultilingualFill,
   },
   },
   mixins: [ModuleMixin],
   mixins: [ModuleMixin],
   data() {
   data() {
     return {
     return {
       data: getFillData(),
       data: getFillData(),
       fillTypeList,
       fillTypeList,
-      multilingualVisible: false,
     };
     };
   },
   },
   watch: {
   watch: {
@@ -213,13 +210,6 @@ export default {
         },
         },
       ];
       ];
     },
     },
-    /**
-     * @description 提交多语言翻译
-     * @param {Array} multilingual
-     */
-    handleMultilingualTranslation(multilingual) {
-      this.data.multilingual = multilingual;
-    },
   },
   },
 };
 };
 </script>
 </script>

+ 14 - 1
src/views/book/courseware/create/components/question/input/Input.vue

@@ -8,6 +8,14 @@
         :font-size="18"
         :font-size="18"
         placeholder="请输入内容"
         placeholder="请输入内容"
       />
       />
+
+      <el-button class="btn" @click="openMultilingual">多语言</el-button>
+      <MultilingualFill
+        :visible.sync="multilingualVisible"
+        :text="data.content"
+        :translations="data.multilingual"
+        @SubmitTranslation="handleMultilingualTranslation"
+      />
     </template>
     </template>
   </ModuleBase>
   </ModuleBase>
 </template>
 </template>
@@ -42,10 +50,15 @@ export default {
         },
         },
       ];
       ];
     },
     },
+    handleMultilingualTranslation(translations) {
+      this.data.multilingual = translations;
+    },
   },
   },
 };
 };
 </script>
 </script>
 
 
 <style lang="scss" scoped>
 <style lang="scss" scoped>
-@use '@/styles/mixin.scss' as *;
+.btn {
+  margin-top: 12px;
+}
 </style>
 </style>

+ 21 - 1
src/views/book/courseware/create/components/question/select/Select.vue

@@ -10,6 +10,9 @@
             </span>
             </span>
             <RichText v-model="item.content" placeholder="输入内容" :inline="true" :height="32" />
             <RichText v-model="item.content" placeholder="输入内容" :inline="true" :height="32" />
           </div>
           </div>
+          <span class="multilingual" @click="openMultilingual(i)">
+            <SvgIcon icon-class="multilingual" class-name="multilingual" width="12" height="12" />
+          </span>
           <span class="delete" @click="deleteOption">
           <span class="delete" @click="deleteOption">
             <SvgIcon icon-class="delete-2" width="12" height="12" />
             <SvgIcon icon-class="delete-2" width="12" height="12" />
           </span>
           </span>
@@ -19,6 +22,14 @@
         <SvgIcon icon-class="add-circle" width="14" height="14" />
         <SvgIcon icon-class="add-circle" width="14" height="14" />
         <span class="add-button" @click="addOption">增加选项</span>
         <span class="add-button" @click="addOption">增加选项</span>
       </div>
       </div>
+
+      <MultilingualFill
+        v-if="curSelectIndex !== -1"
+        :visible.sync="multilingualVisible"
+        :text="data.option_list[curSelectIndex].content"
+        :translations="data.option_list[curSelectIndex].multilingual"
+        @SubmitTranslation="handleMultilingualTranslation"
+      />
     </template>
     </template>
   </ModuleBase>
   </ModuleBase>
 </template>
 </template>
@@ -34,6 +45,7 @@ export default {
   data() {
   data() {
     return {
     return {
       data: getSelectData(),
       data: getSelectData(),
+      curSelectIndex: -1,
     };
     };
   },
   },
   watch: {
   watch: {
@@ -82,6 +94,13 @@ export default {
       const select = this.data.answer.answer_list.length > 1 ? '多选' : '单选';
       const select = this.data.answer.answer_list.length > 1 ? '多选' : '单选';
       this.data.mind_map.node_list = [{ name: `${direction}${select}选择题` }];
       this.data.mind_map.node_list = [{ name: `${direction}${select}选择题` }];
     },
     },
+    openMultilingual(i) {
+      this.curSelectIndex = i;
+      this.multilingualVisible = true;
+    },
+    handleMultilingualTranslation(translations) {
+      this.$set(this.data.option_list[this.curSelectIndex], 'multilingual', translations);
+    },
   },
   },
 };
 };
 </script>
 </script>
@@ -142,7 +161,8 @@ export default {
       }
       }
     }
     }
 
 
-    .delete {
+    .delete,
+    .multilingual {
       margin-left: 8px;
       margin-left: 8px;
       cursor: pointer;
       cursor: pointer;
     }
     }

+ 1 - 0
src/views/book/courseware/data/input.js

@@ -111,5 +111,6 @@ export function getInputData() {
         },
         },
       ],
       ],
     },
     },
+    multilingual: [], // 多语言
   };
   };
 }
 }

+ 1 - 0
src/views/book/courseware/data/richText.js

@@ -476,5 +476,6 @@ export function getRichTextData() {
     mind_map: {
     mind_map: {
       node_list: [{ name: '富文本' }],
       node_list: [{ name: '富文本' }],
     },
     },
+    multilingual: [], // 多语言
   };
   };
 }
 }

+ 1 - 0
src/views/book/courseware/data/select.js

@@ -25,6 +25,7 @@ export function getOption() {
   return {
   return {
     content: '',
     content: '',
     mark: getRandomNumber(),
     mark: getRandomNumber(),
+    multilingual: [], // 多语言
   };
   };
 }
 }
 
 

+ 34 - 28
src/views/book/courseware/preview/components/dialogue_article/RemarkChs.vue

@@ -1,46 +1,52 @@
 <!--  -->
 <!--  -->
 <template>
 <template>
   <div
   <div
+    v-if="
+      remarkDetail &&
+      (remarkDetail.chs || remarkDetail.en || (remarkDetail.img_list && remarkDetail.img_list.length > 0))
+    "
     class="remarkChs"
     class="remarkChs"
-    v-if="remarkDetail && (remarkDetail.chs || remarkDetail.en || (remarkDetail.img_list && remarkDetail.img_list.length>0))"
-    :style="{top:marginTop?marginTop+'px':'0px'}"
+    :style="{ top: marginTop ? marginTop + 'px' : '0px' }"
   >
   >
-    <div class="remark-chs" v-if="remarkDetail.chs">{{ remarkDetail.chs }}</div>
-    <div class="remark-en" v-if="remarkDetail.en">{{ remarkDetail.en }}</div>
-    <div v-if="remarkDetail.img_list && remarkDetail.img_list.length>0" class="remark-img">
-        <el-image
-            :style="{width: remarkDetail.widthNumber ? remarkDetail.widthNumber+'px':'', height: remarkDetail.heightNumber ? remarkDetail.heightNumber+'px':''}"
-            :src="remarkDetail.img_list[0].id"
-            fit="contain"
-            :preview-src-list="[remarkDetail.img_list[0].id]"
-        ></el-image>
+    <div v-if="remarkDetail.chs" class="remark-chs">{{ remarkDetail.chs }}</div>
+    <div v-if="remarkDetail.en" class="remark-en">{{ remarkDetail.en }}</div>
+    <div v-if="remarkDetail.img_list && remarkDetail.img_list.length > 0" class="remark-img">
+      <el-image
+        :style="{
+          width: remarkDetail.widthNumber ? remarkDetail.widthNumber + 'px' : '',
+          height: remarkDetail.heightNumber ? remarkDetail.heightNumber + 'px' : '',
+        }"
+        :src="remarkDetail.img_list[0].id"
+        fit="contain"
+        :preview-src-list="[remarkDetail.img_list[0].id]"
+      />
     </div>
     </div>
   </div>
   </div>
 </template>
 </template>
 
 
 <script>
 <script>
 export default {
 export default {
-  name: "RemarkChs",
+  name: 'RemarkChs',
   components: {},
   components: {},
-  props: ["remarkDetail","marginTop"],
+  props: ['remarkDetail', 'marginTop'],
   data() {
   data() {
     return {};
     return {};
   },
   },
   computed: {},
   computed: {},
   watch: {},
   watch: {},
-  //方法集合
-  methods: {},
-  //生命周期 - 创建完成(可以访问当前this实例)
+  // 生命周期 - 创建完成(可以访问当前this实例)
   created() {},
   created() {},
-  //生命周期 - 挂载完成(可以访问DOM元素)
+  // 生命周期 - 挂载完成(可以访问DOM元素)
   mounted() {},
   mounted() {},
-  beforeCreate() {}, //生命周期 - 创建之前
-  beforeMount() {}, //生命周期 - 挂载之前
-  beforeUpdate() {}, //生命周期 - 更新之前
-  updated() {}, //生命周期 - 更新之后
-  beforeDestroy() {}, //生命周期 - 销毁之前
-  destroyed() {}, //生命周期 - 销毁完成
-  activated() {} //如果页面有keep-alive缓存功能,这个函数会触发
+  beforeCreate() {}, // 生命周期 - 创建之前
+  beforeMount() {}, // 生命周期 - 挂载之前
+  beforeUpdate() {}, // 生命周期 - 更新之前
+  updated() {}, // 生命周期 - 更新之后
+  beforeDestroy() {}, // 生命周期 - 销毁之前
+  destroyed() {}, // 生命周期 - 销毁完成
+  activated() {},
+  // 方法集合
+  methods: {}, // 如果页面有keep-alive缓存功能,这个函数会触发
 };
 };
 </script>
 </script>
 <style lang="scss" scoped>
 <style lang="scss" scoped>
@@ -86,13 +92,13 @@ export default {
     border-radius: 0 0 8px 8px;
     border-radius: 0 0 8px 8px;
   }
   }
 
 
-  > .remark-img{
+  > .remark-img {
     width: 100%;
     width: 100%;
     text-align: center;
     text-align: center;
 
 
-    .el-image{
-        max-width: 178px;
+    .el-image {
+      max-width: 178px;
     }
     }
   }
   }
 }
 }
-</style>
+</style>

+ 18 - 19
src/views/book/courseware/preview/components/dialogue_article/RoleChs.vue

@@ -1,7 +1,6 @@
-<!--  -->
 <template>
 <template>
-  <div class="role-rItem" v-if="curRole">
-    <span v-if="curRole.color" class="adult-book-input-roleText" :style="{ background: this.curRole.color }">{{
+  <div v-if="curRole" class="role-rItem">
+    <span v-if="curRole.color" class="adult-book-input-roleText" :style="{ background: curRole.color }">{{
       curRole.name
       curRole.name
     }}</span>
     }}</span>
     <img
     <img
@@ -10,9 +9,9 @@
       class="adult-book-input-roleImg"
       class="adult-book-input-roleImg"
     />
     />
     <div
     <div
+      v-else-if="curRole.simpleHead !== ''"
       class="adult-book-input-roleImg"
       class="adult-book-input-roleImg"
       :class="['adult-book-input-roleImg' + curRole.simpleHead]"
       :class="['adult-book-input-roleImg' + curRole.simpleHead]"
-      v-else-if="curRole.simpleHead !== ''"
     ></div>
     ></div>
     <template v-if="type != 1 && curRole.detail.wordsList.length > 0">
     <template v-if="type != 1 && curRole.detail.wordsList.length > 0">
       <span class="pinyin" :style="{ color: wordColor }">{{ curRole.detail.wordsList | handlePinyin }}</span>
       <span class="pinyin" :style="{ color: wordColor }">{{ curRole.detail.wordsList | handlePinyin }}</span>
@@ -24,13 +23,12 @@
 <script>
 <script>
 export default {
 export default {
   components: {},
   components: {},
-  props: ['curRole', 'color', 'type'],
   filters: {
   filters: {
     handlePinyin(wordsList) {
     handlePinyin(wordsList) {
       let str = '';
       let str = '';
       wordsList.forEach((item, index) => {
       wordsList.forEach((item, index) => {
         if (index < wordsList.length - 1) {
         if (index < wordsList.length - 1) {
-          str += item.pinyin + ' ';
+          str += `${item.pinyin} `;
         } else {
         } else {
           str += item.pinyin;
           str += item.pinyin;
         }
         }
@@ -41,7 +39,7 @@ export default {
       let str = '';
       let str = '';
       wordsList.forEach((item, index) => {
       wordsList.forEach((item, index) => {
         if (index < wordsList.length - 1) {
         if (index < wordsList.length - 1) {
-          str += item.chs + ' ';
+          str += `${item.chs} `;
         } else {
         } else {
           str += item.chs;
           str += item.chs;
         }
         }
@@ -49,11 +47,12 @@ export default {
       return str;
       return str;
     },
     },
   },
   },
+  props: ['curRole', 'color', 'type'],
   data() {
   data() {
     return {};
     return {};
   },
   },
   computed: {
   computed: {
-    wordColor: function () {
+    wordColor() {
       let color = 'rgba(0,0,0,0.85)';
       let color = 'rgba(0,0,0,0.85)';
       if (this.color) {
       if (this.color) {
         color = this.color;
         color = this.color;
@@ -62,19 +61,19 @@ export default {
     },
     },
   },
   },
   watch: {},
   watch: {},
-  //方法集合
-  methods: {},
-  //生命周期 - 创建完成(可以访问当前this实例)
+  // 生命周期 - 创建完成(可以访问当前this实例)
   created() {},
   created() {},
-  //生命周期 - 挂载完成(可以访问DOM元素)
+  // 生命周期 - 挂载完成(可以访问DOM元素)
   mounted() {},
   mounted() {},
-  beforeCreate() {}, //生命周期 - 创建之前
-  beforeMount() {}, //生命周期 - 挂载之前
-  beforeUpdate() {}, //生命周期 - 更新之前
-  updated() {}, //生命周期 - 更新之后
-  beforeDestroy() {}, //生命周期 - 销毁之前
-  destroyed() {}, //生命周期 - 销毁完成
-  activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
+  beforeCreate() {}, // 生命周期 - 创建之前
+  beforeMount() {}, // 生命周期 - 挂载之前
+  beforeUpdate() {}, // 生命周期 - 更新之前
+  updated() {}, // 生命周期 - 更新之后
+  beforeDestroy() {}, // 生命周期 - 销毁之前
+  destroyed() {}, // 生命周期 - 销毁完成
+  activated() {},
+  // 方法集合
+  methods: {}, // 如果页面有keep-alive缓存功能,这个函数会触发
 };
 };
 </script>
 </script>
 <style lang="scss" scoped>
 <style lang="scss" scoped>

+ 0 - 4
src/views/book/courseware/preview/components/fill/FillPreview.vue

@@ -314,10 +314,6 @@ export default {
   .main {
   .main {
     display: grid;
     display: grid;
     align-items: center;
     align-items: center;
-
-    .lang {
-      grid-area: lang;
-    }
   }
   }
 
 
   .fill-wrapper {
   .fill-wrapper {

+ 22 - 5
src/views/book/courseware/preview/components/input/InputPreview.vue

@@ -3,7 +3,7 @@
   <div class="input-preview" :style="getAreaStyle()">
   <div class="input-preview" :style="getAreaStyle()">
     <SerialNumberPosition v-if="isEnable(data.property.sn_display_mode)" :property="data.property" />
     <SerialNumberPosition v-if="isEnable(data.property.sn_display_mode)" :property="data.property" />
 
 
-    <div class="main">
+    <div class="main" :style="getMainStyle()">
       <span class="rich-text" v-html="sanitizeHTML(data.content)"></span>
       <span class="rich-text" v-html="sanitizeHTML(data.content)"></span>
       <el-input
       <el-input
         ref="input"
         ref="input"
@@ -21,6 +21,9 @@
         ]"
         ]"
         @change="onInputChange"
         @change="onInputChange"
       />
       />
+      <div v-show="showLang" class="lang">
+        {{ data.multilingual.find((item) => item.code === getLang())?.translation }}
+      </div>
     </div>
     </div>
   </div>
   </div>
 </template>
 </template>
@@ -75,6 +78,11 @@ export default {
       }
       }
       this.data.answer.text = answer;
       this.data.answer.text = answer;
     },
     },
+    getMainStyle() {
+      return {
+        gridTemplateAreas: this.showLang ? "'rich input' 'lang lang'" : "'rich input'",
+      };
+    },
   },
   },
 };
 };
 </script>
 </script>
@@ -86,12 +94,21 @@ export default {
   @include preview-base;
   @include preview-base;
 
 
   .main {
   .main {
-    display: flex;
-    column-gap: 4px;
+    display: grid;
+    grid-template-columns: auto 1fr;
+    gap: 4px;
     align-items: center;
     align-items: center;
 
 
-    .rich-text :deep p {
-      word-break: keep-all;
+    .rich-text {
+      grid-area: rich;
+
+      :deep p {
+        word-break: keep-all;
+      }
+    }
+
+    .input {
+      grid-area: input;
     }
     }
 
 
     .input.input-horizontal :deep .el-input__inner {
     .input.input-horizontal :deep .el-input__inner {

+ 7 - 2
src/views/book/courseware/preview/components/rich_text/RichTextPreview.vue

@@ -12,19 +12,23 @@
         />
         />
         <span v-else class="rich-text" @click="handleRichFillClick" v-html="sanitizeHTML(data.content)"></span>
         <span v-else class="rich-text" @click="handleRichFillClick" v-html="sanitizeHTML(data.content)"></span>
       </div>
       </div>
+
+      <div v-show="showLang" class="lang">
+        {{ data.multilingual.find((item) => item.code === getLang())?.translation }}
+      </div>
     </div>
     </div>
 
 
     <el-dialog
     <el-dialog
+      ref="optimizedDialog"
       title=""
       title=""
       :visible.sync="noteDialogVisible"
       :visible.sync="noteDialogVisible"
       width="680px"
       width="680px"
-      ref="optimizedDialog"
       :style="dialogStyle"
       :style="dialogStyle"
       :close-on-click-modal="false"
       :close-on-click-modal="false"
       destroy-on-close
       destroy-on-close
       @close="noteDialogVisible = false"
       @close="noteDialogVisible = false"
     >
     >
-      <span v-html="selectedNote"></span>
+      <span v-html="sanitizeHTML(selectedNote)"></span>
     </el-dialog>
     </el-dialog>
   </div>
   </div>
 </template>
 </template>
@@ -151,6 +155,7 @@ export default {
     position: fixed;
     position: fixed;
     margin: 0 !important;
     margin: 0 !important;
     transition: all 0.2s; /* 添加平滑过渡效果 */
     transition: all 0.2s; /* 添加平滑过渡效果 */
+
     .el-dialog__header {
     .el-dialog__header {
       padding: 0 !important;
       padding: 0 !important;
 
 

+ 0 - 3
src/views/personal_workbench/edit_task/edit/index.vue

@@ -41,8 +41,6 @@
 </template>
 </template>
 
 
 <script>
 <script>
-import Vue from 'vue';
-
 import CreatePage from '@/views/book/courseware/create/index.vue';
 import CreatePage from '@/views/book/courseware/create/index.vue';
 import MenuPage from '@/views/personal_workbench/common/menu.vue';
 import MenuPage from '@/views/personal_workbench/common/menu.vue';
 import * as OpenCC from 'opencc-js';
 import * as OpenCC from 'opencc-js';
@@ -56,7 +54,6 @@ export default {
     CreatePage,
     CreatePage,
     MenuPage,
     MenuPage,
   },
   },
-  // 将 lang、chinese 提供给子组件,并让这几个属性可响应式
   provide() {
   provide() {
     return {
     return {
       getLang: () => this.lang,
       getLang: () => this.lang,