10.16初步搞定

This commit is contained in:
zy123 2024-10-16 20:18:55 +08:00
parent 5673f205f1
commit 1453d4ae70
19 changed files with 729 additions and 241 deletions

1
.idea/encodings.xml generated
View File

@ -4,6 +4,7 @@
<file url="file://$PROJECT_DIR$/flask_app/static/output/1367158c-f68d-4a49-9e17-b91b4d3c60c7/log.txt" charset="GBK" /> <file url="file://$PROJECT_DIR$/flask_app/static/output/1367158c-f68d-4a49-9e17-b91b4d3c60c7/log.txt" charset="GBK" />
<file url="file://$PROJECT_DIR$/flask_app/static/output/73767188-6a8d-45a1-bc28-332d5c79d72c/log.txt" charset="GBK" /> <file url="file://$PROJECT_DIR$/flask_app/static/output/73767188-6a8d-45a1-bc28-332d5c79d72c/log.txt" charset="GBK" />
<file url="file://$PROJECT_DIR$/flask_app/static/output/866bb87b-afb6-4e99-9a1d-93405b2417ab/log.txt" charset="GBK" /> <file url="file://$PROJECT_DIR$/flask_app/static/output/866bb87b-afb6-4e99-9a1d-93405b2417ab/log.txt" charset="GBK" />
<file url="file://$PROJECT_DIR$/flask_app/static/output/87f48f9c-e6ee-4dc1-a981-5a10085c4635/log.txt" charset="GBK" />
<file url="file://$PROJECT_DIR$/flask_app/static/output/c02a12c2-6f7b-49dc-b97f-c3d740c96c21/log.txt" charset="GBK" /> <file url="file://$PROJECT_DIR$/flask_app/static/output/c02a12c2-6f7b-49dc-b97f-c3d740c96c21/log.txt" charset="GBK" />
<file url="file://$PROJECT_DIR$/flask_app/static/output/c432148a-6d7a-463b-8172-235275c2f7ce/log.txt" charset="GBK" /> <file url="file://$PROJECT_DIR$/flask_app/static/output/c432148a-6d7a-463b-8172-235275c2f7ce/log.txt" charset="GBK" />
<file url="file://$PROJECT_DIR$/flask_app/static/output/cfd4959d-5ea9-4112-8b50-9e543803f029/log.txt" charset="GBK" /> <file url="file://$PROJECT_DIR$/flask_app/static/output/cfd4959d-5ea9-4112-8b50-9e543803f029/log.txt" charset="GBK" />

View File

@ -104,7 +104,7 @@ def rename_outer_key(original_data,new_key):
return new_data return new_data
def transform_json_values(data): def transform_json_values(data):
if isinstance(data, dict): if isinstance(data, dict):
return {key: transform_json_values(value) for key, value in data.items()} return {key.replace(' ', ''): transform_json_values(value) for key, value in data.items()}
elif isinstance(data, list): elif isinstance(data, list):
return [transform_json_values(item) for item in data] return [transform_json_values(item) for item in data]
elif isinstance(data, bool): elif isinstance(data, bool):

View File

@ -1,6 +1,6 @@
import logging import logging
import re
import shutil import shutil
import sys
import time import time
import uuid import uuid
from datetime import datetime, timedelta from datetime import datetime, timedelta
@ -143,24 +143,170 @@ def zbparse():
logger.error('Exception occurred: ' + str(e)) logger.error('Exception occurred: ' + str(e))
return jsonify({'error': str(e)}), 500 return jsonify({'error': str(e)}), 500
def post_processing(data,includes): def post_processing(combined_data, includes):
# 初始化结果字典,预设'其他'分类为空字典 # 初始化结果字典,预设'其他'分类为空字典
result = {"其他": {}} processed_data = {"其他": {}}
# 初始化提取的信息字典
extracted_info = {}
# 定义一个辅助函数用于获取嵌套字典中的值
def get_nested(dic, keys, default=None):
for key in keys:
if isinstance(dic, dict):
dic = dic.get(key, default)
else:
return default
return dic
# 定义一个辅助函数用于递归查找包含特定子字符串的键
def find_keys_containing(dic, substring):
found_values = []
if isinstance(dic, dict):
for key, value in dic.items():
if substring in key:
found_values.append(value)
if isinstance(value, dict):
found_values.extend(find_keys_containing(value, substring))
elif isinstance(value, list):
for item in value:
if isinstance(item, dict):
found_values.extend(find_keys_containing(item, substring))
return found_values
# 定义一个辅助函数用于根据候选键列表提取值(部分匹配)
def extract_field(contact_info, candidate_keys):
for candidate in candidate_keys:
for key, value in contact_info.items():
if candidate in key and value not in ["未知", ""]:
return value
return ""
# 定义一个辅助函数用于提取 '投标保证金'
def extract_bid_bond(guarantee_info):
# 定义投标保证金的候选键
bid_bond_candidates = ["投标保证金", "磋商保证金"]
# 第一步:查找包含 "投标保证金" 或 "磋商保证金" 的键
for candidate in bid_bond_candidates:
for key, value in guarantee_info.items():
if candidate in key:
if isinstance(value, dict):
# 在嵌套字典中查找包含 "金额" 的键
for sub_key, sub_value in value.items():
if "金额" in sub_key and sub_value not in ["未知", ""]:
return sub_value
elif isinstance(value, str):
if "金额" in key and value not in ["未知", ""]:
return value
else:
# 如果 value 既不是 dict 也不是 str忽略
continue
# 第二步:如果没有找到包含 "金额" 的键,尝试在所有键值中查找符合模式的值
amount_pattern = re.compile(r'(?:\d{1,3}(?:[,]\d{3})*(?:\.\d+)?|\d+(?:\.\d+)?|[\u4e00-\u9fff]+(?:\.\d+)?)\s*(?:元|万元)')
for key, value in guarantee_info.items():
if isinstance(value, str):
match = amount_pattern.search(value)
if match:
return match.group()
elif isinstance(value, dict):
# 递归查找嵌套字典中的金额
found_amount = extract_bid_bond(value)
if found_amount:
return found_amount
# 如果都没有找到,则返回空字符串
return ""
# 如果 '基础信息' 在 includes 中,则进行字段提取
if "基础信息" in includes:
base_info = combined_data.get("基础信息", {})
# 定义所需字段的映射关系,暂时不包含'联系人'和'联系电话'以及'招标项目地点'
mapping = {
"招标项目名称": [["项目信息", "项目名称"], ["项目信息", "工程名称"]],
"招标项目编号": [["项目信息", "项目编号"], ["项目信息", "招标编号"]],
"开标时间": [["关键时间/内容", "开标时间"]],
"报名截止日期": [["关键时间/内容", "投标文件递交截止日期"]],
"招标项目预算": [["项目信息", "招标控制价"]],
"招标单位名称": [["招标人/代理信息", "招标人"]],
"招标公告地址": [["关键时间/内容", "信息公示媒介"], ["关键时间/内容", "评标结果公示媒介"]]
}
# 提取并映射字段
for new_key, paths in mapping.items():
value = None
for path in paths:
value = get_nested(base_info, path)
if value:
break
extracted_info[new_key] = value if value else ""
# 特殊处理 '招标项目地点'
# 在 '项目信息' 下查找包含 "地点" 的键
project_info = base_info.get("项目信息", {})
location_candidates = find_keys_containing(project_info, "地点")
if location_candidates:
# 选择第一个找到的地点
extracted_info["招标项目地点"] = location_candidates[0]
else:
extracted_info["招标项目地点"] = ""
# 特殊处理 '联系人' 和 '联系电话'
# 提取 '项目联系方式'
project_contact = get_nested(base_info, ["招标人/代理信息", "项目联系方式"], {})
# 提取 '招标人联系方式'
bidder_contact = get_nested(base_info, ["招标人/代理信息", "招标人联系方式"], {})
# 定义候选键列表,按优先级排序
name_candidates = ["名称", "联系人", "招标"]
phone_candidates = ["电话", "手机", "联系方式"]
# 提取 '联系人'
contact_names = [project_contact, bidder_contact]
contact_name = ""
for contact in contact_names:
extracted_name = extract_field(contact, name_candidates)
if extracted_name:
contact_name = extracted_name
break
extracted_info["联系人"] = contact_name
# 提取 '联系电话'
contact_phones = [project_contact, bidder_contact]
contact_phone = ""
for contact in contact_phones:
extracted_phone = extract_field(contact, phone_candidates)
if extracted_phone:
contact_phone = extracted_phone
break
extracted_info["联系电话"] = contact_phone
# 特殊处理 '投标保证金'
# 提取 '保证金相关'
guarantee_info = get_nested(base_info, ["保证金相关"], {})
extracted_info["投标保证金"] = extract_bid_bond(guarantee_info)
# 遍历原始字典的每一个键值对 # 遍历原始字典的每一个键值对
for key, value in data.items(): for key, value in combined_data.items():
if key in includes: if key in includes:
# 如果键在includes列表中直接保留这个键值对 if key == "基础信息":
result[key] = value # 已经处理 '基础信息',保留在处理后的数据中
processed_data[key] = value
else: else:
# 如果键不在includes列表中将这个键值对加入到'其他'分类中 # 直接保留包含在 includes 列表中的键值对
result["其他"][key] = value processed_data[key] = value
else:
# 将不在 includes 列表中的键值对加入到 '其他' 分类中
processed_data["其他"][key] = value
# 如果 '其他' 分类没有任何内容,可以选择删除这个键 # 如果 '其他' 分类没有任何内容,可以选择删除这个键
if not result["其他"]: if not processed_data["其他"]:
del result["其他"] del processed_data["其他"]
return processed_data, extracted_info
return result
# 分段返回 # 分段返回
def process_and_stream(file_url, zb_type): def process_and_stream(file_url, zb_type):
""" """
@ -179,6 +325,9 @@ def process_and_stream(file_url,zb_type):
filename = "ztbfile" filename = "ztbfile"
downloaded_filename = os.path.join(output_folder, filename) downloaded_filename = os.path.join(output_folder, filename)
start_time = time.time() # 记录开始时间
try:
# 下载文件 # 下载文件
downloaded = download_file(file_url, downloaded_filename) downloaded = download_file(file_url, downloaded_filename)
if not downloaded: if not downloaded:
@ -214,7 +363,8 @@ def process_and_stream(file_url,zb_type):
2: goods_bid_main 2: goods_bid_main
} }
processing_func = processing_functions.get(zb_type, engineering_bid_main) processing_func = processing_functions.get(zb_type, engineering_bid_main)
# 从 main_processing 获取数据
# 从 processing_func 获取数据
for data in processing_func(output_folder, downloaded_filepath, file_type, unique_id): for data in processing_func(output_folder, downloaded_filepath, file_type, unique_id):
if not data.strip(): if not data.strip():
logger.error("Received empty data, skipping JSON parsing.") logger.error("Received empty data, skipping JSON parsing.")
@ -226,11 +376,13 @@ def process_and_stream(file_url,zb_type):
logger.error(f"Failed to decode JSON: {e}") logger.error(f"Failed to decode JSON: {e}")
logger.error(f"Data received: {data}") logger.error(f"Data received: {data}")
continue # Skip data if JSON parsing fails continue # Skip data if JSON parsing fails
# 遍历 parsed_data 只提取内层内容进行合并 # 遍历 parsed_data 只提取内层内容进行合并
for outer_key, inner_dict in parsed_data.items(): for outer_key, inner_dict in parsed_data.items():
if isinstance(inner_dict, dict): if isinstance(inner_dict, dict):
combined_data.update(inner_dict) combined_data.update(inner_dict)
# 日志记录已合并数据 # 日志记录已合并数据
# 每次数据更新后,流式返回当前进度 # 每次数据更新后,流式返回当前进度
response = { response = {
'message': 'Processing', 'message': 'Processing',
@ -238,25 +390,37 @@ def process_and_stream(file_url,zb_type):
'data': data 'data': data
} }
yield f"data: {json.dumps(response, ensure_ascii=False)}\n\n" yield f"data: {json.dumps(response, ensure_ascii=False)}\n\n"
# 日志记录已合并数据 # 日志记录已合并数据
logger.info(f"合并后的数据: {json.dumps(combined_data, ensure_ascii=False, indent=4)}") logger.info(f"合并后的数据: {json.dumps(combined_data, ensure_ascii=False, indent=4)}")
# **保存 combined_data 到 output_folder 下的 'final_result.json'** # **保存 combined_data 到 output_folder 下的 'final_result.json'**
output_json_path = os.path.join(output_folder, 'final_result.json') output_json_path = os.path.join(output_folder, 'final_result.json')
includes = ["基础信息", "资格审查", "商务评分", "技术评分", "无效标与废标项", "投标文件要求", "开评定标流程"] includes = ["基础信息", "资格审查", "商务评分", "技术评分", "无效标与废标项", "投标文件要求", "开评定标流程"]
result = post_processing(combined_data, includes) final_result, extracted_info = post_processing(combined_data, includes)
try: try:
with open(output_json_path, 'w', encoding='utf-8') as json_file: with open(output_json_path, 'w', encoding='utf-8') as json_file:
json.dump(result, json_file, ensure_ascii=False, indent=4) json.dump(final_result, json_file, ensure_ascii=False, indent=4)
logger.info(f"合并后的数据已保存到 '{output_json_path}'") logger.info(f"合并后的数据已保存到 '{output_json_path}'")
except IOError as e: except IOError as e:
logger.error(f"保存JSON文件时出错: {e}") logger.error(f"保存JSON文件时出错: {e}")
extracted_info_response = {
'message': 'extracted_info',
'filename': os.path.basename(downloaded_filepath),
'data': json.dumps(extracted_info, ensure_ascii=False)
}
yield f"data: {json.dumps(extracted_info_response, ensure_ascii=False)}\n\n"
# 最后发送合并后的完整数据 # 最后发送合并后的完整数据
complete_response = { complete_response = {
'message': 'Combined data', 'message': 'Combined_data',
'filename': os.path.basename(downloaded_filepath), 'filename': os.path.basename(downloaded_filepath),
'data': json.dumps(result, ensure_ascii=False) 'data': json.dumps(final_result, ensure_ascii=False)
} }
yield f"data: {json.dumps(complete_response, ensure_ascii=False)}\n\n" yield f"data: {json.dumps(complete_response, ensure_ascii=False)}\n\n"
# 发送最终响应 # 发送最终响应
final_response = { final_response = {
'message': 'File uploaded and processed successfully', 'message': 'File uploaded and processed successfully',
@ -265,6 +429,12 @@ def process_and_stream(file_url,zb_type):
} }
yield f"data: {json.dumps(final_response)}\n\n" yield f"data: {json.dumps(final_response)}\n\n"
finally:
end_time = time.time() # 记录结束时间
duration = end_time - start_time
logger.info(f"Total processing time: {duration:.2f} seconds")
@app.route('/api/test_zbparse', methods=['POST']) @app.route('/api/test_zbparse', methods=['POST'])
def test_zbparse(): def test_zbparse():
try: try:

