修改费用计算代码
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import os
|
||||
import json
|
||||
from memory_profiler import profile
|
||||
from typing import Dict, List, Any, Optional, Tuple
|
||||
from equipment_calculation.software_types import (
|
||||
get_software_type,
|
||||
@@ -29,101 +30,65 @@ CATEGORY_MAPPING = {
|
||||
}
|
||||
|
||||
|
||||
def parse_json_content(json_file_path: str) -> Tuple[Optional[str], Optional[str]]:
|
||||
# 项目类型名称映射字典,将各种变体映射到标准类型(预算/清单)
|
||||
PROJECT_TYPE_MAPPING = {
|
||||
# 预算类变体
|
||||
"概预算工程": "预算",
|
||||
}
|
||||
|
||||
|
||||
####应该是加在json后没释放
|
||||
def parse_json_content(json_file_path: str) -> Tuple[Optional[str], Optional[str], Optional[str]]:
|
||||
"""
|
||||
从JSON文件内容中解析软件类别和工程类型
|
||||
从JSON文件内容中解析:
|
||||
- 软件类别: 来自 basicData["软件类别"](若无则尝试 basicData["软件名称"] 作为兜底)
|
||||
- 项目类型: 来自 basicData["项目类型"](期望为 "预算" 或 "清单")
|
||||
- 工程类型: 来自 projectData.projectInfo["工程类型"]
|
||||
|
||||
:param json_file_path: JSON文件路径
|
||||
:return: (category, engineering_type) 元组,如果解析失败则返回 (None, None)
|
||||
:return: (category, project_type, engineering_type) 元组,解析失败对应位置返回 None
|
||||
"""
|
||||
try:
|
||||
with open(json_file_path, "r", encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
|
||||
# 定义阶段类型映射表
|
||||
budget_types = ["概预算", "定额", "定额计价", "概算", "概预算工程"]
|
||||
list_types = ["清单", "结算", "招标控制价", "招投标工程", "清单计价"]
|
||||
|
||||
# 从division字段获取软件名称和阶段类型
|
||||
if "division" in data:
|
||||
division = data["division"]
|
||||
print(f"找到division字段: {division}")
|
||||
|
||||
# 使用-分割division字段
|
||||
parts = division.split("-")
|
||||
if len(parts) == 2:
|
||||
category = parts[0].strip()
|
||||
stage_type = parts[1].strip()
|
||||
elif len(parts) == 3:
|
||||
category = parts[0].strip()
|
||||
stage_type = parts[2].strip()
|
||||
# 提取 basicData
|
||||
basic_data = data.get("basicData", {}) if isinstance(data, dict) else {}
|
||||
# 软件类别(优先 软件类别,其次 软件名称)
|
||||
category = basic_data.get("软件名称") or basic_data.get("软件名称")
|
||||
engineering_type = basic_data.get("项目类型")
|
||||
# 规范化项目类型为 预算/清单
|
||||
if engineering_type:
|
||||
mapped_pt = PROJECT_TYPE_MAPPING.get(engineering_type)
|
||||
if mapped_pt:
|
||||
engineering_type = mapped_pt
|
||||
else:
|
||||
print(f"警告: division字段 '{division}' 格式不正确,无法分割")
|
||||
# 可以选择返回默认值或抛出异常,这里以返回默认值为例
|
||||
category = "主网"
|
||||
print(f"警告: basicData.项目类型 '{engineering_type}' 不是有效值,将使用默认值 '清单'")
|
||||
engineering_type = "清单"
|
||||
print(f"使用默认值: 软件名称={category}, 阶段类型={engineering_type}")
|
||||
return category, engineering_type
|
||||
|
||||
# 使用映射字典规范化软件类别
|
||||
# 规范化软件类别
|
||||
if category:
|
||||
if category in CATEGORY_MAPPING:
|
||||
category = CATEGORY_MAPPING[category]
|
||||
else:
|
||||
print(f"警告: division中的软件名称 '{category}' 不是有效值,将使用默认值 '主网'")
|
||||
print(f"警告: basicData中的软件名称/名称 '{category}' 不是有效值,将使用默认值 '主网'")
|
||||
category = "主网"
|
||||
|
||||
# 映射阶段类型
|
||||
if any(budget_type in stage_type for budget_type in budget_types):
|
||||
engineering_type = "预算"
|
||||
elif any(list_type in stage_type for list_type in list_types):
|
||||
engineering_type = "清单"
|
||||
else:
|
||||
print(f"警告: division中的阶段类型 '{stage_type}' 无法映射到预算或清单,将使用默认值 '清单'")
|
||||
engineering_type = "清单"
|
||||
# 提取工程类型:projectData.projectInfo.工程类型
|
||||
project_info = data.get("projectData", {}).get("projectInfo", {}) if isinstance(data, dict) else {}
|
||||
project_type = project_info.get("工程类型")
|
||||
|
||||
print(f"从division解析: 软件名称={category}, 阶段类型={engineering_type} (原始值: {stage_type})")
|
||||
return category, engineering_type
|
||||
# 打印解析结果(便于调试)
|
||||
print(f"解析完成: 软件类别={category}, 项目类型={engineering_type}, 工程类型={project_type}")
|
||||
|
||||
else:
|
||||
print(f"警告: JSON文件中未找到division字段,尝试从basicData中解析")
|
||||
|
||||
# 作为备选,尝试从basicData中获取
|
||||
if "basicData" in data:
|
||||
basic_data = data["basicData"]
|
||||
category = basic_data.get("软件名称")
|
||||
engineering_type = basic_data.get("阶段类型")
|
||||
|
||||
# 验证解析结果
|
||||
if category and engineering_type:
|
||||
# 使用映射字典规范化软件类别
|
||||
if category in CATEGORY_MAPPING:
|
||||
category = CATEGORY_MAPPING[category]
|
||||
else:
|
||||
print(f"警告: basicData中的软件名称 '{category}' 不是有效值,将使用默认值 '主网'")
|
||||
category = "主网"
|
||||
|
||||
# 确保engineering_type是有效值
|
||||
if engineering_type not in ["预算", "清单"]:
|
||||
print(f"警告: basicData中的阶段类型 '{engineering_type}' 不是有效值,将使用默认值 '清单'")
|
||||
engineering_type = "清单"
|
||||
|
||||
print(f"从basicData解析: 软件名称={category}, 阶段类型={engineering_type}")
|
||||
return category, engineering_type
|
||||
else:
|
||||
print(f"警告: basicData中未找到软件名称或阶段类型")
|
||||
else:
|
||||
print(f"警告: JSON文件中未找到basicData部分")
|
||||
|
||||
return None, None
|
||||
return category, engineering_type, project_type
|
||||
|
||||
except Exception as e:
|
||||
print(f"解析JSON文件内容时出错: {str(e)}")
|
||||
return None, None
|
||||
return None, None, None
|
||||
|
||||
|
||||
def process_json_file(
|
||||
json_file_path: str, output_dir: str, calculate_type: str = "all", project_name: str = None
|
||||
) -> bool:
|
||||
def process_json_file(json_file_path: str, output_dir: str, calculate_type: str, project_name: str = None) -> bool:
|
||||
"""
|
||||
处理单个JSON文件
|
||||
|
||||
@@ -137,20 +102,27 @@ def process_json_file(
|
||||
bool: 处理是否成功
|
||||
"""
|
||||
try:
|
||||
# 从JSON文件内容中解析软件类别和工程类型
|
||||
category, engineering_type = parse_json_content(json_file_path)
|
||||
# 从JSON文件内容中解析软件类别、项目类型(预算/清单) 和 工程类型(如 变电/线路/配网)
|
||||
# parse_json_content 返回顺序为: (category, project_type, engineering_type)
|
||||
category, project_type, engineering_type = parse_json_content(json_file_path)
|
||||
|
||||
# 如果解析失败,使用默认值
|
||||
if category is None:
|
||||
category = "主网"
|
||||
print(f"无法从文件中解析软件类别,使用默认值: {category}")
|
||||
|
||||
if engineering_type is None:
|
||||
engineering_type = "预算"
|
||||
print(f"无法从文件中解析工程类型,使用默认值: {engineering_type}")
|
||||
# 项目类型(预算/清单) 兜底
|
||||
if project_type is None:
|
||||
project_type = "预算"
|
||||
print(f"无法从文件中解析项目类型(预算/清单),使用默认值: {project_type}")
|
||||
|
||||
# 可选:记录工程类型
|
||||
if engineering_type:
|
||||
print(f"工程类型: {engineering_type}")
|
||||
|
||||
# 获取软件类型
|
||||
software_type = get_software_type(category, engineering_type)
|
||||
# 这里的第二个参数应为项目类型(预算/清单)
|
||||
software_type = get_software_type(category, project_type)
|
||||
print(f"使用软件类型: {software_type.name}")
|
||||
|
||||
# 获取计算器
|
||||
@@ -190,6 +162,8 @@ def process_json_file(
|
||||
calculator.calculate_quantity_fee_tables(
|
||||
json_file_path=json_file_path,
|
||||
project_name=project_name,
|
||||
# 这里的 project_type 传递给计算器用于BCL筛选,应为 工程类型,例如"变电/线路/配网"
|
||||
project_type=engineering_type,
|
||||
)
|
||||
|
||||
if calculate_type in ["all", "resource"]:
|
||||
@@ -217,6 +191,8 @@ def process_json_file(
|
||||
custom_calculator.calculate_quantity_fee_tables(
|
||||
json_file_path=json_file_path,
|
||||
project_name=project_name,
|
||||
# 这里的 project_type 传递给计算器用于BCL筛选,应为 工程类型,例如"变电/线路/配网"
|
||||
project_type=engineering_type,
|
||||
)
|
||||
|
||||
if calculate_type in ["all", "resource"]:
|
||||
@@ -236,7 +212,7 @@ def process_json_file(
|
||||
return False
|
||||
|
||||
|
||||
def process_directory(input_dir: str, output_dir: str, calculate_type: str = "all") -> None:
|
||||
def process_directory(input_dir: str, output_dir: str, calculate_type: str = "quantity") -> None:
|
||||
"""
|
||||
批量处理目录中的JSON文件
|
||||
|
||||
@@ -269,7 +245,7 @@ def process_directory(input_dir: str, output_dir: str, calculate_type: str = "al
|
||||
print(f"处理完成,成功: {success_count}/{len(json_files)}")
|
||||
|
||||
|
||||
def bcl_calculate(input_dir: str, output_dir: str, calculate_type: str = "all") -> None:
|
||||
def bcl_calculate(input_dir: str, output_dir: str, calculate_type: str = "quantity") -> None:
|
||||
"""
|
||||
主函数,处理指定目录中的所有JSON文件
|
||||
|
||||
|
||||
Reference in New Issue
Block a user