ZaiZai 3 months ago
parent
commit
2cbd975dde

+ 36 - 0
src/views/project/list/edit-formula.vue

@@ -328,6 +328,11 @@ import { ElMessageBox } from 'element-plus'
 import { VueTagsInput } from '@vojtechlanka/vue-tags-input'
 import draggable from 'vuedraggable'
 
+//辅助解析文件
+import { rangeToString } from './formula/rangeToString'
+import { formulaArrayToString } from './formula/formulaArrayToString'
+import { formulaStringToArray } from './formula/formulaStringToArray'
+
 //接口文件
 import projectApi from '~api/project/project'
 import contractApi from '~api/project/contract'
@@ -374,12 +379,43 @@ const getDataApi = async () => {
     getTypeMapApi().then()
     getWbsFormElementData().then()
     getProjectDataApi().then()
+    getFormulaStringToArrayApi().then()
 }
 
 //保留位数
 const isRetain = ref(false)
 const retainNum = ref(2)
 
+//把公式文本还原数组
+const rightDict = ref([])
+const formulaId = ref('')
+const getFormulaStringToArrayApi = async () => {
+    const { eleId, globalType, nodeId, pid } = getObjValue(dataInfo.value)
+    const { code, data } = await formulaApi.detail({
+        projectId: projectId.value || pid,
+        elementId: eleId,
+        nodeId: nodeId,
+        scope: globalType,
+    })
+    if (code !== 200) return
+    const res = getObjValue(data)
+    console.log(res)
+    if (!isNullES(res.id)) {
+        //获取右边元素的字典
+        let dictMap = getObjValue(res.dict), dictArr = []
+        //遍历
+        for (let i in dictMap) {
+            dictArr.push(dictMap[i])
+        }
+        rightDict.value = dictArr
+        formulaId.value = res.id
+        //把公式字符串还原成数组
+        let formula = formulaStringToArray(res.formula, res.map, formulaMenuMap.value)
+        console.log('formula', formula)
+        processFormula.value = getArrValue(formula?.processFormula)
+    }
+}
+
 //允许偏差值范围
 const deviationRangeShow = ref(false)
 const setDeviationRange = () => {

+ 303 - 0
src/views/project/list/formula/formulaArrayToString.js

@@ -0,0 +1,303 @@
+
+function isFormulaItem(ele) {
+  return ele.type == 'Element' || ele.type == 'ParamData'
+}
+
+//转换公式的参数
+// function transformArguments(children,curEle,eleMap){
+//   let fcReg = /(FC\.\S+\()(.+)\)/;
+//   let fcText = '';
+//   for (let i = (children.length-1); i >= 0; i--) {
+//     let ele = children[i];
+
+//     if(ele.isOn === false){
+//       //点击了开关关闭的,跳过
+//       continue;
+//     }
+//     //console.log(ele.name)
+//     let tmpArr = fcReg.exec(ele.template.ft);
+//     fcText = tmpArr[1] + fcText;//fc.XX( 左括号部分
+//     let argList = tmpArr[2].split(",");//括号里面参数部分#1,#2..
+//     let isNestEle = false;//是否有过嵌套的元素了
+//     let isNestEle2 = false;
+//     //console.log(argList)
+//     //console.log(text)
+//     argList.forEach((argText,index)=>{
+//       if(argText.indexOf('#')>-1){
+//         //#动态参数
+//         let argIndex = index;
+//         for (let j = 0; j < ele.template.args.length; j++) {
+//           if(ele.template.args[j].key == argText){
+//             //找到相同的#编码
+//             argIndex = j;
+//             break;
+//           }
+//         }
+//         let arg = ele.arguments[argIndex];
+
+//         if(arg && isFormulaItem(arg)){
+//           if(!isNestEle && !isNestEle2 && i != (children.length-1) && curEle.id == arg.id){
+//             //不是第一个嵌套的公式,且和当前挂载的是同一个元素
+//             //认为这个参数是之前公式计算的结果,不再写入元素
+//             isNestEle = true;
+//           }else{
+//             if(arg.type == 'Element'){
+//               eleMap[arg.tableElementKey] = {
+//                 id: arg.id,
+//                 name: arg.name,
+//                 tableElementKey: arg.tableElementKey,
+//                 type: "Element",
+//               };
+//               fcText += `E[${arg.tableElementKey}]`;
+//             }else if(arg.type == 'ParamData'){
+//               eleMap[arg.k] = {
+//                 id: arg.id,
+//                 name: arg.name,
+//                 v:arg.v,
+//                 k:arg.k,
+//                 type: "ParamData",
+//               };
+//               fcText += `WP[${arg.k}]`;
+//             }
+
+//           }
+//         }else if(Array.isArray(arg)){
+//           //ifsles方法会进来
+//           arg.forEach((a)=>{
+//             if(a && isFormulaItem(a)){
+//               if(!isNestEle2 && i != (children.length-1) && curEle.id == a.id){
+//                 //不是第一个嵌套的公式,且和当前挂载的是同一个元素
+//                 //认为这个参数是之前公式计算的结果,不再写入元素
+//                 isNestEle2 = true
+//               }else{
+//                 if(a.type == 'Element'){
+//                   eleMap[a.tableElementKey] = {
+//                     id: a.id,
+//                     name: a.name,
+//                     tableElementKey: a.tableElementKey,
+//                     type: "Element",
+//                   };
+//                   fcText += `E[${a.tableElementKey}]`;
+//                 }else if(a.type == 'ParamData'){
+//                   eleMap[a.k] = {
+//                     id: a.id,
+//                     name: a.name,
+//                     v:a.v,
+//                     k:a.k,
+//                     type: "ParamData",
+//                   };
+//                   fcText += `WP[${a.k}]`;
+//                 }
+//               }
+//             }else if(a && a.type == 'Operator'){
+//               //在运算符前后加上空格
+//               fcText += ' '+a.name+' ';
+//               //console.log(fcText)
+//             }else if(a && a.type){
+//               fcText += a.name;
+//             }else{
+//               fcText += a?a:"''";
+//             }
+//           })
+
+//         }else{
+//           fcText += arg?arg:"''";
+//         }
+
+//       }else{
+//         //已有参数
+//         fcText += argText?argText:'';
+//       }
+//       if(index != argList.length-1){
+//         fcText += ',';
+//       }
+//     })
+//     fcText += ')';
+//   }
+
+//   return fcText;
+// }
+function transformArguments(children, curEle, eleMap) {
+  // debugger
+  let fcReg = /(FC\.\S+\()(.+)\)/
+  let fcText = ''
+  for (let i = (children.length - 1); i >= 0; i--) {
+    let ele = children[i]
+
+    if (ele.isOn === false) {
+      //点击了开关关闭的,跳过
+      continue
+    }
+    if (ele.template != null && ele.template != undefined) {
+      let tmpArr = fcReg.exec(ele.template.ft)
+      fcText = tmpArr[1] + fcText//fc.XX( 左括号部分
+      let argList = tmpArr[2].split(',')//括号里面参数部分#1,#2..
+      let isNestEle = false//是否有过嵌套的元素了
+      let isNestEle2 = false
+      //console.log(argList)
+      //console.log(text)
+      argList.forEach((argText, index)=>{
+        if (argText.indexOf('#') > -1) {
+          //#动态参数
+          let argIndex = index
+          for (let j = 0; j < ele.template.args.length; j++) {
+            if (ele.template.args[j].key == argText) {
+              //找到相同的#编码
+              argIndex = j
+              break
+            }
+          }
+          let arg = ele.arguments[argIndex]
+
+          if (arg && isFormulaItem(arg)) {
+            if (!isNestEle && !isNestEle2 && i != (children.length - 1) && curEle.id == arg.id) {
+              //不是第一个嵌套的公式,且和当前挂载的是同一个元素
+              //认为这个参数是之前公式计算的结果,不再写入元素
+              isNestEle = true
+            } else {
+              // let atbkey=arg.tableElementKey.replace('_key',':key')
+              if (arg.type == 'Element') {
+                eleMap[arg.tableElementKey] = {
+                  id: arg.id,
+                  name: arg.name,
+                  tableElementKey: arg.tableElementKey,
+                  type: 'Element',
+                }
+                fcText += `E[${arg.tableElementKey}]`
+              } else if (arg.type == 'ParamData') {
+                eleMap[arg.k] = {
+                  id: arg.id,
+                  name: arg.name,
+                  v:arg.v,
+                  k:arg.k,
+                  type: 'ParamData',
+                }
+                fcText += `WP[${arg.k}]`
+              }
+
+            }
+          } else if (Array.isArray(arg)) {
+            //ifsles方法会进来
+            arg.forEach((a)=>{
+              if (a && isFormulaItem(a)) {
+                if (!isNestEle2 && i != (children.length - 1) && curEle.id == a.id) {
+                  //不是第一个嵌套的公式,且和当前挂载的是同一个元素
+                  //认为这个参数是之前公式计算的结果,不再写入元素
+                  isNestEle2 = true
+                } else {
+                  if (a.type == 'Element') {
+                    eleMap[a.tableElementKey] = {
+                      id: a.id,
+                      name: a.name,
+                      tableElementKey: a.tableElementKey,
+                      type: 'Element',
+                    }
+                    fcText += `E[${a.tableElementKey}]`
+                  } else if (a.type == 'ParamData') {
+                    eleMap[a.k] = {
+                      id: a.id,
+                      name: a.name,
+                      v:a.v,
+                      k:a.k,
+                      type: 'ParamData',
+                    }
+                    fcText += `WP[${a.k}]`
+                  }
+                }
+              } else if (a && a.type == 'Operator') {
+                //在运算符前后加上空格
+                fcText += ' ' + a.name + ' '
+                //console.log(fcText)
+              } else if (a && a.type) {
+                fcText += a.name
+              } else {
+                fcText += a ? a : '\'\''
+              }
+            })
+
+          } else {
+            fcText += arg ? arg : '\'\''
+          }
+
+        } else {
+          //已有参数
+          fcText += argText ? argText : ''
+        }
+        if (index != argList.length - 1) {
+          fcText += ','
+        }
+      })
+
+      fcText += ')'
+
+    }
+    console.log(fcText, 'ele.name')
+
+
+  }
+
+  return fcText
+}
+export const formulaArrayToString = (processFormula, resultFormula) => {
+  let text = ''
+  let eleMap = {}//元素字典,为了回显的时候查询信息
+  let preIsOp = false//前一个参数是否是四则运算(+-*/)
+  processFormula.forEach((item, index) => {
+    if (isFormulaItem(item)) {
+      //console.log(item)
+      if (item.children.length < 1) {
+        if (item.type == 'Element') {
+          eleMap[item.tableElementKey] = {
+            id: item.id,
+            name: item.name,
+            tableElementKey: item.tableElementKey,
+            type: 'Element',
+          }
+          text += `E[${item.tableElementKey}]`
+        } else if (item.type == 'ParamData') {
+          eleMap[item.k] = {
+            id: item.id,
+            name: item.name,
+            v:item.v,
+            k:item.k,
+            type: 'ParamData',
+          }
+          text += `WP[${item.k}]`
+        }
+
+      } else {
+        text += (index > 0 && !preIsOp ? ',' : '') + transformArguments(item.children, item, eleMap)
+        preIsOp = false
+      }
+    } else if (item.type == 'Element') {
+      text += item.template.ft
+    } else if (item.type == 'Operator') {
+      //在运算符前后加上空格
+      preIsOp = true
+      text += ' ' + item.name + ' '
+      //console.log(fcText)
+    } else {
+      text += item.name
+    }
+  })
+  if (resultFormula[0].children.length) {
+    //等号左侧部分
+    let resText = transformArguments(resultFormula[0].children, resultFormula[0], eleMap)
+    //等号左侧元素不需要,左侧的公式嵌套右侧所有结果
+    let fcReg = /(FC\.\S+\()(.+)\)/
+    let leftArr = fcReg.exec(resText)
+    //text = resText.replace(`E[${resultFormula[0].tableElementKey}]`,text);
+    if (!!text && !resText.includes(text) && !!leftArr) {
+       let reg = leftArr[2].replace('OPTION,', '')
+      text = resText.replace(reg, text)
+    } else {
+      text = resText
+    }
+
+
+  }
+
+  console.log(text, '最终')
+  //console.log(eleMap)
+  return { text, eleMap }
+}

+ 422 - 0
src/views/project/list/formula/formulaStringToArray.js

@@ -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,
+    }
+}

