package com.vci.ubcs.code.service.impl; import com.baomidou.mybatisplus.core.toolkit.StringUtils; import com.vci.ubcs.code.mapper.CommonsMapper; import com.vci.ubcs.starter.web.constant.VciSystemVarConstants; import com.vci.ubcs.starter.web.toolmodel.DateConverter; import com.vci.ubcs.starter.web.util.Md5; import com.vci.ubcs.starter.web.util.VciDateUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import javax.annotation.Resource; import java.lang.reflect.Method; import java.math.BigDecimal; import java.time.LocalDate; import java.time.Period; import java.time.format.DateTimeFormatter; import java.util.*; import java.util.concurrent.TimeUnit; /** * 公式处理 * @author weidy * @date 2022-02-11 * */ @Service public class FormulaServiceImpl { /** * 日志文件 */ private Logger logger = LoggerFactory.getLogger(getClass()); /** * 通用查询 */ @Resource CommonsMapper commonsMapper; // /** // * 业务数据服务 // */ // @Autowired // private WebBoServiceI boService; /** * 是否运行完成 */ private Boolean formulaBlag = true; /** * 运算符 */ public static List lc = new ArrayList(); static { lc.add("+"); lc.add("-"); lc.add("*"); lc.add("/"); } /** * 逻辑运算符 */ public static List lj = new ArrayList(); static { lj.add(">"); lj.add("<"); lj.add("="); lj.add("!"); } /** * 函数,int数组注释,第一个标识:0自带函数 1自定义函数;第二个标识:参数个数 */ public static Map funMap = new HashMap(); // int数组注释,第一个标识:0自带函数 1自定义函数;第二个标识:参数个数 static { // 自带函数,可利用反射机制 funMap.put("abs", new int[] { 0, 1 }); funMap.put("acos", new int[] { 0, 1 }); funMap.put("asin", new int[] { 0, 1 }); funMap.put("atan", new int[] { 0, 1 }); funMap.put("cbrt", new int[] { 0, 1 }); funMap.put("ceil", new int[] { 0, 1 }); funMap.put("cos", new int[] { 0, 1 }); funMap.put("cosh", new int[] { 0, 1 }); funMap.put("exp", new int[] { 0, 1 }); funMap.put("expm1", new int[] { 0, 1 }); funMap.put("floor", new int[] { 0, 1 }); funMap.put("log", new int[] { 0, 1 }); funMap.put("log10", new int[] { 0, 1 }); funMap.put("log1p", new int[] { 0, 1 }); funMap.put("random", new int[] { 0, 0 }); funMap.put("rint", new int[] { 0, 1 }); funMap.put("round", new int[] { 0, 1 }); funMap.put("signum", new int[] { 0, 1 }); funMap.put("sin", new int[] { 0, 1 }); funMap.put("sinh", new int[] { 0, 1 }); funMap.put("sqrt", new int[] { 0, 1 }); funMap.put("tan", new int[] { 0, 1 }); funMap.put("tanh", new int[] { 0, 1 }); funMap.put("max", new int[] { 0, 2 }); funMap.put("min", new int[] { 0, 2 }); // 自定义函数 funMap.put("if", new int[] { 1, 3 }); funMap.put("sum", new int[] { 1, 2 }); funMap.put("sub", new int[] { 1, 2 }); funMap.put("mul", new int[] { 1, 2 }); funMap.put("div", new int[] { 1, 2 }); funMap.put("mod", new int[] { 1, 2 }); funMap.put("toInt", new int[] { 1, 1 }); funMap.put("toDouble", new int[] { 1, 1 }); funMap.put("doubleRound", new int[] { 1, 2 }); funMap.put("zeroIfNull", new int[] { 1, 1 }); funMap.put("endsWith", new int[] { 1, 2 }); funMap.put("startsWith", new int[] { 1, 2 }); funMap.put("charAt", new int[] { 1, 2 }); funMap.put("equalsIgnoreCase", new int[] { 1, 2 }); funMap.put("indexOf", new int[] { 1, 2 }); funMap.put("isEmpty", new int[] { 1, 1 }); funMap.put("lastIndexOf", new int[] { 1, 2 }); funMap.put("leftStr", new int[] { 1, 2 }); funMap.put("length", new int[] { 1, 1 }); funMap.put("mid", new int[] { 1, 3 }); funMap.put("right", new int[] { 1, 2 }); funMap.put("rightStr", new int[] { 1, 2 }); funMap.put("tolowercase", new int[] { 1, 1 }); funMap.put("touppercase", new int[] { 1, 1 }); funMap.put("trimzero", new int[] { 1, 1 }); funMap.put("compareDate", new int[] { 1, 2 }); funMap.put("nowDate", new int[] { 1, 0 }); funMap.put("chinaDate", new int[] { 1, 1 }); funMap.put("dateDdd", new int[] { 1, 2 }); funMap.put("dateBalanceYear",new int[] {1,3}); funMap.put("dateBalanceDay",new int[] {1,2}); funMap.put("dateformat", new int[] { 1, 2 }); funMap.put("nowDatetime", new int[] { 1, 0 }); funMap.put("dayOf", new int[] { 1, 1 }); funMap.put("nowMon", new int[] { 1, 1 }); funMap.put("monOf", new int[] { 1, 1 }); funMap.put("nowTime", new int[] { 1, 0 }); funMap.put("nowYear", new int[] { 1, 0 }); funMap.put("yearOf", new int[] { 1, 1 }); funMap.put("getChineseCurrency", new int[] { 1, 1 }); funMap.put("setThmark", new int[] { 1, 1 }); funMap.put("toChinese", new int[] { 1, 1 }); funMap.put("getcolvalue", new int[] { 1, 5 }); funMap.put("MD5", new int[]{1,1}); funMap.put("getValueByMethod", new int[]{1,3}); } /** * 公式初始化转换 * * @param str 公式的内容 * @return 转换后的内容 */ private String strCast(String str) { // str = str.toLowerCase();// 去除空格,变小写 if (str == null ? true : str.length() == 0) { return "0"; } str = str.trim(); if (!checkFormula(str)) { formulaError(); return str; } str = str.replaceAll(",", ","); str = str.replaceAll("\\+-", "-"); str = str.replaceAll("-\\+", "-"); //str = str.replaceAll(" ", ""); return str; } /** * 检查公式中括号出现次数是否正确 * * @param formulaStr 公式的内容 * @return true 表示校验成功 */ private boolean checkFormula(String formulaStr) { formulaBlag = true; int count = 0; for (int i = 0; i < formulaStr.length(); i++) { String s = String.valueOf(formulaStr.charAt(i)); if ("(".equals(s)) { count++; } else if (")".equals(s)) { count--; } if (count < 0) { formulaBlag = false; break; } } formulaBlag = count == 0; return formulaBlag; } /** * 分割函数 * * @param str 字符串 * @param bs 分割符 * @return 转换后的内容 */ private String[] spliteFun(String str, String bs) { List list = new ArrayList(); String bds = ""; int bracket = 0; int len = str.length(); for (int i = 0; i < len; i++) { String s = String.valueOf(str.charAt(i)); if ("(".equals(s)) { bracket++; } else if (")".equals(s)) { bracket--; } if (bracket == 0 && bs.equals(s)) { list.add(bds); bds = ""; continue; } bds += s; } list.add(bds); String[] ss = new String[list.size()]; for (int i = 0; i < list.size(); i++) { ss[i] = list.get(i); } return ss; } /** * 用户自定义函数 * * @param str 字符串 * @param funStr 函数的内容 * @return */ private String customFun(String str, String funStr) { String reval = "false"; String[] gss = spliteFun(str, ","); //每一个参数,我都应该去看看是否还有()。这说明里面是方法 for (int i = 0; i < gss.length; i++) { String record = gss[i]; if(StringUtils.isNotBlank(record) && record.contains("(") && record.contains(")")){ gss[i] = calculate(gss[i]); } } if ("if".equals(funStr)) { //logger.debug("第一个参数:" + gss[0]); if (compare(gss[0])) { reval = calculate(gss[1]); } else { reval = calculate(gss[2]); } } else if ("sum".equals(funStr)) { BigDecimal ln = new BigDecimal(gss[0]); BigDecimal rn = new BigDecimal(gss[1]); reval = ln.add(rn).doubleValue() + ""; } else if ("sub".equals(funStr)) { BigDecimal ln = new BigDecimal(gss[0]); BigDecimal rn = new BigDecimal(gss[1]); reval = ln.subtract(rn).doubleValue() + ""; } else if ("mul".equals(funStr)) { BigDecimal ln = new BigDecimal(gss[0]); BigDecimal rn = new BigDecimal(gss[1]); reval = ln.multiply(rn).doubleValue() + ""; } else if ("div".equals(funStr)) { BigDecimal ln = new BigDecimal(gss[0]); BigDecimal rn = new BigDecimal(gss[1]); if (rn.doubleValue() == 0) { formulaError(); //reval = "0"; return reval; } else { reval = ln.divide(rn, 10, BigDecimal.ROUND_HALF_UP) + ""; } } else if ("mod".equals(funStr)) { int rn = Integer.parseInt(gss[1]); if (rn == 0) { formulaError(); return reval; } int ln = Integer.parseInt(gss[0]); reval = (ln % rn) + ""; } else if ("toInt".equals(funStr)) { reval = (int) Math.floor(new Double(calculate(gss[0]))) + ""; } else if("toDouble".equals(funStr)){ reval = new Double(calculate(gss[0])) + ""; }else if("MD5".equals(funStr)){ reval = Md5.md5(calculate(gss[0])); }else if ("doubleRound".equals(funStr)) { try { BigDecimal b = new BigDecimal(calculate(gss[0])); reval = b.setScale(Integer.parseInt(gss[1]), BigDecimal.ROUND_HALF_UP).doubleValue() + ""; } catch (Exception e) { e.printStackTrace(); formulaError(); } } else if ("zeroIfNull".equals(funStr)) { logger.debug(gss[0]); if ("null".equals(gss[0]) || gss[0].trim().length() == 0) { reval = "0"; return reval; } reval = gss[0]; } else if ("endsWith".equals(funStr)) { reval = "false"; if (gss[0].endsWith(gss[1])) { reval = "true"; } } else if ("startsWith".equals(funStr)) { reval = "false"; if (gss[0].startsWith(gss[1])) { reval = "true"; } } else if ("charAt".equals(funStr)) { try { reval = String.valueOf(gss[0].charAt(Integer.parseInt(gss[1]))); } catch (Exception e) { e.printStackTrace(); formulaError(); reval = ""; } } else if ("equalsignoreCase".equals(funStr)) { if (gss[0].equalsIgnoreCase(gss[1])) { reval = "true"; } } else if ("indexOf".equals(funStr)) { reval = gss[0].indexOf(gss[1]) + ""; } else if ("isEmpty".equals(funStr)) { if (gss[0].trim().length() == 0 || "".equals(gss[0]) || "null".equals(gss[0])) { reval = "true"; } } else if ("lastIndexOf".equals(funStr)) { reval = gss[0].lastIndexOf(gss[1]) + ""; } else if ("leftStr".equals(funStr)) { reval = gss[0].substring(0, Integer.parseInt(gss[1])); } else if ("length".equals(funStr)) { reval = gss[0].length() + ""; } else if ("right".equals(funStr)) { reval = String.valueOf(gss[0].charAt(gss[0].length() - Integer.parseInt(gss[1]))); } else if ("rightStr".equals(funStr)) { reval = gss[0] .substring(gss[0].length() - Integer.parseInt(gss[1])); } else if ("mid".equals(funStr)) { try { reval = gss[0].substring(Integer.parseInt(gss[1]), Integer.parseInt(gss[2])); }catch (Exception e) { e.printStackTrace(); formulaError(); reval = ""; } } else if ("tolowercase".equals(funStr)) { reval = gss[0].toLowerCase(); } else if ("touppercase".equals(funStr)) { reval = gss[0].toUpperCase(); } else if ("trimZero".equals(funStr)) { int len = gss[0].length() - 1; for (int i = len; i >= 0; i--) { if (gss[0].charAt(i) == '0') { gss[0] = gss[0].substring(0, gss[0].length() - 1); } else { reval = gss[0]; break; } } } else if ("compareDate".equals(funStr)) { if (gss[0].indexOf("date") != -1) { gss[0] = calculate(gss[0]); } if (gss[1].indexOf("date") != -1) { gss[1] = calculate(gss[1]); } gss[0] = gss[0].replaceAll("`", "-"); gss[1] = gss[1].replaceAll("`", "-"); String result; try { result = VciDateUtil.compareDate(gss[0], gss[1]); if ("=".equals(result)) { reval = "true"; } ; } catch (Exception e) { e.printStackTrace(); formulaError(); } } else if ("nowDate".equals(funStr)) { reval = VciDateUtil.getNowString("yyyy-MM-dd"); } else if ("chinaDate".equals(funStr)) { try { if (gss[0].indexOf("date") != -1) { gss[0] = calculate(gss[0]); } gss[0] = gss[0].replaceAll("`", "-"); reval = VciDateUtil.getChinaDate(gss[0]); return reval; } catch (Exception e) { e.printStackTrace(); formulaError(); } } else if ("dateAdd".equals(funStr)) { try { if (gss[0].indexOf("date") != -1) { gss[0] = calculate(gss[0]); } gss[0] = gss[0].replaceAll("`", "-"); DateConverter dateConverter = new DateConverter(); dateConverter.setAsText(gss[0]); Date date = VciDateUtil.getDateAddDay(dateConverter.getValue(), Integer.parseInt(gss[1])); reval = VciDateUtil.date2Str(date, VciDateUtil.DateTimeFormat); return reval; } catch (Exception e) { e.printStackTrace(); formulaError(); } } else if("dateBalanceYear".equals(funStr)) { //求时间的差额 //3个参数,对比的源值,对比的目标值,是否进一 String sourceDate = gss[0]; String targetDate = gss[1]; boolean remainderType = "true".equalsIgnoreCase(gss[2]) ? true : false; DateConverter dateConverter = new DateConverter(); dateConverter.setAsText(sourceDate); Date sDate = dateConverter.getValue(); Date tDate = new Date(); if (StringUtils.isBlank(targetDate)) { dateConverter.setAsText(targetDate); tDate = dateConverter.getValue(); } Period p = Period.between(LocalDate.parse(VciDateUtil.date2Str(sDate, VciDateUtil.DateTimeMillFormat), DateTimeFormatter.ofPattern(VciDateUtil.DateTimeMillFormat)), LocalDate.parse(VciDateUtil.date2Str(tDate, VciDateUtil.DateTimeMillFormat), DateTimeFormatter.ofPattern(VciDateUtil.DateTimeMillFormat))); reval = String.valueOf((remainderType && (p.getMonths() > 0 || p.getDays() > 0)) ? (p.getYears() + 1) : p.getYears()); //月份相差是没办法计算 }else if("dateBalanceDay".equals(funStr)){ String sourceDate = gss[0]; String targetDate = gss[1]; DateConverter dateConverter = new DateConverter(); dateConverter.setAsText(sourceDate); Date sDate = dateConverter.getValue(); Date tDate = new Date(); if (StringUtils.isNotBlank(targetDate)) { dateConverter.setAsText(targetDate); tDate = dateConverter.getValue(); } reval = String.valueOf(TimeUnit.DAYS.convert(Math.abs(sDate.getTime()-tDate.getTime()),TimeUnit.MILLISECONDS)); }else if ("dateformat".equals(funStr)) { if (gss[0].indexOf("date") != -1) { gss[0] = calculate(gss[0]); } gss[0] = gss[0].replaceAll("`", "-"); gss[1] = gss[1].replaceAll("`", "-"); Date date; try { if("''".equalsIgnoreCase(gss[0])) { gss[0] = VciDateUtil.getNowString(); } DateConverter dateConverter =new DateConverter(); dateConverter.setAsText(gss[0]); date = dateConverter.getValue(); reval = VciDateUtil.date2Str(date, gss[1].replace("&"," ")); return reval; } catch (Exception e) { e.printStackTrace(); formulaError(); } } else if ("nowDatetime".equals(funStr)) { reval = VciDateUtil.getNowString(); } else if ("dayOf".equals(funStr)) { if (gss[0].indexOf("date") != -1) { gss[0] = calculate(gss[0]); } gss[0] = gss[0].replaceAll("`", "-"); try { Date date = VciDateUtil.str2Date(gss[0], "yyyy-MM-dd"); reval = date.getDate() + ""; return reval; } catch (Exception e) { e.printStackTrace(); formulaError(); } } else if ("nowNon".equals(funStr)) { try { reval = VciDateUtil.getNowString("MM"); return reval; } catch (Exception e) { e.printStackTrace(); formulaError(); } } else if ("monOf".equals(funStr)) { if (gss[0].indexOf("date") != -1) { gss[0] = calculate(gss[0]); } gss[0] = gss[0].replaceAll("`", "-"); try { Date date = VciDateUtil.str2Date(gss[0], "yyyy-MM-dd"); reval = date.getMonth() + ""; return reval; } catch (Exception e) { e.printStackTrace(); formulaError(); } } else if ("nowTime".equals(funStr)) { reval = VciDateUtil.getNowString("HH:mm:ss"); return reval; } else if ("nowYear".equals(funStr)) { reval = VciDateUtil.getNowString("yyyy"); return reval; } else if ("yearOf".equals(funStr)) { if (gss[0].indexOf("date") != -1) { gss[0] = calculate(gss[0]); } gss[0] = gss[0].replaceAll("`", "-"); try { Date date = VciDateUtil.str2Date(gss[0], "yyyy-MM-dd"); reval = date.getYear() + 1900 + ""; return reval; } catch (Exception e) { e.printStackTrace(); formulaError(); } } else if ("getChineseCurrency".equals(funStr)) { gss[0] = calculate(gss[0]); reval = toChineseCurrency(gss[0]); } else if ("setThmark".equals(funStr)) { String numstr = ""; String[] number = gss[0].split("\\."); //logger.debug(number[0]); for (int i = number[0].length() - 1; i >= 0; i--) { if (i % 3 == 2 && i < number[0].length() - 1) { numstr += ","; } numstr += number[0].charAt(i); } reval = ""; for (int i = numstr.toCharArray().length - 1; i >= 0; i--) { reval += numstr.toCharArray()[i]; } if (gss[0].indexOf(".") != -1) { reval += "." + number[1]; } } else if ("toChinese".equals(funStr)) { gss[0] = calculate(gss[0]); //logger.debug(gss[0]); reval = toChinese(gss[0]); } else if ("getcolvalue".equals(funStr)) { if (gss[0].trim().length() == 0 || gss[1].trim().length() == 0 || gss[2].trim().length() == 0 || gss[3].trim().length() == 0 || gss[4].trim().length() == 0) { formulaError(); return reval; } reval = getColValue(gss[0], gss[1], gss[2], gss[3], gss[4]); }else if("getValueByMethod".equalsIgnoreCase(funStr)){ if (gss[0].trim().length() == 0 || gss[1].trim().length() == 0 || gss[2].trim().length() == 0) { formulaError(); return reval; } reval = getValueByMethod(gss[0], gss[1], gss[2]); } return reval; } // 逻辑表达式判断 private boolean compare(String str) { if ("true".equals(calculate(str))) { return true; } else if ("false".equals(calculate(str))) { return false; } boolean flag = false; boolean bs = false; int len = str.length(); int bracket = 0; String ljbds = ""; double d_left = 0; double d_right = 0; for (int i = 0; i < len; i++) { String s = String.valueOf(str.charAt(i)); if ("(".equals(s)) { bracket++; } else if (")".equals(s)) { bracket--; } if (bracket == 0 && lj.contains(s)) { for (int j = i; j < len; j++) { String ts = String.valueOf(str.charAt(j)); if (lj.contains(ts)) { ljbds += ts; } else { bs = true; break; } } } if (bs) { break; } } //logger.debug("逻辑表达式:" + ljbds); String[] s = str.split(ljbds); //logger.debug("左边:" + (s[0])); //logger.debug("右边:" + (s[1])); if (isNumber(calculate(s[0])) && isNumber(calculate(s[1]))) { d_left = new Double(calculate(s[0])); d_right = new Double(calculate(s[1])); } else { formulaError(); return false; } if ("<".equals(ljbds)) { if (d_left < d_right) { return true; } } else if (">".equals(ljbds)) { if (d_left > d_right) { return true; } } else if ("=".equals(ljbds)) { if (d_left == d_right) { return true; } } else if (">=".equals(ljbds)) { if (d_left >= d_right) { return true; } } else if ("<=".equals(ljbds)) { if (d_left <= d_right) { return true; } } else if ("<>".equals(ljbds) || "!=".equals(ljbds)) { if (d_left != d_right) { return true; } } else { formulaError(); } return flag; } /** * 使用公式计算结果 * @param dataMap 本场景变量的值 * @param calculateString 公式的内容 * @return 执行后的值 */ public String getValueByFormula(Map dataMap,String calculateString){ final String[] finalRule = new String[]{calculateString}; if(!CollectionUtils.isEmpty(dataMap)){ dataMap.forEach((key,value)->{ if(value == null){ value = ""; } finalRule[0] = finalRule[0].replace("${" + key + "}",value); }); } return calculate(finalRule[0]); } /** * 递归调用运算,注意变量需要自行替换 * * @param str * @return */ public String calculate(String str) { str = this.strCast(str); if (!formulaBlag) { //logger.debug("公式不正确"); return str; } boolean onlyFunction = str.length()>2 && str.startsWith("->"); if(onlyFunction){ str = str.substring(2); } //需要替换系统变量 Map systemVarValueMap = VciSystemVarConstants.getSystemVarValueMap(); if(!CollectionUtils.isEmpty(systemVarValueMap)){ final String[] finalStr = new String[]{str}; systemVarValueMap.forEach((key,value)->{ if(value == null){ value = ""; } finalStr[0] = finalStr[0].replace( key,value); }); str = finalStr[0]; } String reval = ""; String bds = ""; int bracket = 0;// 对应括号个数 int pos = 0; boolean title = false; // 如果以负数开头,先去掉负号 if (str.substring(0, 1).equals("-")) { str = str.substring(1); title = true; } int len = str.length(); for (int i = 0; i < len; i++) { String s = String.valueOf(str.charAt(i)); pos = i; bracket = 0; if (!lc.contains(s)) {// 如果没遇到运算符 if ("(".equals(s)) {// 如果遇到左括号 if (funMap.containsKey(bds)) {// 如果左括号前是函数 for (int j = i + 1; j < len; j++) {// 从左括号后开始循环 pos++;// 累计移动字符位数 String ts = String.valueOf(str.charAt(j));// 单个字符 // reval+=ts; if ("(".equals(ts))// 如果是左括号累计 { bracket++; } else if (")".equals(ts)) {// 如果是右括号进行减少 bracket--; if (bracket == -1) {// 如果是-1,标识括号结束 reval = reval.substring(0, reval.length() - bds.length());// 重新获得去掉函数头的表达式 reval += this.funCalculate( str.substring(i + 1, j), bds);// 表达式加上函数结果,形成新表达式 i = pos;// 计数器增加 bds = "";// 函数头清空 break;// 退出本次循环 } } } } else if ("".equals(bds) || lc.contains(bds)) {// 如果是普通运算 //logger.debug("普通运算"); for (int j = i + 1; j < len; j++) { pos++; String ts = String.valueOf(str.charAt(j)); if ("(".equals(ts)) { bracket++; } else if (")".equals(ts)) { bracket--; if (bracket == -1) { logger.debug("当前计算的字符串为:" + str.substring(i + 1, pos)); reval += calculate(str .substring(i + 1, pos)); i = pos; bds = ""; break; } } } } else { logger.debug("没有此函数"); formulaError(); } } else {// 累加总表达式和最后一个运算数(或函数) bds += s; reval += s; } } else {// 遇到运算符最后一个运算数(或函数)清空 bds = ""; reval += s; } } // 如果为负数 在前面加负号 if (title) { reval = "0-" + reval; } if(onlyFunction){ return reval; } String result = basicOperation(reval); logger.debug("计算结果" + result); return result; } /** * 函数运算 * * @param gs * @param funStr * @return */ private String funCalculate(String gs, String funStr) { String rval = "0"; logger.debug("函数名:" + funStr); if (funMap.containsKey(funStr)) { int[] csi = funMap.get(funStr); try { if (csi[0] == 0) {// java内部函数,通过反射调用 Class[] cs = new Class[csi[1]]; Object[] objs = new Object[csi[1]]; String[] gss = splitParameter(gs); for (int i = 0; i < csi[1]; i++) { cs[i] = double.class; objs[i] = new Double(calculate(gss[i])); } Class cls = Class.forName("java.lang.Math"); Method m = cls.getMethod(funStr, cs); logger.debug("方法名:" + m); rval = String.valueOf(m.invoke(cls, objs)); } else if (csi[0] == 1) {// 自定义函数 rval = customFun(gs, funStr); } } catch (Exception e) { e.printStackTrace(); } } return rval; } // 公式里的参数分割 public static String[] splitParameter(String str) { int len = str.length(); boolean flag = true; String tstr = ""; for (int i = 0; i < len; i++) { String s = String.valueOf(str.charAt(i)); if ("(".equals(s)) { flag = false; } else if (")".equals(s)) { flag = true; } if (flag && ",".equals(s)) { tstr += "@"; } else { tstr += s; } } return tstr.split("@"); } /** * 四则运算表达式处理 * * @param gs * @return */ private String basicOperation(String gs) { gs = gs + "+0"; // 因为下面的计算是遇到符号才进行,所以多加入一个计算符号,不影响值. if(gs.indexOf("-")>-1){//包含有-号或者是负数 if(gs.startsWith("-")) { gs = "0" + gs; } // if(gs.indexOf("-")>0&&lc.contains(gs.substring(gs.indexOf("-")-1,gs.indexOf("-")))){//紧挨着旁边就是运算符,怎么办啊 // //gs = gs.substring(0,gs.indexOf("-")-1) + "(0" + gs.substring(gs.indexOf("-")) // } } String c1 = "";// 第一个运算符号 String c2 = "";// 第二个运算符号 String s1 = "";// 第一个运算数 String s2 = "";// 第二个运算数 String s3 = "";// 第三个运算数 int len = gs.length(); for (int i = 0; i < len; i++) { String s = String.valueOf(gs.charAt(i));// 获得该位置字符并转换成字符串做比较 if (lc.contains(s)) { // 如果是运算符号 if (c1.length() == 0)// 如果第一个运算符号为空,加入 { c1 = s; } else if (c2.length() == 0) {// 否则,如果第二个运算符号为空,加入 c2 = s;// 第二个运算符号 if ("+".equals(c2) || "-".equals(c2)) {// 如果第二个运算符号级别低,那么进行计算 if(s2.trim().length()>0){ s1 = this.operation(s1, c1, s2);// 第一个和第二个数计算 c1 = c2;// 保存第二个运算符,其他为空 c2 = ""; s2 = ""; }else{//s2还没出现 s2=this.calculate(gs.substring(i)); s1 = this.operation(s1, c1, s2); break; } } } else {// 上述都保存过 if ("+".equals(s) || "-".equals(s)) {// 如果第三个运算符级别低,进行运算 s2 = this.operation(s2, c2, s3);// 先算第二三个数,保存至第二个 s1 = this.operation(s1, c1, s2);// 再算第一二个,保存至第一个 c1 = s;// 保存当前运算符,其他为空 s2 = ""; c2 = ""; s3 = ""; } else {// 如果第三个运算符级别高 s2 = this.operation(s2, c2, s3);// 先算第二三个数,保存至第二个 c2 = s;// 前面不动,保存运算符 s3 = ""; } } } else if (s1.length() > 0 && c1.length() > 0 && c2.length() == 0) {// 如果第一个数,第一个运算符已保存,第二个运算符未保存,保存第二哥数 s2 += s; } else if (c1.length() == 0) {// 如果没有运算符,保存第一个数 s1 += s; } else if (s1.length() > 0 && s2.length() > 0 && c1.length() > 0 && c2.length() > 0) {// 如果第一二个数和运算符都有,保存第三个数 s3 += s; } } return s1; } /** * 基本四则运算 * * @param c1 * 运算数1 * @param s1 * 运算符(加减乘除) * @param c2 * 运算数2 * @return */ private String operation(String c1, String s1, String c2) { String reval = "0"; String c22 = ""; try { for (int i = 0; i < c2.length(); i++) { String s = String.valueOf(c2.charAt(i)); if (lj.contains(s)) { break; } c22 += s; } if (isNumber(c1) && isNumber(c22)) { BigDecimal ln = new BigDecimal(c1.trim()); BigDecimal rn = new BigDecimal(c2.trim()); if ("+".equals(s1)) { return ln.add(rn).doubleValue() + ""; } else if ("-".equals(s1)) { return ln.subtract(rn).doubleValue() + ""; } else if ("*".equals(s1)) { return ln.multiply(rn).doubleValue() + ""; } else if ("/".equals(s1)) { if (rn.doubleValue() == 0) { return reval; } else { return ln.divide(rn, 10, BigDecimal.ROUND_HALF_UP) + ""; } } } else { this.formulaError(); return c1+s1+c2; } } catch (Exception e) { this.formulaError(); e.printStackTrace(); } finally { } return reval; } private Boolean isNumber(String str) { return StringUtils.isNotBlank(str) && str.matches("(-)?([1-9]+[0-9]*|0)(\\.[\\d]+)?"); } private String formulaError() { formulaBlag = false; //logger.debug("公式验证失败,请重新输入"); return "fail"; } public String toChineseCurrency(String value) { String doubleValue = this.calculate("doubleround(" + value + ",2)"); String fushu = ""; if (doubleValue.indexOf("-") == 0) { fushu = "负"; doubleValue = doubleValue.substring(1); // formulaError(); // return ""; } char[] hunit = { '拾', '佰', '仟' }; // 段内位置表示 char[] vunit = { '万', '亿' }; // 段名表示 char[] digit = { '零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖' }; // 数字表示 //double midVal = (Double.parseDouble(doubleValue) * 100); // 转化成整形 //String valStr = String.valueOf(midVal); // 转化成字符串 //String head = valStr.substring(0, valStr.length() - 2); // 取整数部分 //String rail = valStr.substring(valStr.length() - 2); // 取小数部分 String head = ""; String rail = "00"; if(doubleValue.indexOf(".")>-1){ head = doubleValue.substring(0,doubleValue.indexOf(".")); rail = doubleValue.substring(doubleValue.indexOf(".")+1); if(rail.trim().length() == 1) { rail += "0";//必须要保证有分 } } else { head = doubleValue; } String prefix = ""; // 整数部分转化的结果 String suffix = ""; // 小数部分转化的结果 // 处理小数点后面的数 if (rail.equals("00")) { // 如果小数部分为0 suffix = "整"; } else { suffix = digit[rail.charAt(0) - '0'] + "角" + digit[rail.charAt(1) - '0'] + "分"; // 否则把角分转化出来 } // 处理小数点前面的数 char[] chDig = head.toCharArray(); // 把整数部分转化成字符数组 char zero = '0'; // 标志'0'表示出现过0 byte zeroSerNum = 0; // 连续出现0的次数 for (int i = 0; i < chDig.length; i++) { // 循环处理每个数字 int idx = (chDig.length - i - 1) % 4; // 取段内位置 int vidx = (chDig.length - i - 1) / 4; // 取段位置 if (chDig[i] == '0') { // 如果当前字符是0 zeroSerNum++; // 连续0次数递增 if (zero == '0') { // 标志 zero = digit[0]; } else if (idx == 0 && vidx > 0 && zeroSerNum < 4) { prefix += vunit[vidx - 1]; zero = '0'; } continue; } zeroSerNum = 0; // 连续0次数清零 if (zero != '0') { // 如果标志不为0,则加上,例如万,亿什么的 prefix += zero; zero = '0'; } prefix += digit[chDig[i] - '0']; // 转化该数字表示 if (idx > 0) { prefix += hunit[idx - 1]; } if (idx == 0 && vidx > 0) { prefix += vunit[vidx - 1]; // 段结束位置应该加上段名如万,亿 } } if (prefix.length() > 0) { prefix += '圆'; // 如果整数部分存在,则有圆的字样 } return fushu + prefix + suffix; // 返回正确表示 } private String toChinese(String value) { if (!isNumber(value)) { this.formulaError(); return ""; } String fu = ""; // 如果是负数前面加负 if (value.indexOf("-") == 0) { value = value.substring(1); fu += "负"; } char[] hunit = { '拾', '佰', '仟' }; // 段内位置表示 char[] vunit = { '万', '亿' }; // 段名表示 char[] digit = { '零', '一', '二', '三', '四', '五', '六', '七', '八', '九' }; // 数字表示 String head = ""; String rail = ""; String prefix = ""; // 整数部分转化的结果 String suffix = ""; // 小数部分转化的结果 if (value.indexOf(".") != -1 && value.indexOf(".") < value.length() - 1) { String[] number = value.split("\\."); head = number[0]; // 取整数部分 rail = number[1]; suffix += "点"; } else { head = value; } // 处理小数点后面的数 for (int i = 0; i < rail.length(); i++) { suffix += digit[rail.charAt(i) - '0']; } // 处理小数点前面的数 char[] chDig = head.toCharArray(); // 把整数部分转化成字符数组 char zero = '0'; // 标志'0'表示出现过0 byte zeroSerNum = 0; // 连续出现0的次数 for (int i = 0; i < chDig.length; i++) { // 循环处理每个数字 int idx = (chDig.length - i - 1) % 4; // 取段内位置 int vidx = (chDig.length - i - 1) / 4; // 取段位置 if (chDig[i] == '0') { // 如果当前字符是0 zeroSerNum++; // 连续0次数递增 if (zero == '0') { // 标志 zero = digit[0]; } else if (idx == 0 && vidx > 0 && zeroSerNum < 4) { prefix += vunit[vidx - 1]; zero = '0'; } continue; } zeroSerNum = 0; // 连续0次数清零 if (zero != '0') { // 如果标志不为0,则加上,例如万,亿什么的 prefix += zero; zero = '0'; } prefix += digit[chDig[i] - '0']; // 转化该数字表示 if (idx > 0) { prefix += hunit[idx - 1]; } if (idx == 0 && vidx > 0) { prefix += vunit[vidx - 1]; // 段结束位置应该加上段名如万,亿 } } return fu + prefix + suffix; // 返回正确表示 } private String getColValue(String servername, String tableName, String fieldname, String pkfield, String pkvalue) { //暂时不支持server的方式 String sql = "select " + fieldname.trim() + " from " + tableName.trim() + " where " + pkfield + " = '" + pkvalue+"'"; // Map param = new HashMap(); // param.put(pkfield, pkvalue); String str = ""; try{ List data = commonsMapper.selectById(sql); if(data != null || data.size() > 0) { str = (String) ((HashMap) data.get(0)).get(fieldname.trim()); } }catch(Exception e){ } return str; } private String getValueByMethod(String serviceName,String methods,String paramsString){ //暂时不支持通过方法来获取值 return paramsString; } public static void main(String[] args) { } }