上传代码
This commit is contained in:
@@ -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}")
|
||||
|
||||
Reference in New Issue
Block a user