9.3表格提取bug 联合体投标

This commit is contained in:
zy123 2024-09-03 18:04:05 +08:00
parent dc4563f70e
commit 777ef682cb
10 changed files with 119 additions and 67 deletions

View File

@ -1,18 +1,31 @@
from docx import Document from docx import Document
import json import json
def read_tables_from_docx(file_path): def read_tables_from_docx(file_path):
"""读取DOCX文件中的表格数据并以嵌套字典的形式返回.""" """读取DOCX文件中的表格数据并以嵌套字典的形式返回."""
doc = Document(file_path) doc = Document(file_path)
table_list = {} table_list = {}
cur_title = [] cur_title = []
header = None
for table in doc.tables: for table in doc.tables:
for i, row in enumerate(table.rows): for i, row in enumerate(table.rows):
cell_texts = [cell.text.strip() for cell in row.cells]
# 检查是否是表头
if header is None:
header = cell_texts
continue # 跳过第一个表头行
# 如果遇到与第一个表头相同的行,跳过
if cell_texts == header:
continue
cur_level = table_list cur_level = table_list
temp_title = [] temp_title = []
for j, cell in enumerate(row.cells): for j, cell in enumerate(row.cells):
text_str = cell.text.strip().replace(' ', '').replace('\n', '') # 移除键中的换行符 text_str = cell.text.strip().replace(' ', '').replace('\n', '')
if j < len(row.cells) - 1: if j < len(row.cells) - 1:
if text_str == "": if text_str == "":
text_str = cur_title[j] if j < len(cur_title) else "<未识别到上级标题>" text_str = cur_title[j] if j < len(cur_title) else "<未识别到上级标题>"
@ -28,16 +41,16 @@ def read_tables_from_docx(file_path):
if isinstance(cur_level[last_key], dict): if isinstance(cur_level[last_key], dict):
cur_level[last_key] = f"\n{cell_text}" cur_level[last_key] = f"\n{cell_text}"
else: else:
cur_level[last_key] += f"\n{cell_text}" # 追加值到已有键 cur_level[last_key] += f"\n{cell_text}"
else: else:
cur_level[last_key] = cell_text # 初始化键的值 cur_level[last_key] = cell_text
else: else:
last_key = f"{i}行内容" last_key = f"{i}行内容"
if last_key in cur_level: if last_key in cur_level:
if isinstance(cur_level[last_key], dict): if isinstance(cur_level[last_key], dict):
cur_level[last_key] = f"\n{cell_text}" cur_level[last_key] = f"\n{cell_text}"
else: else:
cur_level[last_key] += f"\n{cell_text}" # 追加值到'第i行内容' cur_level[last_key] += f"\n{cell_text}"
else: else:
cur_level[last_key] = cell_text cur_level[last_key] = cell_text
cur_title = temp_title[:] cur_title = temp_title[:]
@ -82,6 +95,6 @@ def extract_tables_main(path, output_filename):
print(f"The data has been processed and saved to '{output_filename}'.") print(f"The data has been processed and saved to '{output_filename}'.")
if __name__ == "__main__": if __name__ == "__main__":
path = 'C:\\Users\\Administrator\\Desktop\\招标文件\\招标03_tobidders_notice_table.docx' path = 'C:\\Users\\Administrator\\Desktop\\招标文件\\招标test文件夹\\zbtest20\\zbtest20_17-22.docx'
output_filename = "C:\\Users\\Administrator\\Desktop\\招标文件\\truncate_output.json" # 前附表json文件 output_filename = "C:\\Users\\Administrator\\Desktop\\招标文件\\招标test文件夹\\zbtest20\\truncate_output.json" # 前附表json文件
extract_tables_main(path, output_filename) extract_tables_main(path, output_filename)

View File

