Browse Source

字词卡片增加放大功能

natasha 3 months ago
parent
commit
d874307afb

+ 85 - 1
src/views/wordcard/cread.vue

@@ -32,6 +32,7 @@
       <template v-else>
       <template v-else>
         <h3>{{ saveName }}</h3>
         <h3>{{ saveName }}</h3>
         <div class="btn-box">
         <div class="btn-box">
+          <span class="checked-number" v-if="filtCardflag && filtTable.length > 0">已选{{ filtTable.length }}张</span>
           <!-- <el-button @click="changeRowLength">{{ showRoeText[showRowLength] }}</el-button> -->
           <!-- <el-button @click="changeRowLength">{{ showRoeText[showRowLength] }}</el-button> -->
           <el-button small @click="handleSureFilt" v-if="filtCardflag">类举</el-button>
           <el-button small @click="handleSureFilt" v-if="filtCardflag">类举</el-button>
           <el-button
           <el-button
@@ -69,6 +70,7 @@
           :filtCardflag="filtCardflag"
           :filtCardflag="filtCardflag"
           :filtId="filtId"
           :filtId="filtId"
           :filtTable="filtTable"
           :filtTable="filtTable"
+          @zoomInCard="zoomInCard"
         />
         />
       </div>
       </div>
     </div>
     </div>
@@ -83,6 +85,27 @@
       @current-change="(val) => handleCurrentChange(val, 'currentPage')"
       @current-change="(val) => handleCurrentChange(val, 'currentPage')"
       v-if="!filtCardflag"
       v-if="!filtCardflag"
     />
     />
+    <el-dialog title="" :visible.sync="showCard" width="100%" class="wordCard-dialog">
+      <i class="el-icon-arrow-left" :class="[showIndex === 0 ? 'disabled' : '']" @click="changeShowIndex('-')"></i>
+      <writeTableZoom
+        :editCardflag="false"
+        :dataConfig="writeTableData"
+        :data="filtTable[showIndex]"
+        :pageNumber="showIndex"
+        :totalNumber="0"
+        :isPreview="true"
+        :filtCardflag="false"
+        ref="writeTableZoom"
+      />
+      <p style="width: 100%; text-align: center; font-size: 20px; color: #fff">
+        {{ showIndex + 1 }} / {{ filtTable.length }}
+      </p>
+      <i
+        class="el-icon-arrow-right"
+        :class="[showIndex === filtTable.length - 1 ? 'disabled' : '']"
+        @click="changeShowIndex('+')"
+      ></i>
+    </el-dialog>
     <!-- <div class="preview_dv" v-if="isPreview" :style="{ top: userID ? '0' : '' }">
     <!-- <div class="preview_dv" v-if="isPreview" :style="{ top: userID ? '0' : '' }">
       <img class="close" src="../../assets/teacherdev/creadCad-close.png" alt="" @click="closepreviewEvent" />
       <img class="close" src="../../assets/teacherdev/creadCad-close.png" alt="" @click="closepreviewEvent" />
       <el-button type="primary" class="print-btn" small @click="download2">打印</el-button>
       <el-button type="primary" class="print-btn" small @click="download2">打印</el-button>
@@ -120,6 +143,7 @@
 import Header from '@/components/Header';
 import Header from '@/components/Header';
 import { getLogin, LearnWebSI, getHZChineseInfo, getContentFile } from '@/api/api';
 import { getLogin, LearnWebSI, getHZChineseInfo, getContentFile } from '@/api/api';
 import writeTable from './writeTableNew.vue';
 import writeTable from './writeTableNew.vue';
+import writeTableZoom from './writeTableZoom.vue';
 import { getToken } from '@/utils/auth';
 import { getToken } from '@/utils/auth';
 import html2canvas from 'html2canvas';
 import html2canvas from 'html2canvas';
 import { jsPDF } from 'jspdf';
 import { jsPDF } from 'jspdf';
@@ -134,6 +158,7 @@ export default {
   components: {
   components: {
     Header,
     Header,
     writeTable,
     writeTable,
+    writeTableZoom,
   },
   },
   props: {},
   props: {},
   data() {
   data() {
@@ -186,6 +211,8 @@ export default {
       filtTableShow: [], //分页后的筛选卡片
       filtTableShow: [], //分页后的筛选卡片
       filtId: [], // 筛选卡片id数组
       filtId: [], // 筛选卡片id数组
       currentPage: 1,
       currentPage: 1,
+      showCard: false, //卡片放大
+      showIndex: null, // 卡片放大索引
     };
     };
   },
   },
   //计算属性 类似于data概念
   //计算属性 类似于data概念