View File

@ -1,51 +1,264 @@
import json
import re import re
from docx import Document combined_data = {
def preprocess_paragraphs(paragraphs): "基础信息": {
processed = [] "招标人/代理信息": {
index = 0 "招标人": "广水市公安局",
while index < len(paragraphs): "招标人联系方式": {
current_text = paragraphs[index].text.strip() "名称": "广水市公安局",
"地址": "广水市应山办事处应十大道 189号",
"联系电话": "未知"
},
"招标代理机构": "湖北楚振捷工程项目管理有限公司",
"招标代理机构联系方式": {
"名称": "湖北楚振捷工程项目管理有限公司",
"地址": "广水市永阳一路 41号",
"联系方式": "0722-6256088"
},
"项目联系方式":{
"名称":"张三",
"联系电话":"11"
}
},
"项目信息": {
"项目名称": "广水市公安局视频会议高清化改造项目",
"项目编号": "HBCZJ-2021-CS12",
"项目概况": "广水市公安局视频会议高清化改造项目",
"项目基本情况": {
"项目编号": "HBCZJ-2021-CS12",
"采购计划备案号": "2021-04-000399",
"项目名称": "广水市公安局视频会议高清化改造项目",
"采购方式": "竞争性磋商",
"预算金额": "192万元",
"最高限价": "192万元",
"采购需求": {
"项目概况及内容": "广水市公安局视频会议高清化改造项目。",
"招标范围": "广水市公安局视频会议高清化改造项目,具体内容见磋商文件第三章。",
"项目地点": "具体以合同约定为准。"
},
"合同履行期限": "以合同签订为准。",
"本项目(是/否)接受联合体投标": "",
"是否可采购进口产品": ""
},
"招标控制价": "192万元",
"投标竞争下浮率": "未知",
"是否允许分包": "未知",
"是否接受联合体投标": ""
},
"采购要求": {
"技术要求": "未提供",
"商务要求": "未提供",
"服务要求": "未提供",
"其他要求": "未提供"
},
"关键时间/内容": {
"投标文件递交截止日期": "2021年 6月 18日 15点 00分",
"开标时间":"111",
"开标地点":"哈哈",
"澄清招标文件的截止时间": "未知",
"投标有效期": "90日历天",
"信息公示媒介": "中国湖北政府采购网http://www.ccgp-hubei.gov.cn, 中国广水网http://www.zggsw.gov.cn/",
"投标文件递交地点": "广水市公共资源交易中心五楼 501号开标室"
# 检测是否为空白行 },
if current_text == '': "保证金相关": {
# 确保有前一行和后一行 "质量保证金": "未知",
if index > 0 and index + 1 < len(paragraphs): "履约保证金": "不提交",
prev_text = paragraphs[index - 1].text.strip() "退还投标保证金": "/",
# print(prev_text) "投标保证金": {
next_text = paragraphs[index + 1].text.strip() "价格":"100000000.00 元"
# print(next_text) }
# print("------------------------------") },
# 检查前一行是否不以指定标点结尾 "其他信息": {
if not prev_text.endswith(('', ',', '', '!', '?')): "是否退还投标文件": "",
# 检查后一行是否以序号开头 "投标费用承担": "供应商应承担所有与准备和参加磋商有关的费用,不论磋商的结果如何,采购人和采购代理机构均无义务和责任承担这些费用。",
if re.match(r'^(\d+(\s*\.\s*\d+)*)\s*', prev_text) and not re.match(r'^(\d+(\s*\.\s*\d+)*)\s*、',next_text) and len(prev_text)>30: "招标代理服务费": {
# 合并前一行和后一行 "支付人": "成交供应商",
merged_text = prev_text + next_text "支付标准": "根据国家发展与改革委员会办公厅发改办价格【2003】857 号文的规定经协商由成交供应商按国家发展和改革委员发改价格【2011】534号文规定货物类取费标准向采购代理机构支付招标代理服务费包含“招标代理费、评标会务费、评标费”如本项目各包服务费不足叁仟元则供应商按叁仟元支付服务费。",
# print(merged_text) "支付方式": "成交服务费由成交供应商在领取成交通知书的同时向代理机构支付,可使用现金或电汇办理",
# print("---------------------------------") "支付时间": "领取成交通知书的同时"
if processed: },
# 用合并后的文本替换已处理的前一行 "偏离": {
processed[-1] = merged_text "偏离项要求": "供应商需在响应文件中提供《采购需求响应、偏离说明表/导读表》具体格式见第六章响应文件格式中的49页。供应商需对采购需求中的各项技术参数和服务要求进行逐项响应明确表明无偏离、正偏离或负偏离的情况。对于负偏离项需详细说明偏离的具体内容及原因。",
"偏离项内容": "未知"
},
"投标预备会": "不召开",
"踏勘现场": "不组织"
}
},
"资格审查": { },
"商务评分": { },
"技术评分": { },
"zhes":"11111"
# 其他键值对
}
includes = ["基础信息", "资格审查", "商务评分", "技术评分", "无效标与废标项", "投标文件要求", "开评定标流程"]
def post_processing(combined_data, includes):
# 初始化结果字典,预设'其他'分类为空字典
processed_data = {"其他": {}}
# 初始化提取的信息字典
extracted_info = {}
# 定义一个辅助函数用于获取嵌套字典中的值
def get_nested(dic, keys, default=None):
for key in keys:
if isinstance(dic, dict):
dic = dic.get(key, default)
else: else:
processed.append(merged_text) return default
# 跳过后一行 return dic
index += 2
# 定义一个辅助函数用于递归查找包含特定子字符串的键
def find_keys_containing(dic, substring):
found_values = []
if isinstance(dic, dict):
for key, value in dic.items():
if substring in key:
found_values.append(value)
if isinstance(value, dict):
found_values.extend(find_keys_containing(value, substring))
elif isinstance(value, list):
for item in value:
if isinstance(item, dict):
found_values.extend(find_keys_containing(item, substring))
return found_values
# 定义一个辅助函数用于根据候选键列表提取值(部分匹配)
def extract_field(contact_info, candidate_keys):
for candidate in candidate_keys:
for key, value in contact_info.items():
if candidate in key and value not in ["未知", ""]:
return value
return ""
# 定义一个辅助函数用于提取 '投标保证金'
def extract_bid_bond(guarantee_info):
# 定义投标保证金的候选键
bid_bond_candidates = ["投标保证金", "磋商保证金"]
# 第一步:查找包含 "投标保证金" 或 "磋商保证金" 的键
for candidate in bid_bond_candidates:
for key, value in guarantee_info.items():
if candidate in key:
if isinstance(value, dict):
# 在嵌套字典中查找包含 "金额" 的键
for sub_key, sub_value in value.items():
if "金额" in sub_key and sub_value not in ["未知", ""]:
return sub_value
elif isinstance(value, str):
if "金额" in key and value not in ["未知", ""]:
return value
else:
# 如果 value 既不是 dict 也不是 str忽略
continue continue
# 第二步:如果没有找到包含 "金额" 的键,尝试在所有键值中查找符合模式的值
amount_pattern = re.compile(r'(?:\d{1,3}(?:[,]\d{3})*(?:\.\d+)?|\d+(?:\.\d+)?|[\u4e00-\u9fff]+(?:\.\d+)?)\s*(?:元|万元)')
for key, value in guarantee_info.items():
if isinstance(value, str):
match = amount_pattern.search(value)
if match:
return match.group()
elif isinstance(value, dict):
# 递归查找嵌套字典中的金额
found_amount = extract_bid_bond(value)
if found_amount:
return found_amount
# 如果都没有找到,则返回空字符串
return ""
# 如果 '基础信息' 在 includes 中,则进行字段提取
if "基础信息" in includes:
base_info = combined_data.get("基础信息", {})
# 定义所需字段的映射关系,暂时不包含'联系人'和'联系电话'以及'招标项目地点'
mapping = {
"招标项目名称": [["项目信息", "项目名称"], ["项目信息", "工程名称"]],
"招标项目编号": [["项目信息", "项目编号"], ["项目信息", "招标编号"]],
"开标时间": [["关键时间/内容", "开标时间"]],
"报名截止日期": [["关键时间/内容", "投标文件递交截止日期"]],
"招标项目预算": [["项目信息", "招标控制价"]],
"招标单位名称": [["招标人/代理信息", "招标人"]],
"招标公告地址": [["关键时间/内容", "信息公示媒介"], ["关键时间/内容", "评标结果公示媒介"]]
}
# 提取并映射字段
for new_key, paths in mapping.items():
value = None
for path in paths:
value = get_nested(base_info, path)
if value:
break
extracted_info[new_key] = value if value else ""
# 特殊处理 '招标项目地点'
# 在 '项目信息' 下查找包含 "地点" 的键
project_info = base_info.get("项目信息", {})
location_candidates = find_keys_containing(project_info, "地点")
if location_candidates:
# 选择第一个找到的地点
extracted_info["招标项目地点"] = location_candidates[0]
else: else:
# 非空白行,直接添加到处理后的列表 extracted_info["招标项目地点"] = ""
processed.append(current_text)
index += 1 # 特殊处理 '联系人' 和 '联系电话'
return processed # 提取 '项目联系方式'
project_contact = get_nested(base_info, ["招标人/代理信息", "项目联系方式"], {})
doc_path = 'D:\\flask_project\\flask_app\\static\\output\\015d997e-c32c-49d1-a611-a2e817ace6a1\\ztbfile.docx' # 提取 '招标人联系方式'
doc = Document(doc_path) bidder_contact = get_nested(base_info, ["招标人/代理信息", "招标人联系方式"], {})
# 假设 doc 是您的文档对象 # 定义候选键列表,按优先级排序
processed_paragraphs = preprocess_paragraphs(doc.paragraphs) name_candidates = ["名称", "联系人", "招标"]
for i in processed_paragraphs: phone_candidates = ["电话", "手机", "联系方式"]
print("___________________________")
print(i) # 提取 '联系人'
contact_names = [project_contact, bidder_contact]
contact_name = ""
for contact in contact_names:
extracted_name = extract_field(contact, name_candidates)
if extracted_name:
contact_name = extracted_name
break
extracted_info["联系人"] = contact_name
# 提取 '联系电话'
contact_phones = [project_contact, bidder_contact]
contact_phone = ""
for contact in contact_phones:
extracted_phone = extract_field(contact, phone_candidates)
if extracted_phone:
contact_phone = extracted_phone
break
extracted_info["联系电话"] = contact_phone
# 特殊处理 '投标保证金'
# 提取 '保证金相关'
guarantee_info = get_nested(base_info, ["保证金相关"], {})
extracted_info["投标保证金"] = extract_bid_bond(guarantee_info)
# 遍历原始字典的每一个键值对
for key, value in combined_data.items():
if key in includes:
if key == "基础信息":
# 已经处理 '基础信息',保留在处理后的数据中
processed_data[key] = value
else:
# 直接保留包含在 includes 列表中的键值对
processed_data[key] = value
else:
# 将不在 includes 列表中的键值对加入到 '其他' 分类中
processed_data["其他"][key] = value
# 如果 '其他' 分类没有任何内容,可以选择删除这个键
if not processed_data["其他"]:
del processed_data["其他"]
return processed_data, extracted_info
res1,res2=post_processing(combined_data,includes)
print(json.dumps(res2,ensure_ascii=False,indent=4))

