|
|
@@ -14,7 +14,7 @@
|
|
|
:font-size="data?.unified_attrib?.font_size"
|
|
|
:font-family="data?.unified_attrib?.font"
|
|
|
:font-color="data?.unified_attrib?.text_color"
|
|
|
- @handleRichTextBlur="identifyText"
|
|
|
+ @handleRichTextBlur="identifyText(false)"
|
|
|
/>
|
|
|
<div v-if="data.property.fill_type === fillTypeList[1].value" class="select-vocabulary">
|
|
|
<h5 class="title">选词列表:</h5>
|
|
|
@@ -70,7 +70,17 @@
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
- <el-divider v-if="isEnable(data.property.view_pinyin)" content-position="left">拼音效果</el-divider>
|
|
|
+ <el-divider v-if="isEnable(data.property.view_pinyin)" content-position="left">
|
|
|
+ <span>拼音效果</span>
|
|
|
+ <el-button
|
|
|
+ v-show="isEnable(data.property.view_pinyin)"
|
|
|
+ type="text"
|
|
|
+ icon="el-icon-refresh"
|
|
|
+ title="刷新"
|
|
|
+ class="refresh-pinyin-btn"
|
|
|
+ @click.native="handleViewPinyin"
|
|
|
+ />
|
|
|
+ </el-divider>
|
|
|
<template v-if="isEnable(data.property.view_pinyin)">
|
|
|
<div v-for="(item, i) in data.model_essay" :key="i" class="pinyin-text-list">
|
|
|
<template v-for="(li, j) in item">
|
|
|
@@ -146,8 +156,11 @@ export default {
|
|
|
},
|
|
|
},
|
|
|
methods: {
|
|
|
- // 识别文本
|
|
|
- identifyText() {
|
|
|
+ /**
|
|
|
+ * 识别文本中
|
|
|
+ * @param {Boolean} isUpdatePinyin 是否更新拼音,默认为 true
|
|
|
+ */
|
|
|
+ identifyText(isUpdatePinyin = true) {
|
|
|
this.data.answer.answer_list = [];
|
|
|
const content = this.data.content || '';
|
|
|
|
|
|
@@ -166,7 +179,7 @@ export default {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- const splitSource = content.split('\n').map((item) => {
|
|
|
+ const splitSource = content.split(/\n|<br>/).map((item) => {
|
|
|
// rich-fill 和 ___ 均转为统一占位符,交给 splitRichText 处理
|
|
|
return this.splitRichText(
|
|
|
item.replace(/<span[^>]*class="[^"]*rich-fill[^"]*"[^>]*>.*?<\/span>|_{3,}/gi, '###$&###'),
|
|
|
@@ -175,7 +188,7 @@ export default {
|
|
|
|
|
|
this.data.model_essay = splitSource;
|
|
|
|
|
|
- this.handleViewPinyin();
|
|
|
+ if (isUpdatePinyin) this.handleViewPinyin();
|
|
|
},
|
|
|
/**
|
|
|
* 分割富文本
|
|
|
@@ -249,14 +262,32 @@ export default {
|
|
|
* @returns {String} 包含向前两个标签内容中最后一个html标签的内容
|
|
|
*/
|
|
|
setTag(index, parts, content) {
|
|
|
- if (index < 2) return content;
|
|
|
+ let i = index;
|
|
|
+ if (i < 2) return content;
|
|
|
let _content = content;
|
|
|
const isEndWithTag = /<\/[^>]+>$/.test(_content); // 判断是否以标签结尾
|
|
|
let startTag = '';
|
|
|
- const part = parts[index - 2] ?? '';
|
|
|
+ const part = parts[i - 2] ?? '';
|
|
|
+
|
|
|
const tagMatch = part.match(/<[^>]+>/g);
|
|
|
if (tagMatch) {
|
|
|
startTag = tagMatch[tagMatch.length - 1]; // 获取最后一个标签
|
|
|
+ // 如果是 <br> 标签,继续往前找,直到找到非 <br> 标签或者没有标签为止
|
|
|
+
|
|
|
+ while (startTag.toLowerCase() === '<br>') {
|
|
|
+ const prevPart = parts[i - 3] ?? '';
|
|
|
+ const prevTagMatch = prevPart.match(/<[^>]+>/g);
|
|
|
+ if (prevTagMatch === null) {
|
|
|
+ startTag = '';
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if (prevTagMatch) {
|
|
|
+ startTag = prevTagMatch[prevTagMatch.length - 1];
|
|
|
+ i -= 1;
|
|
|
+ } else {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
_content = `${startTag}${_content}`;
|
|
|
if (!isEndWithTag) {
|