소스 검색

对话答题模版修改

gcj 3 년 전
부모
커밋
c4c551d7ff

BIN
src/assets/newImage/common/error-btn.png


BIN
src/assets/newImage/common/right-btn.png


+ 5 - 17
src/components/Adult/common/SegwordConfig.vue

@@ -62,6 +62,10 @@
             </el-radio-group>
           </div>
           <div class="adult-book-input-item">
+            <span class="adult-book-lable">设置下划线:</span>
+            <el-checkbox v-model="scope.row.underLine">显示下划线</el-checkbox>
+          </div>
+          <div class="adult-book-input-item">
             <span class="adult-book-lable">设置间距:</span>
             <el-checkbox-group v-model="scope.row.wordPadding">
               <el-checkbox
@@ -94,23 +98,7 @@ export default {
         },
         {
           value: "sub",
-          name: "辅助色",
-        },
-        {
-          value: "#FF8730",
-          name: "橙色",
-        },
-        {
-          value: "#3CB4E7",
-          name: "蓝色",
-        },
-        {
-          value: "#ED5050",
-          name: "浅红色",
-        },
-        {
-          value: "#FF3F3F",
-          name: "红色",
+          name: "主题色",
         },
       ],
       paddingList: [

+ 56 - 22
src/components/Adult/inputModules/DialogueAnswerChs/Wordcard.vue

@@ -1,13 +1,24 @@
 <!--  -->
 <template>
   <div class="Big-Book-Single" v-if="curQue">
+    <div class="adult-book-input-item">
+      <span class="adult-book-lable">拼音位置:</span>
+      <el-radio-group v-model="curQue.pyPosition">
+        <el-radio :label="'top'">字的上面</el-radio>
+        <el-radio :label="'bottom'">字的下面</el-radio>
+        <el-radio :label="'right'">字的右边</el-radio>
+      </el-radio-group>
+    </div>
     <div class="Big-Book-Single-content" style="margin-top: 20px">
       <div
         class="Big-Book-main"
-        v-for="(item, index) in curQue"
+        v-for="(item, index) in curQue.wordcardList"
         :key="'newWord' + index"
         style="border-bottom: 1px #ccc solid; margin-bottom: 20px"
       >
+        <span class="adult-book-lable" style="margin-bottom: 14px"
+          >第{{ index + 1 }}行</span
+        >
         <div
           class="Big-Book-main-inner"
           v-for="(sItem, sIndex) in item"
@@ -16,7 +27,7 @@
           <div class="adult-book-input-item">
             <span class="adult-book-lable">汉字:</span>           
             <el-input
-              style="width: 300px"
+              style="width: 300px; margin-right: 10px"
               placeholder="请输入汉字"
               v-model="sItem.chs"
               @blur="onBlur(sItem, 'chs')"
@@ -24,11 +35,14 @@
               maxlength="200"
               show-word-limit
             ></el-input>
+            <el-button size="mini" type="danger" @click="delword(item, sIndex)">
+              删除汉字
+            </el-button>
           </div>
           <div class="adult-book-input-item">
             <span class="adult-book-lable">拼音:</span>           
             <el-input
-              style="width: 300px"
+              style="width: 300px; margin-right: 10px"
               placeholder="请输入拼音"
               v-model="sItem.pinyin"
               @blur="onBlur(sItem, 'pinyin')"
@@ -36,6 +50,9 @@
               maxlength="200"
               show-word-limit
             ></el-input>
+            <el-button type="primary" size="small" @click="getPinyin(sItem)"
+              >生成拼音</el-button
+            >
           </div>
         </div>
         <div class="addoption addoption2" @click="saddoption(item)">
@@ -52,6 +69,8 @@
 
 <script>
 import NewordPhraseModule from "../../common/NewordPhraseModule.vue";
+import "@/utils/pinyin_dict_withtone";
+import "@/utils/pinyinUtil";
 export default {
   name: "Wordcard",
   props: ["curQue"],
@@ -69,32 +88,43 @@ export default {
       item[field] = item[field] ? item[field].trim() : "";
     },
     addoption() {
-      let leg = this.curQue.option.length;
-      let last = this.curQue.option[leg - 1];
-      let res_data = JSON.parse(JSON.stringify(this.data_structure));
-      let obj = res_data.option[0];
-      obj.index = this.curQue.option.push(obj);
-    },
-    deleteGroup(index, sIndex) {
-      if (this.curQue.option[0].length == 1) {
-        this.$message.warning("至少剩余1个,不能全部删除");
-        return;
-      }
-      this.curQue.option[index].splice(sIndex, 1);
+      let obj = [
+        {
+          chs: "",
+          pinyin: "",
+        },
+      ];
+      let res_data = JSON.parse(JSON.stringify(obj));
+      this.curQue.wordcardList.push(res_data);
     },
     saddoption(item) {
       let con = {
-        new_word: "",
-        cixing: "", //词性
-        definition_list: [""], //需要增加词性
+        chs: "",
         pinyin: "",
-        img_list: [],
-        mp3_list: [],
       };
-      item.push(con);
+      item.push(JSON.parse(JSON.stringify(con)));
     },
     delsItem(index) {
-      this.curQue.option.splice(index, 1);
+      this.curQue.wordcardList.splice(index, 1);
+    },
+    delword(sItem, sIndex) {
+      sItem.splice(sIndex, 1);
+    },
+    // 点击生成拼音
+    getPinyin(item) {
+      let bool = false;
+      let value = "";
+      if (item.chs == "") {
+        this.$message.info("请先输入汉字,再生成拼音");
+        bool = true;
+      } else {
+        value = item.chs;
+      }
+      if (bool) {
+        return;
+      }
+      let result = pinyinUtil.getPinyin(value);
+      item.pinyin = result.replace(/\s+/g, "");
     },
   },
   //生命周期 - 创建完成(可以访问当前this实例)
@@ -113,6 +143,9 @@ export default {
 <style lang='scss' scope>
 //@import url(); 引入公共css类
 .Big-Book-Single {
+  .adult-book-input-item {
+    margin-bottom: 10px;
+  }
   &-content {
     &.m {
       display: flex;
@@ -140,6 +173,7 @@ export default {
         }
       }
       .Big-Book-main-inner {
+        border-bottom: 1px rgb(46, 45, 45) dashed;
       }
     }
   }

+ 24 - 57
src/components/Adult/inputModules/DialogueAnswerChs/index.vue

@@ -28,6 +28,13 @@
       ></el-input>
     </div>
     <div class="NPC-Book-model">
+      <div class="adult-book-input-item">
+        <span class="adult-book-lable">分词模式:</span>
+        <el-radio-group v-model="curQue.segModel">
+          <el-radio :label="'word'">按字分割</el-radio>
+          <el-radio :label="'words'">按词分割</el-radio>
+        </el-radio-group>
+      </div>
       <span class="adult-book-input-lable">拼音位置:</span>
       <el-radio-group v-model="curQue.pyPosition">
         <el-radio :label="'top'">字上面</el-radio>
@@ -61,7 +68,7 @@
     </div>
 
     <el-dialog
-      title="添加对话"
+      title="添加对话22"
       :close-on-click-modal="false"
       :modal-append-to-body="false"
       append-to-body
@@ -85,6 +92,7 @@
       :visible.sync="optionVisible"
       width="80%"
       top="10px"
+      :modal="true"
     >
       <DialogueTem
         :curQue="curQue.option[listIndex]"
@@ -116,13 +124,10 @@
       :modal-append-to-body="false"
       append-to-body
       :visible.sync="wordCardVisible"
-      width="80%"
+      width="40%"
       top="10px"
     >
-      <Wordcard
-        :curQue="curQue.wordcard[listIndex]"
-        :listIndex="'option' + listIndex"
-      />
+      <Wordcard :curQue="curQue.wordcard[listIndex]" />
       <span slot="footer" class="dialog-footer">
         <el-button @click="wordCardVisible = false">取 消</el-button>
         <el-button type="primary" @click="wordCardVisible = false"
@@ -156,7 +161,7 @@ export default {
         name: "对话题",
         model: 1,
         pyPosition: "top", //top 拼音在上面;bottom 拼音在下面
-
+        segModel: "words",
         list: [
           {
             number: "",
@@ -169,22 +174,9 @@ export default {
             wordTime: [],
             taskId: "",
             answer: "",
-            judge: "",
+            judge: [],
             font: "cn",
-            fn_list: [
-              {
-                type: "dialogue_answer_input_chs",
-                name: "填空题",
-                isFn: false,
-                isDisable: false,
-              },
-              {
-                type: "dialogue_answer_judge_chs",
-                name: "判断题",
-                isFn: false,
-                isDisable: false,
-              },
-            ],
+            checkList: ["input"],
           },
         ],
         option: [
@@ -201,14 +193,17 @@ export default {
           },
         ],
         wordcard: [
-          [
-            [
-              {
-                chs: "",
-                pinyin: "",
-              },
+          {
+            pyPosition: "top", //top 拼音在上面;bottom 拼音在下面
+            wordcardList: [
+              [
+                {
+                  chs: "",
+                  pinyin: "",
+                },
+              ],
             ],
-          ],
+          },
         ],
       },
     };
@@ -260,35 +255,7 @@ export default {
   created() {},
   //生命周期 - 挂载完成(可以访问DOM元素)
   mounted() {
-    console.log("文章保存");
-    console.log(this.curQue);
     if (this.curQue) {
-      this.curQue.list.map((item) => {
-        if (!item.fn_list) {
-          item.fn_list = [
-            {
-              type: "dialogue_answer_input_chs",
-              name: "填空题",
-              isFn: false,
-              isDisable: false,
-            },
-            {
-              type: "dialogue_answer_judge_chs",
-              name: "判断题",
-              isFn: false,
-              isDisable: false,
-            },
-          ];
-        }
-        item.detail.map((dItem) => {
-          if (!dItem.judge) {
-            dItem.judge = "";
-          }
-          return dItem;
-        });
-        return item;
-      });
-
       if (this.curQue.detail && this.curQue.detail.length > 0) {
         if (this.curQue.detail[0].para) {
           this.isPara = true;

+ 4 - 2
src/components/Adult/inputModules/DialogueTem/components/ArticleChs.vue

@@ -9,8 +9,6 @@
       placeholder="请输入文章"
       v-model="curQue.article"
       @blur="onBlur(curQue, 'article')"
-      maxlength="5000"
-      show-word-limit
     ></el-input>
     <div style="margin-top: 10px">
       <el-button type="primary" size="small" @click="createPara"
@@ -48,6 +46,7 @@ export default {
       item[field] = item[field] ? item[field].trim() : "";
     },
     createPara() {
+      console.log(this.curQue);
       let paraArr = this.curQue.article.split(/\n+/g);
 
       this.$set(this.curQue, "detail", []);
@@ -57,6 +56,9 @@ export default {
         detailItem.para = con;
         detailItem.paraIndex = i;
         this.curQue.detail.push(detailItem);
+        this.curQue.judge.push(
+          JSON.parse(JSON.stringify({ isJudge: false, judge: "" }))
+        );
         // if (this.curQue.detail.length == 0) {
         //   detailItem.para = con;
         //   detailItem.paraIndex = i;

+ 0 - 2
src/components/Adult/inputModules/DialogueTem/components/ClauseresultChs.vue

@@ -19,8 +19,6 @@
           :readonly="item.isReadonly"
           @change="handleChange(item.para, index)"
           @blur="onBlur(item, 'para')"
-          maxlength="200"
-          show-word-limit
         ></el-input>
         <el-button
           v-if="item.isReadonly"

+ 0 - 2
src/components/Adult/inputModules/DialogueTem/components/CreatetimelistChs.vue

@@ -13,8 +13,6 @@
         placeholder="请输入内容"
         v-model="item.time_str"
         @blur="onBlur(item, 'time_str')"
-        maxlength="500"
-        show-word-limit
       ></el-input>
     </div>
   </div>

+ 16 - 11
src/components/Adult/inputModules/DialogueTem/components/ParagraphChs.vue

@@ -18,6 +18,7 @@
           v-model="item.roleIndex"
           placeholder="请选择角色"
           style="width:120px;margin-right:10px;font-size;12px;"
+          v-if="roleList.length > 0"
         >
           <el-option
             v-for="(rItem, rIndex) in roleList"
@@ -35,8 +36,6 @@
           v-model="item.para"
           @blur="onBlur(item, 'para')"
           :readonly="readonly"
-          maxlength="500"
-          show-word-limit
         ></el-input>
         <div>
           <el-button
@@ -45,11 +44,18 @@
             @click="addRemark(item, index)"
             >{{ item.remark ? "修改备注" : "添加备注" }}</el-button
           >
-          <template>
-            <el-radio-group v-model="item.judge">
-              <el-radio label="true">正确</el-radio>
-              <el-radio label="false">错误</el-radio>
-            </el-radio-group>
+          <template
+            v-if="curQue.checkList && curQue.checkList.indexOf('judge') > -1"
+          >
+            <template v-if="curQue.judge[index].isJudge">
+              <el-radio-group v-model="curQue.judge[index].judge">
+                <el-radio label="right">正确</el-radio>
+                <el-radio label="error">错误</el-radio>
+              </el-radio-group>
+            </template>
+            <el-checkbox v-model="curQue.judge[index].isJudge"
+              >显示判断按钮</el-checkbox
+            >
           </template>
           <img
             @click="deleteOption(index)"
@@ -75,8 +81,6 @@
             placeholder="请输入中文"
             v-model="remark.chs"
             @blur="onBlur(remark, 'chs')"
-            maxlength="200"
-            show-word-limit
           ></el-input>
         </div>
         <div class="adult-book-input-item">
@@ -88,8 +92,6 @@
             placeholder="请输入英文"
             v-model="remark.en"
             @blur="onBlur(remark, 'en')"
-            maxlength="200"
-            show-word-limit
           ></el-input>
         </div>
       </div>
@@ -151,6 +153,9 @@ export default {
       _this.sureSeg();
     },
     initRoleList() {
+      if (!this.curQue.roleList) {
+        return;
+      }
       let roleList = JSON.parse(JSON.stringify(this.curQue.roleList));
       roleList = roleList.map((item) => {
         if (item.detail.fullName) {

+ 0 - 2
src/components/Adult/inputModules/DialogueTem/components/Pinyin.vue

@@ -12,8 +12,6 @@
                 v-model="scope.row.pinyin"
                 placeholder="请输入拼音"
                 @blur="onBlur(scope.row, 'pinyin')"
-                maxlength="200"
-                show-word-limit
               ></el-input>
             </template>
           </el-table-column>

+ 0 - 6
src/components/Adult/inputModules/DialogueTem/components/RoleChs.vue

@@ -10,8 +10,6 @@
         v-model="curRole.role"
         @change="changeRole"
         @blur="onBlur(curRole, 'role')"
-        maxlength="200"
-        show-word-limit
       ></el-input>
       <span style="margin-right: 10px">或</span>
       <Upload
@@ -29,8 +27,6 @@
         placeholder="请输入内容"
         v-model="curRole.detail.fullName"
         @blur="onBlur(curRole.detail, 'fullName')"
-        maxlength="200"
-        show-word-limit
       ></el-input>
       <el-button type="danger" @click="segWord(curRole.detail.fullName)"
         >分词</el-button
@@ -44,8 +40,6 @@
         v-model="curRole.detail.seg_words"
         @change="handleChange"
         @blur="onBlur(curRole.detail, 'seg_words')"
-        maxlength="200"
-        show-word-limit
       ></el-input>
       <el-button type="danger" @click="_createPinyin">生成拼音</el-button>
     </div>

+ 59 - 30
src/components/Adult/inputModules/DialogueTem/components/SegbywordChs.vue

@@ -25,8 +25,6 @@
           v-model="wordItem.sent_str"
           :readonly="!wordItem.isReadonly"
           @change="handleChange"
-          maxlength="1000"
-          show-word-limit
         ></el-input>
         <el-button
           type="danger"
@@ -40,7 +38,7 @@
     <el-dialog
       title="校对分词"
       :visible.sync="proofVisible"
-      width="60%"
+      width="90%"
       :close-on-click-modal="false"
       :modal-append-to-body="false"
       append-to-body
@@ -75,8 +73,6 @@
             :autosize="{ minRows: 1 }"
             placeholder="请输入翻译"
             v-model="paraCon.sentencesEn[sentIndex]"
-            maxlength="200"
-            show-word-limit
           ></el-input>
         </div>
         <div class="NPC-words-box">
@@ -88,12 +84,13 @@
             v-model="paraCon.seg_words[sentIndex].sent_str"
             @click="handleChangeWords"
             @blur="onBlurIndex(sentIndex, 'seg_words')"
-            maxlength="200"
-            show-word-limit
           ></el-input>
           <div class="NPC-gPinyin">
+            <el-button type="danger" size="small" @click="_sureSegWord"
+              >确定分词结果</el-button
+            >
             <el-button type="danger" size="small" @click="_createPinyin"
-              >确定生成拼音</el-button
+              >确定分词结果并生成拼音</el-button
             >
           </div>
         </div>
@@ -101,26 +98,7 @@
           <div class="NPC-words-box">
             <span class="Big-Book-left-text">校对拼音:</span>
             <div class="NPC-words-list">
-              <el-table
-                :data="paraCon.wordsList[sentIndex]"
-                border
-                style="width: 400px"
-              >
-                <el-table-column prop="chs" label="词" width="180">
-                </el-table-column>
-                <el-table-column label="拼音" width="220">
-                  <template slot-scope="scope">
-                    <el-input
-                      v-model="scope.row.pinyin"
-                      placeholder="请输入拼音"
-                      @blur="onBlur(scope.row, 'pinyin')"
-                      maxlength="200"
-                      show-word-limit
-                    ></el-input>
-                  </template>
-                </el-table-column>
-              </el-table>
-              <div></div>
+              <SegwordConfig :data="paraCon.wordsList[sentIndex]" />
             </div>
             <div class="yunmu">
               <span>点击可复制</span>
@@ -154,9 +132,10 @@
 <script>
 import { createPinyin } from "@/api/ajax";
 import { Base64 } from "js-base64";
+import SegwordConfig from "../../../common/SegwordConfig.vue";
 export default {
   name: "SegbywordChs",
-  components: {},
+  components: { SegwordConfig },
   props: ["curQue", "paraIndex", "createPinyin", "segList"],
   data() {
     return {
@@ -249,6 +228,48 @@ export default {
       var RegExp = /^[a-zA-Z]+$/;
       return RegExp.test(str);
     },
+    //确定分词结果
+    _sureSegWord() {
+      let sentIndex = this.sentIndex;
+      let sent_arr = this.paraCon.seg_words[sentIndex].sent_str.split(/\s+/);
+      let res_str = "";
+      sent_arr.forEach((item) => {
+        if (item) {
+          let bool = this.checkEn(item);
+          if (bool) {
+            res_str += item.trim() + " ";
+          } else if (item == "(") {
+            res_str += " " + item.trim() + " ";
+          } else if (item == ")") {
+            res_str += " " + item.trim() + " ";
+          } else {
+            res_str += item.trim();
+          }
+        }
+      });
+      res_str = res_str.replace(/\s+/g, " ");
+      let org_sent = this.paraCon.sentences[sentIndex];
+      if (res_str.trim() != org_sent.trim()) {
+        this.$message.warning("跟原句不一致,请检查是否误删除或新增其他内容");
+        return;
+      }
+      let arr = this.paraCon.seg_words[sentIndex].sent_str.split(/\s+/);
+      this.$set(this.paraCon.segList, sentIndex, arr);
+      let wordsList = [];
+      arr.forEach((sItem) => {
+        let obj = {
+          chs: sItem,
+          pinyin: "",
+          fontSize: "24px",
+          fontColor: "#000",
+          fontFamily: "FZJCGFKTK",
+          wordPadding: [],
+          underLine: false,
+        };
+        wordsList.push(obj);
+      });
+      this.$set(this.paraCon.wordsList, sentIndex, wordsList);
+    },
     //生成拼音
     _createPinyin() {
       let sentIndex = this.sentIndex;
@@ -287,6 +308,14 @@ export default {
       };
       createPinyin(data).then((res) => {
         let wordsList = res.data.result[0];
+        wordsList = wordsList.map((item, index) => {
+          item.fontSize = "24px";
+          item.fontColor = "#000";
+          item.fontFamily = "FZJCGFKTK";
+          item.wordPadding = [];
+          item.underLine = false;
+          return item;
+        });
         this.$set(this.paraCon.wordsList, sentIndex, wordsList);
       });
     },
@@ -400,7 +429,7 @@ export default {
 }
 .yunmu {
   position: absolute;
-  left: 460px;
+  right: 0px;
   top: 80px;
   &-table {
     width: 260px;

+ 121 - 51
src/components/Adult/inputModules/DialogueTem/index.vue

@@ -9,11 +9,9 @@
       <span class="adult-book-lable">序号:</span>
       <el-input
         class="adult-book-input"
-        placeholder="请输入文章提示"
+        placeholder="请输入序号"
         v-model="curQue.number"
         @blur="onBlur(curQue, 'number')"
-        maxlength="200"
-        show-word-limit
       ></el-input>
     </div>
     <div class="Big-Book-mp3">
@@ -43,12 +41,16 @@
     </div>
     <div class="adult-book-input-item">
       <span class="adult-book-lable">功能设置:</span>
-      <el-checkbox-group v-model="checkList" @change="handleCheckedFnChange">
+      <el-checkbox-group
+        v-model="curQue.checkList"
+        @change="handleCheckedFnChange"
+      >
         <el-checkbox
-          v-for="(fnItem, fnIndex) in curQue.fn_list"
+          v-for="(fnItem, fnIndex) in fn_list"
           :key="'dis_fn_list' + fnIndex"
-          :label="fnItem.name"
-        ></el-checkbox>
+          :label="fnItem.type"
+          >{{ fnItem.name }}</el-checkbox
+        >
       </el-checkbox-group>
     </div>
     <div class="adult-book-input-item">
@@ -60,12 +62,13 @@
         placeholder="请输入文章提示"
         v-model="curQue.notice"
         @blur="onBlur(curQue, 'notice')"
-        maxlength="200"
-        show-word-limit
       ></el-input>
     </div>
-    <div class="NPC-Book-role">
-      <ul class="adult-book-input-role" v-if="curQue.roleList.length > 0">
+    <div class="NPC-Book-role" v-if="curQue.roleList">
+      <ul
+        class="adult-book-input-role"
+        v-if="curQue.roleList && curQue.roleList.length > 0"
+      >
         <li
           v-for="(rItem, rIndex) in curQue.roleList"
           :key="'roleList' + rIndex"
@@ -101,6 +104,7 @@
     <div class="NPC-Book-Paragraph" v-if="isPara">
       <Paragraph :curQue="curQue" :isClause="isClause" :sureSeg="sureSeg" />
     </div>
+
     <!---上传rlc文件-->
     <!-- <div class="NPC-Book-Paragraph" v-if="isClause">
       <el-button
@@ -143,7 +147,10 @@
     </template>
     <!---答案-->
 
-    <div class="adult-book-input-item">
+    <div
+      class="adult-book-input-item"
+      v-if="curQue.checkList.indexOf('input') > -1"
+    >
       <span class="adult-book-lable">答案:</span>
       <el-input
         class="adult-book-input"
@@ -152,8 +159,6 @@
         placeholder="请输入答案"
         v-model="curQue.answer"
         @blur="onBlur(curQue, 'answer')"
-        maxlength="200"
-        show-word-limit
       ></el-input>
     </div>
 
@@ -172,14 +177,16 @@
       append-to-body
       width="60%"
     >
-      <template v-if="roleStatus == 1">
-        <RoleChs
-          ref="createRolelist"
-          :curRole="curQue.roleList[curQue.roleList.length - 1]"
-        />
-      </template>
-      <template v-else>
-        <RoleChs ref="createRolelist" :curRole="curRole" />
+      <template v-if="curQue.roleList">
+        <template v-if="roleStatus == 1">
+          <RoleChs
+            ref="createRolelist"
+            :curRole="curQue.roleList[curQue.roleList.length - 1]"
+          />
+        </template>
+        <template v-else>
+          <RoleChs ref="createRolelist" :curRole="curRole" />
+        </template>
       </template>
       <span slot="footer" class="dialog-footer">
         <el-button @click="roleVisible = false">取 消</el-button>
@@ -219,7 +226,7 @@ export default {
     Createtimelist,
     RoleChs,
   },
-  props: ["curQue", "changeCurQue", "listIndex"],
+  props: ["curQue", "changeCurQue", "listIndex", "segModel"],
   filters: {
     handlePinyin(wordsList) {
       let str = "";
@@ -246,7 +253,26 @@ export default {
   },
   data() {
     return {
-      checkList: [],
+      fn_list: [
+        {
+          type: "input",
+          name: "填空题",
+          isFn: false,
+          isDisable: false,
+        },
+        {
+          type: "judge",
+          name: "判断题",
+          isFn: false,
+          isDisable: false,
+        },
+        {
+          type: "record",
+          name: "录音题",
+          isFn: false,
+          isDisable: false,
+        },
+      ],
       imgNumber: 1,
       mp3Number: 1,
       fileCon: {
@@ -297,21 +323,12 @@ export default {
     },
     // 更多配置选择
     handleCheckedFnChange(value) {
-      let fn_list = JSON.parse(JSON.stringify(this.curQue.fn_list));
-
-      this.curQue.fn_list = fn_list.map((item) => {
-        if (value.indexOf(item.name) > -1) {
-          item.isFn = true;
-        } else {
-          item.isFn = false;
-          if (item.type == "dialogue_answer_input_chs") {
-            this.curQue.answer = "";
-          } else if (item.type == "dialogue_answer_judge_chs") {
-            this.curQue.judge = "";
-          }
-        }
-        return item;
-      });
+      if (this.curQue.checkList.indexOf("input") < 0) {
+        this.curQue.answer = "";
+      }
+      if (this.curQue.checkList.indexOf("judge") < 0) {
+        this.curQue.judge = [];
+      }
     },
     changeMp3(fileList) {
       const articleImgList = JSON.parse(JSON.stringify(fileList));
@@ -440,23 +457,67 @@ export default {
     },
     //生成分词
     segByWord(sentences, paraIndex) {
-      this.loading = true;
-      let textList = [];
-      sentences.forEach((item) => {
-        let str = Base64.encode(item);
-        textList.push(str);
-      });
-      let data = {
-        textList: textList,
-      };
-      BatchSegContent(data).then((res) => {
-        this.loading = false;
-        let list = res.data.result.list;
+      if (!this.segModel || this.segModel == "words") {
+        this.loading = true;
+        let textList = [];
+        sentences.forEach((item) => {
+          let str = Base64.encode(item);
+          textList.push(str);
+        });
+        let data = {
+          textList: textList,
+        };
+        BatchSegContent(data).then((res) => {
+          this.loading = false;
+          let list = res.data.result.list;
+          this.$set(this.curQue.detail[paraIndex], "segList", list);
+          this.segList = list;
+          this.isByWord = true;
+          this.paraIndex = paraIndex;
+          this.setWordsList(list, paraIndex);
+        });
+      } else {
+        let list = [];
+        let reg = /_{2,}/g;
+        sentences.forEach((item) => {
+          if (reg.test(item)) {
+            item = item.replace(reg, "^");
+          }
+          let arr = item.split("");
+          arr = arr.map((aItem) => {
+            aItem = aItem == "^" ? "_______" : aItem;
+            return aItem;
+          });
+          list.push(arr);
+        });
+        console.log(list);
+        this.setWordsList(list, paraIndex);
         this.$set(this.curQue.detail[paraIndex], "segList", list);
+        console.log(this.curQue);
         this.segList = list;
         this.isByWord = true;
         this.paraIndex = paraIndex;
+      }
+    },
+    setWordsList(list, paraIndex) {
+      let wordsList = [];
+      list.forEach((item, index) => {
+        let sentArr = [];
+        item.map((sItem) => {
+          let obj = {
+            chs: sItem,
+            pinyin: "",
+            fontSize: "16px",
+            fontColor: "#000",
+            fontFamily: "FZJCGFKTK",
+            wordPadding: [],
+            underLine: false,
+          };
+          sentArr.push(obj);
+        });
+        wordsList.push(sentArr);
       });
+      this.$set(this.curQue.detail[paraIndex], "wordsList", wordsList);
     },
     // 上传音频文件
     handleChange(file, fileList) {
@@ -595,6 +656,15 @@ p {
   margin: 0;
   padding: 0;
 }
+.adult-book-input-item {
+  display: flex;
+  justify-content: flex-start;
+  align-items: center;
+  > span {
+    margin-right: 10px;
+    width: 70px;
+  }
+}
 .adult-book-input-role {
   clear: both;
   overflow: hidden;

+ 43 - 1
src/components/Adult/inputModules/SentenceModule.vue

@@ -470,6 +470,9 @@
               </div>
             </div>
           </div>
+          <el-button @click="addWordcard(items.wordcard)"
+            >添加词汇卡片</el-button
+          >
         </div>
         <div class="addoption" @click="addWOption(col)">添加一题</div>
       </div>
@@ -516,6 +519,25 @@
         <el-button type="primary" @click="saveOptionDetail">确 定</el-button>
       </span>
     </el-dialog>
+    <el-dialog
+      title="添加词汇卡片"
+      :close-on-click-modal="false"
+      :modal-append-to-body="false"
+      append-to-body
+      :visible.sync="wordCardVisible"
+      width="40%"
+      top="10px"
+    >
+      <template v-if="curWordcard">
+        <Wordcard :curQue="curWordcard" />
+      </template>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="wordCardVisible = false">取 消</el-button>
+        <el-button type="primary" @click="wordCardVisible = false"
+          >确 定</el-button
+        >
+      </span>
+    </el-dialog>
   </div>
 </template>
 
@@ -526,6 +548,7 @@ import FnConfig from "../common/FnConfig";
 import selectOption from "../common/selectOption";
 import SentenceSegwordChs from "../common/SentenceSegwordChs";
 import SentenceSegTemp from "../common/SentenceSegTemp";
+import Wordcard from "../inputModules/DialogueAnswerChs/Wordcard.vue";
 
 export default {
   components: {
@@ -535,6 +558,7 @@ export default {
     selectOption,
     SentenceSegwordChs,
     SentenceSegTemp,
+    Wordcard,
   },
   props: ["curQue", "changeCurQue", "tmIndex"],
   filters: {
@@ -571,6 +595,8 @@ export default {
           },
         ],
       },
+      wordCardVisible: false,
+      curWordcard: null,
       optionItemDetail: null,
       addStemVisible: false,
       datailIndex: 0,
@@ -665,7 +691,7 @@ export default {
         numberStyle: "number",
         pyPosition: "top", //top 拼音在上面;bottom 拼音在下面
         pyColor: "black",
-        segModel: "word",
+        segModel: "words", //word 按字分割;words 按词分割
         sortType: "col", //col横;row:纵
         bgColor: "grey", //背景颜色
         option: [
@@ -706,6 +732,18 @@ export default {
                 radio_check: "",
                 record_check: "",
               },
+              wordcard: {
+                //词汇卡片配置
+                pyPosition: "top",
+                wordcardList: [
+                  [
+                    {
+                      chs: "",
+                      pinyin: "",
+                    },
+                  ],
+                ],
+              },
             },
           ],
         ],
@@ -1070,6 +1108,10 @@ export default {
       });
       this.curQue.img_list = JSON.parse(JSON.stringify(articleImgRes));
     },
+    addWordcard(wordcard) {
+      this.wordCardVisible = true;
+      this.curWordcard = wordcard;
+    },
     initCurQueData() {
       let res_data = JSON.parse(JSON.stringify(this.data_structure));
       this.changeCurQue(res_data);

+ 7 - 7
src/components/Adult/inputModules/SentenceSegwordChs/index.vue

@@ -22,7 +22,7 @@
           v-for="(artItem, artIndex) in curQue.img_list"
           :key="'articleImgList' + artIndex"
         >
-          <img :src="artItem.url" style="width: 26px">
+          <img :src="artItem.url" style="width: 26px" />
           <span class="art_name">{{ artItem.name }}</span>
           <p>
             图片放到第<el-input
@@ -37,7 +37,7 @@
             src="@/assets/adult/del-close.png"
             class="del-close"
             @click="delImage(artIndex)"
-          >
+          />
         </li>
       </ul>
     </div>
@@ -128,7 +128,7 @@ export default {
       this.fileCon.img_list = JSON.parse(JSON.stringify(this.curQue.img_list));
       this.fileCon.mp3_list = JSON.parse(JSON.stringify(this.curQue.mp3_list));
     } else {
-      this.initCurQueData();
+      //this.initCurQueData();
     }
   },
   beforeCreate() {}, // 生命周期 - 创建之前
@@ -143,7 +143,7 @@ export default {
     changeMp3(fileList) {
       const articleImgList = JSON.parse(JSON.stringify(fileList));
       const articleImgRes = [];
-      articleImgList.forEach(item => {
+      articleImgList.forEach((item) => {
         if (item.response) {
           const obj = {
             name: item.name,
@@ -158,13 +158,13 @@ export default {
     },
     beforeUploadMp3(file) {
       if (file.size > 20 * 1024 * 1024) {
-        this.$message.warning('上传音频大小不能超过20M');
+        this.$message.warning("上传音频大小不能超过20M");
         return false; // 必须返回false
       }
     },
     beforeUpload(file) {
       if (file.size > 2 * 1024 * 1024) {
-        this.$message.warning('上传图片大小不能超过2M');
+        this.$message.warning("上传图片大小不能超过2M");
         return false; // 必须返回false
       }
     },
@@ -203,7 +203,7 @@ export default {
       let data = {
         textList,
       };
-      BatchSegContent(data).then(res => {
+      BatchSegContent(data).then((res) => {
         this.loading = false;
         let list = res.data.result.list[0];
         this.$set(this.curQue, "segList", list);

+ 87 - 37
src/components/Adult/preview/DialogueArticleViewChs/AnswerModel.vue

@@ -70,7 +70,7 @@
                       >
                         <span class="NNPE-words-box">
                           <span
-                            v-if="pyPosition == 'top'"
+                            v-if="item.isHasPY > 0 && pyPosition == 'top'"
                             class="NNPE-pinyin"
                             :class="[
                               pItem.className ? pItem.className : '',
@@ -91,6 +91,9 @@
                                 curTime <= item.timeList[pItem.sentIndex].ed
                                   ? 'wordActive'
                                   : '',
+                                pItem.config.underLine
+                                  ? 'NNPE-chs-underline'
+                                  : '',
                               ]"
                               >{{ pItem.chs }}</span
                             >
@@ -103,7 +106,7 @@
                             />
                           </template>
                           <span
-                            v-if="pyPosition == 'bottom'"
+                            v-if="item.isHasPY > 0 && pyPosition == 'bottom'"
                             class="NNPE-pinyin"
                             :class="[
                               pItem.className ? pItem.className : '',
@@ -117,7 +120,7 @@
                           v-if="item.wordsList[pIndex + 1]"
                         >
                           <span
-                            v-if="pyPosition == 'top'"
+                            v-if="item.isHasPY > 0 && pyPosition == 'top'"
                             class="NNPE-pinyin"
                             :class="[
                               noFont.indexOf(
@@ -149,7 +152,7 @@
                           >
 
                           <span
-                            v-if="pyPosition == 'bottom'"
+                            v-if="item.isHasPY > 0 && pyPosition == 'bottom'"
                             class="NNPE-pinyin"
                             :class="[
                               noFont.indexOf(
@@ -174,7 +177,11 @@
                           "
                         >
                           <span
-                            v-if="curQue.pyPosition == 'top' && config.isShowPY"
+                            v-if="
+                              item.isHasPY > 0 &&
+                              curQue.pyPosition == 'top' &&
+                              config.isShowPY
+                            "
                             :class="[
                               'NNPE-pinyin',
                               noFont.indexOf(
@@ -214,7 +221,9 @@
                           >
                           <span
                             v-if="
-                              curQue.pyPosition == 'bottom' && config.isShowPY
+                              item.isHasPY > 0 &&
+                              curQue.pyPosition == 'bottom' &&
+                              config.isShowPY
                             "
                             :class="[
                               'NNPE-pinyin',
@@ -233,7 +242,7 @@
                       <!--下一个元素不是标点-->
                       <template v-else>
                         <span
-                          v-if="pyPosition == 'top'"
+                          v-if="item.isHasPY > 0 && pyPosition == 'top'"
                           class="NNPE-pinyin"
                           :class="[
                             pItem.chs != '“' && pItem.padding ? 'padding' : '',
@@ -258,6 +267,9 @@
                               pItem.chs != '“' && pItem.padding
                                 ? 'padding'
                                 : '',
+                              pItem.config.underLine
+                                ? 'NNPE-chs-underline'
+                                : '',
                             ]"
                             >{{ pItem.chs }}</span
                           >
@@ -270,7 +282,7 @@
                           />
                         </template>
                         <span
-                          v-if="pyPosition == 'bottom'"
+                          v-if="item.isHasPY > 0 && pyPosition == 'bottom'"
                           class="NNPE-pinyin"
                           :class="[
                             pItem.chs != '“' && pItem.padding ? 'padding' : '',
@@ -309,23 +321,33 @@
                 </div>
                 <template
                   class="input-record"
-                  v-if="curQue.fn_list && curQue.fn_list[1].isFn"
+                  v-if="
+                    curQue.checkList && curQue.checkList.indexOf('judge') > -1
+                  "
                 >
-                  <div class="judge-box">
+                  <div class="judge-box" v-if="curQue.judge[index].isJudge">
                     <a
                       :class="[
                         'right-btn',
-                        Bookanswer[index] == 'right' ? 'active' : '',
+                        Bookanswer.judge[index] == 'right' ? 'active' : '',
                       ]"
                       @click="handleSelectJudge('right', index)"
-                    ></a>
+                    >
+                      <img
+                        src="../../../../assets/newImage/common/right-btn.png"
+                      />
+                    </a>
                     <a
                       :class="[
                         'error-btn',
-                        Bookanswer[index] == 'error' ? 'active' : '',
+                        Bookanswer.judge[index] == 'error' ? 'active' : '',
                       ]"
                       @click="handleSelectJudge('error', index)"
-                    ></a>
+                    >
+                      <img
+                        src="../../../../assets/newImage/common/error-btn.png"
+                      />
+                    </a>
                   </div>
                 </template>
               </div>
@@ -408,23 +430,33 @@
                 </div>
                 <template
                   class="input-record"
-                  v-if="curQue.fn_list && curQue.fn_list[1].isFn"
+                  v-if="
+                    curQue.checkList && curQue.checkList.indexOf('judge') > -1
+                  "
                 >
-                  <div class="judge-box">
+                  <div class="judge-box" v-if="curQue.judge[index].isJudge">
                     <a
                       :class="[
                         'right-btn',
-                        Bookanswer[index] == 'right' ? 'active' : '',
+                        Bookanswer.judge[index] == 'right' ? 'active' : '',
                       ]"
                       @click="handleSelectJudge('right', index)"
-                    ></a>
+                    >
+                      <img
+                        src="../../../../assets/newImage/common/right-btn.png"
+                      />
+                    </a>
                     <a
                       :class="[
                         'error-btn',
-                        Bookanswer[index] == 'error' ? 'active' : '',
+                        Bookanswer.judge[index] == 'error' ? 'active' : '',
                       ]"
                       @click="handleSelectJudge('error', index)"
-                    ></a>
+                    >
+                      <img
+                        src="../../../../assets/newImage/common/error-btn.png"
+                      />
+                    </a>
                   </div>
                 </template>
               </div>
@@ -461,7 +493,6 @@ export default {
     "curQue",
     "pyPosition",
     "colorBox",
-    "saveBookanswer",
     "listIndex",
     "Bookanswer",
     "TaskModel",
@@ -523,7 +554,7 @@ export default {
       isHasRemark: false,
       paraArr: [],
       answer: [],
-      hengIndex:0,
+      hengIndex: 0,
     };
   },
   computed: {},
@@ -533,11 +564,8 @@ export default {
     // 判断题选择
     handleSelectJudge(obj, index) {
       let _this = this;
-      this.$set(this.Bookanswer, index, obj);
-      this.$forceUpdate();
-      if (_this.saveBookanswer) {
-        _this.saveBookanswer(this.Bookanswer, this.listIndex);
-      }
+      _this.$set(_this.Bookanswer.judge, index, obj);
+      _this.$forceUpdate();
     },
     handleWav(list, tmIndex) {
       tmIndex = tmIndex ? tmIndex : 0;
@@ -553,6 +581,7 @@ export default {
       let curQue = JSON.parse(JSON.stringify(this.curQue));
       let hengIndex = 0;
       curQue.detail.forEach((dItem, dIndex) => {
+        let isHasPY = 0;
         let isRecord = 0;
         let roleDetail = this.getRole(dItem);
         let remarkDetail = dItem.remark;
@@ -564,7 +593,9 @@ export default {
           dItem.wordsList.forEach((sItem, sIndex) => {
             sItem.forEach((wItem, wIndex) => {
               this.mergeWordSymbol(wItem);
-
+              if (wItem.pinyin) {
+                isHasPY++;
+              }
               let obj = {
                 paraIndex: dIndex, //段落索引
                 sentIndex: sIndex, //在段落中句子索引
@@ -576,6 +607,13 @@ export default {
                 className: wItem.className,
                 isShow: wItem.isShow,
                 isNewWord: this.newWords.indexOf(wItem.chs) > -1 ? true : false,
+                config: {
+                  fontColor: wItem.fontColor,
+                  fontFamily: wItem.fontFamily,
+                  fontSize: wItem.fontSize,
+                  underLine: wItem.underLine,
+                  wordPadding: wItem.wordPadding,
+                },
               };
               if (obj.isHeng) {
                 isRecord = isRecord + 1;
@@ -604,7 +642,12 @@ export default {
             timeList: timeList,
             roleDetail: roleDetail,
             remarkDetail: remarkDetail,
-            isRecord: isRecord > 0 ? true : false,
+            isRecord:
+              isRecord > 0 ||
+              (curQue.checkList && curQue.checkList.indexOf("record") > -1)
+                ? true
+                : false,
+            isHasPY: isHasPY,
           };
           resArr.push(paraObj);
         }
@@ -623,7 +666,7 @@ export default {
     handlePYData() {
       let pararArr = [];
       let curQue = JSON.parse(JSON.stringify(this.curQue));
-      this.hengIndex = 0
+      this.hengIndex = 0;
       curQue.detail.forEach((dItem, dIndex) => {
         let para = dItem.para;
         let paraObj = this.handlePara(para);
@@ -714,7 +757,7 @@ export default {
         if (item == "^") {
           obj.isHeng = true;
           obj.answer = "";
-          this.hengIndex ++;
+          this.hengIndex++;
           obj.hengIndex = this.hengIndex;
         }
         resArr.push(obj);
@@ -847,6 +890,9 @@ export default {
             &.wordActive {
               color: #de4444;
             }
+            &.NNPE-chs-underline {
+              text-decoration: underline;
+            }
           }
           &.padding {
             padding: 0 3px;
@@ -889,6 +935,9 @@ export default {
           &.wordActive {
             color: #de4444;
           }
+          &.NNPE-chs-underline {
+            text-decoration: underline;
+          }
         }
         &.padding {
           padding: 0 3px;
@@ -1018,11 +1067,15 @@ export default {
   a {
     width: 32px;
     height: 32px;
-    background: #fff url("../../../../assets/newImage/common/right-btn.png")
-      center no-repeat;
-    background-size: 24px;
     border-radius: 8px;
     border: 1px solid rgba(0, 0, 0, 0.1);
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    > img {
+      width: 24px;
+      height: 24px;
+    }
     &:hover,
     &.active {
       background-color: #e5fff0;
@@ -1030,9 +1083,6 @@ export default {
     }
   }
   a.error-btn {
-    background: #fff url("../../../../assets/newImage/common/error-btn.png")
-      center no-repeat;
-    background-size: 24px;
     margin-left: 4px;
     &:hover,
     &.active {

+ 33 - 9
src/components/Adult/preview/DialogueArticleViewChs/DialogueAnswerViewChs.vue

@@ -119,6 +119,19 @@
           >
             <OptionModel :curOption="curQue.option[index]" :index="index" />
           </template>
+          <template
+            v-if="
+              curQue.wordcard &&
+              curQue.wordcard.length > 0 &&
+              curQue.wordcard[index]
+            "
+          >
+            <WordcardModel
+              :curWordcard="curQue.wordcard[index]"
+              :index="index"
+              :pyPosition="curQue.pyPosition"
+            />
+          </template>
         </div>
       </div>
     </template>
@@ -132,6 +145,7 @@ import RemarkChs from "./RemarkChs.vue";
 import Soundrecord from "../Soundrecord.vue";
 import AnswerModel from "./AnswerModel.vue";
 import OptionModel from "./OptionModel.vue";
+import WordcardModel from "./WordcardModel.vue";
 
 export default {
   name: "DialogueAnswerViewChs",
@@ -142,6 +156,7 @@ export default {
     Soundrecord,
     AnswerModel,
     OptionModel,
+    WordcardModel,
   },
   props: ["curQue", "colorBox", "TaskModel"],
   data() {
@@ -159,9 +174,6 @@ export default {
   watch: {},
   //方法集合
   methods: {
-    saveBookanswer(answer, listIndex, hengIndex) {
-      this.curQue.Bookanswer[listIndex].input[hengIndex] = answer;
-    },
     handleChangeTab() {
       this.wordShow = !this.wordShow;
     },
@@ -171,13 +183,25 @@ export default {
       let list = JSON.parse(JSON.stringify(this.curQue.list));
       list.forEach((item, index) => {
         let arr = item.article.match(reg);
-        let userAnswer = JSON.parse(JSON.stringify(this.userAnswer));
-        arr.forEach((aItem) => {
-          userAnswer.input.push("");
-        });
         let paraLeg = item.detail.length;
-        for (let i = 0; i < paraLeg; i++) {
-          userAnswer.recordList.push(null);
+        let userAnswer = JSON.parse(JSON.stringify(this.userAnswer));
+        if (arr) {
+          arr.forEach((aItem) => {
+            userAnswer.input.push("");
+          });
+          for (let i = 0; i < paraLeg; i++) {
+            userAnswer.recordList.push(null);
+          }
+        } else if (item.checkList && item.checkList.indexOf("record") > -1) {
+          for (let i = 0; i < paraLeg; i++) {
+            userAnswer.recordList.push(null);
+          }
+        }
+
+        if (item.checkList && item.checkList.indexOf("judge") > -1) {
+          for (let i = 0; i < paraLeg; i++) {
+            userAnswer.judge.push("");
+          }
         }
         BookAnswer.push(userAnswer);
       });

+ 142 - 0
src/components/Adult/preview/DialogueArticleViewChs/WordcardModel.vue

@@ -0,0 +1,142 @@
+<!--  -->
+<template>
+  <div
+    class="wordcard"
+    v-if="
+      curWordcard &&
+      curWordcard.wordcardList &&
+      curWordcard.wordcardList.length > 0 &&
+      curWordcard.wordcardList[0] &&
+      curWordcard.wordcardList[0].length > 0 &&
+      (curWordcard.wordcardList[0][0].chs ||
+        curWordcard.wordcardList[0][0].pinyin)
+    "
+  >
+    <table cellpadding="0" cellspacing="0" class="tab">
+      <div class="empty-tr"></div>
+
+      <tr
+        class="wordcard-list"
+        v-for="(item, index) in curWordcard.wordcardList"
+        :key="'wordcard' + index"
+      >
+        <td class="empty-td"></td>
+        <td
+          :class="[
+            'wordcard-item',
+            index == curWordcard.wordcardList.length - 1
+              ? 'wordcard-item-last'
+              : '',
+          ]"
+          v-for="(wItem, wIndex) in item"
+          :key="'wordcard' + index + wIndex"
+        >
+          <div
+            :class="[curWordcard.pyPosition == 'right' ? 'pinyin-right' : '']"
+          >
+            <span class="pinyin" v-if="curWordcard.pyPosition == 'top'">{{
+              wItem.pinyin
+            }}</span>
+            <span :class="['chs']">{{ wItem.chs }}</span>
+            <span
+              class="pinyin"
+              v-if="
+                curWordcard.pyPosition == 'bottom' ||
+                curWordcard.pyPosition == 'right'
+              "
+              >{{ wItem.pinyin }}</span
+            >
+          </div>
+        </td>
+        <td class="empty-td"></td>
+      </tr>
+      <div class="empty-tr"></div>
+    </table>
+  </div>
+</template>
+
+<script>
+export default {
+  components: {},
+  props: ["curWordcard", "pyPosition"],
+  data() {
+    return {};
+  },
+  computed: {},
+  watch: {},
+  //方法集合
+  methods: {},
+  //生命周期 - 创建完成(可以访问当前this实例)
+  created() {},
+  //生命周期 - 挂载完成(可以访问DOM元素)
+  mounted() {
+    console.log(this.curWordcard);
+  },
+  beforeCreate() {}, //生命周期 - 创建之前
+  beforeMount() {}, //生命周期 - 挂载之前
+  beforeUpdate() {}, //生命周期 - 更新之前
+  updated() {}, //生命周期 - 更新之后
+  beforeDestroy() {}, //生命周期 - 销毁之前
+  destroyed() {}, //生命周期 - 销毁完成
+  activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
+};
+</script>
+<style lang='scss' scoped>
+//@import url(); 引入公共css类
+.wordcard {
+  background: #ffffff;
+  border: 1px solid rgba(0, 0, 0, 0.1);
+  box-sizing: border-box;
+  box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1);
+  border-radius: 8px;
+  .tab {
+    .empty-tr {
+      width: 100%;
+      height: 8px;
+    }
+    td {
+      padding: 8px 0 8px;
+      &.wordcard-item {
+        border-bottom: 1px solid rgba(0, 0, 0, 0.1);
+      }
+      &.wordcard-item-last {
+        border-bottom: 0;
+      }
+      &.empty-td {
+        width: 16px;
+        height: 8px;
+      }
+      > div {
+        min-width: 48px;
+        box-sizing: border-box;
+        padding: 8px;
+        > span {
+          display: block;
+          &.chs {
+            font-weight: 400;
+            font-size: 16px;
+            line-height: 150%;
+            color: #000000;
+            font-family: "FZJCGFKTK";
+          }
+          &.pinyin {
+            font-size: 12px;
+            line-height: 100%;
+            color: rgba(0, 0, 0, 0.5);
+            font-family: "GB-PINYINOK-B";
+          }
+        }
+        &.pinyin-right {
+          display: flex;
+          > .chs {
+            margin-right: 10px;
+          }
+          > .pinyin {
+            line-height: 24px;
+          }
+        }
+      }
+    }
+  }
+}
+</style>