diff --git a/flask_app/general/json_utils.py b/flask_app/general/json_utils.py index 3e43abc..dcf20a8 100644 --- a/flask_app/general/json_utils.py +++ b/flask_app/general/json_utils.py @@ -407,39 +407,23 @@ def transform_json_values(data): if __name__ == "__main__": data="""{ - "表头": { - "内容": "技术部分", - "范围": [(0, 0), (0, 4)] - }, - "序号": { - "内容": "序号", - "位置": (1, 0), - "方向": "水平" - }, - "产品": { - "内容": "", - "方向": "" - }, - "重要参数要求": { - "内容": "采购文件要求 部分", - "位置": (1, 1), - "方向": "水平" - }, - "对标": { - "内容": "响应文件响应 部分", - "位置": (1, 2), - "方向": "水平" - }, - "偏离": { - "内容": "偏离说明", - "位置": (1, 3), - "方向": "水平" - }, - "备注": { - "内容": "填写相应技术文 件/说明所在页码", - "位置": (1, 4), - "方向": "水平" - } + "新内容": "六、残疾人福利性单位声明函(适用于货物类项目 + +广水市政府采购中心: +本单位郑重声明,根据《财政部 民政部 中国残疾人联合会关于促进残疾人就业政府采购政策的通知》(财库〔2017〕141号)的规定,本单位为符合条件的残疾人福利性单位(详见“残疾人福利性单位应当满足的条件”)。 +1.本单位授权[$$blank_mark_1$$](投标人)参加[$$blank_mark_2$$](采购人)的项目(项目编号:[$$blank_mark_3$$])采购活动提供本单位制造的货物。本条所称货物不包括使用非残疾人福利性单位注册商标的货物。 +2.由本单位制造的货物清单见下表: + + +本单位对上述声明的真实性负责。如有虚假,将依法承担相应责任。 + +说明:1、投标人所投货物为自己制造的,也应按本声明函格式填写。 +2、组成联合体的大中型企业和其他自然人、法人或者其他组织,与残疾人福利性单位之间不得存在投资关系。 +3、以联合体方式参与项目投标的供应商,应由联合体双方签字盖章。 + +制造商(公章): +制造商法定代表人(签字或盖章): +日期:" } """ res=clean_json_string(data) diff --git a/flask_app/general/截取pdf_main.py b/flask_app/general/截取pdf_main.py index a28d0d0..bda0e62 100644 --- a/flask_app/general/截取pdf_main.py +++ b/flask_app/general/截取pdf_main.py @@ -116,7 +116,7 @@ if __name__ == "__main__": # pdf_path=r"C:\Users\Administrator\Desktop\货物标\zbfiles\094定稿-湖北工业大学轻武器模拟射击设备采购项目招标文件.pdf" # pdf_path = r"C:\Users\Administrator\Desktop\货物标\zbfiles\zbtest4_evaluation_method.pdf" # pdf_path = r"C:\Users\Administrator\Desktop\招标文件\招标02.pdf" - pdf_path=r'C:\Users\Administrator\Desktop\货物\test2\2020-安徽-安徽省生态环境厅电梯采购.pdf' + pdf_path=r"C:\Users\Administrator\Downloads\河北省承德监狱2025年供应站水果及干果采购项目招标文件(定).pdf" # input_path=r"C:\Users\Administrator\Desktop\招标文件\招标test文件夹\zbtest8.pdf" output_folder = r"C:\Users\Administrator\Desktop\货物\test" # selections = [1, 4] # 仅处理 selection 4、1 diff --git a/flask_app/general/截取pdf通用函数.py b/flask_app/general/截取pdf通用函数.py index 8b3679b..886a32c 100644 --- a/flask_app/general/截取pdf通用函数.py +++ b/flask_app/general/截取pdf通用函数.py @@ -162,7 +162,7 @@ def get_invalid_file(file_path, output_folder, common_header,begin_page): # 定义排除模式 exclusion_pattern = regex.compile( - r'文件的构成|文件的组成|须对应|需对应|须按照|需按照|须根据|需根据|文件组成|文件构成', + r'文件的构成|文件的组成|须对应|需对应|须按照|需按照|须根据|需根据|文件组成|文件构成|文件的编制|文件编制', regex.MULTILINE ) diff --git a/flask_app/general/证明材料提取.py b/flask_app/general/证明材料提取.py deleted file mode 100644 index e69de29..0000000 diff --git a/flask_app/general/通用功能函数.py b/flask_app/general/通用功能函数.py index a4414c0..23fb30c 100644 --- a/flask_app/general/通用功能函数.py +++ b/flask_app/general/通用功能函数.py @@ -79,6 +79,13 @@ def aggregate_basic_info(baseinfo_list,mode="engineering"): # 按键组分类并嵌套 for group_name, keys in key_groups.items(): group_data = {key: combined_data.get(key, "未提供") for key in keys} + # 仅对 "项目联系方式" 进行特殊处理 + if group_name == "招标人/代理信息" and "项目联系方式" in group_data: + project_contact = group_data["项目联系方式"] + if isinstance(project_contact, dict): + if all(inner_value == "未知" for inner_value in project_contact.values()): + # 移除 "项目联系方式" + del group_data["项目联系方式"] combined_data[group_name] = group_data # 从 unclassified_items 中移除已分类的键 for key in keys: diff --git a/flask_app/routes/工程标解析main.py b/flask_app/routes/工程标解析main.py index 1d86e8e..272ee9f 100644 --- a/flask_app/routes/工程标解析main.py +++ b/flask_app/routes/工程标解析main.py @@ -91,7 +91,6 @@ def preprocess_files(output_folder, file_path, file_type,logger): } # 基本信息 - def fetch_project_basic_info(invalid_deleted_docx, merged_baseinfo_path, merged_baseinfo_path_more, tobidders_notice, clause_path, logger): logger.info("starting 基础信息...") start_time = time.time() diff --git a/flask_app/static/提示词/基本信息工程标.txt b/flask_app/static/提示词/基本信息工程标.txt index 3b8696d..cd1e3c1 100644 --- a/flask_app/static/提示词/基本信息工程标.txt +++ b/flask_app/static/提示词/基本信息工程标.txt @@ -41,12 +41,23 @@ 12.该项目是否接受联合体投标?请按json格式给我提供信息,键名为'是否接受联合体投标','是否接受联合体投标'的键值仅限于'是'、'否'、'未知'。 -13.该招标文件中对投标文件中偏离项的要求或内容是怎样的?请以json格式给我提供信息,外层键名为'偏离',请不要回答具体的技术参数,若存在未知信息,在对应的键值中填'未知'。 - -14.该项目的开标时间(或开启时间)和开标地点(或开启地点、开启方式)是?请按json格式给我提供信息,键名为'开标时间'和'开标地点',键值为原文中相关内容的表述。 +13.该项目的开标时间(或开启时间)和开标地点(或开启地点、开启方式)是?请按json格式给我提供信息,键名为'开标时间'和'开标地点',键值为原文中相关内容的表述。 对于'开标时间',若文中没有明确时间却有诸如'同投标截止时间'的表述,则将相关表述返回;若存在未知信息,在对应的键值中填'未知', 示例输出如下,仅供格式参考: { "开标时间":"详见湖北省政府采购网公告", "开标地点":"线上开标" +} + +13.该招标文件对响应文件(投标文件)偏离项的要求或内容是怎样的?请不要回答具体的技术参数,也不要回答具体的评分要求。请以json格式给我提供信息,外层键名为'偏离',若存在嵌套信息,嵌套内容键名为文件中对应字段或是你的总结,而嵌套键值必须与原文保持一致,若存在未知信息,在对应的键值中填'未知'。示例输出如下,仅供格式参考: +示例1,嵌套键值对情况: +{ + "偏离":{ + "技术和服务要求":"以★标示的内容为不允许负偏离的实质性要求", + "商务要求":"以★标示的内容为不允许负偏离的实质性要求" + } +} +示例2,无嵌套键值对情况: +{ + "偏离":"所有参数需在技术响应偏离表内响应,如应答有缺项,且无有效证明材料的,评标委员会有权不予认可,视同负偏离处理" } \ No newline at end of file diff --git a/flask_app/static/提示词/基本信息货物标.txt b/flask_app/static/提示词/基本信息货物标.txt index 41abe3d..6fbdd5b 100644 --- a/flask_app/static/提示词/基本信息货物标.txt +++ b/flask_app/static/提示词/基本信息货物标.txt @@ -41,9 +41,7 @@ 12.该项目是否接受联合体投标?请按json格式给我提供信息,键名为'是否接受联合体投标','是否接受联合体投标'的键值仅限于'是'、'否'、'未知'。 -13.该招标文件中对投标文件中偏离项的要求或内容是怎样的?请以json格式给我提供信息,外层键名为'偏离',请不要回答具体的技术参数,若存在未知信息,在对应的键值中填'未知'。 - -14.该项目的开标时间(或开启时间)和开标地点(或开启地点、开启方式)是?请按json格式给我提供信息,键名为'开标时间'和'开标地点',键值为原文中相关内容的表述。 +13.该项目的开标时间(或开启时间)和开标地点(或开启地点、开启方式)是?请按json格式给我提供信息,键名为'开标时间'和'开标地点',键值为原文中相关内容的表述。 对于'开标时间',若文中没有明确时间却有诸如'同投标截止时间'的表述,则将相关表述返回;若存在未知信息,在对应的键值中填'未知'。 示例输出如下,仅供格式参考: { diff --git a/flask_app/工程标/截取pdf工程标版.py b/flask_app/工程标/截取pdf工程标版.py index 3e64d7f..302dd01 100644 --- a/flask_app/工程标/截取pdf工程标版.py +++ b/flask_app/工程标/截取pdf工程标版.py @@ -25,7 +25,7 @@ def extract_pages_tobidders_notice(pdf_path, output_folder, begin_pattern, begin text = page.extract_text() or "" cleaned_text = clean_page_content(text, common_header) - if exclusion_pattern and regex.search(exclusion_pattern, cleaned_text) and mid_page is not None: + if mid_page is not None and exclusion_pattern and regex.search(exclusion_pattern, cleaned_text): continue if start_page is None: @@ -130,6 +130,7 @@ def extract_pages(pdf_path, output_folder, begin_pattern, begin_page, end_patter pdf_document = PdfReader(pdf_path) start_page = None end_page = None + flag=True exclusion_pattern = regex.compile(r'文件的构成|文件的组成|须对应|需对应|须按照|需按照|须根据|需根据|文件组成|文件构成|文件的编制|文件编制') # 遍历文档的每一页,查找开始和结束短语的位置 for i in range(len(pdf_document.pages)): @@ -137,7 +138,8 @@ def extract_pages(pdf_path, output_folder, begin_pattern, begin_page, end_patter text = page.extract_text() if text: cleaned_text = clean_page_content(text, common_header) - if regex.search(exclusion_pattern, cleaned_text): + if flag and regex.search(exclusion_pattern, cleaned_text): + flag=False continue if regex.search(begin_pattern, cleaned_text) and i >= begin_page: if start_page and (output_suffix == "notice" or output_suffix == "invalid"): @@ -434,11 +436,11 @@ if __name__ == "__main__": logger=get_global_logger("123") start_time = time.time() # input_path = r"C:\Users\Administrator\Desktop\new招标文件\工程标" - pdf_path=r"C:\Users\Administrator\Desktop\货物标\zbfiles" + pdf_path=r"C:\Users\Administrator\Desktop\fsdownload\305c1fea-e0bd-4135-955f-38fb46388166\ztbfile.pdf" # pdf_path = r"C:\Users\Administrator\Desktop\招标文件\招标02.pdf" # input_path=r"C:\Users\Administrator\Desktop\招标文件\招标test文件夹\zbtest8.pdf" - output_folder = r"C:\Users\Administrator\Desktop\招标文件\招标test文件夹\tmp" + output_folder = r"C:\Users\Administrator\Desktop\fsdownload\305c1fea-e0bd-4135-955f-38fb46388166\tmp" selection = 5 # 例如:1 - 招标公告, 2 - 评标办法, 3 -资格审查条件 4-投标人须知前附表+正文 5-无效标 generated_files = truncate_pdf_main_engineering(pdf_path, output_folder, selection,logger) print(generated_files) diff --git a/flask_app/货物标/截取pdf货物标版.py b/flask_app/货物标/截取pdf货物标版.py index a4dc270..9aa563a 100644 --- a/flask_app/货物标/截取pdf货物标版.py +++ b/flask_app/货物标/截取pdf货物标版.py @@ -20,7 +20,8 @@ def extract_pages_generic(pdf_document, begin_pattern, end_pattern, begin_page, flag=False continue else: - if exclusion_pattern and flag and regex.search(exclusion_pattern, cleaned_text): + #一般投标文件的编制、组成在'投标人须知前附表/正文'中,需要防止begin_pattern匹配到这部分内容,所以在start_page is None的时候使用该exclusion_pattern + if exclusion_pattern and flag and (start_page is None) and regex.search(exclusion_pattern, cleaned_text): flag=False continue if start_page is None and regex.search(begin_pattern, cleaned_text): @@ -33,7 +34,7 @@ def extract_pages_generic(pdf_document, begin_pattern, end_pattern, begin_page, end_page = i break else: - if regex.search(end_pattern, cleaned_text) and i > start_page and not regex.search(begin_pattern,cleaned_text): + if regex.search(end_pattern, cleaned_text) and (i > start_page) and not regex.search(begin_pattern,cleaned_text): end_page = i break return start_page, end_page @@ -99,7 +100,7 @@ def get_patterns_for_procurement(): r'第[一二三四五六七八九十1-9]+(?:章|部分)\s*' # 匹配“第X章”或“第X部分” r'[\u4e00-\u9fff、()()]*?' # 匹配允许的字符 r'(?:(?:服务|项目|商务|技术|供货)[\u4e00-\u9fff、()()]*?要求[\u4e00-\u9fff、()()]*?\s*$|' # 匹配“服务”、“项目”、“商务”或“技术”后跟“要求” - r'(?:采购(?:内容|要求|需求))[\u4e00-\u9fff、()()]*?|' + r'(?:(采购|招标)(?:内容|要求|需求))[\u4e00-\u9fff、()()]*?|' r'需求书[\u4e00-\u9fff、()()]*?)\s*$', regex.MULTILINE ) @@ -503,7 +504,7 @@ def truncate_pdf_main_goods(input_path, output_folder, selection,logger, output_ r'谈判(?=.*(?:办法|方法|内容))|评标|评定|评审))' ) end_pattern = regex.compile( - r'^第[一二三四五六七八九十百千]+(?:章|部分)\s*[\u4e00-\u9fff]+' + r'^第[一二三四五六七八九十百千]+(?:章|部分)\s*[\u4e00-\u9fff]+',regex.MULTILINE ) local_output_suffix = "evaluation_method" elif selection == 3: @@ -525,11 +526,11 @@ def truncate_pdf_main_goods(input_path, output_folder, selection,logger, output_ elif selection == 5: begin_pattern = regex.compile( r'^第[一二三四五六七八九十百千]+(?:章|部分).*?(?:服务|项目|商务|技术|供货).*?要求|' - r'^第[一二三四五六七八九十百千]+(?:章|部分)(?!.*说明).*(?:采购(?:内容|要求|需求)).*|' + r'^第[一二三四五六七八九十百千]+(?:章|部分)(?!.*说明).*(?:(采购|招标)(?:内容|要求|需求)).*|' r'^第[一二三四五六七八九十百千]+(?:章|部分).*?需求书' ) end_pattern = regex.compile( - r'^第[一二三四五六七八九十百千]+(?:章|部分)\s*[\u4e00-\u9fff]+' + r'^第[一二三四五六七八九十百千]+(?:章|部分)\s*[\u4e00-\u9fff]+',regex.MULTILINE ) local_output_suffix = "procurement" elif selection == 6: @@ -606,17 +607,17 @@ def truncate_pdf_main_goods(input_path, output_folder, selection,logger, output_ # TODO:交通智能系统和招标(1)(1)文件有问题 包头 绍兴 工程标中,判断是符合性审查之后,可以将它们设为同一章 - +#TODO: 验证所有文件的切分逻辑。 # ztbfile.pdf少资格评审 包头少符合性评审 if __name__ == "__main__": logger = get_global_logger("123") # input_path = r"C:\Users\Administrator\Desktop\new招标文件\货物标" # pdf_path = r"C:\Users\Administrator\Desktop\招标文件-采购类\2024-贵州-贵州医科大学附属医院导视系统零星制作安装项目.pdf" - pdf_path=r"C:\Users\Administrator\Desktop\fsdownload\80286859-52da-4b29-8396-52b3d104c32b\ztbfile.pdf" + pdf_path=r"C:\Users\Administrator\Downloads\河北省承德监狱2025年供应站水果及干果采购项目招标文件(定).pdf" # input_path = r"C:\Users\Administrator\Desktop\货物标\zbfiles\2-招标文件(广水市教育局封闭管理).pdf" # pdf_path=r"C:\Users\Administrator\Desktop\文件解析问题\文件解析问题\1414cb9c-7bf4-401c-8761-2acde151b9c2\ztbfile.pdf" - output_folder = r"C:\Users\Administrator\Desktop\fsdownload\80286859-52da-4b29-8396-52b3d104c32b\tmp" + output_folder = r"C:\Users\Administrator\Desktop\货物标\output55" # output_folder = r"C:\Users\Administrator\Desktop\new招标文件\output2" selection = 5 # 例如:1 - 公告, 2 - 评标办法, 3 - 资格审查后缀有qualification1或qualification2(与评标办法一致) 4.投标人须知前附表part1 投标人须知正文part2 5-采购需求 generated_files = truncate_pdf_main_goods(pdf_path, output_folder, selection,logger) - print(generated_files) + # print(generated_files)