修改费用计算代码

This commit is contained in:
chentianrui
2025-08-22 18:13:09 +08:00
parent 8d595b339c
commit be848c3e78
20 changed files with 2569 additions and 360 deletions
+88 -3
View File
@@ -1,16 +1,19 @@
from __future__ import annotations
import logging
from memory_profiler import profile
import xml.etree.ElementTree as ET
from typing import Dict, Callable, Any, Optional
import os
from enum import Enum, auto
from equipment_calculation.expressioncalculator import ExpressionCalculator
import copy
import re
from xml.dom import minidom
# 配置logging
logging.basicConfig(
level=logging.DEBUG,
level=logging.INFO,
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
handlers=[logging.FileHandler("bcl_calculator.log"), logging.StreamHandler()],
)
@@ -744,6 +747,86 @@ def strfind_func(funcname: str, claculate, context: BCLContext, *args):
return BCLVariant(position)
def _is_in_range(value, range_expression):
"""判断值是否在范围表达式中
Args:
value (str): 要检查的值
range_expression (str): 范围表达式,支持以下格式:
- 单个值: "JYT19-71"
- 范围: "JYT17-1~189"
- 范围(后半省略前缀且带前导零): "C09032001~09032315"
- 多个范围用逗号分隔: "JYT17-1~189,JYT18-1~100"
Returns:
bool: 如果值在范围中返回True,否则返回False
"""
# 统一转为字符串
if value is None or range_expression is None:
return False
value = str(value).strip()
range_expression = str(range_expression).strip()
# 拆分为(前缀, 尾部数字)——前缀为末尾数字前的全部,数字为末尾一段数字
def split_prefix_num(s: str) -> tuple[str, Optional[int]]:
s = str(s)
m = re.match(r"^(.*?)(\d+)$", s)
if not m:
return s, None
prefix, num_str = m.group(1), m.group(2)
try:
return prefix, int(num_str)
except ValueError:
return prefix, None
value_prefix, value_num = split_prefix_num(value)
# 处理多个范围表达式(用逗号分隔)
for seg in range_expression.split(","):
seg = seg.strip()
if not seg:
continue
# 范围:start~end
if "~" in seg:
try:
start, end = [x.strip() for x in seg.split("~", 1)]
s_pref, s_num = split_prefix_num(start)
e_pref, e_num = split_prefix_num(end)
# 允许 end 省略前缀(如 JYT17-1~189 或 C09032001~09032315),
# 即只要 end 全为数字,则继承 start 的前缀,并按数值比较(忽略前导零差异)
if e_pref == "" and end.isdigit():
e_pref = s_pref
try:
e_num = int(end)
except ValueError:
e_num = None
# 要求前缀完全一致
if s_pref != e_pref:
continue
# 值必须与范围前缀完全一致
if value_prefix != s_pref:
continue
# 三者数字齐备方可比较
if value_num is None or s_num is None or e_num is None:
continue
if s_num <= value_num <= e_num:
return True
except Exception:
continue
else:
# 单值:要求完全相等
if value == seg:
return True
return False
def in_func(funcname: str, claculate, context: BCLContext, *args):
# 参数数量校验
if len(args) != 2:
@@ -780,8 +863,8 @@ def in_func(funcname: str, claculate, context: BCLContext, *args):
else param2.value
)
# 判断value1是否在value2中
result = value1 in value2
# 使用自定义的范围判断函数
result = _is_in_range(value1, value2)
# 返回布尔类型的BCLVariant对象
return BCLVariant(result)
@@ -1173,6 +1256,8 @@ class BCLCalculator:
return False
name = expr.get("name")
if name in self.expressions:
logging.warning(f"BCLExpression名称重复: {name},后来的定义将覆盖之前的。")
self.expressions[name] = expr
return True