You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
411 lines
12 KiB
411 lines
12 KiB
<!--
|
|
@ 作者: 秦东
|
|
@ 时间: 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>
|
|
|