@ -1,34 +1,23 @@
import re def add_entry_level1(data, combined_value):
# 假设这里我们基于某些逻辑添加了一个条目
combined_value.append("Level 1 data: " + data)
add_entry_level2("Data from Level 1", combined_value)
def extract_key_value_from_line(line): def add_entry_level2(data, combined_value):
# 更新正则表达式以处理带序号和不带序号的情况 # 在第二层,我们再添加一个条目
pattern = r'^((?:\d+(?:\.\d+)*\.?\s*)?)(.+?)\s*/\s*$' combined_value.append("Level 2 data: " + data)
match = re.match(pattern, line) add_entry_level3("Data from Level 2", combined_value)
if match: def add_entry_level3(data, combined_value):
# 获取键名,并去除多余的空格 # 在第三层,我们添加最后一个条目
key = match.group(2).strip() combined_value.append("Level 3 data: " + data)
# 设置值为"无"
value = ""
return {key: value}
return {}
# 测试函数 # 主函数或测试代码
def test_extraction(): def main():
test_cases = [ combined_value = []
"1.1.6 设计人 /", initial_data = "Initial Entry"
"3.4 某个键名:/", add_entry_level1(initial_data, combined_value)
"5. 另一个键名 /", print("Combined values after processing:", combined_value)
"1.2.3.4 复杂序号键名:/",
"6.简单键名/",
"不带序号的行:/",
"纯文本/",
]
for case in test_cases: if __name__ == "__main__":
result = extract_key_value_from_line(case) main()
print(f"Input: {case}")
print(f"Result: {result}\n")
# 运行测试
test_extraction()

View File

