上传代码

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
+109 -76
View File
@@ -29,30 +29,36 @@ def generate_session_id():
return "".join(random.choices(string.ascii_uppercase + string.digits, k=8))
# 创建会话工作目录
# 创建会话工作目录(仅会话根目录)
def create_session_directories(session_id):
# 定义工作目录
upload_dir = os.path.join(BASE_DIR, "uploads", session_id)
output_dir = os.path.join(BASE_DIR, "outputs", session_id)
json_dir = os.path.join(output_dir, "json")
merged_dir = os.path.join(output_dir, "merged")
bcl_results_dir = os.path.join(output_dir, "bclresults")
final_dir = os.path.join(output_dir, "final")
# 创建所有目录
for directory in [upload_dir, json_dir, merged_dir, bcl_results_dir, final_dir]:
os.makedirs(directory, exist_ok=True)
# 仅创建会话根目录用于容纳每个文件的独立GUID临时目录
session_root = os.path.join(BASE_DIR, "outputs", session_id)
os.makedirs(session_root, exist_ok=True)
return {
"upload_dir": upload_dir,
"json_dir": json_dir,
"merged_dir": merged_dir,
"bcl_results_dir": bcl_results_dir,
"final_dir": final_dir,
"output_dir": output_dir,
"session_root": session_root,
}
# 为单个上传文件创建独立的GUID临时目录,包含六个子目录
def create_file_workdirs(session_id):
file_guid = uuid.uuid4().hex
root = os.path.join(BASE_DIR, "outputs", session_id, file_guid)
dirs = {
"root": root,
"upload_dir": os.path.join(root, "uploads"), # 生成json前的上传文件夹
"bcl_dir": os.path.join(root, "bcl"), # bcl计算文件文件夹(备用,当前流程未直接使用)
"json_dir": os.path.join(root, "json"), # 生成后的json文件夹
"merged_dir": os.path.join(root, "merged"),
"bcl_results_dir": os.path.join(root, "bclresults"),
"final_dir": os.path.join(root, "final"),
}
for d in dirs.values():
os.makedirs(d, exist_ok=True)
return dirs
# 清理会话目录
def clean_session_directories(session_id):
upload_dir = os.path.join(BASE_DIR, "uploads", session_id)
@@ -78,79 +84,106 @@ def clean_session_directories(session_id):
# 整合的转化流程函数,执行步骤1到步骤4
def convert_all_steps(files, progress=gr.Progress()):
try:
# 生成会话ID并创建工作目录
# 生成会话ID并创建会话根目录
session_id = generate_session_id()
print(f"生成会话ID: {session_id}")
session_dirs = create_session_directories(session_id)
session_root = session_dirs["session_root"]
dirs = create_session_directories(session_id)
upload_dir = dirs["upload_dir"]
json_dir = dirs["json_dir"]
merged_dir = dirs["merged_dir"]
bcl_results_dir = dirs["bcl_results_dir"]
final_dir = dirs["final_dir"]
# 步骤1.1: 保存上传的文件
file_paths = []
progress(0.05, desc="保存上传文件")
for i, file in enumerate(files):
file_name = os.path.basename(file.name)
save_path = os.path.join(upload_dir, file_name)
shutil.copy(file.name, save_path)
file_paths.append(save_path)
progress(0.05 + (0.05 * (i + 1) / len(files)), desc=f"已保存 {i + 1}/{len(files)} 个文件")
# 步骤1.2: 转换为JSON
progress(0.1, desc="步骤1: 转换工程文件为JSON")
success, file_num = convert_project_to_json(upload_dir, json_dir)
# 步骤1.3: 处理JSON文件结构
progress(0.2, desc="处理JSON文件结构")
process_directory(json_dir)
# 步骤2: 费用向上汇总
progress(0.3, desc="步骤2: 费用向上汇总")
result_step2 = costsummary_upwards(json_dir, merged_dir)
# 步骤3.1: 计算工程量取费表
progress(0.5, desc="步骤3: 计算工程量取费表")
bcl_calculate(merged_dir, bcl_results_dir)
# 步骤3.2: 将BCL结果写入JSON
progress(0.6, desc="将计算结果写入JSON")
success_count_step3 = batch_write_BCLresult_into_json(merged_dir, bcl_results_dir, final_dir)
# 步骤4: 写入知识图谱
progress(0.7, desc="步骤4: 连接Neo4j数据库")
# 连接Neo4j(提前连接,避免逐文件重复连接)
progress(0.05, desc="步骤0: 连接Neo4j数据库")
config = read_config()
if not connect_to_neo4j(
config.get("neo4j", "uri"), config.get("neo4j", "user"), config.get("neo4j", "password")
):
# 清理会话目录
clean_session_directories(session_id)
return "转化失败:无法连接到Neo4j数据库。", []
progress(0.9, desc="创建知识图谱")
success_count_step4, total_count_step4, deleted_projects = create_KGs_from_folder(final_dir)
total_files = len(files) if files else 0
if total_files == 0:
clean_session_directories(session_id)
return "未选择任何文件。", []
# 结果累计
total_converted_to_json = 0
total_cost_files = 0
total_bcl_json_write = 0
total_kg_created = 0
total_kg_expected = 0
all_deleted_projects = []
# 逐文件处理
for idx, file in enumerate(files, start=1):
file_name = os.path.basename(file.name)
stage_base = (idx - 1) / total_files
stage_span = 0.9 / total_files # 从0.1到1.0之间分配给各文件
# 创建该文件的独立GUID临时目录
fdirs = create_file_workdirs(session_id)
upload_dir = fdirs["upload_dir"]
json_dir = fdirs["json_dir"]
merged_dir = fdirs["merged_dir"]
bcl_results_dir = fdirs["bcl_results_dir"]
final_dir = fdirs["final_dir"]
# 步骤1.1: 保存上传的该文件
progress(stage_base + stage_span * 0.05, desc=f"[{idx}/{total_files}] 保存上传文件: {file_name}")
save_path = os.path.join(upload_dir, file_name)
shutil.copy(file.name, save_path)
# 步骤1.2: 转换为JSON
progress(stage_base + stage_span * 0.15, desc=f"[{idx}/{total_files}] 步骤1: 转换为JSON")
success, file_num = convert_project_to_json(upload_dir, json_dir)
total_converted_to_json += file_num if success else 0
# 步骤1.3: 处理JSON文件结构
progress(stage_base + stage_span * 0.30, desc=f"[{idx}/{total_files}] 处理JSON结构")
process_directory(json_dir)
# 步骤2: 费用向上汇总
progress(stage_base + stage_span * 0.45, desc=f"[{idx}/{total_files}] 步骤2: 费用向上汇总")
result_step2 = costsummary_upwards(json_dir, merged_dir)
total_cost_files += len(result_step2) if result_step2 else 0
# 步骤3.1: 计算工程量取费表
progress(stage_base + stage_span * 0.65, desc=f"[{idx}/{total_files}] 步骤3: 计算工程量取费表")
# 传入该文件工作区的 bcl 目录
bcl_calculate(merged_dir, bcl_results_dir, bcl_dir_path=fdirs["bcl_dir"])
# 步骤3.2: 将BCL结果写入JSON
progress(stage_base + stage_span * 0.80, desc=f"[{idx}/{total_files}] 写入BCL结果到JSON")
success_count_step3 = batch_write_BCLresult_into_json(merged_dir, bcl_results_dir, final_dir)
total_bcl_json_write += success_count_step3 if success_count_step3 else 0
# 步骤4: 写入知识图谱(针对该文件的final目录)
progress(stage_base + stage_span * 0.95, desc=f"[{idx}/{total_files}] 创建知识图谱")
success_count_step4, total_count_step4, deleted_projects = create_KGs_from_folder(final_dir)
total_kg_created += success_count_step4 if success_count_step4 else 0
total_kg_expected += total_count_step4 if total_count_step4 else 0
if deleted_projects:
all_deleted_projects.extend(deleted_projects)
# 清理所有会话目录
progress(0.95, desc="清理所有临时文件")
progress(0.98, desc="清理所有临时文件")
clean_session_directories(session_id)
progress(1.0, desc="转化完成")
# 返回处理结果摘要
# 汇总结果
deleted_msg = ""
if deleted_projects:
deleted_msg = f"\n已删除 {len(deleted_projects)} 个同名工程:{', '.join(deleted_projects)}"
if all_deleted_projects:
deleted_msg = f"\n已删除 {len(all_deleted_projects)} 个同名工程:{', '.join(all_deleted_projects)}"
result_summary = f"""转化完成!
步骤1: 成功转换 {file_num} 个工程文件到JSON
步骤2: 成功处理 {len(result_step2) if result_step2 else 0} 个费用汇总文件
步骤3: 成功处理 {success_count_step3}BCL计算结果
步骤4: 成功创建 {success_count_step4}/{total_count_step4} 个知识图谱{deleted_msg}
所有临时文件已清理。
请在下方选择知识图谱并点击"导出到Excel"按钮下载。"""
result_summary = (
f"转化完成!\n"
f"步骤1: 成功转换 {total_converted_to_json} 个工程文件到JSON\n"
f"步骤2: 成功处理 {total_cost_files}费用汇总文件\n"
f"步骤3: 成功处理 {total_bcl_json_write} 个BCL计算结果\n"
f"步骤4: 成功创建 {total_kg_created}/{total_kg_expected} 个知识图谱"
f"{deleted_msg}\n"
f"所有临时文件已清理。\n\n"
f'请在下方选择知识图谱并点击"导出到Excel"按钮下载。'
)
# 获取知识图谱列表
kg_list = get_engineering_data_nodes()
@@ -448,8 +481,8 @@ def create_interface():
# 主函数
def main():
# 确保基础目录存在
os.makedirs(os.path.join(BASE_DIR, "uploads"), exist_ok=True)
os.makedirs(os.path.join(BASE_DIR, "outputs"), exist_ok=True)
# os.makedirs(os.path.join(BASE_DIR, "uploads"), exist_ok=True)
# os.makedirs(os.path.join(BASE_DIR, "outputs"), exist_ok=True)
# 创建并启动Gradio界面
app = create_interface()