|
|
|
@ -6,6 +6,7 @@ import "tinymce/models/dom"; // 特别注意 tinymce 6.0.0 版本之后必须引 |
|
|
|
import "tinymce/themes/silver/theme"; |
|
|
|
import Editor from "@tinymce/tinymce-vue"; // 引入组件 |
|
|
|
import { v4 as uuidv4 } from "uuid"; |
|
|
|
import { ElMessage } from 'element-plus' |
|
|
|
|
|
|
|
let onlyNumber = uuidv4().replaceAll('-','').toString(); //获取唯一编码 |
|
|
|
|
|
|
|
@ -46,17 +47,131 @@ let $emit = defineEmits(["textChange"]); |
|
|
|
|
|
|
|
const tinymceHtml = ref("") |
|
|
|
tinymceHtml.value = props.aftText |
|
|
|
|
|
|
|
const tinymceBox = ref(null) |
|
|
|
|
|
|
|
|
|
|
|
onMounted(() => { |
|
|
|
tinymce.init({}); // 初始化富文本 |
|
|
|
}); |
|
|
|
watch(()=>tinymceHtml.value, (val:any) => { |
|
|
|
$emit('textChange',val); |
|
|
|
}, |
|
|
|
$emit('textChange',val); |
|
|
|
nextTick(()=>{ |
|
|
|
let formulaOne = []; |
|
|
|
let formulaTwo = []; |
|
|
|
tinymceBox.value.childNodes.forEach(element => { |
|
|
|
|
|
|
|
element.childNodes.forEach(child => { |
|
|
|
formulaOne.push(child.innerText?child.innerText:child.data) |
|
|
|
if(child.dataset&&child.dataset.keyid){ |
|
|
|
formulaTwo.push(child.dataset.keyid) |
|
|
|
}else{ |
|
|
|
formulaTwo.push(child.innerText?child.innerText:child.data) |
|
|
|
} |
|
|
|
}) |
|
|
|
}); |
|
|
|
let suanShitwo = formulaTwo.join('').replace(/\s+/g, ""); |
|
|
|
let gongShi ={ |
|
|
|
formulaHtml:tinymceBox.value.innerHTML, |
|
|
|
mathsString:tinymceBox.value.innerText, |
|
|
|
mathsFormula:suanShitwo, |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if(containsNewline(gongShi.mathsString)){ |
|
|
|
errorCondition("条件不允许换行") |
|
|
|
}else if(!gongShi.formulaHtml.startsWith("<p><span")){ |
|
|
|
errorCondition("条件需以蓝色块开头") |
|
|
|
}else if(gongShi.formulaHtml.endsWith("</span></p>")){ |
|
|
|
errorCondition("条件不能以蓝色块结尾") |
|
|
|
}else if(countSpanTags(gongShi.formulaHtml)>1){ |
|
|
|
errorCondition("不允许出现多个蓝色块") |
|
|
|
}else if(!containsSingleComparator(gongShi.mathsFormula)){ |
|
|
|
errorCondition("不存在有效符号") |
|
|
|
}else if(checkEnding(gongShi.mathsFormula)){ |
|
|
|
errorCondition("不能以符号为结尾") |
|
|
|
}else{ |
|
|
|
succCondition() |
|
|
|
} |
|
|
|
}) |
|
|
|
|
|
|
|
}, |
|
|
|
{ deep: true } |
|
|
|
) |
|
|
|
function checkEnding(str: string) { |
|
|
|
const symbols = ['==', '>=', '>', '<=', '<', '!=', '=']; |
|
|
|
const trimmedStr = str.trim(); |
|
|
|
for (let symbol of symbols) { |
|
|
|
if (trimmedStr.endsWith(symbol)) { |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
return false; |
|
|
|
} |
|
|
|
function containsSingleComparator(str: string) { |
|
|
|
// 定义需要检查的运算符 |
|
|
|
const comparators = ['==', '>=', '>', '<=', '<', '!=']; |
|
|
|
let found = false; // 用于标记是否找到运算符 |
|
|
|
let i = 0; // 字符串索引 |
|
|
|
|
|
|
|
while (i < str.length - 1) { // 至少需要两个字符来形成运算符 |
|
|
|
// 遍历每个可能的运算符 |
|
|
|
for (const comparator of comparators) { |
|
|
|
if (str.substr(i, comparator.length) === comparator) { |
|
|
|
// 如果找到了一个运算符 |
|
|
|
if (found) { |
|
|
|
// 如果已经找到了一个运算符,则返回false |
|
|
|
return false; |
|
|
|
} |
|
|
|
found = true; // 标记为已找到 |
|
|
|
// 跳过当前找到的运算符的剩余部分,避免重复检查 |
|
|
|
i += comparator.length - 1; |
|
|
|
break; // 跳出内层循环 |
|
|
|
} |
|
|
|
} |
|
|
|
i++; // 继续检查下一个字符 |
|
|
|
} |
|
|
|
|
|
|
|
// 检查是否只找到了一个运算符 |
|
|
|
return found; |
|
|
|
} |
|
|
|
|
|
|
|
function containsComparator(str: string) { |
|
|
|
if(str.includes("==")||str.includes("!=")||str.includes(">")||str.includes(">=")||str.includes("<")||str.includes("<=")){ |
|
|
|
return true |
|
|
|
}else{ |
|
|
|
return false |
|
|
|
} |
|
|
|
} |
|
|
|
const containsNewline = (str: string) => { |
|
|
|
//console.log("Testing string:", str); // 查看传递给函数的实际字符串 |
|
|
|
return /\n/.test(str); |
|
|
|
}; |
|
|
|
const countSpanTags = (str: string) => { |
|
|
|
// 使用正则表达式匹配所有出现的<span>(不考虑闭合标签或属性) |
|
|
|
const matches = str.match(/<span\b[^>]*>/gi); |
|
|
|
// 如果matches是null,表示没有找到匹配项,返回0 |
|
|
|
// 否则,返回匹配项数组的长度 |
|
|
|
return matches ? matches.length : 0; |
|
|
|
}; |
|
|
|
function succCondition(){ |
|
|
|
ElMessage.closeAll() |
|
|
|
ElMessage({ |
|
|
|
showClose: true, |
|
|
|
message: '条件格式校验通过', |
|
|
|
type: 'success', |
|
|
|
duration:3500, |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
function errorCondition(str:string){ |
|
|
|
ElMessage.closeAll() |
|
|
|
ElMessage({ |
|
|
|
showClose: true, |
|
|
|
message: '条件格式错误 : '+str+' , 正确条件格式如 : 年龄==10', |
|
|
|
type: 'error', |
|
|
|
duration:3500, |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const addIcon = (currentObject:any) =>{ |
|
|
|
@ -83,6 +198,7 @@ const focusEditor = ()=>{ |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
defineExpose({ |
|
|
|
tinymceHtml, |
|
|
|
addIcon, |
|
|
|
@ -96,12 +212,20 @@ defineExpose({ |
|
|
|
</script> |
|
|
|
<template > |
|
|
|
<div > |
|
|
|
<editor :id="onlyNumber" v-model="tinymceHtml" :init="tinymceInit"></editor> |
|
|
|
<editor :id="onlyNumber" v-model="tinymceHtml" :init="tinymceInit" ></editor> |
|
|
|
</div> |
|
|
|
<div class="isHidde"> |
|
|
|
<div ref="tinymceBox" v-html="tinymceHtml"> </div> |
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
</template> |
|
|
|
|
|
|
|
<style lang='scss' scoped> |
|
|
|
|
|
|
|
.isHidde{ |
|
|
|
display:none; |
|
|
|
position: fixed; |
|
|
|
z-index: 1; |
|
|
|
margin-top: -10px |
|
|
|
} |
|
|
|
</style> |
|
|
|
|