| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453 |
- <template>
- <ModuleBase ref="base" :type="data.type">
- <template #content>
- <!-- eslint-disable max-len -->
- <div v-loading="loading" class="article-wrapper">
- <div class="table-rich-toolbar" v-if="articleAttrib">
- <el-select
- v-model="articleAttrib.font"
- placeholder="请选择"
- style="width: 130px"
- @change="handleChangeStyles"
- >
- <el-option v-for="{ value, label } in fontFamilyList" :key="value" :label="label" :value="value" />
- </el-select>
- <el-select v-model="articleAttrib.font_size" placeholder="请选择" style="width: 130px">
- <el-option
- v-for="(value, index) in 16"
- :key="index"
- :label="6 + value * 2 + 'pt'"
- :value="6 + value * 2 + 'pt'"
- />
- </el-select>
- <el-form :model="articleAttrib" inline>
- <el-form-item label="文字颜色">
- <el-color-picker v-model="articleAttrib.text_color" @change="handleChangeStyles" />
- </el-form-item>
- </el-form>
- <span :class="[data.other_attrib.isUnderline ? 'active' : '']" @click="setActiveTextStyle('underline')">
- <SvgIcon icon-class="underline" size="20" />
- </span>
- <span :class="[data.other_attrib.isBold ? 'active' : '']" @click="setActiveTextStyle('bold')">
- <SvgIcon icon-class="font-bold" size="20" />
- </span>
- <!-- <span
- :class="[data.other_attrib.isItalic ? 'active' : '']"
- @click="data.other_attrib.isItalic = !data.other_attrib.isItalic"
- >
- <SvgIcon icon-class="font-italic" size="20" />
- </span> -->
- <span
- :class="[data.other_attrib.isStrikethrough ? 'active' : '']"
- @click="setActiveTextStyle('line-through')"
- >
- <SvgIcon icon-class="strikethrough" size="20" />
- </span>
- <span :class="[data.other_attrib.border === 'dotted' ? 'active' : '']">
- <SvgIcon icon-class="borderDotted" title="下划虚线" size="16" @click="setActiveTextStyle('border')" />
- </span>
- <span :class="[articleAttrib.align === 'LEFT' ? 'active' : '']" @click="setActiveTextStyle('align', 'LEFT')">
- <SvgIcon icon-class="align-left" size="20" />
- </span>
- <span
- :class="[articleAttrib.align === 'MIDDLE' ? 'active' : '']"
- @click="setActiveTextStyle('align', 'MIDDLE')"
- >
- <SvgIcon icon-class="align-center" size="20" />
- </span>
- <span
- :class="[articleAttrib.align === 'RIGHT' ? 'active' : '']"
- @click="setActiveTextStyle('align', 'RIGHT')"
- >
- <SvgIcon icon-class="align-right" size="20" />
- </span>
- </div>
- <el-input v-model="data.content" placeholder="输入" type="textarea" />
- <div class="btn-box">
- <SelectUpload label="课文音频" type="audio" @uploadSuccess="uploadAudioSuccess" />
- <el-button :loading="autoLoading" @click="handleAutoAudio">自动生成音频</el-button>
- </div>
- <div v-if="data.mp3_list.length > 0" class="upload-file">
- <div class="file-name">
- <span>
- <SvgIcon icon-class="note" size="12" />
- <span>{{ data.mp3_list[0].name }}</span>
- </span>
- </div>
- <SvgIcon icon-class="delete-black" size="12" @click="removeFile" />
- <ResourcesOperate :data="data.mp3_list[0]" />
- </div>
- <span v-if="data.content" class="tips">说明:需先点击“生成分词”按钮后,再进行文章校对或生成字幕节点</span>
- <div v-if="data.content" class="btn-box">
- <a @click="handleChangeContent">生成分词</a>
- <a @click="checkArticle">文章校对</a>
- <a @click="picArticle">添加图片</a>
- <a @click="editWordsFlag = !editWordsFlag">编辑生词短语注释</a>
- <template v-if="data.wordTime && data.wordTime.length > 0">
- <!-- <span>已有字幕时间节点</span> -->
- <a type="text" @click="againWordTime">重新生成字幕时间</a>
- <a size="medium" @click="openCheckSubtitles('句子')">校对句子字幕时间</a>
- <!-- <a size="medium" @click="compareTime('句子')">校对句子字幕时间</a> -->
- <a size="medium" @click="compareTime('文字')">校对文字字幕时间</a>
- </template>
- <template v-else>
- <a v-if="!isWordTime" size="medium" @click="createWordTimes">自动生成字幕节点</a>
- <p v-else>字幕节点生成中...请等待</p>
- </template>
- <el-button @click="handleMultilingual">课文多语言</el-button>
- <MultilingualFill
- :visible.sync="multilingualVisible"
- :text="multilingualText"
- :translations="data.multilingual"
- @SubmitTranslation="handleMultilingualTranslation"
- />
- </div>
- </div>
- <el-dialog
- v-if="dialogFlag"
- :visible.sync="dialogFlag"
- :show-close="false"
- :close-on-click-modal="false"
- :modal-append-to-body="false"
- :modal="false"
- width="250px"
- class="article-checkpinyin-dialog"
- >
- <div class="check-box">
- <div class="content">
- <div class="words-box">
- <span class="pinyin">
- {{ itemActive.pinyin }}
- </span>
- <span class="words">
- {{ itemActive.chs }}
- </span>
- </div>
- </div>
- <!-- <el-input v-model="checkPinyinInput" type="text" class="checkPinyinInput" /> -->
- <el-select
- v-model="checkPinyinInput"
- placeholder="请选择"
- filterable
- allow-create
- default-first-option
- class="checkPinyinInput"
- >
- <el-option v-for="item in pinyinList" :key="item.pinyin" :value="item.pinyin.replace(/,/g, '')">
- <span style="float: left">{{ item.pinyin.replace(/,/g, '') }}</span>
- <span style="float: right; font-size: 13px; color: #8492a6">{{
- item.storage_type === 1 ? '机构库' : item.storage_type === 2 ? '全域库' : '个人库'
- }}</span>
- </el-option>
- </el-select>
- <p class="tips">
- 一到四声分别用数字1-4表示。拼音间用空格隔开,儿化音用_代替空格,如“骨朵儿”输入“gu1 duo3_er”。
- </p>
- <div class="btn-box">
- <el-button type="info" size="small" @click="cancleDialog">取消</el-button>
- <el-button type="primary" size="small" @click="surePinyin">保存</el-button>
- </div>
- </div>
- </el-dialog>
- <el-dialog
- v-if="showArticleFlag"
- :visible.sync="showArticleFlag"
- :show-close="true"
- :close-on-click-modal="true"
- :modal-append-to-body="true"
- :append-to-body="true"
- :lock-scroll="true"
- width="80%"
- class="practiceBox"
- >
- <CheckArticle
- ref="CheckArticle"
- :data="data"
- @saveWord="saveWord"
- @savePinyin="savePinyin"
- @saveStyle="saveStyle"
- />
- </el-dialog>
- <el-dialog title="校对字幕时间" :visible.sync="compareShow" width="50%" :before-close="handleClose" top="0">
- <CompareTime
- :data="compareData"
- :type="compareType"
- :changewords-result-list="changewordsResultList"
- :open-check-subtitles="openCheckSubtitles"
- />
- <span slot="footer" class="dialog-footer">
- <el-button @click="handleClose">取 消</el-button>
- <el-button :loading="compareloading" type="primary" @click="saveCompare">确 定</el-button>
- </span>
- </el-dialog>
- <!-- <el-dialog title="" :visible.sync="editWordsFlag" width="80%" :close-on-click-modal="true" top="0"> -->
- <template v-if="editWordsFlag">
- <div class="tabs-box">
- <a :class="[editWordIndex === 0 ? 'active' : '']" @click="editWordIndex = 0">生词</a>
- <a :class="[editWordIndex === 2 ? 'active' : '']" @click="editWordIndex = 2">其他词汇</a>
- <a :class="[editWordIndex === 1 ? 'active' : '']" @click="editWordIndex = 1">注释</a>
- </div>
- <NewWord
- v-if="editWordIndex === 0"
- key="new_word"
- :data-new-word="data.new_word_list"
- :unified-attrib="data.unified_attrib ? data.unified_attrib : null"
- @sureNewWords="sureNewWords"
- />
- <Notes
- v-if="editWordIndex === 1"
- key="notes"
- :data-notes="data.notes_list"
- :unified-attrib="data.unified_attrib ? data.unified_attrib : null"
- @sureNotes="sureNotes"
- />
- <NewWord
- v-if="editWordIndex === 2"
- :data-new-word="data.other_word_list"
- :unified-attrib="data.unified_attrib ? data.unified_attrib : null"
- @sureNewWords="sureOtherNewWords"
- />
- </template>
- <template v-if="isEnable(data.property.view_pinyin)">
- <el-divider content-position="left"
- >拼音效果<el-button
- v-show="isEnable(data.property.view_pinyin)"
- type="text"
- icon="el-icon-refresh"
- title="刷新"
- class="refresh-pinyin-btn"
- @click.native="handleChangeContent"
- /></el-divider>
- <div v-for="(item, index) in data.detail" :key="index" class="text">
- <template v-for="(witem, windex) in item.wordsList">
- <div
- v-for="(wItem, wIndex) in witem"
- :key="windex + '-' + wIndex"
- class="text-item"
- :style="{
- textAlign: windex === 0 && wIndex === 0 ? 'left' : '',
- }"
- @click="selectItem(wItem)"
- >
- <span class="pinyin">{{
- windex === 0 &&
- wIndex === 0 &&
- data.property.is_first_sentence_first_hz_pinyin_first_char_upper_case === 'true'
- ? wItem.pinyin_up
- : wItem.pinyin
- }}</span>
- <span
- class="word"
- :style="{
- fontFamily: wItem.fontFamily,
- textDecoration: wItem.textDecoration,
- borderBottom: wItem.border === 'dotted' ? '1px dotted' : '',
- fontWeight: wItem.fontWeight,
- color: wItem.color,
- }"
- >{{ wItem.chs }}</span
- >
- </div>
- </template>
- </div>
- </template>
- <!-- </el-dialog> -->
- <!-- 添加图片 -->
- <el-dialog
- v-if="showPicArticleFlag"
- :visible.sync="showPicArticleFlag"
- :show-close="true"
- :close-on-click-modal="true"
- :modal-append-to-body="true"
- :append-to-body="true"
- :lock-scroll="true"
- width="80%"
- class="practiceBox"
- >
- <CheckPic :data="data" />
- </el-dialog>
- <CheckSubtitles
- v-if="visible"
- :visible.sync="visible"
- :audio-id="data.mp3_list[0] && data.mp3_list[0].file_id ? data.mp3_list[0].file_id : ''"
- :option-list="subtitleList"
- @saveSubtitles="saveSubtitles"
- />
- </template>
- </ModuleBase>
- </template>
- <script>
- import ModuleMixin from '../../common/ModuleMixin';
- import SelectUpload from '@/views/book/courseware/create/components/common/SelectUpload.vue';
- import CheckArticle from './CheckArticle.vue';
- import CompareTime from './CompareTime.vue';
- import NewWord from './NewWord.vue';
- import Notes from './Notes.vue';
- import CheckPic from './CheckPic.vue';
- import CheckSubtitles from '@/views/book/courseware/create/components/question/voice_matrix/CheckSubtitles.vue';
- import ResourcesOperate from '../../common/ResourcesOperate.vue';
- import { getArticleData } from '@/views/book/courseware/data/article';
- import { fontFamilyList } from '@/views/book/courseware/data/table';
- import { TextToAudioFile } from '@/api/app';
- import { isEnable } from '@/views/book/courseware/data/common';
- import {
- segSentences,
- BatchSegContent,
- getWordTime,
- prepareTranscribe,
- fileToBase64Text,
- getWordTimes,
- } from '@/api/article';
- const Base64 = require('js-base64').Base64;
- import cnchar from 'cnchar';
- import { toolGetWordPinyinCorrectionList } from '@/api/pinyinCorrection';
- export default {
- name: 'ArticlePage',
- components: {
- SelectUpload,
- CheckArticle,
- CompareTime,
- NewWord,
- Notes,
- CheckPic,
- CheckSubtitles,
- ResourcesOperate,
- },
- mixins: [ModuleMixin],
- data() {
- return {
- fontFamilyList,
- isEnable,
- data: getArticleData(),
- showArticleFlag: false, // 校对文章
- showPicArticleFlag: false, // 添加图片
- toneList: [' ', 'ˉ', 'ˊ', 'ˇ', 'ˋ'],
- loading: false,
- isWordTime: false,
- compareType: '', // 校对类型
- compareIndex: null, // 校对句子索引
- compareShow: false,
- compareData: null,
- compareloading: false,
- editWordsFlag: false,
- editWordIndex: 0,
- multilingualText: '',
- autoLoading: false,
- visible: false,
- subtitleList: [],
- itemActive: null,
- dialogFlag: false,
- checkPinyinInput: '',
- oldInput: '',
- tableData: [
- ['ā', 'á', 'ǎ', 'à', 'a'],
- ['ō', 'ó', 'ǒ', 'ò', 'o'],
- ['ē', 'é', 'ě', 'è', 'e'],
- ['ī', 'í', 'ǐ', 'ì', 'i'],
- ['ū', 'ú', 'ǔ', 'ù', 'u'],
- ['ǖ', 'ǘ', 'ǚ', 'ǜ', 'ü'],
- ['Ā', 'Á', 'Â', 'À', 'A'],
- ['Ō', 'Ó', 'Ô', 'Ò', 'O'],
- ['Ē', 'É', 'Ê', 'È', 'E'],
- ['Ī', 'Í', 'Î', 'Ì', 'I'],
- ['Ū', 'Ú', 'Û', 'Ù', 'U'],
- ['n', 'ń', 'ň', 'ǹ', 'n'],
- ['m̄', 'ḿ', 'm', 'm̀', 'm'],
- ],
- pinyinList: [], // 拼音校正列表
- articleAttrib: null,
- };
- },
- watch: {
- 'data.content': 'handleMindMap',
- 'data.unified_attrib': {
- handler(val) {
- if (val) {
- this.articleAttrib = JSON.parse(JSON.stringify(val));
- this.handleChangeStyles();
- }
- },
- deep: true,
- immediate: true,
- },
- // 'data.unified_attrib.font': {
- // handler(val) {
- // if (val) {
- // this.handleChangeStyles();
- // }
- // },
- // deep: true,
- // immediate: true,
- // },
- // 'data.unified_attrib.text_color': {
- // handler(val) {
- // if (val) {
- // this.handleChangeStyles();
- // }
- // },
- // deep: true,
- // immediate: true,
- // },
- // 'data.unified_attrib.align': {
- // handler(val) {
- // if (val) {
- // this.handleChangeStyles();
- // }
- // },
- // deep: true,
- // immediate: true,
- // },
- },
- created() {},
- methods: {
- // 全局样式变化
- handleChangeStyles() {
- if (this.articleAttrib.font !== this.data.other_attrib.oldFont) {
- this.data.other_attrib.oldFont = this.articleAttrib.font;
- this.data.detail.forEach((item) => {
- item.wordsList.forEach((items) => {
- items.forEach((itemss) => {
- itemss.fontFamily = this.articleAttrib.font;
- });
- });
- });
- } else if (this.articleAttrib.text_color !== this.data.other_attrib.oldColor) {
- this.data.other_attrib.oldColor = this.articleAttrib.text_color;
- this.data.detail.forEach((item) => {
- item.wordsList.forEach((items) => {
- items.forEach((itemss) => {
- itemss.color = this.articleAttrib.text_color;
- });
- });
- });
- } else if (this.articleAttrib.align !== this.data.other_attrib.oldAlign) {
- this.data.other_attrib.oldAlign = this.articleAttrib.align;
- this.data.detail.forEach((item) => {
- item.paraAlign =
- this.articleAttrib.align === 'RIGHT' ? 'right' : this.articleAttrib.align === 'MIDDLE' ? 'center' : 'left';
- });
- }
- },
- // 解析输入内容
- handleChangeContent() {
- this.loading = true;
- this.data.detail = [];
- if (this.data.content.trim()) {
- let contentArr = this.data.content.split('\n');
- let textList = [];
- let detailItem = {
- paraIndex: 0,
- para: '',
- sentences: [],
- segList: [],
- seg_words: [],
- wordsList: [],
- timeList: [],
- isTitle: false,
- sentencesEn: [],
- paraAlign: this.articleAttrib
- ? this.articleAttrib.align === 'RIGHT'
- ? 'right'
- : this.articleAttrib.align === 'MIDDLE'
- ? 'center'
- : 'left'
- : 'left',
- remark: {
- chs: '',
- en: '',
- heightNumber: null,
- img_list: [],
- widthNumber: null,
- chsBg: '#988ed6',
- enBg: '#fff',
- },
- sourceList: [],
- sourcePosition: 'after',
- heightNumber: null,
- widthNumber: null,
- };
- // 分段
- contentArr.forEach((item, index) => {
- if (item.trim()) {
- detailItem.para = item;
- detailItem.paraIndex = index;
- this.data.detail.push(JSON.parse(JSON.stringify(detailItem)));
- let str = Base64.encode(item);
- textList.push(str);
- }
- });
- BatchSegContent({
- text: this.data.content,
- is_build_pinyin: 'true',
- is_custom_fc: 'false',
- is_vocabulary_pinyin_lt: 'true',
- is_fill_punctuation_mark: 'true',
- })
- .then((res) => {
- this.loading = false;
- if (res.status === 1) {
- res.paragraph_list.forEach((item, index) => {
- let sentenceList = []; // 句子按段数组
- let segList = []; // 句子分词结果
- item.forEach((items) => {
- let sentence = items.reduce((acc, itemss) => `${acc + itemss.text}`, '');
- let seg = items.map((itemss) => itemss.text);
- sentenceList.push(sentence);
- segList.push(seg);
- });
- this.data.detail[index].sentences = sentenceList;
- this.data.detail[index].segList = segList;
- this.setWordsList(item, index);
- });
- this.handleSenWord();
- }
- })
- .catch(() => {
- this.loading = false;
- });
- // 分句
- // let sentenceList = []; // 句子按段数组
- // let data = {
- // textList,
- // };
- // segSentences(data)
- // .then((res) => {
- // let result = res.data.result;
- // sentenceList = JSON.parse(JSON.stringify(res.data.result));
- // result.forEach((item, index) => {
- // let sentenceListBase64 = [];
- // this.data.detail[index].sentences = item;
- // item.forEach((items) => {
- // sentenceListBase64.push(Base64.encode(items));
- // });
- // // 分词
- // BatchSegContent({ textList: sentenceListBase64 })
- // .then((res) => {
- // let list = res.data.result.list;
- // this.data.detail[index].segList = list;
- // this.setWordsList(list, index);
- // if (index === result.length - 1) {
- // this.handleSenWord();
- // this.loading = false;
- // }
- // })
- // .catch(() => {
- // this.loading = false;
- // });
- // });
- // })
- // .catch(() => {
- // this.loading = false;
- // });
- }
- },
- // 处理句子和词的关系
- handleSenWord() {
- this.data.sentence_list_mp = [];
- this.data.detail.forEach((item) => {
- item.sentences.forEach((items, indexs) => {
- let word_list = [];
- item.segList[indexs].forEach((itemw) => {
- word_list.push({
- word: itemw,
- });
- });
- let obj = {
- sentence: items,
- word_list,
- };
- this.data.sentence_list_mp.push(obj);
- });
- });
- },
- setWordsList(list, paraIndex) {
- let wordsList = [];
- list.forEach((item, index) => {
- let sentArr = [];
- item.map((sItem) => {
- // let toneStr = [];
- // for (let i = 0; i < sItem.length; i++) {
- // const pattern = /[\u4e00-\u9fa5]/;
- // if (cnchar.isCnChar(sItem[i]) && !pattern.test(cnchar.spell(sItem[i], 'low', 'tone'))) {
- // toneStr.push(this.toneList[cnchar.spellInfo(cnchar.spell(sItem[i], 'low', 'tone')).tone]);
- // } else {
- // toneStr.push(' ');
- // }
- // }
- let obj = {
- chs: sItem.text,
- pinyin: sItem.pinyin,
- pinyin_up: sItem.pinyin_up,
- pinyin_tone: sItem.pinyin_tone,
- fontFamily: this.articleAttrib ? this.articleAttrib.font : '楷体',
- textDecoration: this.data.other_attrib
- ? this.data.other_attrib.isUnderline
- ? this.data.other_attrib.isUnderline
- : this.data.other_attrib.isStrikethrough
- ? this.data.other_attrib.isStrikethrough
- : ''
- : '',
- fontWeight: this.data.other_attrib ? this.data.other_attrib.isBold : '',
- border: this.data.other_attrib ? this.data.other_attrib.border : '',
- color: this.articleAttrib ? this.articleAttrib.text_color : '',
- matchWords: '',
- matchNotes: '',
- notesColor: '',
- img: [],
- imgPosition: 'after',
- };
- sentArr.push(obj);
- });
- wordsList.push(sentArr);
- });
- this.data.detail[paraIndex].wordsList = wordsList;
- },
- uploadAudioSuccess(fileList) {
- if (fileList.length > 0) {
- const { file_name: name, file_url: temporary_url, file_id, media_duration } = fileList[0];
- this.data.mp3_list = [
- {
- name,
- media_duration,
- temporary_url,
- url: file_id,
- file_id,
- },
- ];
- this.data.file_id_list = [file_id];
- }
- },
- removeFile() {
- this.$confirm('是否删除当前文件?', '提示', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning',
- })
- .then(() => {
- this.data.mp3_list = [];
- this.data.file_id_list = [];
- })
- .catch(() => {});
- },
- // 校对文章
- checkArticle() {
- let verseList = [];
- this.data.detail.forEach((item) => {
- verseList = verseList.concat(item.sentences);
- });
- if (verseList.length > 0) {
- this.showArticleFlag = true;
- } else {
- this.$message.warning('请先生成分词');
- }
- },
- saveWord(saveArr) {
- BatchSegContent({
- text: this.data.content,
- is_build_pinyin: 'true',
- is_custom_fc: 'true',
- is_vocabulary_pinyin_lt: 'true',
- is_fill_punctuation_mark: 'true',
- fc_paragraph_list: saveArr,
- }).then((res) => {
- if (res.status === 1) {
- res.paragraph_list.forEach((item, index) => {
- let sentenceList = []; // 句子按段数组
- let segList = []; // 句子分词结果
- let sentenceStr = [];
- let para = '';
- let wordsList = [];
- item.forEach((items) => {
- let sentence = items.reduce((acc, itemss) => `${acc + itemss.text}`, '');
- let sentenceS = items.reduce((acc, itemss) => `${acc + itemss.text} `, '');
- let seg = items.map((itemss) => itemss.text);
- para += items.map((itemss) => itemss.text);
- sentenceList.push(sentence);
- sentenceStr.push(sentenceS);
- segList.push(seg);
- let sentArr = [];
- items.forEach((sItem) => {
- let obj = {
- chs: sItem.text,
- pinyin: sItem.pinyin,
- pinyin_up: sItem.pinyin_up,
- pinyin_tone: sItem.pinyin_tone,
- fontFamily: this.articleAttrib ? this.articleAttrib.font : '楷体',
- textDecoration: this.data.other_attrib
- ? this.data.other_attrib.isUnderline
- ? this.data.other_attrib.isUnderline
- : this.data.other_attrib.isStrikethrough
- ? this.data.other_attrib.isStrikethrough
- : ''
- : '',
- fontWeight: this.data.other_attrib ? this.data.other_attrib.isBold : '',
- border: this.data.other_attrib ? this.data.other_attrib.border : '',
- color: this.articleAttrib ? this.articleAttrib.text_color : '',
- matchWords: '',
- matchNotes: '',
- notesColor: '',
- img: [],
- imgPosition: 'after',
- };
- sentArr.push(obj);
- });
- wordsList.push(sentArr);
- });
- if (this.data.detail[index]) {
- this.data.detail[index].segList = segList;
- this.data.detail[index].para = para;
- this.data.detail[index].sentenceStr = sentenceStr;
- this.data.detail[index].sentences = sentenceList;
- this.data.detail[index].wordsList = wordsList;
- } else {
- let obj = {
- paraIndex: index,
- para,
- sentences: sentenceList,
- segList: item,
- seg_words: [],
- wordsList,
- timeList: [],
- isTitle: false,
- sentencesEn: [],
- sentenceStr,
- paraAlign: this.articleAttrib
- ? this.articleAttrib.align === 'RIGHT'
- ? 'right'
- : this.articleAttrib.align === 'MIDDLE'
- ? 'center'
- : 'left'
- : 'left',
- remark: {
- chs: '',
- en: '',
- heightNumber: null,
- img_list: [],
- widthNumber: null,
- chsBg: '#988ed6',
- enBg: '#fff',
- },
- sourceList: [],
- sourcePosition: 'after',
- heightNumber: null,
- widthNumber: null,
- };
- this.data.detail.push(obj);
- }
- });
- this.$refs.CheckArticle.refreshData();
- }
- });
- this.$message.success('保存成功,请校对拼音');
- this.handleSenWord();
- },
- // 保存拼音
- savePinyin(paraIndex, sentenceIndex, wordIndex, pinyin) {
- if (this.data.pinyin_type === 'tone') {
- this.data.detail[paraIndex].wordsList[sentenceIndex][wordIndex].pinyin_tone = pinyin;
- } else if (wordIndex === 0) {
- this.data.detail[paraIndex].wordsList[sentenceIndex][wordIndex].pinyin_up = pinyin;
- } else {
- this.data.detail[paraIndex].wordsList[sentenceIndex][wordIndex].pinyin = pinyin;
- }
- },
- saveStyle(
- paraIndex,
- sentenceIndex,
- wordIndex,
- fontFamily,
- textDecoration,
- fontWeight,
- border,
- color,
- matchWords,
- matchNotes,
- notesColor,
- img,
- imgPosition,
- ) {
- this.data.detail[paraIndex].wordsList[sentenceIndex][wordIndex].fontFamily = fontFamily;
- this.data.detail[paraIndex].wordsList[sentenceIndex][wordIndex].textDecoration = textDecoration;
- this.data.detail[paraIndex].wordsList[sentenceIndex][wordIndex].fontWeight = fontWeight;
- this.data.detail[paraIndex].wordsList[sentenceIndex][wordIndex].border = border;
- this.data.detail[paraIndex].wordsList[sentenceIndex][wordIndex].color = color;
- this.data.detail[paraIndex].wordsList[sentenceIndex][wordIndex].matchWords = matchWords;
- this.data.detail[paraIndex].wordsList[sentenceIndex][wordIndex].matchNotes = matchNotes;
- this.data.detail[paraIndex].wordsList[sentenceIndex][wordIndex].notesColor = notesColor;
- this.data.detail[paraIndex].wordsList[sentenceIndex][wordIndex].img = img;
- this.data.detail[paraIndex].wordsList[sentenceIndex][wordIndex].imgPosition = imgPosition;
- },
- // 保存校对
- saveCompare() {
- this.compareloading = false;
- this.data.wordTime = this.compareData;
- this.handleClose();
- // this.compareloading = true;
- // compareSenTenceTime({ matchList: JSON.stringify(this.compareData) })
- // .then((res) => {
- // this.compareloading = false;
- // this.data.wordTime = res.data.result;
- // })
- // .catch(() => {
- // this.compareloading = false;
- // });
- },
- // 校对时间
- compareTime(type) {
- this.compareType = type;
- this.compareData = JSON.parse(JSON.stringify(this.data.wordTime));
- this.compareShow = true;
- },
- handleClose() {
- this.compareShow = false;
- this.compareData = null;
- this.compareType = '';
- },
- // 校对每个字的时间
- changewordsResultList(index, item) {
- this.data.wordTime[index].wordsResultList = JSON.parse(JSON.stringify(item));
- },
- againWordTime() {
- this.isWordTime = false;
- this.data.wordTime = [];
- },
- createWordTimes() {
- let _this = this;
- let verseList = [];
- if (_this.data.mp3_list && _this.data.mp3_list.length > 0 && _this.data.mp3_list[0].file_id) {
- if (_this.data.content) {
- _this.data.detail.forEach((item) => {
- verseList = verseList.concat(item.sentences);
- });
- if (verseList.length > 0) {
- _this.isWordTime = true;
- let data = {
- audio_file_id: _this.data.mp3_list[0].file_id,
- text: _this.data.content,
- text_type: 'line_text_list',
- line_text_list: verseList,
- };
- getWordTimes(data).then((res) => {
- _this.data.wordTime = res.data.result;
- _this.isWordTime = false;
- });
- } else {
- this.$message.warning('请先生成分词');
- }
- }
- } else {
- _this.$message.warning('请先上传音频');
- _this.loading = false;
- }
- },
- createWordTime() {
- let _this = this;
- this.getfillLiu().then(() => {
- if (_this.data.taskId) {
- let verseList = [];
- _this.data.detail.forEach((item) => {
- verseList = verseList.concat(item.sentences);
- });
- if (verseList.length > 0) {
- _this.isWordTime = true;
- let data = {
- taskId: _this.data.taskId,
- verseList: JSON.stringify(verseList),
- matchType: 'chinese',
- language: 'ch',
- };
- getWordTime(data).then((res) => {
- _this.data.wordTime = res.data.result;
- _this.isWordTime = false;
- });
- }
- } else {
- _this.$message.warning('请先上传音频');
- _this.loading = false;
- }
- });
- },
- // 得到文件流
- getfillLiu() {
- this.loading = true;
- let _this = this;
- return new Promise(function (resolve, reject) {
- if (_this.data.mp3_list && _this.data.mp3_list.length > 0 && _this.data.mp3_list[0].file_id) {
- let id = _this.data.mp3_list[0].file_id;
- let data = {
- file_id: id,
- };
- fileToBase64Text(data).then((res) => {
- let taskIddata = {
- fileName: _this.data.mp3_list[0].name,
- speechBase64: res.base64_text,
- language: 'ch',
- };
- prepareTranscribe(taskIddata)
- .then((ress) => {
- _this.$set(_this.data, 'taskId', ress.data.taskId);
- _this.loading = false;
- resolve();
- })
- .catch(() => {
- _this.loading = false;
- });
- });
- } else {
- _this.$message.warning('请先上传音频');
- _this.loading = false;
- }
- });
- },
- sureNewWords(data) {
- this.data.new_word_list = data;
- },
- sureOtherNewWords(data) {
- this.data.other_word_list = data;
- },
- sureNotes(data) {
- this.data.notes_list = data;
- },
- handleMindMap() {
- // 思维导图数据
- let node_list = [];
- node_list.push({
- name: this.data.content,
- id: Math.random().toString(36).substring(2, 12),
- });
- this.data.mind_map.node_list = node_list;
- },
- handleMultilingual() {
- this.multilingualText = '';
- let flag = false;
- this.data.detail.forEach((item) => {
- if (item.para) {
- if (item.sentences && item.sentences.length > 0) {
- flag = true;
- }
- item.sentences.forEach((items) => {
- this.multilingualText += `<p>${items}<p>`;
- });
- } else {
- this.multilingualText += '<p> </p>';
- }
- // this.multilingualText += item.para ? '<p>' + item.para + '<p>' : '<p> </p>';
- });
- if (flag) {
- this.multilingualVisible = true;
- } else {
- this.$message.warning('请先生成分词');
- }
- },
- // 点击插入图片按钮
- picArticle() {
- let verseList = [];
- this.data.detail.forEach((item) => {
- verseList = verseList.concat(item.sentences);
- });
- if (verseList.length > 0) {
- this.showPicArticleFlag = true;
- } else {
- this.$message.warning('请先生成分词');
- }
- },
- // 自动生成音频
- handleAutoAudio() {
- this.autoLoading = true;
- TextToAudioFile({
- text: this.data.content,
- voice_type: this.data.property.voice_type,
- emotion: this.data.property.emotion,
- speed_ratio: this.data.property.speed_ratio,
- })
- .then(({ status, file_id, file_url }) => {
- this.autoLoading = false;
- if (status === 1) {
- this.data.mp3_list = [
- {
- name: '自动生成课文音频.mp3',
- media_duration: 0,
- temporary_url: file_url,
- url: file_id,
- file_id,
- },
- ];
- this.data.file_id_list = [file_id];
- }
- })
- .catch(() => {
- this.autoLoading = false;
- });
- },
- /**
- * 打开校对字幕
- */
- openCheckSubtitles(type, index) {
- this.compareType = type;
- // this.compareData = JSON.parse(JSON.stringify(this.data.wordTime));
- // this.compareShow = true;
- if (this.data.mp3_list.length === 0) {
- return this.$message.warning('请先上传音频文件');
- }
- this.subtitleList = [];
- if (this.compareType === '句子') {
- this.data.wordTime.forEach((item, index) => {
- let obj = {
- content: item.onebest,
- lrc_data: {
- begin_time: item.bg,
- end_time: item.ed,
- },
- };
- this.subtitleList.push(obj);
- });
- } else {
- this.compareIndex = index;
- this.data.wordTime[index].wordsResultList.forEach((item, index) => {
- let obj = {
- content: item.wordsName,
- lrc_data: {
- begin_time: item.wordBg,
- end_time: item.wordEd,
- },
- };
- this.subtitleList.push(obj);
- });
- }
- this.visible = true;
- },
- /**
- * 保存字幕
- * @param {Array} dataList
- */
- saveSubtitles(dataList) {
- if (this.compareType === '句子') {
- this.data.wordTime.forEach((item, index) => {
- item.bg = dataList[index] ? dataList[index].lrc_data.begin_time : 0;
- item.ed = dataList[index] ? dataList[index].lrc_data.end_time : 0;
- });
- } else {
- this.data.wordTime[this.compareIndex].wordsResultList.forEach((item, index) => {
- item.wordBg = dataList[index] ? dataList[index].lrc_data.begin_time : 0;
- item.wordEd = dataList[index] ? dataList[index].lrc_data.end_time : 0;
- });
- }
- },
- selectItem(item) {
- this.itemActive = item;
- this.pinyinList = [];
- toolGetWordPinyinCorrectionList({
- word: item.chs,
- })
- .then((res) => {
- if (res.status === 1) {
- this.pinyinList = res.pinyin_correction_list;
- }
- this.dialogFlag = true;
- })
- .catch(() => {
- this.dialogFlag = true;
- });
- this.checkPinyinInput = '';
- },
- cancleDialog() {
- this.itemActive = null;
- this.checkPinyinInput = '';
- this.oldInput = '';
- this.dialogFlag = false;
- },
- surePinyin() {
- this.oldInput = JSON.parse(JSON.stringify(this.checkPinyinInput.trim()));
- this.handleReplaceTone(this.checkPinyinInput.trim());
- },
- handleReplaceTone(e) {
- let _this = this;
- _this.$nextTick(() => {
- let value = e;
- _this.resArr = [];
- if (value) {
- let valueArr = [];
- value.replace(/\s+/g, ' ');
- valueArr = value.split(' ');
- // let reg = /\s+/g;
- // valueArr = value.split(reg);
- valueArr.forEach((item, index) => {
- if (this.data.pinyin_type === 'tone') {
- this.resArr.push([
- {
- con: this.toneList[Number(item)],
- },
- ]);
- } else {
- this.handleValue(item);
- }
- });
- let str = '';
- setTimeout(() => {
- _this.resArr.forEach((item) => {
- str += ' ';
- item.forEach((sItem) => {
- if (sItem.number && sItem.con) {
- let number = Number(sItem.number);
- let con = sItem.con;
- let word = _this.addTone(number, con);
- str += word;
- } else if (sItem.number) {
- str += sItem.number;
- } else if (sItem.con) {
- str += ` ${sItem.con} `;
- }
- });
- });
- this.checkPinyinInput = str.trim();
- this.itemActive.pinyin = this.checkPinyinInput.replace(/\s+/g, '');
- this.$message.success('保存成功');
- // this.itemActive = null;
- this.checkPinyinInput = '';
- this.oldInput = '';
- this.dialogFlag = false;
- }, 10);
- }
- });
- },
- handleValue(valItem) {
- let reg = /\d/;
- let reg2 = /[A-Za-z]+\d/g;
- let numList = [];
- let valArr = valItem.split('');
- if (reg2.test(valItem)) {
- for (let i = 0; i < valArr.length; i++) {
- let item = valItem[i];
- if (reg.test(item)) {
- let numIndex = numList.length === 0 ? 0 : numList[numList.length - 1].index;
- let con = valItem.substring(numIndex, i);
- con = con.replace(/\d/g, '');
- let obj = {
- index: i,
- number: item,
- con,
- isTran: true,
- };
- numList.push(obj);
- }
- }
- } else {
- numList = [];
- }
- if (numList.length === 0) {
- this.resArr.push([{ con: valItem }]);
- } else {
- this.resArr.push(numList);
- }
- },
- addTone(number, con) {
- let _this = this;
- let zmList = ['a', 'o', 'e', 'i', 'u', 'v', 'A', 'O', 'E', 'I', 'U', 'n', 'm'];
- if (number) {
- for (let i = 0; i < zmList.length; i++) {
- let zm = zmList[i];
- if (con.indexOf(zm) > -1) {
- let zm2 = _this.tableData[i][number - 1];
- if (con.indexOf('iu') > -1) {
- zm2 = _this.tableData[4][number - 1];
- con = con.replace('u', zm2);
- } else if (con.indexOf('ui') > -1) {
- zm2 = _this.tableData[3][number - 1];
- con = con.replace('i', zm2);
- } else if (
- con.indexOf('yv') > -1 ||
- con.indexOf('jv') > -1 ||
- con.indexOf('qv') > -1 ||
- con.indexOf('xv') > -1
- ) {
- zm2 = _this.tableData[4][number - 1];
- con = con.replace('v', zm2);
- } else {
- con = con.replace(zm, zm2);
- }
- break;
- }
- }
- }
- return con;
- },
- // 设置样式
- setActiveTextStyle(type, val) {
- let style = this.data.other_attrib;
- if (type === 'underline') {
- style.isUnderline = style.isUnderline === 'underline' ? '' : 'underline';
- if (style.isUnderline === 'underline') {
- style.isStrikethrough = '';
- }
- this.data.detail.forEach((item) => {
- item.wordsList.forEach((items) => {
- items.forEach((itemss) => {
- itemss.textDecoration = style.isUnderline;
- });
- });
- });
- } else if (type === 'bold') {
- style.isBold = style.isBold === 'bold' ? '' : 'bold';
- this.data.detail.forEach((item) => {
- item.wordsList.forEach((items) => {
- items.forEach((itemss) => {
- itemss.fontWeight = style.isBold;
- });
- });
- });
- } else if (type === 'line-through') {
- style.isStrikethrough = style.isStrikethrough === 'line-through' ? '' : 'line-through';
- if (style.isStrikethrough === 'line-through') {
- style.isUnderline = '';
- }
- this.data.detail.forEach((item) => {
- item.wordsList.forEach((items) => {
- items.forEach((itemss) => {
- itemss.textDecoration = style.isStrikethrough;
- });
- });
- });
- } else if (type === 'border') {
- style.border = style.border === 'dotted' ? '' : 'dotted';
- this.data.detail.forEach((item) => {
- item.wordsList.forEach((items) => {
- items.forEach((itemss) => {
- itemss.border = style.border;
- });
- });
- });
- } else if (type === 'align') {
- style.align = val;
- this.articleAttrib.align = val;
- this.data.detail.forEach((item) => {
- item.paraAlign =
- this.articleAttrib.align === 'RIGHT' ? 'right' : this.articleAttrib.align === 'MIDDLE' ? 'center' : 'left';
- });
- }
- },
- },
- };
- </script>
- <style lang="scss" scoped>
- .article-wrapper {
- display: flex;
- flex-direction: column;
- row-gap: 16px;
- align-items: flex-start;
- }
- .upload-file {
- display: flex;
- column-gap: 12px;
- align-items: center;
- margin: 8px 0;
- .file-name {
- display: flex;
- column-gap: 14px;
- align-items: center;
- justify-content: space-between;
- max-width: 360px;
- padding: 8px 12px;
- font-size: 14px;
- color: #1d2129;
- background-color: #f7f8fa;
- span {
- display: flex;
- column-gap: 14px;
- align-items: center;
- }
- }
- .svg-icon {
- cursor: pointer;
- }
- }
- .btn-box {
- display: flex;
- flex-flow: wrap;
- gap: 10px;
- a {
- padding: 5px 16px;
- font-size: 14px;
- line-height: 22px;
- color: #4e5969;
- cursor: pointer;
- background: #f2f3f5;
- border-radius: 2px;
- }
- p {
- margin: 0;
- }
- }
- .tips {
- margin: 0;
- font-size: 12px;
- color: #e82d2d;
- }
- .tabs-box {
- display: flex;
- column-gap: 12px;
- margin: 12px 0;
- a {
- padding: 5px 16px;
- font-size: 14px;
- font-weight: 400;
- line-height: 22px; /* 157.143% */
- color: #4e5969;
- cursor: pointer;
- border-radius: 100px;
- &.active {
- color: #165dff;
- background: #f2f3f5;
- }
- }
- }
- .text {
- display: flex;
- flex-flow: wrap;
- .text-item {
- padding: 0 1px;
- text-align: center;
- }
- .pinyin {
- display: block;
- font-family: 'PINYIN-B';
- }
- .word {
- display: block;
- }
- }
- .table-rich-toolbar {
- display: flex;
- gap: 5px;
- padding: 5px 0;
- /* align-items: center; */
- :deep .el-form-item--small.el-form-item {
- margin: 0 5px 0 0;
- }
- :deep .el-form-item__label {
- padding-right: 3px;
- }
- > span {
- height: 30px;
- padding: 5px 6px;
- color: #222f3e;
- cursor: pointer;
- border-radius: 5px;
- &:hover {
- background: #cce2fa;
- }
- &.active {
- background: #a6ccf7;
- }
- }
- }
- </style>
- <style lang="scss">
- .article-checkpinyin-dialog {
- .el-dialog__header {
- padding: 0;
- }
- .el-dialog__body {
- padding: 0;
- }
- .el-input__inner {
- text-align: center;
- background: #f3f3f3;
- }
- .check-box {
- padding: 24px;
- background: #fff;
- border-radius: 4px;
- box-shadow: 0 4px 4px 0 rgba(0, 0, 0, 25%);
- .content {
- display: flex;
- align-items: center;
- justify-content: center;
- .words-box {
- color: #000;
- text-align: center;
- .words {
- display: block;
- font-size: 28px;
- font-weight: 400;
- line-height: 40px;
- }
- .pinyin {
- display: block;
- height: 20px;
- font-family: 'League';
- font-size: 20px;
- font-weight: 400;
- line-height: 1;
- }
- }
- }
- .checkPinyinInput {
- margin: 16px 0 8px;
- }
- .tips {
- margin: 0 0 24px;
- font-size: 12px;
- font-weight: 400;
- line-height: 18px;
- color: #a0a0a0;
- }
- .btn-box {
- display: block;
- text-align: right;
- .el-button {
- padding: 2px 12px;
- font-size: 12px;
- line-height: 20px;
- }
- }
- }
- }
- </style>
|