上传代码

This commit is contained in:
chentianrui
2025-09-08 17:58:02 +08:00
parent be848c3e78
commit f5f26c5cf8
76 changed files with 839039 additions and 2695 deletions
+76 -8
View File
@@ -1,5 +1,6 @@
import os
import json
import logging
from memory_profiler import profile
from typing import Dict, List, Any, Optional, Tuple
from equipment_calculation.software_types import (
@@ -32,8 +33,15 @@ CATEGORY_MAPPING = {
# 项目类型名称映射字典,将各种变体映射到标准类型(预算/清单)
PROJECT_TYPE_MAPPING = {
# 预算类变体
"概预算工程": "预算",
"初步设计概算": "预算",
"可行性研究投资估算": "预算",
"施工图预算": "预算",
"配网定额计价": "预算",
"招标控制价": "清单",
"投标报价": "清单",
"招投标工程": "清单",
"配网清单招投标计价": "清单",
}
@@ -55,8 +63,8 @@ def parse_json_content(json_file_path: str) -> Tuple[Optional[str], Optional[str
# 提取 basicData
basic_data = data.get("basicData", {}) if isinstance(data, dict) else {}
# 软件类别(优先 软件类别,其次 软件名称)
category = basic_data.get("软件名称") or basic_data.get("软件名称")
engineering_type = basic_data.get("项目类型")
category = basic_data.get("软件类别") or basic_data.get("软件名称")
engineering_type = basic_data.get("项目类型") or basic_data.get("工程类型") or basic_data.get("工程类别")
# 规范化项目类型为 预算/清单
if engineering_type:
mapped_pt = PROJECT_TYPE_MAPPING.get(engineering_type)
@@ -88,7 +96,13 @@ def parse_json_content(json_file_path: str) -> Tuple[Optional[str], Optional[str
return None, None, None
def process_json_file(json_file_path: str, output_dir: str, calculate_type: str, project_name: str = None) -> bool:
def process_json_file(
json_file_path: str,
output_dir: str,
calculate_type: str,
project_name: str = None,
bcl_dir_path: str | None = None,
) -> bool:
"""
处理单个JSON文件
@@ -127,6 +141,9 @@ def process_json_file(json_file_path: str, output_dir: str, calculate_type: str,
# 获取计算器
calculator = get_calculator(software_type)
# 若提供了 bcl 目录,优先使用新接口
if hasattr(calculator, "set_bcl_dir") and bcl_dir_path:
calculator.set_bcl_dir(bcl_dir_path)
if not calculator:
print(f"错误: 未找到软件类型 {software_type.name} 的计算器")
return False
@@ -184,6 +201,9 @@ def process_json_file(json_file_path: str, output_dir: str, calculate_type: str,
# 创建自定义输出目录的计算器
custom_calculator = CustomOutputCalculator(calculator, custom_output_dir)
# 自定义计算器同样继承 bcl_dir 设置
if hasattr(custom_calculator, "set_bcl_dir") and bcl_dir_path:
custom_calculator.set_bcl_dir(bcl_dir_path)
# 根据计算类型执行计算
if calculate_type in ["all", "quantity"]:
@@ -212,7 +232,9 @@ def process_json_file(json_file_path: str, output_dir: str, calculate_type: str,
return False
def process_directory(input_dir: str, output_dir: str, calculate_type: str = "quantity") -> None:
def process_directory(
input_dir: str, output_dir: str, calculate_type: str = "quantity", bcl_dir_path: str | None = None
) -> None:
"""
批量处理目录中的JSON文件
@@ -239,13 +261,15 @@ def process_directory(input_dir: str, output_dir: str, calculate_type: str = "qu
json_file_path = os.path.join(input_dir, json_file)
print(f"处理文件 {i}/{len(json_files)}: {json_file}")
if process_json_file(json_file_path, output_dir, calculate_type):
if process_json_file(json_file_path, output_dir, calculate_type, bcl_dir_path=bcl_dir_path):
success_count += 1
print(f"处理完成,成功: {success_count}/{len(json_files)}")
def bcl_calculate(input_dir: str, output_dir: str, calculate_type: str = "quantity") -> None:
def bcl_calculate(
input_dir: str, output_dir: str, calculate_type: str = "quantity", bcl_dir_path: str | None = None
) -> None:
"""
主函数,处理指定目录中的所有JSON文件
@@ -254,10 +278,54 @@ def bcl_calculate(input_dir: str, output_dir: str, calculate_type: str = "quanti
output_dir: 输出目录路径
calculate_type: 计算类型(all: 全部, quantity: 工程量取费, resource: 人材机合价)
"""
# 将日志写入本次工程的 bclresults 目录
_configure_bcl_logging(output_dir)
print(f"开始处理目录: {input_dir}")
print(f"输出目录: {output_dir}")
print(f"计算类型: {calculate_type}")
process_directory(input_dir, output_dir, calculate_type)
process_directory(input_dir, output_dir, calculate_type, bcl_dir_path=bcl_dir_path)
print("所有文件处理完成")
def _configure_bcl_logging(log_dir: str):
"""将 bcl 计算日志写入指定目录下的 bcl_calculator.log。
- 清理先前的 FileHandler,避免多次叠加/重复输出。
- 保留/添加一个 StreamHandler 以在控制台输出。
"""
try:
os.makedirs(log_dir, exist_ok=True)
log_path = os.path.join(log_dir, "bcl_calculator.log")
logger = logging.getLogger()
logger.setLevel(logging.INFO)
# 移除已有的 FileHandler,避免写到旧位置或重复写
for h in list(logger.handlers):
if isinstance(h, logging.FileHandler):
logger.removeHandler(h)
try:
h.close()
except Exception:
pass
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
file_handler = logging.FileHandler(log_path, mode="w", encoding="utf-8")
file_handler.setLevel(logging.INFO)
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
# 确保有一个控制台输出
if not any(isinstance(h, logging.StreamHandler) for h in logger.handlers):
stream_handler = logging.StreamHandler()
stream_handler.setLevel(logging.INFO)
stream_handler.setFormatter(formatter)
logger.addHandler(stream_handler)
print(f"日志输出重定向到: {log_path}")
except Exception as e:
print(f"配置日志输出失败,将继续使用默认日志配置: {e}")