View File

@ -46,11 +46,11 @@ def merge_json_to_list(merged):
merged['分包'] = '不允许' merged['分包'] = '不允许'
merged.pop('是否允许分包', None) merged.pop('是否允许分包', None)
# 处理是否递交投标保证金或磋商保证金
guarantee_key = '是否递交投标保证金' if '是否递交投标保证金' in merged else '是否递交磋商保证金' guarantee_key = '是否递交投标保证金' if '是否递交投标保证金' in merged else '是否递交磋商保证金'
if merged.get(guarantee_key) == '': if merged.get(guarantee_key) == '':
chosen_numbers.extend([2, 3]) chosen_numbers.extend([2, 3])
else: merged.pop(guarantee_key, None)
elif merged.get(guarantee_key) == '':
guarantee_type = '投标' if '投标' in guarantee_key else '磋商' guarantee_type = '投标' if '投标' in guarantee_key else '磋商'
merged[f'{guarantee_type}保证金'] = '不提交' merged[f'{guarantee_type}保证金'] = '不提交'
merged[f'退还{guarantee_type}保证金'] = '/' merged[f'退还{guarantee_type}保证金'] = '/'
@ -82,7 +82,8 @@ def merge_json_to_list(merged):
preparation_key = '是否召开投标预备会' if '是否召开投标预备会' in merged else '是否召开投标答疑会' preparation_key = '是否召开投标预备会' if '是否召开投标预备会' in merged else '是否召开投标答疑会'
if merged.get(preparation_key) == '': if merged.get(preparation_key) == '':
chosen_numbers.append(7) chosen_numbers.append(7)
else: merged.pop(preparation_key, None)
elif merged.get(preparation_key) == '':
meeting_type = '预备会' if '预备会' in preparation_key else '答疑会' meeting_type = '预备会' if '预备会' in preparation_key else '答疑会'
merged[f'投标{meeting_type}']='不召开' merged[f'投标{meeting_type}']='不召开'
merged.pop(preparation_key,None) merged.pop(preparation_key,None)

View File