+ 89 - 0
src/views/project/list/formula/rangeToString.js

@@ -0,0 +1,89 @@
+import { isNullES } from 'js-fast-way'
+import { formulaArrayToString } from './formulaArrayToString'
+
+// 范围操作符配置对象
+const RANGE_CONFIGS = {
+    // 闭区间配置
+    '【min,max】': {
+        left: '[', // 左边界符号
+        right: ']', // 右边界符号
+        defaultMin: null, // 默认最小值
+        defaultMax: null, // 默认最大值
+    },
+    // 大于区间配置
+    '>': {
+        left: '(',
+        right: ')',
+        defaultMin: null,
+        defaultMax: '100000', // 设置最大值上限
+    },
+    // 小于区间配置
+    '<': {
+        left: '(',
+        right: ')',
+        defaultMin: '0', // 设置最小值下限
+        defaultMax: null,
+    },
+    // 大于等于区间配置
+    '≥': {
+        left: '[',
+        right: ']',
+        defaultMin: null,
+        defaultMax: '100000',
+    },
+    // 小于等于区间配置
+    '≤': {
+        left: '[',
+        right: ']',
+        defaultMin: '0',
+        defaultMax: null,
+    },
+}
+
+/**
+ * 将范围表达式转换为字符串
+ * @param {Object} processFormula - 包含范围表达式的对象
+ * @param {Object} eleMap - 元素映射对象
+ * @returns {string} 格式化后的范围字符串
+ */
+export const rangeToString = (processFormula, eleMap) => {
+    // 如果两个参数都为空,返回空字符串
+    if (isNullES(processFormula.arguments1) && isNullES(processFormula.arguments2)) {
+        return ''
+    }
+    // 获取对应符号的配置
+    const config = RANGE_CONFIGS[processFormula.symbol]
+    // 如果符号不支持,抛出错误
+    if (!config) {
+        throw new Error(`不支持的符号: ${processFormula.symbol}`)
+    }
+
+    // 处理最小值和最大值,使用配置中的默认值或处理参数值
+    const min = config.defaultMin ?? getArg(processFormula.arguments1, eleMap)
+    const max = config.defaultMax ?? getArg(processFormula.arguments2, eleMap)
+
+    // 拼接并返回最终的范围字符串
+    return `${config.left}${min},${max}${config.right}`
+}
+
+/**
+ * 处理参数值
+ * @param {Array|string} arg - 参数值,可以是数组或字符串
+ * @param {Object} eleMap - 元素映射对象
+ * @returns {string} 处理后的参数字符串
+ */
+function getArg(arg, eleMap) {
+    // 如果参数为空,返回空字符串
+    if (!arg) return ''
+
+    // 如果参数是数组,使用 formulaArrayToString 处理
+    if (Array.isArray(arg)) {
+        const { text: argtext, eleMap: argeleMap } = formulaArrayToString(arg, [{ children: [] }])
+        // 合并元素映射对象
+        Object.assign(eleMap, argeleMap)
+        return argtext
+    }
+
+    // 如果参数是其他类型,转换为字符串返回
+    return String(arg)
+}