@@ -306,6 +333,7 @@ export default {
             this.loading = false;
             this.loading = false;
           });
           });
       }
       }
+      this.filtCardflag = true;
     },
     },
 
 
     // 字句详情
     // 字句详情
@@ -499,6 +527,22 @@ export default {
         this.showRowLength,
         this.showRowLength,
       );
       );
     },
     },
+    zoomInCard(index) {
+      this.showIndex = index;
+      this.showCard = true;
+    },
+    changeShowIndex(type) {
+      if (type === '+') {
+        if (this.showIndex !== this.filtTable.length - 1) {
+          this.showIndex++;
+        }
+      } else {
+        if (this.showIndex !== 0) {
+          this.showIndex--;
+        }
+      }
+      this.$refs.writeTableZoom.changeRota();
+    },
   },
   },
   //生命周期 - 创建完成(可以访问当前this实例)
   //生命周期 - 创建完成(可以访问当前this实例)
   created() {},
   created() {},
@@ -606,7 +650,7 @@ export default {
     align-items: center;
     align-items: center;
     cursor: pointer;
     cursor: pointer;
     &-preview {
     &-preview {
-      width: 184px;
+      width: 300px;
     }
     }
     .el-icon-arrow-left {
     .el-icon-arrow-left {
       font-size: 16px;
       font-size: 16px;
@@ -637,6 +681,12 @@ export default {
       margin-right: 8px;
       margin-right: 8px;
       font-size: 16px;
       font-size: 16px;
     }
     }
+    .checked-number {
+      margin-right: 8px;
+      font-size: 14px;
+      color: red;
+      line-height: 40px;
+    }
   }
   }
   .content {
   .content {
     // padding-top: 88px;
     // padding-top: 88px;
@@ -731,6 +781,40 @@ export default {
   width: 1200px;
   width: 1200px;
   margin: 0 auto;
   margin: 0 auto;
 }
 }
+:deep .el-dialog {
+  background: transparent;
+}
+:deep .el-dialog__headerbtn {
+  right: 200px;
+}
+:deep .el-dialog__headerbtn .el-dialog__close {
+  color: #f2f3f5;
+  font-size: 24px;
+}
+.wordCard-dialog {
+  :deep .el-dialog {
+    box-shadow: none;
+  }
+
+  .el-icon-arrow-left,
+  .el-icon-arrow-right {
+    color: #f2f2f2;
+    font-size: 40px;
+    position: fixed;
+    top: 50%;
+    margin-top: -20px;
+    left: 200px;
+    cursor: pointer;
+    &.disabled {
+      color: darkgrey;
+      cursor: not-allowed;
+    }
+  }
+  .el-icon-arrow-right {
+    left: auto;
+    right: 200px;
+  }
+}
 </style>
 </style>
 <style lang="scss">
 <style lang="scss">
 .cread {
 .cread {

+ 8 - 3
src/views/wordcard/writeTableNew.vue

@@ -128,7 +128,7 @@
             @change="changeCheck(data.id)"
             @change="changeCheck(data.id)"
             v-if="filtCardflag"
             v-if="filtCardflag"
           ></el-checkbox>
           ></el-checkbox>
-          <i class="el-icon-zoom-in" v-else></i>
+          <i class="el-icon-zoom-in" @click="zoomInCard(data.id)" v-else></i>
 
 
           <a class="overturn-btn" v-if="isPreview" @click="changeShowLeft"><i class="el-icon-refresh"></i></a>
           <a class="overturn-btn" v-if="isPreview" @click="changeShowLeft"><i class="el-icon-refresh"></i></a>
         </div>
         </div>
@@ -190,7 +190,7 @@
                     :palyWidth="'18px'"
                     :palyWidth="'18px'"
                     :BoxbgType="'0'"
                     :BoxbgType="'0'"
                     :curItem="itemh.hzDetail.hz_json"
                     :curItem="itemh.hzDetail.hz_json"
-                    :targetDiv="'writeTops-item-' + pageNumber + '-' + indexh + '-' + itemh.con"
+                    :targetDiv="'writeTops-item-' + pageNumber + '-' + indexh + '-' + itemh.con + '-' + totalNumber"
                     :class="[indexh !== 0 ? 'writeTop-item-noLeft' : '']"
                     :class="[indexh !== 0 ? 'writeTop-item-noLeft' : '']"
                     class="writeTop-item"
                     class="writeTop-item"
                     :style="{ borderColor: data.borderColor }"
                     :style="{ borderColor: data.borderColor }"
@@ -255,7 +255,7 @@
             @change="changeCheck(data.id)"
             @change="changeCheck(data.id)"
             v-if="filtCardflag"
             v-if="filtCardflag"
           ></el-checkbox>
           ></el-checkbox>
-          <i class="el-icon-zoom-in" v-else></i>
+          <i class="el-icon-zoom-in" v-else @click="zoomInCard(data.id)"></i>
           <a class="overturn-btn" v-if="isPreview" @click="changeShowLeft"><i class="el-icon-refresh"></i></a>
           <a class="overturn-btn" v-if="isPreview" @click="changeShowLeft"><i class="el-icon-refresh"></i></a>
         </div>
         </div>
       </template>
       </template>
@@ -468,6 +468,11 @@ export default {
         this.isCheck = true;
         this.isCheck = true;
       }
       }
     },
     },