@ -18,11 +18,13 @@ def aggregate_basic_info(baseinfo_list):
- dict: 合并和分类后的基础信息字典 - dict: 合并和分类后的基础信息字典
""" """
key_groups = { key_groups = {
"招标人/代理信息": ["招标人", "招标人联系方式", "招标代理机构", "招标代理机构联系方式","招标代理服务费"], "招标人/代理信息": ["招标人", "招标人联系方式", "招标代理机构", "招标代理机构联系方式"],
"项目信息": ["项目名称", "招标编号", "项目概况", "招标范围", "招标控制价", "投标竞争下浮率"], "项目信息": ["项目名称", "招标编号", "项目概况", "招标范围", "招标控制价", "投标竞争下浮率"],
"关键时间/内容": [ "关键时间/内容": [
"投标文件递交截止日期", "投标文件递交截止日期",
"递交方式", "投标文件递交方式",
"开标时间",
"开标地点",
"投标人要求澄清招标文件的截止时间", "投标人要求澄清招标文件的截止时间",
"投标有效期", "投标有效期",
"评标结果公示媒介" "评标结果公示媒介"
@ -30,8 +32,9 @@ def aggregate_basic_info(baseinfo_list):
"保证金相关": ["质量保证金", "退还投标保证金"], "保证金相关": ["质量保证金", "退还投标保证金"],
"其他信息": [ "其他信息": [
"重新招标、不再招标和终止招标", "重新招标、不再招标和终止招标",
"投标费用承担",
"招标代理服务费",
"是否退还投标文件", "是否退还投标文件",
"投标费用承担"
] ]
} }
@ -60,11 +63,17 @@ def aggregate_basic_info(baseinfo_list):
def dynamic_key_handling(key_groups, detected_keys): def dynamic_key_handling(key_groups, detected_keys):
# 检查和调整键组配置 # 检查和调整键组配置
for key in detected_keys: for key in detected_keys:
if "投标保证金" in key or "履约保证金" in key: # 处理“保证金相关”组,插到"质量保证金"前
key_groups["保证金相关"].append(key) if "保证金" in key:
elif "是否接受联合体" in key: group = key_groups["保证金相关"]
key_groups["项目信息"].append(key) insert_before = "质量保证金"
elif "联合体投标要求" in key: if insert_before in group:
index = group.index(insert_before)
if key not in group: # 避免重复插入
group.insert(index, key)
else:
group.append(key) # 如果没有找到特定键,则追加到末尾
elif "联合体" in key:
key_groups["项目信息"].append(key) key_groups["项目信息"].append(key)
elif "分包" in key: elif "分包" in key:
key_groups["项目信息"].append(key) key_groups["项目信息"].append(key)

View File

@ -34,14 +34,33 @@ prom = '请记住以下材料,他们对回答问题有帮助,请你简洁准
def read_questions_from_file(file_path): def read_questions_from_file(file_path):
questions = [] questions = []
current_question = ""
current_number = 0
with open(file_path, 'r', encoding='utf-8') as file: with open(file_path, 'r', encoding='utf-8') as file:
for line in file: for line in file:
line = line.strip() line = line.strip()
# 使用正则表达式匹配以数字开头,后接一个点的行 if not line: # 跳过空行
if re.match(r'\d+\.', line): continue
# 从点后分割并去除前后空格获取问题部分
question = line.split('.', 1)[1].strip() # 检查是否是新的问题编号
questions.append(question) match = re.match(r'^(\d+)\.', line)
if match:
# 如果有之前的问题,保存它
if current_question:
questions.append(current_question.strip())
# 开始新的问题
current_number = int(match.group(1))
current_question = line.split('.', 1)[1].strip() + "\n"
else:
# 继续添加到当前问题
current_question += line + "\n"
# 添加最后一个问题
if current_question:
questions.append(current_question.strip())
return questions return questions
@ -258,40 +277,40 @@ def multi_threading(queries, knowledge_name="", file_id="", llm_type=1):
# 检查是否所有结果都是 None # 检查是否所有结果都是 None
if all(result is None for result in results): if all(result is None for result in results):
return [] return []
# 过滤掉None值
results = [r for r in results if r is not None]
# 返回一个保证是列表的结构 # 返回一个保证是列表的结构
return results return results
if __name__ == "__main__": if __name__ == "__main__":
# start_time=time.time() start_time=time.time()
# # 读取问题列表 # # 读取问题列表
# questions =read_questions_from_file('../static/提示词/前两章提问总结.txt') baseinfo_file_path = 'D:\\flask_project\\flask_app\\static\\提示词\\前两章提问总结.txt'
# for i in questions: questions =read_questions_from_file(baseinfo_file_path)
# print(i) knowledge_name = "招标解析5word"
# knowledge_name = "招标解析5word" llm_type=1
# llm_type=1 results = multi_threading(questions, knowledge_name)
# results = multi_threading(questions, knowledge_name) end_time = time.time()
# end_time = time.time() if not results:
print("errror!")
else:
print("elapsed time:"+str(end_time-start_time))
# 打印结果
for question, response in results:
print(f"Response: {response}")
# file_path = "C:\\Users\\Administrator\\Desktop\\货物标\\zbfiles\\6.2定版视频会议磋商文件(1)\\6.2定版视频会议磋商文件_1-21.pdf"
# file_id = upload_file(file_path)
# questions=["该招标文件的项目名称是项目编号或招标编号采购人或招标人采购代理机构或招标代理机构请按json格式给我提供信息键名分别是'项目名称','项目编号','采购人','采购代理机构',若存在未知信息,在对应的键值中填'未知'。","该招标文件的项目概况是项目基本情况是请按json格式给我提供信息键名分别为'项目概况','项目基本情况',若存在嵌套信息,嵌套内容键名以文件中对应字段命名,而嵌套键值必须与原文保持一致,若存在未知信息,在对应的键值中填'未知'。"]
# results=multi_threading(questions,"",file_id,2) #1代表使用百炼rag 2代表使用qianwen-long
# if not results: # if not results:
# print("errror!") # print("errror!")
# else: # else:
# print("elapsed time:"+str(end_time-start_time))
# # 打印结果 # # 打印结果
# for question, response in results: # for question, response in results:
# print(f"Question: {question}") # print(f"Question: {question}")
# print(f"Response: {response}") # print(f"Response: {response}")
file_path = "C:\\Users\\Administrator\\Desktop\\货物标\\zbfiles\\6.2定版视频会议磋商文件(1)\\6.2定版视频会议磋商文件_1-21.pdf"
file_id = upload_file(file_path)
questions=["该招标文件的项目名称是项目编号或招标编号采购人或招标人采购代理机构或招标代理机构请按json格式给我提供信息键名分别是'项目名称','项目编号','采购人','采购代理机构',若存在未知信息,在对应的键值中填'未知'","该招标文件的项目概况是项目基本情况是请按json格式给我提供信息键名分别为'项目概况','项目基本情况',若存在嵌套信息,嵌套内容键名以文件中对应字段命名,而嵌套键值必须与原文保持一致,若存在未知信息,在对应的键值中填'未知'"]
results=multi_threading(questions,"",file_id,2) #1代表使用百炼rag 2代表使用qianwen-long
if not results:
print("errror!")
else:
# 打印结果
for question, response in results:
print(f"Question: {question}")
print(f"Response: {response}")
# ques=["关于'资格要求',本采购文件第一章第二款要求的内容是怎样的请按json格式给我提供信息键名为'资格要求',而键值需要完全与原文保持一致,不要擅自总结、删减,如果存在未知信息,请在对应键值处填'未知'。"] # ques=["关于'资格要求',本采购文件第一章第二款要求的内容是怎样的请按json格式给我提供信息键名为'资格要求',而键值需要完全与原文保持一致,不要擅自总结、删减,如果存在未知信息,请在对应键值处填'未知'。"]
# # ques=["该招标文件的工程名称项目名称招标编号是招标人是招标代理机构是请按json格式给我提供信息键名分别是'工程名称','招标编号','招标人','招标代理机构',若存在未知信息,在对应的键值中填'未知'。","该招标文件的工程概况或项目概况招标范围是请按json格式给我提供信息键名分别为'工程概况','招标范围',若存在嵌套信息,嵌套内容键名以文件中对应字段命名,若存在未知信息,在对应的键值中填'未知'。"] # # ques=["该招标文件的工程名称项目名称招标编号是招标人是招标代理机构是请按json格式给我提供信息键名分别是'工程名称','招标编号','招标人','招标代理机构',若存在未知信息,在对应的键值中填'未知'。","该招标文件的工程概况或项目概况招标范围是请按json格式给我提供信息键名分别为'工程概况','招标范围',若存在嵌套信息,嵌套内容键名以文件中对应字段命名,若存在未知信息,在对应的键值中填'未知'。"]
# results = multi_threading(ques, "6.2视频会议docx") # results = multi_threading(ques, "6.2视频会议docx")

View File

@ -297,7 +297,7 @@ def handle_query(file_path, user_query, output_file, result_key, keywords, trunc
file_id = upload_file(output_file) file_id = upload_file(output_file)
qianwen_ans = qianwen_long(file_id, user_query) qianwen_ans = qianwen_long(file_id, user_query)
num_list = process_string_list(qianwen_ans) num_list = process_string_list(qianwen_ans)
print(num_list) print(result_key+"选中的序号:"+str(num_list))
for index in num_list: for index in num_list:
if index - 1 < len(qianwen_txt): if index - 1 < len(qianwen_txt):

View File

@ -0,0 +1,33 @@
1.该招标文件的项目名称或工程名称招标编号或项目编号招标人是招标代理机构是请按json格式给我提供信息键名分别是'项目名称','招标编号','招标人','招标代理机构',若存在未知信息,在对应的键值中填'未知'。
#该招标文件的项目概况(或工程概况)是?招标范围是?招标控制价(可指代投标限价、投资概算金额、工程概算金额、合同估算价,但非监理费用)是?该项目的计划工期(监理服务期)是该项目是否接受联合体投标请按json格式给我提供信息键名分别为'工程概况','招标范围','招标控制价','计划工期','是否接受联合体投标',若存在嵌套信息,嵌套内容键名以文件中对应字段命名,若存在未知信息,在对应的键值中填'未知''是否接受联合体投标'的键值仅限于'是'、'否'、'未知'。
2.该招标文件的工程概况或项目概况招标范围是请按json格式给我提供信息键名分别为'项目概况','招标范围',若存在嵌套信息,嵌套内容键名以文件中对应字段命名,若存在未知信息,在对应的键值中填'未知'。
3.该招标文件的招标控制价可指代投标限价、投资概算金额、工程概算金额、合同估算价但非监理费用请按json格式给我提供信息键名为'招标控制价',若存在未知信息,在对应的键值中填'未知'。
4.投标文件递交截止日期是递交方式是请按json格式给我提供信息键名分别是'投标文件递交截止日期','投标文件递交方式',若存在未知信息,在对应的键值中填'未知'。
5.招标人和招标代理机构的联系方式是请按json格式给我提供信息键名分别是'招标人联系方式''招标代理机构联系方式',若存在嵌套信息,嵌套内容键名以文件中对应字段命名,若存在未知信息,在对应的键值中填'未知'。
##(三个问题分开问)根据第二章投标人须知的内容,该招标文件是否允许分包? 是否需要递交投标保证金是否有履约保证金履约担保是否有招标代理服务费你需要留意☑后的内容。请按json格式给我提供信息键名分别为'是否允许分包','是否递交投标保证金','是否有履约保证金','是否有招标代理服务费',键值仅限于'是','否','未知'。可以一起问设置摘取分段为8仍存在问题pdf转word文件打勾符号可能会无法正常显示解决思路1根据原pdf进行提取
6.该招标文件的评标结果定标候选人公示媒介在哪请按json格式给我提供信息键名是'评标结果公示媒介',若存在未知信息,在对应的键值中填'未知'。
7.该招标文件的投标竞争下浮率是多少请按json格式给我提供信息键名是'投标竞争下浮率',若存在未知信息,在对应的键值中填'未知'。
#11.该招标文件的投标竞争下浮率是多少若请按json格式给我提供信息键名是'投标竞争下浮率',若存在嵌套信息,嵌套内容键名以文件中对应字段命名,若存在未知信息,在对应的键值中填'未知'。
8.该项目的投标有效期是什么请按json格式给我提供信息键名是'投标有效期',若存在未知信息,在对应的键值中填'未知'。
#该招标中对于实质性要求(废标项)的内容有哪些规定投标人不得存在的情形有哪些文件中提及的否决和无效投标情形有哪些请以json格式返回结果键名分别'实质性要求','不得存在的情形','否决和无效投标情形',若存在未知信息,请在对应键值中填'未知',你的回答一切以原文内容为准,不可改动。
#8.该招标文件的电子招标文件获取方式是请按原文段落全部完整内容回答以json的格式给我提供信息键名是'电子招标文件获取方式',若存在未知信息,在对应的键值中填'未知'。
9.该招标文件中对投标人准备和参加投标活动发生的费用是如何规定的请以json的格式给我提供信息键名是'投标费用承担',若存在未知信息,在对应的键值中填'未知'。
10.求澄清的招标文件截止时间是请以json的格式给我提供信息键名是'投标人要求澄清招标文件的截止时间',若存在未知信息,在对应的键值中填'未知'。
11.该文档要求扣留的质量保证金百分比是多少请以json格式给我提供信息键名为'质量保证金',如果没有则以'未知'填充。
12.该项目是否接受联合体投标请按json格式给我提供信息键名为'是否接受联合体投标''是否接受联合体投标'的键值仅限于'是'、'否'、'未知'。
13.该项目的开标时间开启时间和开标地点是请按json格式给我提供信息键名为'开标时间'和'开标地点',若存在未知信息,在对应的键值中填'未知'。

View File

@ -1,6 +1,5 @@
1.该招标文件的项目名称或工程名称招标编号或项目编号招标人是招标代理机构是请按json格式给我提供信息键名分别是'项目名称','招标编号','招标人','招标代理机构',若存在未知信息,在对应的键值中填'未知'。 1.该招标文件的项目名称或工程名称招标编号或项目编号招标人是招标代理机构是请按json格式给我提供信息键名分别是'项目名称','招标编号','招标人','招标代理机构',若存在未知信息,在对应的键值中填'未知'。
#该招标文件的项目概况(或工程概况)是?招标范围是?招标控制价(可指代投标限价、投资概算金额、工程概算金额、合同估算价,但非监理费用)是?该项目的计划工期(监理服务期)是该项目是否接受联合体投标请按json格式给我提供信息键名分别为'工程概况','招标范围','招标控制价','计划工期','是否接受联合体投标',若存在嵌套信息,嵌套内容键名以文件中对应字段命名,若存在未知信息,在对应的键值中填'未知''是否接受联合体投标'的键值仅限于'是'、'否'、'未知'。
2.该招标文件的工程概况或项目概况招标范围是请按json格式给我提供信息键名分别为'项目概况','招标范围',若存在嵌套信息,嵌套内容键名以文件中对应字段命名,若存在未知信息,在对应的键值中填'未知'。 2.该招标文件的工程概况或项目概况招标范围是请按json格式给我提供信息键名分别为'项目概况','招标范围',若存在嵌套信息,嵌套内容键名以文件中对应字段命名,若存在未知信息,在对应的键值中填'未知'。
3.该招标文件的招标控制价可指代投标限价、投资概算金额、工程概算金额、合同估算价但非监理费用请按json格式给我提供信息键名为'招标控制价',若存在未知信息,在对应的键值中填'未知'。 3.该招标文件的招标控制价可指代投标限价、投资概算金额、工程概算金额、合同估算价但非监理费用请按json格式给我提供信息键名为'招标控制价',若存在未知信息,在对应的键值中填'未知'。
@ -9,20 +8,11 @@
5.招标人和招标代理机构的联系方式是请按json格式给我提供信息键名分别是'招标人联系方式''招标代理机构联系方式',若存在嵌套信息,嵌套内容键名以文件中对应字段命名,若存在未知信息,在对应的键值中填'未知'。 5.招标人和招标代理机构的联系方式是请按json格式给我提供信息键名分别是'招标人联系方式''招标代理机构联系方式',若存在嵌套信息,嵌套内容键名以文件中对应字段命名,若存在未知信息,在对应的键值中填'未知'。
##8.该项目的开标时间和地点是请按json格式给我提供信息键名为'开标时间'和'开标地点',若存在未知信息,在对应的键值中填'未知'。
##(三个问题分开问)根据第二章投标人须知的内容,该招标文件是否允许分包? 是否需要递交投标保证金是否有履约保证金履约担保是否有招标代理服务费你需要留意☑后的内容。请按json格式给我提供信息键名分别为'是否允许分包','是否递交投标保证金','是否有履约保证金','是否有招标代理服务费',键值仅限于'是','否','未知'。可以一起问设置摘取分段为8仍存在问题pdf转word文件打勾符号可能会无法正常显示解决思路1根据原pdf进行提取
6.该招标文件的评标结果定标候选人公示媒介在哪请按json格式给我提供信息键名是'评标结果公示媒介',若存在未知信息,在对应的键值中填'未知'。 6.该招标文件的评标结果定标候选人公示媒介在哪请按json格式给我提供信息键名是'评标结果公示媒介',若存在未知信息,在对应的键值中填'未知'。
7.该招标文件的投标竞争下浮率是多少请按json格式给我提供信息键名是'投标竞争下浮率',若存在未知信息,在对应的键值中填'未知'。 7.该招标文件的投标竞争下浮率是多少请按json格式给我提供信息键名是'投标竞争下浮率',若存在未知信息,在对应的键值中填'未知'。
#11.该招标文件的投标竞争下浮率是多少若请按json格式给我提供信息键名是'投标竞争下浮率',若存在嵌套信息,嵌套内容键名以文件中对应字段命名,若存在未知信息,在对应的键值中填'未知'。
8.该项目的投标有效期是什么请按json格式给我提供信息键名是'投标有效期',若存在未知信息,在对应的键值中填'未知'。 8.该项目的投标有效期是什么请按json格式给我提供信息键名是'投标有效期',若存在未知信息,在对应的键值中填'未知'。
#该招标中对于实质性要求(废标项)的内容有哪些规定投标人不得存在的情形有哪些文件中提及的否决和无效投标情形有哪些请以json格式返回结果键名分别'实质性要求','不得存在的情形','否决和无效投标情形',若存在未知信息,请在对应键值中填'未知',你的回答一切以原文内容为准,不可改动。
#8.该招标文件的电子招标文件获取方式是请按原文段落全部完整内容回答以json的格式给我提供信息键名是'电子招标文件获取方式',若存在未知信息,在对应的键值中填'未知'。
9.该招标文件中对投标人准备和参加投标活动发生的费用是如何规定的请以json的格式给我提供信息键名是'投标费用承担',若存在未知信息,在对应的键值中填'未知'。 9.该招标文件中对投标人准备和参加投标活动发生的费用是如何规定的请以json的格式给我提供信息键名是'投标费用承担',若存在未知信息,在对应的键值中填'未知'。
@ -31,3 +21,5 @@
11.该文档要求扣留的质量保证金百分比是多少请以json格式给我提供信息键名为'质量保证金',如果没有则以'未知'填充。 11.该文档要求扣留的质量保证金百分比是多少请以json格式给我提供信息键名为'质量保证金',如果没有则以'未知'填充。
12.该项目是否接受联合体投标请按json格式给我提供信息键名为'是否接受联合体投标''是否接受联合体投标'的键值仅限于'是'、'否'、'未知'。 12.该项目是否接受联合体投标请按json格式给我提供信息键名为'是否接受联合体投标''是否接受联合体投标'的键值仅限于'是'、'否'、'未知'。
13.该项目的开标时间开启时间和开标地点是请按json格式给我提供信息键名为'开标时间'和'开标地点',若存在未知信息,在对应的键值中填'未知'。

View File

@ -6,7 +6,22 @@
4.投标文件或响应文件递交截止时间是递交地点或方式请按json格式给我提供信息键名分别是'投标文件递交截止日期','投标文件递交地点'(或'投标文件递交方式',若存在未知信息,在对应的键值中填'未知'。 4.投标文件或响应文件递交截止时间是递交地点或方式请按json格式给我提供信息键名分别是'投标文件递交截止日期','投标文件递交地点'(或'投标文件递交方式',若存在未知信息,在对应的键值中填'未知'。
5.采购人招标人和采购代理机构或招标代理机构的联系方式是请按json格式给我提供信息键名分别是'招标人联系方式''招标代理机构联系方式',若存在嵌套信息,嵌套内容键名以文件中对应字段命名,若存在未知信息,在对应的键值中填'未知'。 5.采购人招标人和采购代理机构或招标代理机构和项目的联系方式是请按json格式给我提供信息外层键名分别是'招标人联系方式''招标代理机构联系方式'"项目联系方式",嵌套键名至少包含"名称"和"联系电话",若还有其他字段则添加在后面,若存在未知信息,在对应的键值中填'未知'。示例输出如下:
{
"招标人联系方式":{
"名称":"广水市中医医院",
"联系电话":"13972990000",
"地址":"洪山街道"
},
"招标代理机构联系方式":{
"名称":"湖北众恒永业工程项目管理有限公司广水分公司",
"联系电话":"13972991234"
},
"项目联系方式":{
"名称":"张三",
"联系电话":"未知"
}
}
6.该招标文件的信息公示媒介在哪请按json格式给我提供信息键名是'信息公示媒介',若存在未知信息,在对应的键值中填'未知'。 6.该招标文件的信息公示媒介在哪请按json格式给我提供信息键名是'信息公示媒介',若存在未知信息,在对应的键值中填'未知'。
@ -24,6 +39,8 @@
13.该招标文件中对投标文件中偏离项的要求或内容是怎样的请以json格式给我提供信息外层键名为'偏离',请不要回答具体的技术参数,若存在未知信息,在对应的键值中填'未知'。 13.该招标文件中对投标文件中偏离项的要求或内容是怎样的请以json格式给我提供信息外层键名为'偏离',请不要回答具体的技术参数,若存在未知信息,在对应的键值中填'未知'。
14.该项目的开标时间或开启时间和开标地点是请按json格式给我提供信息键名为'开标时间'和'开标地点',若存在未知信息,在对应的键值中填'未知'。

View File

@ -1,10 +1,15 @@
#pdf提取之后的提示词调用普通通译千问
#请你依据以上信息回答,是否允许分包? 是否需要递交投标保证金是否有履约保证金履约担保是否有招标代理服务费请按json格式给我提供信息键名分别为'是否允许分包','是否递交投标保证金','是否有履约保证金','是否有招标代理服务费',键值仅限于'是','否','未知'。
1.该招标文件对于分包的要求是怎样的请按json格式给我提供信息键名为'分包'。 1.该招标文件对于分包的要求是怎样的请按json格式给我提供信息键名为'分包'。
2.根据招标文件第二章投标人须知该项目投标保证金需要缴纳金额是多少到账截止时间是缴纳形式是请按json格式给我提供信息外层键名为'投标保证金',嵌套键名分别为'缴纳金额','到账截止时间','缴纳形式',若存在多种缴纳形式,则在'缴纳形式'下以各种缴纳形式作为嵌套键名,再在对应的缴纳形式下嵌套写出缴纳步骤或要求或账户信息,请详细回答,不要遗漏原文信息。 2.根据招标文件第二章投标人须知该项目投标保证金需要缴纳金额是多少到账截止时间是缴纳形式是请按json格式给我提供信息外层键名为'投标保证金',嵌套键名分别为'缴纳金额','到账截止时间','缴纳形式',若存在多种缴纳形式,则在'缴纳形式'下以各种缴纳形式作为嵌套键名,再在对应的缴纳形式下嵌套写出缴纳步骤或要求或账户信息,请详细回答,不要遗漏原文信息。
3.该招标文件对于投标保证金的退还相关的规章办法是怎样的请按json格式给我提供信息键名为'退还投标保证金',若存在嵌套信息,嵌套内容键名以文档中对应字段命名。 3.该招标文件对于投标保证金的退还相关的规章办法是怎样的请按json格式给我提供信息键名为'退还投标保证金',若存在嵌套信息,嵌套内容键名以文档中对应字段命名。
4.根据投标人须知前附表,该项目对于履约保证金(担保)的要求中它的履约担保形式是怎样的它的履约担保金额是多少请按json格式给我提供信息外层键名为'履约保证金',嵌套键名分别是'履约担保形式','担保金额',若存在多种履约担保形式,则在'履约担保形式'下以各种履约担保形式作为嵌套键名,若存在未知信息,在对应的键值中填'未知'。 4.根据投标人须知前附表,该项目对于履约保证金(担保)的要求中它的履约担保形式是怎样的它的履约担保金额是多少请按json格式给我提供信息外层键名为'履约保证金',嵌套键名分别是'履约担保形式','担保金额',若存在多种履约担保形式,则在'履约担保形式'下以各种履约担保形式作为嵌套键名,若存在未知信息,在对应的键值中填'未知'。
5.本项目的招标代理服务费由谁支付支付标准是什么支付方式是什么支付时间是什么请按json格式给我提供信息外层键名为'招标代理服务费',嵌套键名分别是'支付人','支付标准','支付方式','支付时间',若存在未知信息,在对应的键值中填'未知'。 5.本项目的招标代理服务费由谁支付支付标准是什么支付方式是什么支付时间是什么请按json格式给我提供信息外层键名为'招标代理服务费',嵌套键名分别是'支付人','支付标准','支付方式','支付时间',若存在未知信息,在对应的键值中填'未知'。
6.该招标文件对于踏勘现场是怎样的踏勘时间和踏勘集中地点是请以json格式给我提供信息外层键名为'踏勘现场',嵌套键名分别是'踏勘时间','踏勘地点',若存在其他信息,新增嵌套键名'备注',填入其中,若存在未知信息,在对应的键值中填'未知'。 6.该招标文件对于踏勘现场是怎样的踏勘时间和踏勘集中地点是请以json格式给我提供信息外层键名为'踏勘现场',嵌套键名分别是'踏勘时间','踏勘地点',若存在其他信息,新增嵌套键名'备注',填入其中,若存在未知信息,在对应的键值中填'未知'。
7.该招标文件对于投标预备会内容是怎样的召开时间和召开地点是请以json格式给我提供信息外层键名为'投标预备会',嵌套键名分别是'召开时间','召开地方',若存在其他信息,新增嵌套键名'备注',填入其中,若存在未知信息,在对应的键值中填'未知'。 7.该招标文件对于投标预备会内容是怎样的召开时间和召开地点是请以json格式给我提供信息外层键名为'投标预备会',嵌套键名分别是'召开时间','召开地方',若存在其他信息,新增嵌套键名'备注',填入其中,若存在未知信息,在对应的键值中填'未知'。
8.本项目可偏离的项目和范围是怎样的请以json格式给我提供信息外层键名为'偏离'。 8.本项目可偏离的项目和范围是怎样的请以json格式给我提供信息外层键名为'偏离'。

View File

@ -1,9 +1,13 @@
#pdf提取之后的提示词调用普通通译千问
#请你依据以上信息回答,是否允许分包? 是否需要递交投标保证金是否有履约保证金履约担保是否有招标代理服务费请按json格式给我提供信息键名分别为'是否允许分包','是否递交投标保证金','是否有履约保证金','是否有招标代理服务费',键值仅限于'是','否','未知'。
1.该招标文件对于分包的要求是怎样的请按json格式给我提供信息键名为'分包',若需要以嵌套键值对返回结果,那么嵌套键名为你对相应要求的总结,而对应键值需要完全与原文保持一致。。 1.该招标文件对于分包的要求是怎样的请按json格式给我提供信息键名为'分包',若需要以嵌套键值对返回结果,那么嵌套键名为你对相应要求的总结,而对应键值需要完全与原文保持一致。。
2.根据招标文件第二章投标人须知该项目投标保证金或磋商保证金的内容或要求是什么请按json格式给我提供信息外层键名为"投标保证金"(或"磋商保证金"),若需要以嵌套键值对返回结果,那么嵌套键名为你对相应要求的总结,而对应键值需要完全与原文保持一致。 2.根据招标文件第二章投标人须知该项目投标保证金或磋商保证金的内容或要求是什么请按json格式给我提供信息外层键名为"投标保证金"(或"磋商保证金"),若需要以嵌套键值对返回结果,那么嵌套键名为你对相应要求的总结,而对应键值需要完全与原文保持一致。
3.该招标文件对于投标保证金的退还相关的规章办法是怎样的请按json格式给我提供信息键名为'退还投标保证金',若存在嵌套信息,嵌套内容键名以文档中对应字段命名。 3.该招标文件对于投标保证金的退还相关的规章办法是怎样的请按json格式给我提供信息键名为'退还投标保证金',若存在嵌套信息,嵌套内容键名以文档中对应字段命名。
4.根据投标人须知前附表,该项目对于履约保证金(担保)的内容或要求是怎样的请按json格式给我提供信息外层键名为"履约保证金",若需要以嵌套键值对返回结果,那么嵌套键名为你对相应要求的总结,而对应键值需要完全与原文保持一致。 4.根据投标人须知前附表,该项目对于履约保证金(担保)的内容或要求是怎样的请按json格式给我提供信息外层键名为"履约保证金",若需要以嵌套键值对返回结果,那么嵌套键名为你对相应要求的总结,而对应键值需要完全与原文保持一致。
5.本项目的招标代理服务费或中标服务费、成交服务费的相关内容是怎样的请按json格式给我提供信息外层键名为'招标代理服务费',若需要以嵌套键值对返回结果,那么嵌套键名为你对相应要求的总结,而对应键值需要完全与原文保持一致。 5.本项目的招标代理服务费或中标服务费、成交服务费的相关内容是怎样的请按json格式给我提供信息外层键名为'招标代理服务费',若需要以嵌套键值对返回结果,那么嵌套键名为你对相应要求的总结,而对应键值需要完全与原文保持一致。
6.该招标文件对于踏勘现场的内容或要求是怎样的请按json格式给我提供信息外层键名为"踏勘现场",若需要以嵌套键值对返回结果,那么嵌套键名为你对相应要求的总结,而对应键值需要完全与原文保持一致。 6.该招标文件对于踏勘现场的内容或要求是怎样的请按json格式给我提供信息外层键名为"踏勘现场",若需要以嵌套键值对返回结果,那么嵌套键名为你对相应要求的总结,而对应键值需要完全与原文保持一致。
7.该招标文件对于投标预备会或投标答疑会内容是怎样的请按json格式给我提供信息外层键名为"投标预备会"(或"投标答疑会"),若需要以嵌套键值对返回结果,那么嵌套键名为你对相应要求的总结,而对应键值需要完全与原文保持一致。 7.该招标文件对于投标预备会或投标答疑会内容是怎样的请按json格式给我提供信息外层键名为"投标预备会"(或"投标答疑会"),若需要以嵌套键值对返回结果,那么嵌套键名为你对相应要求的总结,而对应键值需要完全与原文保持一致。

View File

@ -22,20 +22,22 @@ def aggregate_basic_info(baseinfo_list):
- dict: 合并和分类后的基础信息字典 - dict: 合并和分类后的基础信息字典
""" """
key_groups = { key_groups = {
"招标人/代理信息": ["招标人", "招标人联系方式", "招标代理机构", "招标代理机构联系方式"], "招标人/代理信息": ["招标人", "招标人联系方式", "招标代理机构", "招标代理机构联系方式","项目联系方式"],
"项目信息": ["项目名称", "项目编号", "项目概况", "项目基本情况", "招标控制价", "投标竞争下浮率"], "项目信息": ["项目名称", "项目编号", "项目概况", "项目基本情况", "招标控制价", "投标竞争下浮率"],
"采购要求": ["技术要求","商务要求","服务要求","其他要求"], "采购要求": ["技术要求","商务要求","服务要求","其他要求"],
"关键时间/内容": [ "关键时间/内容": [
"投标文件递交截止日期", "投标文件递交截止日期",
"开标时间",
"开标地点",
"澄清招标文件的截止时间", "澄清招标文件的截止时间",
"投标有效期", "投标有效期",
"信息公示媒介" "信息公示媒介"
], ],
"保证金相关": ["质量保证金"], "保证金相关": ["质量保证金"],
"其他信息": [ "其他信息": [
"是否退还投标文件",
"投标费用承担", "投标费用承担",
"招标代理服务费" "招标代理服务费",
"是否退还投标文件"
] ]
} }
@ -63,12 +65,17 @@ def aggregate_basic_info(baseinfo_list):
def dynamic_key_handling(key_groups, detected_keys): def dynamic_key_handling(key_groups, detected_keys):
# 检查和调整键组配置 # 检查和调整键组配置
for key in detected_keys: for key in detected_keys:
# print(key) # 处理“保证金相关”组
if "保证金" in key: if "保证金" in key:
key_groups["保证金相关"].append(key) group = key_groups["保证金相关"]
elif "是否接受联合体" in key: insert_before = "质量保证金"
key_groups["项目信息"].append(key) if insert_before in group:
elif "联合体投标要求" in key: index = group.index(insert_before)
if key not in group: # 避免重复插入
group.insert(index, key)
else:
group.append(key) # 如果没有找到特定键,则追加到末尾
elif "联合体" in key:
key_groups["项目信息"].append(key) key_groups["项目信息"].append(key)
elif "分包" in key: elif "分包" in key:
key_groups["项目信息"].append(key) key_groups["项目信息"].append(key)
@ -79,7 +86,17 @@ def dynamic_key_handling(key_groups, detected_keys):
elif "偏离" in key: elif "偏离" in key:
key_groups["其他信息"].append(key) key_groups["其他信息"].append(key)
elif "递交方式" in key or "递交地点" in key: elif "递交方式" in key or "递交地点" in key:
key_groups["关键时间/内容"].append(key) group = key_groups["关键时间/内容"]
insert_after = "投标文件递交截止日期"
if insert_after in group:
index = group.index(insert_after)
# 确保新键不重复
if key not in group:
group.insert(index + 1, key)
else:
# 如果“投标文件递交截止日期”不存在,则追加到末尾
if key not in group:
group.append(key)
def get_base_info(baseinfo_file_path): def get_base_info(baseinfo_file_path):
file_id = upload_file(baseinfo_file_path) file_id = upload_file(baseinfo_file_path)
@ -145,7 +162,7 @@ def combine_basic_info(baseinfo_file_path, procurement_file_path):
if __name__ == "__main__": if __name__ == "__main__":
start_time=time.time() start_time=time.time()
baseinfo_file_path = "C:\\Users\\Administrator\\Desktop\\货物标\\zboutpub\\merged_baseinfo.pdf" baseinfo_file_path = "C:\\Users\\Administrator\\Desktop\\货物标\\truncate_all\\ztbfile_merged_baseinfo\\ztbfile_merged_baseinfo_3-31.pdf"
# procurement_file_path = "C:\\Users\\Administrator\\Desktop\\fsdownload\\b4601ea1-f087-4fa2-88ae-336ad4d8e1e9\\tmp\\ztbfile_procurement.pdf" # procurement_file_path = "C:\\Users\\Administrator\\Desktop\\fsdownload\\b4601ea1-f087-4fa2-88ae-336ad4d8e1e9\\tmp\\ztbfile_procurement.pdf"
procurement_file_path = "C:\\Users\\Administrator\\Desktop\\货物标\\zboutpub\\广水农商行门禁控制主机及基础验证设备采购项目——磋商文件定稿三次_procurement.pdf" procurement_file_path = "C:\\Users\\Administrator\\Desktop\\货物标\\zboutpub\\广水农商行门禁控制主机及基础验证设备采购项目——磋商文件定稿三次_procurement.pdf"
res = combine_basic_info(baseinfo_file_path, procurement_file_path) res = combine_basic_info(baseinfo_file_path, procurement_file_path)

View File

@ -111,7 +111,6 @@ def get_technical_requirements(file_id):
# 更新原始采购需求字典 # 更新原始采购需求字典
combine_and_update_results(cleaned_res['技术要求'], technical_requirements_combined_res) combine_and_update_results(cleaned_res['技术要求'], technical_requirements_combined_res)
final_res = postprocess(cleaned_res) final_res = postprocess(cleaned_res)
print("更新后的采购需求处理完成.")
# 输出最终的 JSON 字符串 # 输出最终的 JSON 字符串
return final_res return final_res
@ -133,14 +132,15 @@ def test_all_files_in_folder(input_folder, output_folder):
output_file_path = os.path.join(output_folder, os.path.splitext(filename)[0] + '.json') output_file_path = os.path.join(output_folder, os.path.splitext(filename)[0] + '.json')
# 保存JSON结果到文件 # 保存JSON结果到文件
with open(output_file_path, 'w', encoding='utf-8') as json_file: with open(output_file_path, 'w', encoding='utf-8') as json_file:
json_file.write(json_result) json.dump(json_result, json_file, ensure_ascii=False, indent=4)
print(f"结果已保存到: {output_file_path}") print(f"结果已保存到: {output_file_path}")
except Exception as e: except Exception as e:
print(f"处理文件 {file_path} 时出错: {e}") print(f"处理文件 {file_path} 时出错: {e}")
if __name__ == "__main__": if __name__ == "__main__":
truncate_file="C:\\Users\\Administrator\\Desktop\\货物标\\zboutpub\\广水农商行门禁控制主机及基础验证设备采购项目——磋商文件定稿三次_procurement.pdf" # truncate_file="C:\\Users\\Administrator\\Desktop\\货物标\\zboutpub\\广水农商行门禁控制主机及基础验证设备采购项目——磋商文件定稿三次_procurement.pdf"
truncate_file="D:\\flask_project\\flask_app\\static\\output\\71334d6b-9478-4e4d-abe0-a5cb3100d681\\ztbfile_procurement.pdf"
file_id = upload_file(truncate_file) file_id = upload_file(truncate_file)
res=get_technical_requirements(file_id) res=get_technical_requirements(file_id)
json_string = json.dumps(res, ensure_ascii=False, indent=4) json_string = json.dumps(res, ensure_ascii=False, indent=4)

View File

@ -213,11 +213,11 @@ def extract_from_notice(clause_path, type):
final_result=process_nested_data(transformed_data) final_result=process_nested_data(transformed_data)
return final_result return final_result
#TODO: 再审视一下zbtest20的处理是否合理
if __name__ == "__main__": if __name__ == "__main__":
file_path = 'C:\\Users\\Administrator\\Desktop\\招标文件\\' file_path = 'D:\\flask_project\\flask_app\\static\\output\\87f48f9c-e6ee-4dc1-a981-5a10085c4635\\tmp\\clause1.json'
# file_path = 'D:\\flask_project\\flask_app\\static\\output\\87f48f9c-e6ee-4dc1-a981-5a10085c4635\\clause1.json'
try: try:
res = extract_from_notice(file_path, 1) # 可以改变此处的 type 参数测试不同的场景 res = extract_from_notice(file_path, 2) # 可以改变此处的 type 参数测试不同的场景
res2=json.dumps(res,ensure_ascii=False,indent=4) res2=json.dumps(res,ensure_ascii=False,indent=4)
print(res2) print(res2)
except ValueError as e: except ValueError as e:

View File

@ -167,6 +167,15 @@ def parse_text_by_heading(text):
current_content = [line_content] current_content = [line_content]
append_newline = len(new_key.rstrip('.').split('.')) <= 2 append_newline = len(new_key.rstrip('.').split('.')) <= 2
last_main_number = new_key.split('.')[0] last_main_number = new_key.split('.')[0]
# if current_key is None or (current_key != new_key and (
# len(current_content) == 0 or current_content[-1][-1] != '第')):
# if current_key is not None:
# content_string = ''.join(current_content).strip()
# data[current_key] = data.get(current_key, '') + content_string.replace(' ', '')
# current_key = new_key
# current_content = [line_content]
# append_newline = len(new_key.rstrip('.').split('.')) <= 2
# last_main_number = new_key.split('.')[0]
else: else:
append_newline = handle_content_append(current_content, line_stripped, append_newline, keywords) append_newline = handle_content_append(current_content, line_stripped, append_newline, keywords)
elif dot_match: elif dot_match:
@ -321,17 +330,6 @@ def clean_content(content):
return cleaned_content return cleaned_content
# def convert_to_json(file_path, start_word, end_phrases):
# if file_path.endswith('.docx'):
# text = extract_text_from_docx(file_path)
# elif file_path.endswith('.pdf'):
# text = extract_text_from_pdf(file_path,start_word,end_phrases)
# else:
# raise ValueError("Unsupported file format")
# # print(text)
# parsed_data = parse_text_by_heading(text)
# return parsed_data
def convert_clause_to_json(file_path,output_folder,type=1,suffix_counter="1.json"): def convert_clause_to_json(file_path,output_folder,type=1,suffix_counter="1.json"):
if not os.path.exists(file_path): if not os.path.exists(file_path):
print(f"The specified file does not exist: {file_path}") print(f"The specified file does not exist: {file_path}")
@ -377,15 +375,16 @@ def process_folder(input_folder, output_folder):
print(f"Error processing {file_name}: {e}") print(f"Error processing {file_name}: {e}")
#TODO:'C:\\Users\\Administrator\\Desktop\\货物标\\output4\\广水农商行门禁控制主机及基础验证设备采购项目——磋商文件定稿三次_tobidders_notice_part2.pdf' PYPDF2库读取有遗漏 #TODO:'C:\\Users\\Administrator\\Desktop\\货物标\\output4\\广水农商行门禁控制主机及基础验证设备采购项目——磋商文件定稿三次_tobidders_notice_part2.pdf' PYPDF2库读取有遗漏
#TODO:标题'一'应该越来越大,与'1.1'的逻辑分开'
#TODO:911904c3-4d6e-47e0-acd8-b05e582209cb文件夹运行有问题百炼出错了 #TODO:911904c3-4d6e-47e0-acd8-b05e582209cb文件夹运行有问题百炼出错了
#TODO: 投标人须知正文这块,序号可能是乱序的,或许可以删除判断序号大小的逻辑,只要出现在开头的序号就作为新的键 eg:2-招标文件。目前将这种情况当特殊处理
if __name__ == "__main__": if __name__ == "__main__":
# file_path = 'D:\\flask_project\\flask_app\\static\\output\\cfd4959d-5ea9-4112-8b50-9e543803f029\\ztbfile_tobidders_notice.pdf' # file_path = 'D:\\flask_project\\flask_app\\static\\output\\cfd4959d-5ea9-4112-8b50-9e543803f029\\ztbfile_tobidders_notice.pdf'
file_path='C:\\Users\\Administrator\\Desktop\\货物标\\output5\\094定稿-湖北工业大学轻武器模拟射击设备采购项目招标文件_notice.pdf' file_path='D:\\flask_project\\flask_app\\static\\output\\87f48f9c-e6ee-4dc1-a981-5a10085c4635\\ztbfile_tobidders_notice_part2.pdf'
# file_path = 'C:\\Users\\Administrator\\Desktop\\货物标\\output4\\2-招标文件2020年广水市中小学教师办公电脑系统及多媒体“班班通”设备采购安装项目_tobidders_notice_part2.pdf' # file_path = 'C:\\Users\\Administrator\\Desktop\\货物标\\output4\\2-招标文件2020年广水市中小学教师办公电脑系统及多媒体“班班通”设备采购安装项目_tobidders_notice_part2.pdf'
output_folder = 'C:\\Users\\Administrator\\Desktop\\货物标\\output5\\tmp2' output_folder = 'D:\\flask_project\\flask_app\\static\\output\\87f48f9c-e6ee-4dc1-a981-5a10085c4635\\tmp'
try: try:
output_path = convert_clause_to_json(file_path,output_folder,2) output_path = convert_clause_to_json(file_path,output_folder,1)
print(f"Final JSON result saved to: {output_path}") print(f"Final JSON result saved to: {output_path}")
except ValueError as e: except ValueError as e:
print("Error:", e) print("Error:", e)

View File

@ -438,18 +438,20 @@ def save_extracted_pages(pdf_document, start_page, end_page, pdf_path, output_fo
return output_pdf_path return output_pdf_path
#合并封面+招标公告+投标人须知前附表+须知正文 #合并封面+招标公告+投标人须知前附表+须知正文
def merge_selected_pdfs(output_folder, truncate_files, output_path): def merge_selected_pdfs(output_folder, truncate_files, output_path, base_file_name):
""" """
合并 output_folder 中以 _before 结尾的 PDF 文件以及 truncate_files 中的指定文件 合并 output_folder 中以 {base_file_name}_before.pdf 结尾的 PDF 文件以及 truncate_files 中的指定文件
参数 参数
- output_folder (str): 包含以 _before 结尾的 PDF 文件的文件夹路径 - output_folder (str): 包含以 {base_file_name}_before.pdf 结尾的 PDF 文件的文件夹路径
- truncate_files (list): 包含 PDF 文件路径的列表 - truncate_files (list): 包含 PDF 文件路径的列表
- output_path (str): 合并后的 PDF 文件保存路径 - output_path (str): 合并后的 PDF 文件保存路径
- base_file_name (str): 用于匹配文件名的基础名称
""" """
# 1. 查找 output_folder 中以 _before.pdf 结尾的 PDF 文件 # 1. 查找 output_folder 中以 {base_file_name}_before.pdf 结尾的 PDF 文件
before_pdfs = glob.glob(os.path.join(output_folder, '*_before.pdf')) pattern = f'*{base_file_name}_before.pdf'
print(f"找到 {len(before_pdfs)} 个以 '_before.pdf' 结尾的文件。") before_pdfs = glob.glob(os.path.join(output_folder, pattern))
print(f"找到 {len(before_pdfs)} 个以 '{base_file_name}_before.pdf' 结尾的文件。")
# 2. 获取 truncate_files 中指定的文件索引5、3、4 # 2. 获取 truncate_files 中指定的文件索引5、3、4
selected_indices = [5, 3, 4] # 注意索引从0开始 selected_indices = [5, 3, 4] # 注意索引从0开始
@ -534,22 +536,29 @@ def truncate_pdf_main(input_path, output_folder, selection, output_suffix="defau
return process_input(input_path, output_folder, begin_pattern, begin_page, end_pattern, output_suffix) return process_input(input_path, output_folder, begin_pattern, begin_page, end_pattern, output_suffix)
def truncate_pdf_multiple(input_path, output_folder): def truncate_pdf_multiple(pdf_path, output_folder):
base_file_name = os.path.splitext(os.path.basename(pdf_path))[0]
truncate_files = [] truncate_files = []
for selection in range(1, 6): for selection in range(1, 6):
files = truncate_pdf_main(input_path, output_folder, selection) files = truncate_pdf_main(pdf_path, output_folder, selection)
if files:
truncate_files.extend(files) truncate_files.extend(files)
merged_output_path =os.path.join(output_folder,"merged_baseinfo.pdf")
merge_selected_pdfs(output_folder,truncate_files,merged_output_path) if truncate_files:
print(merged_output_path) merged_output_path = os.path.join(output_folder, f"{base_file_name}_merged_baseinfo.pdf")
merge_selected_pdfs(output_folder, truncate_files, merged_output_path,base_file_name)
truncate_files.append(merged_output_path) truncate_files.append(merged_output_path)
print(f"已生成合并文件: {merged_output_path}")
else:
print(f"没有文件需要合并 for {pdf_path}")
return truncate_files return truncate_files
# TODO:交通智能系统和招标(1)(1)文件有问题 sele=4的时候excludsion有问题 # TODO:交通智能系统和招标(1)(1)文件有问题 sele=4的时候excludsion有问题
if __name__ == "__main__": if __name__ == "__main__":
input_path = "C:\\Users\\Administrator\\Desktop\\货物标\\zbfiles\\094定稿-湖北工业大学轻武器模拟射击设备采购项目招标文件.pdf" input_path = "C:\\Users\\Administrator\\Desktop\\货物标\\zbfiles\\6.2定版视频会议磋商文件.pdf"
output_folder = "C:\\Users\\Administrator\\Desktop\\货物标\\zboutpub" output_folder = "C:\\Users\\Administrator\\Desktop\\货物标\\truncate_all"
files = truncate_pdf_multiple(input_path, output_folder) files = truncate_pdf_multiple(input_path, output_folder)
print(files) print(files)

View File

@ -9,7 +9,6 @@ from flask_app.货物标.投标人须知正文提取指定内容货物标版 imp
from flask_app.货物标.货物标截取pdf import truncate_pdf_multiple from flask_app.货物标.货物标截取pdf import truncate_pdf_multiple
from concurrent.futures import ThreadPoolExecutor from concurrent.futures import ThreadPoolExecutor
import concurrent.futures import concurrent.futures
from flask_app.main.知识库操作 import addfileToKnowledge, deleteKnowledge
from flask_app.货物标.投标人须知正文条款提取成json文件货物标版 import convert_clause_to_json from flask_app.货物标.投标人须知正文条款提取成json文件货物标版 import convert_clause_to_json
from flask_app.货物标.无效标和废标和禁止投标整合main import combine_find_invalid from flask_app.货物标.无效标和废标和禁止投标整合main import combine_find_invalid
from flask_app.货物标.资格审查main import combine_qualification_review from flask_app.货物标.资格审查main import combine_qualification_review
@ -211,7 +210,7 @@ def goods_bid_main(output_folder, file_path, file_type, unique_id):
# 删除知识索引 # 删除知识索引
# deleteKnowledge(index) # deleteKnowledge(index)
#TODO:目前的无效标这块的键值都删去空格了,所有的键名都删去空格
if __name__ == "__main__": if __name__ == "__main__":
output_folder = "flask_app/static/output/zytest1" output_folder = "flask_app/static/output/zytest1"