@ -1,3 +1,5 @@
import json
from flask_app.main.json_utils import clean_json_string, nest_json_under_key,rename_outer_key, combine_json_results from flask_app.main.json_utils import clean_json_string, nest_json_under_key,rename_outer_key, combine_json_results
from flask_app.main.投标人须知正文提取指定内容 import extract_from_notice from flask_app.main.投标人须知正文提取指定内容 import extract_from_notice
from flask_app.main.判断是否分包等 import judge_whether_main, read_questions_from_judge from flask_app.main.判断是否分包等 import judge_whether_main, read_questions_from_judge
@ -7,7 +9,7 @@ def combine_basic_info(baseinfo_list):
combined_baseinfo_list = [] combined_baseinfo_list = []
key_groups = { key_groups = {
"招标人/代理信息": ["招标人","招标人联系方式", "招标代理机构","招标代理机构联系方式"], "招标人/代理信息": ["招标人","招标人联系方式", "招标代理机构","招标代理机构联系方式"],
"项目信息": ["工程名称", "招标编号","工程概况","招标范围","招标控制价","投标竞争下浮率","是否接受联合体投标"], "项目信息": ["工程名称", "招标编号","工程概况","招标范围","招标控制价","投标竞争下浮率"],
"关键时间/内容":["投标文件递交截止日期","递交方式","投标人要求澄清招标文件的截止时间","投标有效期","评标结果公示媒介"], "关键时间/内容":["投标文件递交截止日期","递交方式","投标人要求澄清招标文件的截止时间","投标有效期","评标结果公示媒介"],
"保证金相关":['质量保证金','退还投标保证金'], "保证金相关":['质量保证金','退还投标保证金'],
"其他信息":["重新招标、不再招标和终止招标","是否退还投标文件","费用承担"] "其他信息":["重新招标、不再招标和终止招标","是否退还投标文件","费用承担"]
@ -45,6 +47,8 @@ def dynamic_key_handling(key_groups, detected_keys):
for key in detected_keys: for key in detected_keys:
if "投标保证金" in key or "履约保证金" in key: if "投标保证金" in key or "履约保证金" in key:
key_groups["保证金相关"].append(key) key_groups["保证金相关"].append(key)
elif "是否接受联合体" in key:
key_groups["项目信息"].append(key)
elif "联合体投标要求" in key: elif "联合体投标要求" in key:
key_groups["项目信息"].append(key) key_groups["项目信息"].append(key)
elif "分包" in key: elif "分包" in key:
@ -56,13 +60,23 @@ def dynamic_key_handling(key_groups, detected_keys):
elif "偏离" in key: elif "偏离" in key:
key_groups["其他信息"].append(key) key_groups["其他信息"].append(key)
def judge_consortium_bidding(baseinfo_list): def judge_consortium_bidding(baseinfo_list):
updated_list = []
accept_bidding = False
for baseinfo in baseinfo_list: for baseinfo in baseinfo_list:
json_data = clean_json_string(baseinfo) json_data = clean_json_string(baseinfo)
# 检查 "是否接受联合体投标" 键是否存在且其值为 "是" # 检查 "是否接受联合体投标" 键是否存在且其值为 "是"
if json_data.get("是否接受联合体投标") == "": if "是否接受联合体投标" in json_data and json_data["是否接受联合体投标"] == "":
return True accept_bidding = True
return False # 从字典中移除特定键值对
json_data.pop("是否接受联合体投标", None)
# 将修改后的 json 数据转换回 JSON 字符串(如果需要)
updated_info = json.dumps(json_data)
updated_list.append(updated_info)
# 更新原始列表,如果你想保留修改
baseinfo_list[:] = updated_list
return accept_bidding
def project_basic_info(knowledge_name,truncate0,output_folder,clause_path): #投标人须知前附表 def project_basic_info(knowledge_name,truncate0,output_folder,clause_path): #投标人须知前附表
# 调用大模型回答项目基础信息 # 调用大模型回答项目基础信息
print("starting基础信息...") print("starting基础信息...")
@ -90,7 +104,7 @@ def project_basic_info(knowledge_name,truncate0,output_folder,clause_path): #
judge_consortium = judge_consortium_bidding(baseinfo_list) #通过招标公告判断是否接受联合体投标 judge_consortium = judge_consortium_bidding(baseinfo_list) #通过招标公告判断是否接受联合体投标
if judge_consortium: if judge_consortium:
judge_consortium_question = "该招标文件对于联合体投标的要求是怎样的请按json格式给我提供信息外层键名为'联合体投标要求'" judge_consortium_question = "该招标文件对于联合体投标的要求是怎样的请按json格式给我提供信息外层键名为'联合体投标要求',其中有一个嵌套键值对为:\"是否接受联合体投标\":\"\""
judge_questions.append(judge_consortium_question) judge_questions.append(judge_consortium_question)
file_id=upload_file(truncate0) file_id=upload_file(truncate0)
@ -124,9 +138,9 @@ def project_basic_info(knowledge_name,truncate0,output_folder,clause_path): #
if __name__ == "__main__": if __name__ == "__main__":
knowledge_name = "ztb" knowledge_name = "ztb"
output_folder="C:\\Users\\Administrator\\Desktop\\招标文件\\test2" output_folder="C:\\Users\\Administrator\\Desktop\\fsdownload\\temp8\\3abb6e16-19db-42ad-9504-53bf1072dfe7"
truncate0="C:\\Users\\Administrator\\Desktop\\招标文件\\test2\\zbtest10_tobidders_notice_table.pdf" truncate0="C:\\Users\\Administrator\\Desktop\\fsdownload\\temp8\\3abb6e16-19db-42ad-9504-53bf1072dfe7\\ztbfile_tobidders_notice_table.pdf"
clause_path="C:\\Users\\Administrator\\Desktop\\招标文件\\output1\\clause1.json" clause_path="C:\\Users\\Administrator\\Desktop\\fsdownload\\temp8\\3abb6e16-19db-42ad-9504-53bf1072dfe7\\clause.json"
res=project_basic_info(knowledge_name,truncate0,output_folder,clause_path) res=project_basic_info(knowledge_name,truncate0,output_folder,clause_path)
print(res) print(res)

View File

@ -26,6 +26,7 @@ prompt = """
请注意上述技能执行时将直接利用并参考${document1}的具体内容以确保所有产出紧密相关且高质量 请注意上述技能执行时将直接利用并参考${document1}的具体内容以确保所有产出紧密相关且高质量
""" """
def extract_matching_keys(json_data): def extract_matching_keys(json_data):
# 函数首先检查输入 json_data 是否为字符串类型。如果是,它会使用 json.loads() 将字符串解析为字典。 # 函数首先检查输入 json_data 是否为字符串类型。如果是,它会使用 json.loads() 将字符串解析为字典。
if isinstance(json_data, str): if isinstance(json_data, str):
@ -151,7 +152,7 @@ def process_reviews(original_dict_data,knowledge_name, truncate0_jsonpath,clause
print(f"Error processing response for query index {_}: {e}") print(f"Error processing response for query index {_}: {e}")
# Assume JSON file paths are defined or configured correctly # Assume JSON file paths are defined or configured correctly
combined_results = process_and_merge_entries(entries_with_numbers, truncate0_jsonpath, clause_json_path) #脚本提取的要求 combined_results = process_and_merge_entries(entries_with_numbers, truncate0_jsonpath, clause_json_path) #脚本提取的要求 [{'xxx': '3.7.45'}]
updated_json = update_json_data(original_dict_data, combined_results, second_response_list) updated_json = update_json_data(original_dict_data, combined_results, second_response_list)
return updated_json return updated_json

View File

@ -142,9 +142,9 @@ def truncate_pdf_multiple(input_path, output_folder):
return truncate_files return truncate_files
if __name__ == "__main__": if __name__ == "__main__":
input_path = "C:\\Users\\Administrator\\Desktop\\招标文件\\招标03.pdf" input_path = "C:\\Users\\Administrator\\Desktop\\招标文件\\招标test文件夹"
output_folder = "C:\\Users\\Administrator\\Desktop\\招标文件\\test" output_folder = "C:\\Users\\Administrator\\Desktop\\招标文件\\招标test文件夹"
# truncate_pdf_multiple(input_path,output_folder) # truncate_pdf_multiple(input_path,output_folder)
selection = 5 # 例如1 - 投标人须知前附表, 2 - 评标办法, 3 - 投标人须知正文 4-资格审查条件 selection = 4 # 例如1 - 投标人须知前附表, 2 - 评标办法, 3 - 投标人须知正文 4-资格审查条件 5-无效标
generated_files = truncate_pdf_main(input_path, output_folder, selection) generated_files = truncate_pdf_main(input_path, output_folder, selection)
# print("生成的文件:", generated_files) # print("生成的文件:", generated_files)

View File

@ -207,7 +207,8 @@ def main_processing(output_folder,downloaded_file_path,file_type,unique_id): #
# #
# deleteKnowledge(processed_data['knowledge_index']) # deleteKnowledge(processed_data['knowledge_index'])
#TODO:如果上传的是pdf转过的docx文件那么提取打勾符号就会有问题
#TODO:如果上传的是pdf转过的docx文件那么提取打勾符号就会有问题 zbtest20 跳转涉及二级跳转 对于跳转到第一章 招标公告的要做额外处理 资格审查位置在第一章后面。如果未截取成功,需要作额外处理 logger不能保存控制台输出
if __name__ == "__main__": if __name__ == "__main__":
output_folder = "C:\\Users\\Administrator\\Desktop\\招标文件\\test" output_folder = "C:\\Users\\Administrator\\Desktop\\招标文件\\test"

View File

@ -1,4 +1,16 @@
import json import json
import re
def extract_content_after_special_chars(content):
"""
提取特定符号后的内容直到遇到结束符号
"""
pattern = r'[\x01\x02☑√团]([^□]+)'
match = re.search(pattern, content)
if match:
return match.group(1).strip() # 提取匹配的内容,并去除多余空格
return content # 如果没有找到匹配,返回原内容
def load_json(file_path): def load_json(file_path):
""" """
@ -36,7 +48,6 @@ def find_entries_in_jsons(entries, json_primary, json_secondary):
found_in_primary = process_json_with_subentries(json_primary, value, combined_value) found_in_primary = process_json_with_subentries(json_primary, value, combined_value)
if not found_in_primary: if not found_in_primary:
process_json_with_subentries(json_secondary, value, combined_value) process_json_with_subentries(json_secondary, value, combined_value)
if combined_value: if combined_value:
results[key] = "\n".join(combined_value) results[key] = "\n".join(combined_value)
return results return results
@ -45,9 +56,13 @@ def process_json_with_subentries(json_data, value, combined_value):
""" """
处理JSON数据寻找指定的条目考虑全角和半角括号 处理JSON数据寻找指定的条目考虑全角和半角括号
""" """
value = standardize_brackets(value) value = standardize_brackets(value) #将1.11(1)->1.111
if "" in value and "" in value: if "" in value and "" in value: #存在()的情况
base_key, subentry_key = value.split("") first_content=get_values_only(json_data.get(value))
if first_content:
combined_value.append(first_content)
return True
base_key, subentry_key = value.split("") #base_key:1.11 subentry_key:1
subentry_key = "" + subentry_key subentry_key = "" + subentry_key
content = json_data.get(base_key.strip()) content = json_data.get(base_key.strip())
if content: if content:
@ -59,18 +74,19 @@ def process_json_with_subentries(json_data, value, combined_value):
else: else:
return False return False
else: else:
return process_json(json_data, value, combined_value) return extarct_normal(json_data, value, combined_value)
def process_json(json_data, value, combined_value): def extarct_normal(json_data, value, combined_value):
found_subentries = check_and_collect_subentries(json_data, value, combined_value) found_subentries = check_and_collect_subentries(json_data, value, combined_value)
if not found_subentries: if not found_subentries: #若无子条目,直接查找
content = json_data.get(value, "") content = json_data.get(value, "") #从一个字典 json_data 中获取与键名 value 相关联的值,默认值为""
if content: if content:
combined_value.append(get_values_only(content)) combined_value.append(get_values_only(content))
return True return True
return found_subentries return found_subentries
#用于查找和处理由主条目派生的子条目 eg如果 value 是 "1.1",它将查找所有像 "1.1.1", "1.1.2" 等以 "1.1." 开头的键,不会匹配仅为 "1.1" 的键。
def check_and_collect_subentries(json_data, value, combined_value): def check_and_collect_subentries(json_data, value, combined_value):
found_subentries = False found_subentries = False
subentry_index = 1 subentry_index = 1
@ -82,6 +98,7 @@ def check_and_collect_subentries(json_data, value, combined_value):
found_subentries = True found_subentries = True
return found_subentries return found_subentries
#针对于有子序号()的情况
def extract_specific_subentry(content, subentry_key): def extract_specific_subentry(content, subentry_key):
""" """
提取指定的子条目文本考虑全角和半角括号 提取指定的子条目文本考虑全角和半角括号
@ -101,9 +118,24 @@ def extract_specific_subentry(content, subentry_key):
def get_values_only(content): def get_values_only(content):
if isinstance(content, dict): if isinstance(content, dict):
return " / ".join(content.values()) # 如果内容是字典,首先将字典的值转换为字符串
return content content = " / ".join(content.values())
# 检查并处理特殊字符
return extract_content_after_special_chars(content)
def extract_content_after_special_chars(content):
"""
提取特定符号后的内容直到遇到结束符号或内容末尾
"""
# 定义搜索特殊字符的正则表达式
pattern = r'[\x01\x02☑√团]([^□]*)'
match = re.search(pattern, content)
if match:
# 如果找到匹配,返回从特殊字符之后到下一个□或到内容末尾的部分
return match.group(1).strip() # 去除多余空白字符
# 如果没有找到特殊字符,返回原始内容
return content
def standardize_brackets(value): def standardize_brackets(value):
""" """
将输入中的所有半角括号转换为全角括号 将输入中的所有半角括号转换为全角括号
@ -119,9 +151,9 @@ def process_and_merge_entries(entries_with_numbers, primary_json_path, secondary
if __name__ == "__main__": if __name__ == "__main__":
# Hypothetical entries and file paths for testing # Hypothetical entries and file paths for testing
# entries_with_numbers = [{'形式评审标准.投标文件签字盖章': '3.7.3(3)'}, {'形式评审标准.多标段投标': '10.1'}, {'形式评审标准.“技术暗标”': '3.7.4(5)'}, {'响应性评审标准.投标内容': '1.3.1'}, {'响应性评审标准.工期': '1.3.2'}, {'响应性评审标准.工程质量': '1.3.3'}, {'响应性评审标准.投标有效期': '3.3.1'}, {'响应性评审标准.投标保证金': '3.4.1'}, {'响应性评审标准.分包计划': '1.11'}] # entries_with_numbers = [{'形式评审标准.投标文件签字盖章': '3.7.3(3)'}, {'形式评审标准.多标段投标': '10.1'}, {'形式评审标准.“技术暗标”': '3.7.4(5)'}, {'响应性评审标准.投标内容': '1.3.1'}, {'响应性评审标准.工期': '1.3.2'}, {'响应性评审标准.工程质量': '1.3.3'}, {'响应性评审标准.投标有效期': '3.3.1'}, {'响应性评审标准.投标保证金': '3.4.1'}, {'响应性评审标准.分包计划': '1.11'}]
entries_with_numbers=[{'xxx': '3.7.45'}] entries_with_numbers=[{'xxx': '3.4.1'}]
primary_json_path = 'C:\\Users\\Administrator\\Desktop\\招标文件\\output1\\truncate_output3.json' primary_json_path = 'C:\\Users\\Administrator\\Desktop\\fsdownload\\temp8\\3abb6e16-19db-42ad-9504-53bf1072dfe7\\truncate_output.json'
secondary_json_path = 'C:\\Users\\Administrator\\Desktop\\招标文件\\output1\\clause3.json' secondary_json_path = 'C:\\Users\\Administrator\\Desktop\\fsdownload\\temp8\\3abb6e16-19db-42ad-9504-53bf1072dfe7\\clause.json'
# Since this is just a test block, make sure these paths point to actual JSON files with the appropriate structure # Since this is just a test block, make sure these paths point to actual JSON files with the appropriate structure
try: try:

View File

@ -15,7 +15,7 @@ def combine_review_standards(truncate1,truncate3,knowledge_name,truncate0_jsonpa
user_query_1 = "根据该文档中的评标办法前附表请你列出该文件中的形式评审标准和响应性评审标准和资格评审标准请以json格式返回外层键名为'形式评审标准''响应性评审标准''资格评审标准',嵌套键名为'评审因素'中的内容,相应的键值为对应'评审标准'中的内容。" user_query_1 = "根据该文档中的评标办法前附表请你列出该文件中的形式评审标准和响应性评审标准和资格评审标准请以json格式返回外层键名为'形式评审标准''响应性评审标准''资格评审标准',嵌套键名为'评审因素'中的内容,相应的键值为对应'评审标准'中的内容。"
results = qianwen_long(file_id, user_query_1) results = qianwen_long(file_id, user_query_1)
original_dict_data = extract_content_from_json(results) original_dict_data = extract_content_from_json(results)
qualification_review = original_dict_data.pop('资格评审标准', '默认值或None') qualification_review = original_dict_data.pop('资格评审标准', '默认值或None') #qianwen-long有关资格评审的内容
final_qualify_json=process_qualification(qualification_review,truncate3,knowledge_name) final_qualify_json=process_qualification(qualification_review,truncate3,knowledge_name)
form_response_dict=process_reviews(original_dict_data, knowledge_name, truncate0_jsonpath, clause_path) form_response_dict=process_reviews(original_dict_data, knowledge_name, truncate0_jsonpath, clause_path)
print("形式响应评审done") print("形式响应评审done")

View File

@ -53,11 +53,11 @@ def extract_matching_keys_qual(dict_data):
non_matching_keys[key] = value non_matching_keys[key] = value
return matching_keys,non_matching_keys #matching:['资质条件', '财务状况'] non_matching_keys:{'营业执照': '具备有效的营业执照', '施工机械设备': '具备完善的施工设备'} return matching_keys,non_matching_keys #matching:['资质条件', '财务状况'] non_matching_keys:{'营业执照': '具备有效的营业执照', '施工机械设备': '具备完善的施工设备'}
def process_qualification(qualification_review,truncate4,knowledge_name): def process_qualification(qualification_review,truncate3,knowledge_name):
# 资格评审 # 资格评审
matching_keys_list, non_matching_dict = extract_matching_keys_qual(qualification_review) matching_keys_list, non_matching_dict = extract_matching_keys_qual(qualification_review)
user_querys = generate_qual_question(matching_keys_list) # 生成提问->附件:资格审查 user_querys = generate_qual_question(matching_keys_list) # 生成提问->附件:资格审查
file_id2 = upload_file(truncate4) file_id2 = upload_file(truncate3)
results2 = multi_threading(user_querys, "", file_id2, 2) # 资格评审表 results2 = multi_threading(user_querys, "", file_id2, 2) # 资格评审表
res_list = [] res_list = []
if not results2: if not results2:

View File

@ -3,7 +3,7 @@
#该招标文件的工程概况(或项目概况)是?招标范围是?招标控制价(可指代投标限价、投资概算金额、工程概算金额、合同估算价,但非监理费用)是?该项目的计划工期(监理服务期)是该项目是否接受联合体投标请按json格式给我提供信息键名分别为'工程概况','招标范围','招标控制价','计划工期','是否接受联合体投标',若存在嵌套信息,嵌套内容键名以文件中对应字段命名,若存在未知信息,在对应的键值中填'未知''是否接受联合体投标'的键值仅限于'是'、'否'、'未知'。 #该招标文件的工程概况(或项目概况)是?招标范围是?招标控制价(可指代投标限价、投资概算金额、工程概算金额、合同估算价,但非监理费用)是?该项目的计划工期(监理服务期)是该项目是否接受联合体投标请按json格式给我提供信息键名分别为'工程概况','招标范围','招标控制价','计划工期','是否接受联合体投标',若存在嵌套信息,嵌套内容键名以文件中对应字段命名,若存在未知信息,在对应的键值中填'未知''是否接受联合体投标'的键值仅限于'是'、'否'、'未知'。
2.该招标文件的工程概况或项目概况招标范围是请按json格式给我提供信息键名分别为'工程概况','招标范围',若存在嵌套信息,嵌套内容键名以文件中对应字段命名,若存在未知信息,在对应的键值中填'未知'。 2.该招标文件的工程概况或项目概况招标范围是请按json格式给我提供信息键名分别为'工程概况','招标范围',若存在嵌套信息,嵌套内容键名以文件中对应字段命名,若存在未知信息,在对应的键值中填'未知'。
3.该招标文件的招标控制价(可指代投标限价、投资概算金额、工程概算金额、合同估算价,但非监理费用)是?该项目是否接受联合体投标?请按json格式给我提供信息键名分别为'招标控制价''是否接受联合体投标'若存在未知信息,在对应的键值中填'未知''是否接受联合体投标'的键值仅限于'是'、'否'、'未知'。 3.该招标文件的招标控制价可指代投标限价、投资概算金额、工程概算金额、合同估算价但非监理费用请按json格式给我提供信息键名为'招标控制价',若存在未知信息,在对应的键值中填'未知'。
4.投标文件递交截止日期是递交方式是请按json格式给我提供信息键名分别是'投标文件递交截止日期','递交方式',若存在未知信息,在对应的键值中填'未知'。 4.投标文件递交截止日期是递交方式是请按json格式给我提供信息键名分别是'投标文件递交截止日期','递交方式',若存在未知信息,在对应的键值中填'未知'。
@ -29,3 +29,5 @@
10.求澄清的招标文件截止时间是请以json的格式给我提供信息键名是'投标人要求澄清招标文件的截止时间',若存在未知信息,在对应的键值中填'未知'。 10.求澄清的招标文件截止时间是请以json的格式给我提供信息键名是'投标人要求澄清招标文件的截止时间',若存在未知信息,在对应的键值中填'未知'。
11.该文档要求扣留的质量保证金百分比是多少请以json格式给我提供信息键名为'质量保证金',如果没有则以'未知'填充。 11.该文档要求扣留的质量保证金百分比是多少请以json格式给我提供信息键名为'质量保证金',如果没有则以'未知'填充。
12.该项目是否接受联合体投标请按json格式给我提供信息键名为'是否接受联合体投标''是否接受联合体投标'的键值仅限于'是'、'否'、'未知'。