+    // 卡片放大
+    zoomInCard(id) {
+      let index = this.filtId.indexOf(id);
+      this.$emit('zoomInCard', index);
+    },
   },
   },
   //生命周期 - 创建完成(可以访问当前this实例)
   //生命周期 - 创建完成(可以访问当前this实例)
   created() {
   created() {

+ 871 - 0
src/views/wordcard/writeTableZoom.vue

@@ -0,0 +1,871 @@
+<template>
+  <div :class="['writeTable', editCardflag ? '' : 'writeTable-preview writeTable-preview-' + totalNumber]" v-if="data">
+    <div class="writeTop" v-bind:class="{ flipped: isFlipped }">
+      <div
+        class="left left-preview"
+        :class="[data.left.fileList.length === 0 ? 'left-big' : '']"
+        v-if="(isPreview && showLeft) || !isPreview"
+        :style="{
+          borderColor: data.borderColor,
+          padding:
+            data.left.con && (data.headerCon || data.label)
+              ? ''
+              : !data.left.con && (data.headerCon || data.label)
+              ? '40px 12px 0 12px'
+              : '12px',
+        }"
+      >
+        <div class="header-info-preview">
+          <h5 :style="{ textAlign: data.fontAlign }">{{ data.headerCon }}</h5>
+          <label :style="{ background: data.borderColor }">{{ data.label }}</label>
+        </div>
+        <div class="item-image" v-if="data.left.fileList.length > 0">
+          <el-image
+            :style="{
+              width: '568px',
+              height:
+                data.left.con && !data.right.hideHanzi && (data.headerCon || data.label)
+                  ? '340px'
+                  : (!data.left.con || (data.right.hideHanzi && data.left.con)) && (data.headerCon || data.label)
+                  ? '382px'
+                  : '410px',
+            }"
+            :src="data.left.fileList[0].fileUrl"
+            :preview-src-list="[data.left.fileList[0].fileUrl]"
+            fit="contain"
+          />
+        </div>
+        <h2
+          :class="['con-preview', data.left.fileList.length === 0 ? 'con-preview-big' : '']"
+          v-if="data.left.con && !data.right.hideHanzi"
+        >
+          {{ data.left.con }}
+        </h2>
+
+        <a class="overturn-btn" v-if="isPreview" @click="changeShowLeft"><i class="el-icon-refresh"></i></a>
+      </div>
+      <div
+        class="right right-preview left-preview"
+        :class="[isPreview ? 'right-preview-rota' : '']"
+        v-if="(isPreview && !showLeft) || !isPreview"
+        :style="{
+          borderColor: data.borderColor,
+          paddingTop: data.right.collocation || data.right.exampleSent || data.right.definition ? '' : '80px',
+        }"
+      >
+        <div class="header-info-preview">
+          <h5 :style="{ textAlign: data.fontAlign }">{{ data.headerCon }}</h5>
+          <label :style="{ background: data.borderColor }">{{ data.label }}</label>
+        </div>
+        <div
+          :style="{
+            display: 'flex',
+            justifyContent:
+              !(data.right.collocation && data.right.exampleSent) && data.left.con.length < 4 ? 'center' : 'auto',
+            columnGap: '16px',
+          }"
+        >
+          <div style="width: max-content" v-if="data.right.hz_info.length > 0">
+            <AudioPlay
+              :style="{ background: data.borderColor }"
+              :file-id="data.right.audio_file"
+              v-if="data.right.audio_file"
+            />
+            <p
+              :style="{ color: data.borderColor }"
+              v-if="data.right.pinyin && data.right.pinyin.split(' ').length === 1"
+              class="pinyin-box"
+            >
+              {{ data.right.pinyin }}
+            </p>
+            <div class="hz-box">
+              <div class="hz-item" v-for="(itemh, indexh) in data.right.hz_info" :key="indexh">
+                <p
+                  :style="{ color: data.borderColor }"
+                  v-if="data.right.pinyin && data.right.pinyin.split(' ').length > 1"
+                >
+                  {{ data.right.pinyin.split(' ')[indexh] ? data.right.pinyin.split(' ')[indexh] : '' }}
+                </p>
+                <Strockplay
+                  className="adult-strockplay"
+                  :Book_text="itemh.con"
+                  :playStorkes="true"
+                  :strokePlayColor="data.borderColor"
+                  :strokeColor="'#000000'"
+                  :palyWidth="'24px'"
+                  :BoxbgType="'0'"
+                  :curItem="itemh.hzDetail.hz_json"
+                  :targetDiv="'writeTops-item-' + pageNumber + '-' + indexh + '-' + itemh.con + '-' + totalNumber"
+                  :class="[indexh !== 0 ? 'writeTop-item-noLeft' : '']"
+                  class="writeTop-item"
+                  :style="{ borderColor: data.borderColor }"
+                />
+              </div>
+            </div>
+          </div>
+
+          <div
+            class="definition-box"
+            v-if="(data.right.collocation || data.right.exampleSent) && data.left.con.length < 4"
+            :style="{
+              flex: '1',
+              marginTop: data.right.audio_file ? '104px' : '36px',
+            }"
+          >
+            <div v-if="data.right.cixing">
+              <p>词性:{{ data.right.cixing }}</p>
+            </div>
+            <div v-if="data.right.definition">
+              <p>释义:{{ data.right.definition }}</p>
+            </div>
+          </div>
+        </div>
+        <div
+          class="definition-box"
+          :style="{
+            width:
+              !(data.right.collocation || data.right.exampleSent) && data.left.con.length < 4
+                ? data.right.hz_info.length * 98 + 'px'
+                : '',
+            margin:
+              !(data.right.collocation || data.right.exampleSent) && data.left.con.length < 4 ? '16px auto 0 auto' : '',
+          }"
+          v-if="data.right.collocation || data.right.exampleSent || data.right.definition || data.right.cixing"
+        >
+          <template v-if="!(data.right.collocation || data.right.exampleSent) || data.left.con.length >= 4">
+            <div v-if="data.right.cixing">
+              <label class="card-label">词性:</label>
+              <p>{{ data.right.cixing }}</p>
+            </div>
+            <div v-if="data.right.definition">
+              <p>释义:{{ data.right.definition }}</p>
+            </div>
+          </template>
+          <div v-if="data.right.collocation">
+            <label class="card-label">搭配:</label>
+            <p>{{ data.right.collocation }}</p>
+          </div>
+          <div v-if="data.right.exampleSent">
+            <p>例句:{{ data.right.exampleSent }}</p>
+          </div>
+        </div>
+        <a class="overturn-btn" v-if="isPreview" @click="changeShowLeft"><i class="el-icon-refresh"></i></a>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+//这里可以导入其它文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
+import StrockplayredlineTable from '../../components/corpus/StrockplayredlineTable.vue';
+import Strockplay from '../../components/corpus/Strockplay.vue';
+import Strockred from '../../components/corpus/Strockred.vue';
+import FreewriteLettle from '../../components/corpus/FreewriteLettle.vue';
+import UploadDrag from './UploadDrag.vue';
+import AudioPlay from './AudioPlay.vue';
+const HanziWriter = require('hanzi-writer');
+import { getLogin, getHZChineseInfo } from '@/api/api';
+
+export default {
+  //import引入的组件需要注入到对象中才能使用
+  components: {
+    StrockplayredlineTable,
+    Strockplay,
+    Strockred,
+    FreewriteLettle,
+    UploadDrag,
+    AudioPlay,
+  },
+  props: [
+    'isPreview',
+    'data',
+    'pageNumber',
+    'totalNumber',
+    'editCardflag',
+    'none',
+    'is_preview',
+    'filtCardflag',
+    'filtId',
+    'filtTable',
+  ],
+  data() {
+    //这里存放数据
+    return {
+      ifFreeShow: false,
+      activeIndex: null,
+      activeColIndex: null,
+      fileList: [],
+      info: {
+        definition: '',
+        collocation: '',
+        exampleSent: '',
+      },
+      writer: null,
+      audio_file: '',
+      loading: false,
+      isFlipped: false,
+      showLeft: true,
+    };
+  },
+  //计算属性 类似于data概念
+  computed: {},
+  //监控data中数据变化
+  watch: {
+    editCardflag: {
+      handler: function (val, oldVal) {
+        if (val != oldVal) {
+          this.showLeft = true;
+          this.isFlipped = false;
+        }
+      },
+      deep: true,
+    },
+    pageNumber: {
+      handler: function (val, oldVal) {
+        if (val != oldVal) {
+          this.initHanziwrite();
+        }
+      },
+      deep: true,
+    },
+    filtCardflag: {
+      handler: function (val, oldVal) {
+        this.showLeft = true;
+        this.isFlipped = false;
+      },
+      deep: true,
+    },
+  },
+  //方法集合
+  methods: {
+    ExerciseChangeCurQue(answer, rowIndex, colIndex) {
+      if (answer) {
+        this.data.list[rowIndex][colIndex].strokes_image_url = answer.strokes_image_url;
+        this.data.list[rowIndex][colIndex].history = answer.history;
+        this.$forceUpdate();
+      }
+    },
+    changeFillId(file, fileList) {
+      let obj = {
+        name: file.name,
+        fileId: file.file_id,
+        fileUrl: file.file_url_open,
+      };
+      this.data.left.fileList.push(obj);
+    },
+    handleDeleteImg() {
+      this.data.left.fileList = [];
+    },
+    initHanziwrite() {
+      if (this.data.left.con.trim() && this.data.right.audio_file === '') {
+        this.loading = true;
+        let MethodName = 'tool-TextToVoiceFile';
+        let datas = {
+          text: this.data.left.con.trim(),
+        };
+        getLogin(MethodName, datas)
+          .then((res) => {
+            this.loading = false;
+            if (res.status === 1) {
+              this.data.right.audio_file = res.file_id;
+            }
+          })
+          .catch(() => {
+            this.loading = false;
+          });
+      }
+    },
+    handleDelItem() {
+      this.$emit('handleDelItem', this.pageNumber - 1);
+    },
+    // 获取数据
+    handleBlurCon() {
+      this.loading = true;
+      let con = this.data.left.con.trim();
+      let MethodName = 'hz_resource_manager-GetMultHZStrokesContent';
+      let data = {
+        hz_str: con,
+      };
+      getLogin(MethodName, data)
+        .then((res) => {
+          this.loading = false;
+          for (let key in res) {
+            if (key != 'status' && key != ',' && res[key]) {
+              res[key] = JSON.parse(res[key]);
+            }
+          }
+          let hzDetailList = res;
+          let hz_list = [];
+          con.split('').forEach((items) => {
+            let res = JSON.parse(JSON.stringify(hzDetailList[items]));
+            let obj = {
+              con: items,
+              hzDetail: {
+                hz_json: res,
+              },
+            };
+            hz_list.push(obj);
+          });
+          this.data.right.hz_info = hz_list;
+          this.data.right.pinyin = cnchar.spell(con, 'array', 'low', 'tone').join(' ');
+          let MethodName = 'tool-TextToVoiceFile';
+          if (con) {
+            let datas = {
+              text: con,
+            };
+            getLogin(MethodName, datas).then((res) => {
+              if (res.status === 1) {
+                this.data.right.audio_file = res.file_id;
+              }
+            });
+          }
+        })
+        .catch(() => {
+          this.loading = false;
+        });
+    },
+    // 更改拼音
+    handleChangePinyin() {
+      let pinyin = this.data.right.pinyin.trim().split(' ').join(',');
+      let MethodName = 'tool-PinyinToVoiceFile';
+      if (this.data.right.pinyin.trim()) {
+        let datas = {
+          pinyin: pinyin,
+        };
+        getLogin(MethodName, datas).then((res) => {
+          if (res.status === 1) {
+            this.data.right.audio_file = res.file_id;
+          }
+        });
+      }
+    },
+    // 翻面
+    changeShowLeft() {
+      this.showLeft = !this.showLeft;
+      this.isFlipped = !this.isFlipped;
+    },
+    changeRota() {
+      this.showLeft = true;
+      this.isFlipped = false;
+    },
+  },
+  //生命周期 - 创建完成(可以访问当前this实例)
+  created() {
+    this.initHanziwrite();
+  },
+  //生命周期 - 挂载完成(可以访问DOM元素)
+  mounted() {
+    // let _this = this;
+    // _this.$nextTick(() => {
+    //   if (_this.data.hz_info && _this.data.hz_info.length === 1) {
+    //     _this.initHanziwrite();
+    //   }
+    // });
+  },
+  //生命周期-创建之前
+  beforeCreated() {},
+  //生命周期-挂载之前
+  beforeMount() {},
+  //生命周期-更新之前
+  beforUpdate() {},
+  //生命周期-更新之后
+  updated() {},
+  //生命周期-销毁之前
+  beforeDestory() {},
+  //生命周期-销毁完成
+  destoryed() {},
+  //如果页面有keep-alive缓存功能,这个函数会触发
+  activated() {},
+};
+</script>
+<style lang="scss" scoped>
+.writeTable {
+  width: 1208px;
+  margin: 0 auto 19px auto;
+  // height: 842px;
+  box-sizing: border-box;
+  perspective: 1000px;
+  &-preview {
+    width: 600px;
+  }
+  .writeTop {
+    min-height: 450px;
+    display: flex;
+    column-gap: 8px;
+    perspective: 1000px;
+    transition: 0.6s;
+    transform-style: preserve-3d;
+
+    position: relative;
+    .left,
+    .right {
+      width: 100%;
+      min-height: 270px;
+      padding: 8px 12px 18px 12px;
+      border-radius: 24px;
+      background: #fff;
+      box-sizing: border-box;
+      position: relative;
+      border: 4px solid #fff;
+      overflow: hidden;
+      .header-info {
+        display: flex;
+        width: 100%;
+        justify-content: space-between;
+        margin-bottom: 12px;
+        :deep .el-input__inner {
+          color: rgba(0, 0, 0, 1);
+          font-size: 24px;
+          font-weight: 400;
+          line-height: 100%;
+          height: 24px;
+          border: none;
+          padding: 0;
+        }
+        .label {
+          :deep .el-input__inner {
+            text-align: right;
+          }
+        }
+      }
+    }
+    .left-preview {
+      padding-top: 40px;
+      // padding-bottom: 32px;
+      // position: absolute;
+      backface-visibility: hidden;
+    }
+    .header-info-preview {
+      position: absolute;
+      width: 100%;
+      left: 0;
+      top: 0;
+      z-index: 1;
+      h5 {
+        color: #000;
+        font-size: 24px;
+        font-weight: 400;
+        line-height: 32px;
+        padding: 0 12px;
+      }
+      label {
+        position: absolute;
+        right: -4px;
+        top: -4px;
+        border-radius: 0px 8px;
+        background: #fff;
+        padding: 0px 16px 0px 8px;
+        color: #fff;
+        font-size: 24px;
+        font-weight: 500;
+        line-height: 150%;
+      }
+    }
+    .left-big {
+      display: flex;
+      align-items: center;
+      justify-content: center;
+    }
+    .del-btn {
+      cursor: pointer;
+      border-radius: 40px;
+      background: #f56767;
+      padding: 5px 8px;
+      position: absolute;
+      right: 8px;
+      bottom: 8px;
+      color: #fff;
+      font-size: 24px;
+    }
+    .overturn-btn {
+      position: absolute;
+      right: 8px;
+      bottom: 8px;
+      border-radius: 8px;
+      background: #e0e0e0;
+      padding: 8px;
+      width: 24px;
+      height: 24px;
+      color: #fff;
+      font-size: 24px;
+      line-height: 1;
+      cursor: pointer;
+    }
+    .el-icon-zoom-in,
+    .filt-check {
+      position: absolute;
+      left: 8px;
+      bottom: 8px;
+      font-size: 24px;
+      width: 30px;
+      height: 30px;
+      cursor: pointer;
+      :deep .el-checkbox__inner {
+        width: 24px;
+        height: 24px;
+      }
+      :deep .el-checkbox__inner::after {
+        width: 6px;
+        height: 14px;
+        left: 8px;
+      }
+    }
+    .right {
+      display: flex;
+      align-items: center;
+      flex-flow: wrap;
+      padding: 16px 24px 26px 24px;
+      row-gap: 8px;
+
+      .card-label {
+        width: 100%;
+        color: #4e5969;
+        font-size: 14px;
+        font-weight: 400;
+        line-height: 22px;
+        height: 22px;
+      }
+      :deep .el-textarea {
+        height: 64px;
+      }
+      .config-box {
+        display: flex;
+        align-items: center;
+        width: 100%;
+        span {
+          color: #000;
+          font-size: 14px;
+          line-height: 20px;
+          margin-right: 8px;
+        }
+        .el-color-picker {
+          height: 32px;
+        }
+        :deep .el-color-picker__trigger {
+          height: 32px;
+        }
+        .el-radio {
+          margin-right: 8px;
+        }
+        .el-radio-group {
+          display: flex;
+        }
+        :deep .el-radio__input.is-checked .el-radio__inner {
+          border-color: #000;
+          background: #000;
+        }
+        :deep .el-radio__input.is-checked + .el-radio__label {
+          color: #000;
+        }
+      }
+    }
+    .right-preview {
+      padding: 36px;
+      display: block;
+      .pinyin-box {
+        color: #de4444;
+        font-feature-settings: 'cv01' on;
+        font-family: League;
+        font-size: 22px;
+        line-height: 120%;
+        margin-bottom: 8px;
+        text-align: center;
+      }
+      .hz-box {
+        width: 100%;
+        .hz-item {
+          text-align: center;
+          :deep .strockplayInner {
+            width: 98px;
+            height: 98px;
+          }
+          p {
+            color: #de4444;
+            font-feature-settings: 'cv01' on;
+            font-family: League;
+            font-size: 22px;
+            line-height: 120%;
+            margin-bottom: 12px;
+          }
+        }
+      }
+      :deep .audio-wrapper {
+        margin: 0 auto 8px auto;
+        border-radius: 40px;
+        background: #f3f3f3;
+        padding: 18px;
+        width: 60px;
+        height: 60px;
+        box-sizing: border-box;
+        cursor: pointer;
+        .voice-play {
+          width: 30px;
+          height: 30px;
+        }
+      }
+      .definition-box {
+        white-space: pre;
+        margin-top: 16px;
+        > div {
+          display: flex;
+          margin-bottom: 8px;
+          label,
+          p {
+            width: 40px;
+            color: #000;
+            font-size: 20px;
+            font-weight: 400;
+            line-height: 150%;
+          }
+          label {
+            width: 54px;
+          }
+          p {
+            flex: 1;
+            word-break: break-word;
+            white-space: pre-wrap;
+          }
+        }
+      }
+    }
+    .right-preview-rota {
+      transform: rotateY(180deg);
+    }
+    .item-image {
+      position: relative;
+      // background: #f2f3f5;
+      border-radius: 8px;
+      overflow: hidden;
+      font-size: 0;
+      .item-image-del {
+        position: absolute;
+        top: 8px;
+        right: 8px;
+        width: 16px;
+        height: 16px;
+        display: block;
+        cursor: pointer;
+        background-color: #ffffff;
+        color: #ee3232;
+        padding: 8px;
+        border-radius: 50%;
+        box-shadow: 0px 4px 4px 0px rgba(0, 0, 0, 0.25);
+        font-size: 16px;
+      }
+    }
+    .item-con {
+      width: 50%;
+      display: flex;
+      align-items: center;
+      margin-top: 16px;
+      label {
+        color: #4e5969;
+        font-size: 14px;
+        font-weight: 400;
+        line-height: 22px;
+        width: 44px;
+      }
+      :deep .el-input__inner {
+        border-radius: 2px;
+        background: #f2f3f5;
+        width: 235px;
+        border: none;
+        font-size: 14px;
+        font-weight: 400;
+        line-height: 22px;
+        height: 32px;
+        font-family: FZJCGFKTK;
+      }
+      .pinyin {
+        :deep .el-input__inner {
+          font-family: League;
+        }
+      }
+    }
+
+    .con-preview {
+      margin-top: 8px;
+      color: #000;
+      text-align: center;
+      font-family: 'FZJCGFKTK';
+      font-size: 46px;
+      font-weight: 400;
+      line-height: 100%;
+      &-big {
+        font-size: 86px;
+        margin-top: 0;
+      }
+    }
+    .writeTop-row {
+      display: flex;
+      justify-content: center;
+    }
+  }
+
+  .writeTop-nopadding {
+    padding-top: 0;
+    height: 842px;
+  }
+  .item-info {
+    display: flex;
+    width: 100%;
+    padding: 0 46px 8px 46px;
+    column-gap: 16px;
+    box-sizing: border-box;
+    &-left {
+      .writeTop-item {
+        width: 98px;
+        height: 98px;
+        :deep .strock-play-box {
+          width: 18px !important;
+          height: 18px !important;
+        }
+        :deep .playStorkes-btn {
+          width: 18px !important;
+          height: 18px !important;
+        }
+        &-small {
+          width: 62px;
+          height: 62px;
+          :deep .strock-play-box {
+            width: 11px !important;
+            height: 11px !important;
+          }
+          :deep .playStorkes-btn {
+            width: 11px !important;
+            height: 11px !important;
+          }
+        }
+      }
+      &-long {
+        width: 100%;
+      }
+    }
+    &-right {
+      flex: 1;
+    }
+    :deep .el-textarea__inner {
+      resize: none;
+      background-color: #f3f3f3;
+      border: none;
+      outline: none;
+    }
+    .voice-box {
+      width: 100%;
+      height: 32px;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      column-gap: 4px;
+      img {
+        width: 24px;
+        height: 24px;
+      }
+      span {
+        font-family: League;
+        font-size: 16px;
+        font-weight: 400;
+        color: #de4444;
+      }
+    }
+    .item-info-row {
+      display: flex;
+      column-gap: 11px;
+      margin-bottom: 6px;
+      :deep .el-input__inner {
+        background-color: #f3f3f3;
+        border: none;
+        outline: none;
+        height: 32px;
+      }
+    }
+    .item-info-half,
+    .item-info-all {
+      width: 50%;
+      display: flex;
+      font-size: 14px;
+      line-height: 22px;
+      height: 22px;
+    }
+    .item-info-all {
+      width: 100%;
+    }
+  }
+  .hz-box {
+    display: flex;
+    width: max-content;
+  }
+  .writeTop-item {
+    border: 1px solid #de4444;
+  }
+  .writeTop-item-noLeft {
+    border-left: none;
+  }
+
+  .tian-div {
+    width: 100%;
+    height: 100%;
+    position: relative;
+    .tian {
+      width: 100%;
+      height: 100%;
+    }
+    img {
+      width: 100%;
+      height: 100%;
+      position: absolute;
+      left: 0;
+      top: 0;
+    }
+  }
+
+  .flipped {
+    transform: rotateY(180deg);
+  }
+  .flipped-back {
+    transform: rotateY(180deg);
+  }
+}
+</style>
+<style lang="scss">
+.writeTable {
+  input::placeholder {
+    font-family: initial;
+  }
+  input::-webkit-input-placeholder {
+    font-family: initial;
+  }
+
+  input::-moz-placeholder {
+    font-family: initial;
+  }
+
+  input:-moz-placeholder {
+    font-family: initial;
+  }
+
+  input:-ms-input-placeholder {
+    font-family: initial;
+  }
+  .header-info {
+    input::placeholder {
+      font-size: 16px;
+    }
+    input::-webkit-input-placeholder {
+      font-size: 16px;
+    }
+
+    input::-moz-placeholder {
+      font-size: 16px;
+    }
+
+    input:-moz-placeholder {
+      font-size: 16px;
+    }
+
+    input:-ms-input-placeholder {
+      font-size: 16px;
+    }
+  }
+}
+</style>