3 changed files with 634 additions and 392 deletions
@ -0,0 +1,413 @@ |
|||
<!-- |
|||
@ 作者: 秦东 |
|||
@ 时间: 2023-12-11 13:28:37 |
|||
@ 备注: 模拟计算公式编辑器 |
|||
--> |
|||
<template> |
|||
|
|||
<el-dialog |
|||
v-model="isShow" |
|||
title="公式编辑" |
|||
width="800px" |
|||
:before-close="handleClose" |
|||
> |
|||
<div>目标字段 =</div> |
|||
<el-row :gutter="20"> |
|||
<el-col :span="16"> |
|||
<editor ref="hjks" id="tinymce" v-model="tinymceHtml" :init="tinymceInit"></editor> |
|||
</el-col> |
|||
<el-col :span="8"> |
|||
<el-row> |
|||
<el-col :span="6"> |
|||
<el-button plain class="butkey" @click="computeNumber('(')">(</el-button> |
|||
</el-col> |
|||
<el-col :span="6"> |
|||
<el-button plain class="butkey" @click="computeNumber(')')">)</el-button> |
|||
</el-col> |
|||
<el-col :span="6"> |
|||
<el-button plain class="butkey" @click="computeNumber('C')">C</el-button> |
|||
</el-col> |
|||
<el-col :span="6"> |
|||
<el-button plain class="butkey" @click="computeNumber('+')">+</el-button> |
|||
</el-col> |
|||
<el-col :span="6"> |
|||
<el-button plain class="butkey" @click="computeNumber('1')">1</el-button> |
|||
</el-col> |
|||
<el-col :span="6"> |
|||
<el-button plain class="butkey" @click="computeNumber('2')">2</el-button> |
|||
</el-col> |
|||
<el-col :span="6"> |
|||
<el-button plain class="butkey" @click="computeNumber('3')">3</el-button> |
|||
</el-col> |
|||
<el-col :span="6"> |
|||
<el-button plain class="butkey" @click="computeNumber('-')">-</el-button> |
|||
</el-col> |
|||
<el-col :span="6"> |
|||
<el-button plain class="butkey" @click="computeNumber('4')">4</el-button> |
|||
</el-col> |
|||
<el-col :span="6"> |
|||
<el-button plain class="butkey" @click="computeNumber('5')">5</el-button> |
|||
</el-col> |
|||
<el-col :span="6"> |
|||
<el-button plain class="butkey" @click="computeNumber('6')">6</el-button> |
|||
</el-col> |
|||
<el-col :span="6"> |
|||
<el-button plain class="butkey" @click="computeNumber('*')">×</el-button> |
|||
</el-col> |
|||
<el-col :span="6"> |
|||
<el-button plain class="butkey" @click="computeNumber('7')">7</el-button> |
|||
</el-col> |
|||
<el-col :span="6"> |
|||
<el-button plain class="butkey" @click="computeNumber('8')">8</el-button> |
|||
</el-col> |
|||
<el-col :span="6"> |
|||
<el-button plain class="butkey" @click="computeNumber('9')">9</el-button> |
|||
</el-col> |
|||
<el-col :span="6"> |
|||
<el-button plain class="butkey" @click="computeNumber('/')">÷</el-button> |
|||
</el-col> |
|||
<el-col :span="6"> |
|||
<el-button plain class="butkey" @click="computeNumber('%')">%</el-button> |
|||
</el-col> |
|||
<el-col :span="6"> |
|||
<el-button plain class="butkey" @click="computeNumber('0')">0</el-button> |
|||
</el-col> |
|||
<el-col :span="6"> |
|||
<el-button plain class="butkey" @click="computeNumber('.')">.</el-button> |
|||
</el-col> |
|||
|
|||
<el-col :span="6"> |
|||
<el-button plain class="butkey" @click="computeNumber('=')">=</el-button> |
|||
</el-col> |
|||
</el-row> |
|||
</el-col> |
|||
</el-row> |
|||
|
|||
|
|||
<el-row> |
|||
<el-col :span="4"> |
|||
<el-button type="primary" @click="testAndVerify">校验公式</el-button> |
|||
</el-col> |
|||
<el-col :span="16">{{suanShitwo}}</el-col> |
|||
<el-col :span="4"></el-col> |
|||
</el-row> |
|||
|
|||
<div class="tipBox">{{ errorMsg }}</div> |
|||
<el-row :gutter="10"> |
|||
<el-col :span="6"> |
|||
<div class="colBox"> |
|||
<div class="colBoxTitle">当前表单字段</div> |
|||
<div class="colBoxContent"> |
|||
|
|||
<el-collapse v-model="fieldCurCollapse"> |
|||
|
|||
<el-collapse-item v-for="(group,group_idx) in fieldList" :key="group_idx" :title="group.name" :name="group.id"> |
|||
<div v-for="(i,idx) in group.children" :key="idx" class="item" @mouseenter="itemMouseenter(i)" @mouseleave="itemMouseleave" @click="addTag(i,'field')"> |
|||
<div class="name">{{i.name}}</div> |
|||
<div class="type" :style="typeColors.find(x=>x.name==i.dataType)?.typeStyle"> |
|||
{{i.dataTypeName}} |
|||
</div> |
|||
</div> |
|||
</el-collapse-item> |
|||
</el-collapse> |
|||
|
|||
|
|||
</div> |
|||
</div> |
|||
</el-col> |
|||
<el-col :span="6"> |
|||
<div class="colBox"> |
|||
<div class="colBoxTitle">函数列表</div> |
|||
<div class="colBoxContent"> |
|||
|
|||
<el-collapse v-model="funcCurCollapse"> |
|||
|
|||
<el-collapse-item v-for="(group,group_idx) in funcList" :key="group_idx" :title="group.name" :name="group.id"> |
|||
<div v-for="(i,idx) in group.children" :key="idx" class="item" @mouseenter="itemMouseenter(i)" @mouseleave="itemMouseleave" @click="addTag(i,'func')"> |
|||
<div class="name">{{i.name}}</div> |
|||
<div class="type" :style="typeColors.find(x=>x.name==i.dataType)?.typeStyle"> |
|||
{{i.dataTypeName}} |
|||
</div> |
|||
</div> |
|||
</el-collapse-item> |
|||
</el-collapse> |
|||
|
|||
|
|||
</div> |
|||
</div> |
|||
</el-col> |
|||
<el-col :span="12"> |
|||
<div class="colBox"> |
|||
<div class="colBoxTitle">说明</div> |
|||
<div class="colBoxContent"> |
|||
|
|||
<div class="mathMsg"> |
|||
<div v-html="descContent"> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</el-col> |
|||
</el-row> |
|||
|
|||
{{tinymceHtml}} |
|||
<hr /> |
|||
{{ removeHTMLTag(tinymceHtml) }} |
|||
<div ref="tinymceBox" v-html="tinymceHtml"> </div> |
|||
<template #footer> |
|||
<span class="dialog-footer"> |
|||
<el-button @click="isShow = false">关闭</el-button> |
|||
<el-button type="primary" @click="isShow = false">确定</el-button> |
|||
|
|||
</span> |
|||
</template> |
|||
</el-dialog> |
|||
</template> |
|||
<script lang='ts' setup> |
|||
import { ref, onMounted } from "vue"; |
|||
import typeColors from "./unitcss"; |
|||
import { fieldList,funcList } from "./mathFunction" |
|||
/** |
|||
* 富文本组件 |
|||
*/ |
|||
import tinymce from "tinymce/tinymce"; |
|||
import "tinymce/models/dom"; // 特别注意 tinymce 6.0.0 版本之后必须引入,否则不显示 |
|||
import "tinymce/themes/silver/theme"; |
|||
import Editor from "@tinymce/tinymce-vue"; // 引入组件 |
|||
/** |
|||
* 初始富文本组件 |
|||
*/ |
|||
const tinymceInit = { |
|||
language_url: "/tinymce/langs/zh-Hans.js", // 引入语言包(该语言包在public下,注意文件名称) |
|||
language: "zh-Hans", // 这里名称根据 zh-Hans.js 里面写的名称而定 |
|||
skin_url: "/tinymce/skins/ui/oxide", // 这里引入的样式 |
|||
height: 260, // 限制高度 |
|||
statusbar:false, |
|||
toolbar:false, |
|||
branding: false, //是否禁用“Powered by TinyMCE” |
|||
menubar: false, //顶部菜单栏显示 |
|||
forced_root_block:'', |
|||
newline_behavior:"", |
|||
content_css: "/tinymce/skins/content/default/content.css", //以css文件方式自定义可编辑区域的css样式,css文件需自己创建并引入 |
|||
} |
|||
onMounted(() => { |
|||
tinymce.init({}); // 初始化富文本 |
|||
console.log("funcList",funcListw) |
|||
}); |
|||
const errorMsg = ref("") //错误信息 |
|||
const tinymceHtml = ref("") |
|||
let fieldCurCollapse = ref(""); |
|||
let funcCurCollapse = ref(""); |
|||
const funcListw = ref(funcList); |
|||
const descContent = ref(""); //函数说明 |
|||
const isShow = ref(true) |
|||
|
|||
const hjks = ref<any>(null) |
|||
|
|||
const tinymceBox = ref(null) |
|||
//数学函数说明操作 |
|||
const itemMouseenter = (item) => { |
|||
descContent.value = item.desc; |
|||
}; |
|||
const itemMouseleave = () => { |
|||
descContent.value = ""; |
|||
}; |
|||
|
|||
//添加数据标签 |
|||
const addTag = (data:any,type:string) => { |
|||
console.log("tinymce----->",hjks); |
|||
|
|||
let viewStyle = type == "field" ? typeColors.find((x) => x.name == data.dataType)?.viewStyle : typeColors.find((x) => x.name == "func")?.viewStyle; |
|||
let viewStyleStr = "margin:0 5px;"; |
|||
Object.keys(viewStyle).map((key) => { |
|||
let keyStr = key.replace(/([A-Z])/g, "-$1").toLowerCase(); |
|||
viewStyleStr += `${keyStr}:${viewStyle[key]};`; |
|||
}); |
|||
if (type == "field") { |
|||
tinymce.activeEditor.execCommand('mceInsertContent', false, `<span style="${viewStyleStr}" contenteditable="false" data-keyid="${data.id}">${data.name}</span>`); |
|||
}else{ |
|||
tinymce.activeEditor.execCommand('mceInsertContent', false, `<span class="hanshu" style="${viewStyleStr}" contenteditable="false">${data.name}</span><span class="exp" style="${viewStyleStr}" contenteditable="false">(</span><span class="exp" style="${viewStyleStr}" contenteditable="false">)</span>`); |
|||
} |
|||
|
|||
// nextTick(()=>{ |
|||
|
|||
|
|||
// }) |
|||
|
|||
|
|||
// console.log("tinymceBox--3--->",fsdf); |
|||
// if(tinymceBox.value.childNodes.length >=0){ |
|||
// tinymceBox.value.childNodes.forEach(element =>{ |
|||
// console.log("tinymceBox---4-->",element.value.childNodes); |
|||
// }) |
|||
// } |
|||
|
|||
} |
|||
const suanShioen = ref<any[]>() |
|||
const suanShitwo = ref<any[]>() |
|||
//验证公式 |
|||
const testAndVerify = () => { |
|||
let pattern = "(<p>)(.*)(<\/p>)"; |
|||
|
|||
console.log("tinymceBox----->",tinymceBox); |
|||
console.log("tinymceBox--1--->",tinymceBox.value.innerHTML); |
|||
console.log("tinymceBox--2--->",tinymceBox.value.innerText); |
|||
console.log("tinymceBox--3--->",tinymceBox.value); |
|||
let fsdf = tinymceBox.value.innerHTML.match(pattern); |
|||
console.log("tinymceBox--4--->",fsdf,fsdf[2]); |
|||
|
|||
console.log("tinymceBox--5--->",tinymceBox.value.childNodes); |
|||
let formulaOne = []; |
|||
let formulaTwo = []; |
|||
tinymceBox.value.childNodes.forEach(element => { |
|||
console.log("element----->",element.childNodes); |
|||
element.childNodes.forEach(child => { |
|||
console.log("child--classList--->",child.classList); |
|||
console.log("child----->",child.innerText,child.data); |
|||
formulaOne.push(child.innerText?child.innerText:child.data) |
|||
|
|||
if(child.dataset&&child.dataset.keyid){ |
|||
console.log("child.dataset--222222--->",child.dataset.keyid); |
|||
formulaTwo.push(child.dataset.keyid) |
|||
}else{ |
|||
formulaTwo.push(child.innerText?child.innerText:child.data) |
|||
} |
|||
|
|||
// if(child.classList){ |
|||
// formulaTwo.push(child.innerHTML) |
|||
// if(child.classList.value == "hanshu" || child.classList.value == "exp"){ |
|||
// formulaOne.push(child.innerHTML) |
|||
// } |
|||
// if(child.dataset && child.dataset.key){ |
|||
// formulaTwo.push(child.dataset.keyid) |
|||
// } |
|||
// }else{ |
|||
// formulaOne.push(child.data) |
|||
// formulaTwo.push(child.data) |
|||
// } |
|||
|
|||
|
|||
}) |
|||
|
|||
|
|||
}); |
|||
console.log("formulaOne------>",formulaOne); |
|||
console.log("formulaTwo",formulaTwo); |
|||
suanShioen.value = formulaOne.join('').replace(/\s+/g, ""); |
|||
suanShitwo.value = formulaTwo.join('').replace(/\s+/g, ""); |
|||
console.log("suanShioen",suanShioen.value); |
|||
console.log("suanShitwo",suanShitwo.value); |
|||
} |
|||
|
|||
|
|||
|
|||
// watch(tinymceBox,() => { |
|||
// console.log("tinymceBox--见识--->",tinymceBox); |
|||
// },{ deep:true, immediate: true }) |
|||
|
|||
const removeHTMLTag = (str:any) => { |
|||
// str = str.replace(/<\/?[^>]*>/g, ""); //去除HTML tag |
|||
// str = str.replace(/[ | ]*\n/g, "\n"); //去除行尾空白 |
|||
// str = str.replace(/\n[\s| | ]*\r/g, "\n"); //去除多余空行 |
|||
// str = str.replace(/ /gi, ""); //去掉 |
|||
return str; |
|||
} |
|||
/** |
|||
* 计算器 |
|||
*/ |
|||
const computeNumber = (val:string) =>{ |
|||
if(val === "C"){ |
|||
tinymceHtml.value = ""; |
|||
}else{ |
|||
tinymce.activeEditor.execCommand('mceInsertContent', false, val); |
|||
} |
|||
|
|||
} |
|||
</script> |
|||
<style lang='scss' scoped> |
|||
.butkey{ |
|||
width:45px; |
|||
height:40px; |
|||
margin-bottom:15px; |
|||
} |
|||
.tipBox{ |
|||
width:100%; |
|||
height:30px; |
|||
line-height:30px; |
|||
} |
|||
.el-row { |
|||
// margin-top: 20px; |
|||
} |
|||
.yincnag{ |
|||
display:none; |
|||
} |
|||
.tox-tinymce{ |
|||
border-radius: 0px; |
|||
} |
|||
.colBox{ |
|||
border: 1px solid #eee; |
|||
border-radius: 0px; |
|||
.colBoxTitle{ |
|||
width:100%; |
|||
line-height:35px; |
|||
border-bottom: 1px solid #eee; |
|||
padding-left: 15px; |
|||
} |
|||
.colBoxContent{ |
|||
width:100%; |
|||
height:300px; |
|||
overflow: hidden; |
|||
overflow-y: auto; |
|||
.item { |
|||
display: flex; |
|||
align-items: center; |
|||
margin: 8px 0; |
|||
padding: 0 8px; |
|||
.name { |
|||
color: #000; |
|||
font-weight: 700; |
|||
|
|||
} |
|||
.type { |
|||
min-width: 50px; |
|||
padding: 1px 5px; |
|||
border-radius: 5px; |
|||
color: #fff; |
|||
margin-left: auto; |
|||
font-weight: 700; |
|||
text-align: center; |
|||
} |
|||
} |
|||
} |
|||
.mathMsg{ |
|||
text-align: left; |
|||
padding:10px 15px; |
|||
ul { |
|||
list-style-type: circle; |
|||
li{ |
|||
cursor: pointer; |
|||
.info { |
|||
font-weight: 700; |
|||
color: #4a538a; |
|||
} |
|||
.example { |
|||
font-weight: 700; |
|||
.func { |
|||
color: #871ab3; |
|||
} |
|||
.param { |
|||
background: #1e87b6; |
|||
color: #fff; |
|||
padding: 3px 5px; |
|||
border-radius: 3px; |
|||
margin: 0px 5px; |
|||
} |
|||
} |
|||
} |
|||
|
|||
} |
|||
} |
|||
} |
|||
|
|||
</style> |
|||
|
|||
Loading…
Reference in new issue