|
@@ -0,0 +1,422 @@
|
|
|
+function isFormulaItem(ele) {
|
|
|
+ return ele.type == 'Element' || ele.type == 'ParamData'
|
|
|
+}
|
|
|
+
|
|
|
+function parseFormula(arr, resultFormula, processFormula, isAllFun) {
|
|
|
+ let tmpArr = []//放置这一层的数组
|
|
|
+ for (let i = 0; i < arr.length; i++) {
|
|
|
+ tmpArr.push(arr[i])
|
|
|
+ if (arr[i].type != 'Function') {
|
|
|
+ isAllFun = false
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (isAllFun) {
|
|
|
+ for (let i = 0; i < tmpArr.length; i++) {
|
|
|
+ parseArguments(resultFormula[0], tmpArr[i])
|
|
|
+ parseFormula(arr[i].children, resultFormula, processFormula, isAllFun)
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ for (let j = 0; j < tmpArr.length; j++) {
|
|
|
+ let data = tmpArr[j]
|
|
|
+ if (data.type == 'Function') {
|
|
|
+ let obj = {
|
|
|
+ children: [],
|
|
|
+ name: '临时占位',
|
|
|
+ selected: false,
|
|
|
+ type: 'Element',
|
|
|
+ }
|
|
|
+ parseProcessFormula(arr[j], obj)
|
|
|
+ processFormula.push(Object.assign({}, obj))
|
|
|
+ delete obj.children
|
|
|
+ } else if (data.name) {
|
|
|
+ processFormula.push(data)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+//解析方法里面的参数
|
|
|
+function parseArguments(ele, funObj) {
|
|
|
+ let fcReg = /(FC\.\S+\()(.+)\)/
|
|
|
+ let fun = {
|
|
|
+ example: funObj.example,
|
|
|
+ name: funObj.name,
|
|
|
+ template: funObj.template,
|
|
|
+ }
|
|
|
+ //特殊公式需要number
|
|
|
+ if (funObj.number) {
|
|
|
+ fun.number = funObj.number
|
|
|
+ }
|
|
|
+ let argTextArr = funObj.children//放参数文本的数组
|
|
|
+
|
|
|
+ //根据逗号位置分割参数
|
|
|
+ let index = 0
|
|
|
+ let argSpliceArr = [[]]
|
|
|
+ while (index < argTextArr.length) {
|
|
|
+ if (argTextArr[index].type == 'Comma') {
|
|
|
+ argSpliceArr.push([])
|
|
|
+ } else {
|
|
|
+ argSpliceArr[argSpliceArr.length - 1].push(argTextArr[index])
|
|
|
+ }
|
|
|
+ index++
|
|
|
+ }
|
|
|
+
|
|
|
+ fun.arguments = []
|
|
|
+
|
|
|
+ if (funObj.template != null && funObj.template != undefined) {
|
|
|
+ let tmpArr = fcReg.exec(funObj.template.ft)
|
|
|
+ let argList = tmpArr[2].split(',')//括号里面参数部分#1,#2..
|
|
|
+
|
|
|
+ argList.forEach((argText, index) => {
|
|
|
+ //只用动态的
|
|
|
+ if (argText.indexOf('#') > -1 || /^[A-Z]+$/.test(argText)) {
|
|
|
+ if (argSpliceArr[index].length > 1) {
|
|
|
+ if (fun.name == '判断') {
|
|
|
+ fun.arguments.push(ifFunArgumentsHandle(argSpliceArr[index]))
|
|
|
+ } else {
|
|
|
+ //是前面的计算结果
|
|
|
+ fun.arguments.push(ele)
|
|
|
+ }
|
|
|
+
|
|
|
+ } else {
|
|
|
+ let arg = argSpliceArr[index][0]
|
|
|
+ if (!arg) {
|
|
|
+ fun.arguments.push(undefined)
|
|
|
+ } else if (arg.type == 'Element') {
|
|
|
+ fun.arguments.push(arg)
|
|
|
+ } else if (arg.type == 'ParamData') {
|
|
|
+ fun.arguments.push(arg)
|
|
|
+ } else if (arg.type == 'Function') {
|
|
|
+ fun.arguments.push(ele)
|
|
|
+ } else if (arg.type == 'Text') {
|
|
|
+ fun.arguments.push(arg.tag)
|
|
|
+ } else {
|
|
|
+ fun.arguments.push(undefined)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ ele.children.push(fun)
|
|
|
+}
|
|
|
+
|
|
|
+function parseProcessFormula(funObj, ele) {
|
|
|
+ parseArguments(ele, funObj)
|
|
|
+ let inFun = false//是不是有Function
|
|
|
+ let endEle = null//认为最下面一层第一个元素是显示的元素
|
|
|
+ for (let i = 0; i < funObj.children.length; i++) {
|
|
|
+ if (funObj.children[i].type == 'Function') {
|
|
|
+ parseProcessFormula(funObj.children[i], ele)
|
|
|
+ inFun = true
|
|
|
+ } else if (isFormulaItem(funObj.children[i]) && !endEle) {
|
|
|
+ endEle = funObj.children[i]
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!inFun) {
|
|
|
+ //把临时的属性改为最终找到的
|
|
|
+ if (endEle.type == 'Element') {
|
|
|
+ ele.id = endEle.id
|
|
|
+ ele.name = endEle.name
|
|
|
+ ele.tableElementKey = endEle.tableElementKey
|
|
|
+ } else if (endEle.type == 'ParamData') {
|
|
|
+ ele.id = endEle.id
|
|
|
+ ele.name = endEle.name
|
|
|
+ ele.v = endEle.v
|
|
|
+ ele.k = endEle.k
|
|
|
+ ele.type = 'ParamData'
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+//处理if方法的参数
|
|
|
+function ifFunArgumentsHandle(argArr) {
|
|
|
+ let arr = []
|
|
|
+
|
|
|
+ argArr.forEach((Element) => {
|
|
|
+ if (Element.type == 'Text' || Element.type == 'Logical') {
|
|
|
+ arr.push(Element.tag)
|
|
|
+ } else {
|
|
|
+ if (Element.type == 'Function') {
|
|
|
+ let rootObj = { root: null }
|
|
|
+ getRootElement(Element.children, rootObj)
|
|
|
+ arr.push(rootObj.root)
|
|
|
+ } else {
|
|
|
+ arr.push(Element)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ return arr
|
|
|
+}
|
|
|
+
|
|
|
+//获取嵌套里面根节点元素,认为是if显示的元素
|
|
|
+function getRootElement(children, rootObj) {
|
|
|
+ let inFun = false//是不是有Function
|
|
|
+ let endEle = null//认为最下面一层第一个元素是显示的元素
|
|
|
+ children.forEach((Element) => {
|
|
|
+ if (Element.type == 'Function') {
|
|
|
+ getRootElement(Element.children, rootObj)
|
|
|
+ inFun = true
|
|
|
+ } else if (isFormulaItem(Element) && !endEle) {
|
|
|
+ endEle = Element
|
|
|
+ }
|
|
|
+ })
|
|
|
+ if (!inFun) {
|
|
|
+ //把临时的属性改为最终找到的
|
|
|
+ rootObj.root = Object.assign({}, endEle)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+export const formulaStringToArray = (text, elemap, formulaMap) => {
|
|
|
+// debugger
|
|
|
+ // 匹配开始的FC.xxx(
|
|
|
+ const startFCRegExp = /^FC\.([a-zA-Z0-9]+)\(/
|
|
|
+ const startBracketsReg = /^\(///左括号
|
|
|
+ const endBracketsReg = /^\)///右括号
|
|
|
+ //const elementReg = /^E\[(.[^\]]+_.[^\]]+)\]/;//元素
|
|
|
+ const elementReg = /^E\[([^\]]+)\]///元素
|
|
|
+ const paramReg = /^WP\[(.[^\]]+)\]///节点参数
|
|
|
+ const commaReg = /^,///逗号
|
|
|
+ const operatorReg = /^ (\+|-|\*|%|\/) ///加减乘除
|
|
|
+ // const wordReg = /^[\u4e00-\u9fa5\w0-9'"-]+/;//文本
|
|
|
+ const wordReg = /^[\u4e00-\u9fa5\{\}\w\\.0-9'"-]+///文本
|
|
|
+
|
|
|
+
|
|
|
+ const logicalReg = /^(>=|<=|>|<|=|&&)///逻辑符号
|
|
|
+
|
|
|
+ let elementMap = JSON.parse(elemap)//元素字典
|
|
|
+
|
|
|
+ let resArr = []//结果数组
|
|
|
+ let strIndex = 0//位置索引
|
|
|
+ let nuText = text//未处理的字符串
|
|
|
+ //let startStack = [];//方法体开始部分和左括号 放进来的栈
|
|
|
+ let contentStack = []//内容放进来的栈
|
|
|
+
|
|
|
+ while (strIndex < text.length) {
|
|
|
+ nuText = text.substring(strIndex)
|
|
|
+ if (startFCRegExp.test(nuText)) {
|
|
|
+ //匹配FC开始部分FC.xxx(
|
|
|
+ let regRes = nuText.match(startFCRegExp)
|
|
|
+ let startText = regRes[0]//匹配到的文本
|
|
|
+
|
|
|
+ let obj = {}
|
|
|
+ if (formulaMap[startText]) {
|
|
|
+ Object.assign(obj, formulaMap[startText])
|
|
|
+ Object.assign(obj, {
|
|
|
+ type: 'Function',
|
|
|
+ children: [],
|
|
|
+ tag: startText,
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ obj = {
|
|
|
+ type: 'Function',
|
|
|
+ children: [],
|
|
|
+ tag: startText,
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //startStack.push(startText);
|
|
|
+ contentStack.push(obj)
|
|
|
+
|
|
|
+ strIndex += startText.length//索引移动
|
|
|
+ } else if (endBracketsReg.test(nuText)) {
|
|
|
+ //匹配右括号
|
|
|
+ let endBrackets = nuText.match(endBracketsReg)[0]
|
|
|
+
|
|
|
+ let popObj = contentStack.pop()
|
|
|
+ let arrType = []
|
|
|
+
|
|
|
+ if (contentStack.length > 0) {
|
|
|
+ let content = contentStack[contentStack.length - 1]
|
|
|
+ content.children.push(popObj)
|
|
|
+ arrType = content.children
|
|
|
+ } else {
|
|
|
+ //匹配完成最顶层的一整个方法体,或括号
|
|
|
+ resArr.push(popObj)
|
|
|
+ arrType = resArr
|
|
|
+ }
|
|
|
+
|
|
|
+ if (popObj.type == 'Brackets') {
|
|
|
+ let brackArr = []
|
|
|
+ //如果是括号,把括号里面的提出一层
|
|
|
+ popObj.children.forEach((ele) => {
|
|
|
+ brackArr.push(ele)
|
|
|
+ })
|
|
|
+ //补个右括号
|
|
|
+ brackArr.push({
|
|
|
+ type: 'Brackets',
|
|
|
+ selected: false,
|
|
|
+ name: ')',
|
|
|
+ })
|
|
|
+ arrType.push(...brackArr)
|
|
|
+ delete popObj.children
|
|
|
+ }
|
|
|
+
|
|
|
+ strIndex += endBrackets.length//索引移动
|
|
|
+ } else if (startBracketsReg.test(nuText)) {
|
|
|
+ //匹配左括号
|
|
|
+ let startBrackets = nuText.match(startBracketsReg)[0]
|
|
|
+
|
|
|
+ contentStack.push({
|
|
|
+ type: 'Brackets',
|
|
|
+ children: [],
|
|
|
+ selected: false,
|
|
|
+ name: startBrackets,
|
|
|
+ tag: startBrackets,
|
|
|
+ })
|
|
|
+
|
|
|
+ strIndex += startBrackets.length//索引移动
|
|
|
+ } else if (elementReg.test(nuText)) {
|
|
|
+ //匹配元素
|
|
|
+ let eleArr = nuText.match(elementReg)
|
|
|
+ let obj = {}
|
|
|
+ if (elementMap[eleArr[1]]) {
|
|
|
+ Object.assign(obj, elementMap[eleArr[1]])
|
|
|
+ Object.assign(obj, {
|
|
|
+ selected: false,
|
|
|
+ children: [],
|
|
|
+ tag: eleArr[0],
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ obj = {
|
|
|
+ type: 'Element',
|
|
|
+ name: eleArr[1].split('_')[1],
|
|
|
+ tableElementKey: eleArr[1],
|
|
|
+ children: [],
|
|
|
+ selected: false,
|
|
|
+ tag: eleArr[0],
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ let content = contentStack[contentStack.length - 1]
|
|
|
+ if (content) {
|
|
|
+ content.children.push(obj)
|
|
|
+ } else {
|
|
|
+ //如果没有,那就是在最上层
|
|
|
+ resArr.push(obj)
|
|
|
+ }
|
|
|
+
|
|
|
+ strIndex += eleArr[0].length//索引移动
|
|
|
+ } else if (paramReg.test(nuText)) {
|
|
|
+ //匹配节点参数
|
|
|
+ let eleArr = nuText.match(paramReg)
|
|
|
+ let obj = {}
|
|
|
+ if (elementMap[eleArr[1]]) {
|
|
|
+ Object.assign(obj, elementMap[eleArr[1]])
|
|
|
+ Object.assign(obj, {
|
|
|
+ selected: false,
|
|
|
+ children: [],
|
|
|
+ tag: 'paramData',
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ obj = {
|
|
|
+ type: 'ParamData',
|
|
|
+ name: elementMap[eleArr[1]].name,
|
|
|
+ v: elementMap[eleArr[1]].v,
|
|
|
+ k: elementMap[eleArr[1]].k,
|
|
|
+ children: [],
|
|
|
+ selected: false,
|
|
|
+ tag: 'paramData',
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ let content = contentStack[contentStack.length - 1]
|
|
|
+ if (content) {
|
|
|
+ content.children.push(obj)
|
|
|
+ } else {
|
|
|
+ //如果没有,那就是在最上层
|
|
|
+ resArr.push(obj)
|
|
|
+ }
|
|
|
+
|
|
|
+ strIndex += eleArr[0].length//索引移动
|
|
|
+ } else if (commaReg.test(nuText)) {
|
|
|
+ //匹配逗号
|
|
|
+ let comma = nuText.match(commaReg)[0]
|
|
|
+
|
|
|
+ contentStack[contentStack.length - 1].children.push({
|
|
|
+ type: 'Comma',
|
|
|
+ tag: comma,
|
|
|
+ })
|
|
|
+
|
|
|
+ strIndex += comma.length//索引移动
|
|
|
+ } else if (logicalReg.test(nuText)) {
|
|
|
+ let logical = nuText.match(logicalReg)[0]
|
|
|
+
|
|
|
+ contentStack[contentStack.length - 1].children.push({
|
|
|
+ type: 'Logical',
|
|
|
+ tag: logical,
|
|
|
+ })
|
|
|
+
|
|
|
+ strIndex += logical.length//索引移动
|
|
|
+
|
|
|
+ } else if (operatorReg.test(nuText)) {
|
|
|
+ //匹配加减乘除
|
|
|
+ let operator = nuText.match(operatorReg)[0]
|
|
|
+ let obj = {
|
|
|
+ type: 'Operator',
|
|
|
+ name: operator,
|
|
|
+ selected: false,
|
|
|
+ tag: operator,
|
|
|
+ }
|
|
|
+ if (formulaMap[operator]) {
|
|
|
+ obj.example = formulaMap[operator].example
|
|
|
+ obj.template = formulaMap[operator].template
|
|
|
+ }
|
|
|
+
|
|
|
+ if (contentStack.length > 0) {
|
|
|
+ //不然就在方法体或括号里面
|
|
|
+ contentStack[contentStack.length - 1].children.push(obj)
|
|
|
+ } else {
|
|
|
+ //如果没有,那就是在最上层
|
|
|
+ resArr.push(obj)
|
|
|
+ }
|
|
|
+
|
|
|
+ strIndex += operator.length//索引移动
|
|
|
+ } else if (wordReg.test(nuText)) {
|
|
|
+ //匹配文本
|
|
|
+ let word = nuText.match(wordReg)[0]
|
|
|
+ if (word == '\'\'') {
|
|
|
+ word = ''
|
|
|
+ }
|
|
|
+
|
|
|
+ let obj = {
|
|
|
+ type: 'Text',
|
|
|
+ tag: word,
|
|
|
+ }
|
|
|
+
|
|
|
+ let content = contentStack[contentStack.length - 1]
|
|
|
+ if (content) {
|
|
|
+ content.children.push(obj)
|
|
|
+ } else {
|
|
|
+ //如果没有,那就是在最上层
|
|
|
+ obj.name = word
|
|
|
+ obj.selected = false
|
|
|
+ resArr.push(obj)
|
|
|
+ }
|
|
|
+
|
|
|
+ strIndex += word.length ? word.length : 2//索引移动
|
|
|
+ } else {
|
|
|
+ //匹配不到
|
|
|
+ strIndex++
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ let resultFormula = [{
|
|
|
+ children: [],
|
|
|
+ name: '临时占位',
|
|
|
+ selected: false,
|
|
|
+ type: 'Element',
|
|
|
+ }]
|
|
|
+
|
|
|
+ let processFormula = []
|
|
|
+ let isAllFun = true//一层全是方法,有其他说明到了显示层
|
|
|
+
|
|
|
+ //从顶层开始
|
|
|
+ parseFormula(resArr, resultFormula, processFormula, isAllFun)
|
|
|
+ return {
|
|
|
+ processFormula: processFormula,
|
|
|
+ resultFormula: resultFormula,
|
|
|
+ }
|
|
|
+}
|