diff --git a/lis-common/src/main/java/com/czlis/common/utils/ComOptionUtils.java b/lis-common/src/main/java/com/czlis/common/utils/ComOptionUtils.java index bdd01a7..4dff3b6 100644 --- a/lis-common/src/main/java/com/czlis/common/utils/ComOptionUtils.java +++ b/lis-common/src/main/java/com/czlis/common/utils/ComOptionUtils.java @@ -15,7 +15,7 @@ public class ComOptionUtils { * 设置字典缓存 * * @param key 参数键 - * @param dictDatas 字典数据列表 + * @param optDatas 字典数据列表 */ public static void setOptCache(String key, List optDatas) { //先清除该key的所有缓存,然后再重新设置该key的缓存 diff --git a/lis-interfaceCommon/src/main/java/com/czlis/interfaceCommon/utils/CalcUtils.java b/lis-interfaceCommon/src/main/java/com/czlis/interfaceCommon/utils/CalcUtils.java new file mode 100644 index 0000000..2fd283a --- /dev/null +++ b/lis-interfaceCommon/src/main/java/com/czlis/interfaceCommon/utils/CalcUtils.java @@ -0,0 +1,236 @@ +package com.czlis.interfaceCommon.utils; +import org.springframework.expression.Expression; +import org.springframework.expression.ExpressionParser; +import org.springframework.expression.spel.standard.SpelExpressionParser; +import org.springframework.expression.spel.support.StandardEvaluationContext; + +import java.util.HashMap; +import java.util.Map; +import java.util.Stack; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class CalcUtils { + /** + * 工具类,计算公式计算,使用PB的计算公式加入参得出结果值 + * @param CalcExpression PB原始计算公式 + * @param variableMap 入参MAP + * @return + */ + public static String getValueFromCalc(String CalcExpression,Map variableMap){ + // 创建SpEL解析器 + ExpressionParser parser = new SpelExpressionParser(); + // 创建评估上下文 + StandardEvaluationContext context = new StandardEvaluationContext(); + // 循环遍历Map,将键值对添加到上下文 + for (Map.Entry entry : variableMap.entrySet()) { + // 键作为变量名,值作为变量值 + String str = entry.getValue(); + if(isNumber(str)){ + context.setVariable(entry.getKey(), Double.parseDouble(str)); + }else { + context.setVariable(entry.getKey(), entry.getValue()); + } + } + // 测试表达式:使用多个变量进行判断"#score >= 60 ? #name + '的' + #subject + '成绩及格' : #name + '的' + #subject + '成绩不及格'" + String expression = getCalc(CalcExpression); + Expression exp = parser.parseExpression(expression); + // 执行表达式(传入上下文) + try { + String result = exp.getValue(context, String.class); + //System.out.println(result); // 输出:张三的数学成绩及格 + return result; + } catch (Exception e) { + // 意外错误时返回null + return null; + } + + } + public static boolean getBooleanFromCalc(String CalcExpression,Map variableMap){ + ExpressionParser parser = new SpelExpressionParser(); + StandardEvaluationContext context = new StandardEvaluationContext(); + for (Map.Entry entry : variableMap.entrySet()) { + context.setVariable(entry.getKey(), entry.getValue()); + } + String expression = getCalc(CalcExpression); + Expression exp = parser.parseExpression(expression); + boolean result = exp.getValue(context, Boolean.class); + return result; + } + + /** + * 此方法把PB的计算公式转换为SpEL表达式 + * @param CalcExpression + * @return + */ + public static String getCalc(String CalcExpression){ + // 1. 替换逻辑运算符:and→&&,or→|| + String processed = CalcExpression.replaceAll("\\band\\b", "&&").replaceAll("\\bor\\b", "||"); + processed = processed.replaceAll("\\bAND\\b", "&&").replaceAll("\\bOR\\b", "||"); + // 2. 替换变量格式:[a] → #a + processed = processed.replaceAll("\\[(\\w+)\\]", "#$1"); + // 3. 替换len()函数为length()方法:len(xxx) → xxx.length() + processed = replaceLenFunction(processed); + //5.case表达式暂时不处理,后期看需要扩展 + //4. 递归处理if结构:if(cond, trueExpr, falseExpr) → cond?trueExpr:falseExpr + return processIf(processed); + } + /** + * 递归解析并替换if表达式 + */ + private static String processIf(String expr) { + int start = expr.indexOf("if("); + if (start == -1) { + return expr; + } + + int end = findIfEnd(expr, start); + if (end == -1) { + return expr; + } + + String inner = expr.substring(start + 3, end); + String[] parts = splitIfParts(inner); + if (parts.length != 3) { + return expr; + } + + String condition = parts[0].trim(); + String trueExpr = parts[1].trim(); + String falseExpr = parts[2].trim(); + + // 递归处理分支,确保嵌套表达式被正确包裹 + String processedTrue = processIf(trueExpr); + String processedFalse = processIf(falseExpr); + + // 关键修复:为分支表达式添加括号,尤其是嵌套情况 + // 判断分支是否包含三元运算符,如果是则添加括号 + String wrappedTrue = needsParentheses(processedTrue) ? "(" + processedTrue + ")" : processedTrue; + String wrappedFalse = needsParentheses(processedFalse) ? "(" + processedFalse + ")" : processedFalse; + + // 拼接三元表达式 + String ternary = condition + "?" + wrappedTrue + ":" + wrappedFalse; + + String before = expr.substring(0, start); + String after = expr.substring(end + 1); + return processIf(before + ternary + after); + } + // 判断表达式是否需要添加括号(包含三元运算符时) + private static boolean needsParentheses(String expr) { + // 统计三元运算符的数量,排除括号内的情况 + int colonCount = 0; + int questionCount = 0; + Stack stack = new Stack<>(); + + for (char c : expr.toCharArray()) { + if (c == '(') { + stack.push('('); + } else if (c == ')') { + if (!stack.isEmpty()) stack.pop(); + } else if (stack.isEmpty()) { + if (c == '?') questionCount++; + if (c == ':') colonCount++; + } + } + + // 存在完整的三元运算符(?和:数量相等且至少一个) + return questionCount > 0 && colonCount > 0 && questionCount == colonCount; + } + private static int findIfEnd(String expr, int start) { + Stack stack = new Stack<>(); + stack.push('('); + int pos = start + 3; + + while (pos < expr.length()) { + char c = expr.charAt(pos); + if (c == '(') { + stack.push('('); + } else if (c == ')') { + stack.pop(); + if (stack.isEmpty()) { + return pos; + } + } + pos++; + } + return -1; + } + private static String[] splitIfParts(String inner) { + Stack stack = new Stack<>(); + int partIndex = 0; + StringBuilder[] parts = new StringBuilder[3]; + for (int i = 0; i < 3; i++) { + parts[i] = new StringBuilder(); + } + + for (char c : inner.toCharArray()) { + if (c == ',' && stack.isEmpty()) { + partIndex++; + if (partIndex >= 3) { + break; + } + } else { + if (c == '(') { + stack.push('('); + } else if (c == ')') { + if (!stack.isEmpty()) { + stack.pop(); + } + } + parts[partIndex].append(c); + } + } + + return new String[]{ + parts[0].toString(), + parts[1].toString(), + parts[2].toString() + }; + } + /** + * 替换len(表达式)为表达式.length() + * 支持处理嵌套的len函数,如len(len(#a)) + */ + private static String replaceLenFunction(String expr) { + // 正则匹配len(...)结构,处理括号嵌套 + Pattern pattern = Pattern.compile("len\\(([^()]+|\\([^()]*\\))*\\)"); + Matcher matcher = pattern.matcher(expr); + StringBuffer result = new StringBuffer(); + + while (matcher.find()) { + String match = matcher.group(); + // 提取括号内的内容(去掉len(和最后的)) + String inner = match.substring(4, match.length() - 1); + // 递归处理嵌套的len函数 + String processedInner = replaceLenFunction(inner); + // 替换为xxx.length() + matcher.appendReplacement(result, processedInner + ".length()"); + } + matcher.appendTail(result); + + return result.toString(); + } + /** + * 使用正则表达式判断字符串是否为数字 + * 支持:整数(123)、小数(123.45)、正负号(-123、+45.6) + */ + public static boolean isNumber(String str) { + if (str == null || str.trim().isEmpty()) { + return false; + } + // 正则表达式:匹配正负整数、正负小数 + String regex = "^[+-]?([0-9]+(\\.[0-9]*)?|\\.[0-9]+)$"; + return str.matches(regex); + } + + // 测试 + public static void main(String[] args) { + Map variables = new HashMap<>(); + variables.put("ALB", "4.0"); // 示例值 + // variables.put("TP", "6.0"); + String testCalc = "[ALB] /( [TP] - [ALB] )"; + //System.out.println(getCalc(testCalc)); + System.out.println(getValueFromCalc(testCalc,variables)); + + } +} diff --git a/liswork/src/main/java/com/czlis/liswork/mapper/LisWorkOperMapper.java b/liswork/src/main/java/com/czlis/liswork/mapper/LisWorkOperMapper.java index 240ae3f..6b90fee 100644 --- a/liswork/src/main/java/com/czlis/liswork/mapper/LisWorkOperMapper.java +++ b/liswork/src/main/java/com/czlis/liswork/mapper/LisWorkOperMapper.java @@ -1,14 +1,17 @@ package com.czlis.liswork.mapper; +import com.czlis.liswork.pojo.DTO.ResultCalcDTO; import org.apache.ibatis.annotations.Param; import java.util.Date; +import java.util.List; import java.util.Map; public interface LisWorkOperMapper { Long checkReqClass(@Param("sqh") String sqh,@Param("yq") String yq); - String selectsqxmdh(String sqh); - String selectyqdl(String yq); + String selectSqxmdh(String sqh); + String selectYqdl(String yq); void sp_setrefs(Map map); void updatelabresultsqxmdhall(@Param("jyrq") Date jyrq,@Param("yq") String yq,@Param("ybh") String ybh,@Param("sqxmdh") String sqxmdh); void updatelabresultsqxmdh(@Param("jyrq") Date jyrq,@Param("yq") String yq,@Param("ybh") String ybh,@Param("sqh") String sqh); + List getResultCalc(@Param("jyrq") Date jyrq, @Param("yq") String yq, @Param("ybh") String ybh); } diff --git a/liswork/src/main/java/com/czlis/liswork/pojo/DTO/ResultCalcDTO.java b/liswork/src/main/java/com/czlis/liswork/pojo/DTO/ResultCalcDTO.java new file mode 100644 index 0000000..be9d5c2 --- /dev/null +++ b/liswork/src/main/java/com/czlis/liswork/pojo/DTO/ResultCalcDTO.java @@ -0,0 +1,16 @@ +package com.czlis.liswork.pojo.DTO; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class ResultCalcDTO { + private String jsxm; + private String xmdh; + private String csjg; + private String jsgs; +} + diff --git a/liswork/src/main/java/com/czlis/liswork/service/impl/LisWorkOperServiceImpl.java b/liswork/src/main/java/com/czlis/liswork/service/impl/LisWorkOperServiceImpl.java index aeab11b..5f770c1 100644 --- a/liswork/src/main/java/com/czlis/liswork/service/impl/LisWorkOperServiceImpl.java +++ b/liswork/src/main/java/com/czlis/liswork/service/impl/LisWorkOperServiceImpl.java @@ -11,19 +11,18 @@ import com.czlis.interfaceCommon.mapper.LabReqmainMapper; import com.czlis.interfaceCommon.pojo.inter.DayMessage; import com.czlis.interfaceCommon.pojo.inter.GetReqInterface; import com.czlis.interfaceCommon.pojo.inter.SetReqStatus; -import com.czlis.interfaceCommon.utils.AgeUtils; -import com.czlis.interfaceCommon.utils.CommonUtil; -import com.czlis.interfaceCommon.utils.LisInterfaceUtil; -import com.czlis.interfaceCommon.utils.LisUtil; +import com.czlis.interfaceCommon.utils.*; import com.czlis.liswork.mapper.LisWorkOperMapper; import com.czlis.liswork.mapper.dict.LabInstrvsreqclassMapper; +import com.czlis.liswork.pojo.DTO.ResultCalcDTO; import com.czlis.liswork.service.LisWorkOperService; import com.czlis.liswork.utils.LisWorkUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; - +import org.springframework.expression.ExpressionParser; +import org.springframework.expression.spel.standard.SpelExpressionParser; import java.util.*; import java.util.stream.Collectors; @@ -265,7 +264,10 @@ public class LisWorkOperServiceImpl implements LisWorkOperService { } } - String yqdl=lisWorkOperMapper.selectyqdl(yq); + LabPat labPat=commonUtil.getLabPatOne(jyrq, yq, ybh); + //计算项目更新 + calcsample(jyrq, yq, ybh, labPat); + String yqdl=lisWorkOperMapper.selectYqdl(yq); if(!"细菌仪".equals(yqdl)) { Map map = new HashMap<>(); map.put("jyrq", jyrq); @@ -278,10 +280,14 @@ public class LisWorkOperServiceImpl implements LisWorkOperService { String retCode = String.valueOf(map.get("retcode")); String retMsg = String.valueOf(map.get("retmsg")); log.info("调用存储过程{}返回值:{},{}", "sp_setrefs", retCode, retMsg); - if (retCode == null || "".equals(retCode) || "-1".equals(retCode)) - return new Result("-1", "保存常规参考值失败!"); + if (retCode == null || "".equals(retCode) || "-1".equals(retCode)) return new Result("-1", "保存常规参考值失败!"); + int wjz=saverefs(jyrq, yq, ybh, labPat); + if(wjz==1){ + //危急值处理过程 + } } - setItemSqxmdh(jyrq, yq, ybh); + String sqh=labPat.getSqh(); + setItemSqxmdh(jyrq, yq, ybh,sqh); return new Result("0","保存成功!"); } @@ -294,24 +300,77 @@ public class LisWorkOperServiceImpl implements LisWorkOperService { public void setItemSqxmdh(Date jyrq, String yq, String ybh){ String sqh=commonUtil.getSqhByKey(jyrq,yq,ybh); if (sqh==null || "".equals(sqh)) {}else{ - int sl=labReqdetailMapper.getCountByKey(sqh); - if(sl==1){ - String sqxmdh=lisWorkOperMapper.selectsqxmdh(sqh); - lisWorkOperMapper.updatelabresultsqxmdhall(jyrq,yq,ybh,sqxmdh); - }else{ - lisWorkOperMapper.updatelabresultsqxmdh(jyrq,yq,ybh,sqh); - } + setItemSqxmdh(jyrq, yq, ybh,sqh); + } + } + //内部使用 + private void setItemSqxmdh(Date jyrq, String yq, String ybh, String sqh){ + if (sqh==null || "".equals(sqh)) {}else{ + int sl=labReqdetailMapper.getCountByKey(sqh); + if(sl==1){ + String sqxmdh=lisWorkOperMapper.selectSqxmdh(sqh); + lisWorkOperMapper.updatelabresultsqxmdhall(jyrq,yq,ybh,sqxmdh); + }else{ + lisWorkOperMapper.updatelabresultsqxmdh(jyrq,yq,ybh,sqh); + } } } - /** * 计算项目增加及重新计算 * @param jyrq * @param yq * @param ybh */ - public void calcsample(Date jyrq, String yq, String ybh){ + public Result calcsample(Date jyrq, String yq, String ybh){ + LabPat labPat=commonUtil.getLabPatOne(jyrq, yq, ybh); + calcsample(jyrq, yq, ybh, labPat); + return new Result("0","保存成功!"); + } + //内部使用 + private void calcsample(Date jyrq, String yq, String ybh,LabPat labPat){ + List resultCalcDTO=lisWorkOperMapper.getResultCalc(jyrq,yq,ybh); + String xmdhold=""; + for (ResultCalcDTO resultCalc : resultCalcDTO) { + String jsgs=resultCalc.getJsgs(); + String xmdh= resultCalc.getJsxm(); + if(!xmdhold.equals(xmdh)) { + xmdhold = xmdh; + String sex=labPat.getBrxb().trim(); + if( "1".equals(sex))sex="男"; + if( "2".equals(sex))sex="女"; + double age = AgeUtils.getDecimalAge(AgeUtils.getBirthDateByAge(labPat.getNl(), labPat.getNldw())); + Map variables = new HashMap<>(); + variables.put("SEX", sex); // 示例值 + variables.put("AGE", String.valueOf(age)); + String result=CalcUtils.getValueFromCalc(jsgs,variables); + if (result != null && !result.trim().isEmpty()) { + //插入结果值 + } + } + } + } + /** + * 计算项目参考值结果异常标志 + * @param jyrq + * @param yq + * @param ybh + */ + public Result saverefs(Date jyrq, String yq, String ybh){ + LabPat labPat=commonUtil.getLabPatOne(jyrq, yq, ybh); + saverefs(jyrq, yq, ybh, labPat); + return new Result("0","保存成功!"); + } + /** + * 计算项目参考值结果异常标志(内部使用) + * @param jyrq + * @param yq + * @param ybh + * @param labPat + * @return 返回值0正常,1有危急值明细存在 + */ + private int saverefs(Date jyrq, String yq, String ybh,LabPat labPat){ + return 0; } diff --git a/liswork/src/main/resources/mapper/LisWorkOperMapper.xml b/liswork/src/main/resources/mapper/LisWorkOperMapper.xml index 7da986f..4113843 100644 --- a/liswork/src/main/resources/mapper/LisWorkOperMapper.xml +++ b/liswork/src/main/resources/mapper/LisWorkOperMapper.xml @@ -8,10 +8,10 @@ where lab_reqdetail.sqxmdh=xm_feeinstr.sfxmdh and lab_reqdetail.sqh=#{sqh} and xm_feeinstr.yq=#{yq}; - select sqxmdh from lab_reqdetail where lab_reqdetail.sqh=#{sqh} - select yqdl from lab_instr where lab_instr.yq=#{yq} @@ -31,4 +31,13 @@ #{retcode,mode=OUT,jdbcType=INTEGER}) } + +