From a26393d58685e2bc757a5ded78abc56120f2074d Mon Sep 17 00:00:00 2001 From: zy123 <646228430@qq.com> Date: Wed, 25 Dec 2024 14:35:52 +0800 Subject: [PATCH] =?UTF-8?q?12.25=20=E8=A7=A3=E6=9E=90=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- flask_app/general/file2markdown.py | 2 +- flask_app/general/商务技术评分提取.py | 152 ++++++++++++------ flask_app/general/截取pdf通用函数.py | 2 +- .../general/投标人须知正文提取指定内容.py | 3 +- flask_app/test_case/test_qianwen_long.py | 2 - .../投标人须知正文提取指定内容工程标.py | 2 +- flask_app/货物标/截取pdf货物标版.py | 17 +- .../投标人须知正文提取指定内容货物标版.py | 6 +- flask_app/货物标/提取json货物标版.py | 4 +- 9 files changed, 120 insertions(+), 70 deletions(-) diff --git a/flask_app/general/file2markdown.py b/flask_app/general/file2markdown.py index 98de8a3..c939789 100644 --- a/flask_app/general/file2markdown.py +++ b/flask_app/general/file2markdown.py @@ -75,6 +75,6 @@ def convert_file_to_markdown(file_path): if __name__ == "__main__": # file_path=r"C:\Users\Administrator\Desktop\fsdownload\e702f1e6-095d-443d-bb7d-ef2e42037cb1\ztbfile_procurement.pdf" - file_path=r"C:\Users\Administrator\Desktop\文件解析问题\文件解析问题\baada43d-24f6-459d-8a81-219d130f20da\ztbfile_procurement.pdf" + file_path=r"C:\Users\Administrator\Desktop\文件解析问题\文件解析问题\3496bb36-c476-42f0-947e-3e39c295f8bc\ztbfile_evaluation_method.pdf" res=convert_file_to_markdown(file_path) print(res) \ No newline at end of file diff --git a/flask_app/general/商务技术评分提取.py b/flask_app/general/商务技术评分提取.py index 12e1751..9a6783e 100644 --- a/flask_app/general/商务技术评分提取.py +++ b/flask_app/general/商务技术评分提取.py @@ -1,4 +1,5 @@ import json +import os import re import time from collections import defaultdict @@ -115,7 +116,16 @@ def reorganize_data(input_dict, include=None): reorganized["商务评分"][package] = categories["商务评分"] return reorganized - +# 格式要求: +# 请以 JSON 格式返回结果,最外层键名为 '技术评分'、'商务评分' 和 '投标报价评分'。在每大项下,用键值对表示具体评分项,键为具体的评审因素,若评审因素存在嵌套(表格中存在层级),请使用嵌套键值对表示,具体规则如下: +# 1. 如果评审因素存在嵌套,使用嵌套键值对表示: +# -主评审因素的键名后需附加括号,表示该主因素下所有子因素总分,例如:产品技术响应(8分) +# -子评审因素作为主评审因素的内层键名 +# 2. 如果评审因素不存在嵌套,那么键名就是该评审因素 +# 3. 每个评审因素的最内层键值都是列表,列表中包含描述评分及要求的字典,字典需包含以下键: +# '评分':具体得分或定性指标(如 '合格制'),无评分时可删去'评分'键值对。 +# '要求':说明评分标准。 +# 4.若这三大项评分中存在额外信息(不属于某个评审因素,即该大项评分的整体要求),在该评分项内部新增键名为'备注',值为该要求。 def combine_evaluation_standards(evaluation_method_path,invalid_path,zb_type): # 定义默认的评审结果字典 DEFAULT_EVALUATION_REVIEW = { @@ -144,15 +154,26 @@ def combine_evaluation_standards(evaluation_method_path,invalid_path,zb_type): # 执行查询 return qianwen_long(file_id, query),file_id def run_second_qeury(file_id): + print("获取评分项...") # 执行 user_query 相关的逻辑 user_query_1 = ( """ 你是一个对招投标业务非常熟悉的专家。根据该文档中的评标办法表格,请你列出该文件的技术评分,商务评分,投标报价评分以及它们对应的具体评分要求,请以JSON格式返回结果。 - 格式要求: - 请以 JSON 格式返回结果,最外层键名为 '技术评分'、'商务评分' 和 '投标报价评分'。在每大项下,用键值对表示具体评分项,键为具体的评审因素,若评审因素存在嵌套(表格中存在层级),请使用嵌套键值对表示,外层键名为主评审因素,嵌套的子评审因素作为内层键名,最内键值为列表,列表中包含描述评分及要求的字典。每个字典的键包括: - '评分':具体得分或定性指标(如 '合格制'),无评分时可删去'评分'键值对。 - '要求':说明评分标准。 - 若这三大项评分中存在额外信息(不属于某个评审因素,即该大项评分的整体要求),在该评分项内部新增键名为'备注'。 +格式要求: +1.总体结构: + -JSON 的最外层包含三个键:技术评分、商务评分 和 投标报价评分。 + -每个大项(如技术评分、商务评分)下包含具体的评分项,评分项按以下规则表示。 +2.评分项表示规则: + -层级嵌套规则: + 若评分因素存在嵌套关系:主评分因素需附加括号,括号中注明该主评分项的总分。例如:产品技术响应(8分);子评分因素作为嵌套键,列在主评分因素之下,无需再附加括号表示评分。 + 若评分因素不存在嵌套关系:键名直接为评分因素,无需附加括号表示总分。 + -评分项内容: + -每个评分项最内层值都是一个列表,列表中包含一个或多个描述评分标准的字典。 + -字典结构如下: + 评分(可选):具体得分(如 8分),若为定性指标(如“合格制”),可标明“合格制”。 + 要求:详细描述评分标准及要求。 +3.备注信息: + -若评分部分包含附加信息(如大项评分的整体要求,未直接归属于具体评分项),需添加一个 备注 键,值为该附加信息。 要求与指南: 1. 请首先定位评分细则的表格,不要回答有关资格审查的内容,也不要从评标办法正文中提取回答 @@ -171,7 +192,7 @@ def combine_evaluation_standards(evaluation_method_path,invalid_path,zb_type): { "一包": { "技术评分": { - "实施方案":{ + "实施方案(16分)":{ "总体实施方案":[ { "评分":8, @@ -185,29 +206,29 @@ def combine_evaluation_standards(evaluation_method_path,invalid_path,zb_type): } ] }, + "设计创意": [ + { + "评分": "10分", + "要求": "主题突出,形式多样,内容与形式完美统一,得10分,其他酌情打分" + } + ], + "备注": "技术标采用暗标形式,暗标不得出现投标人名称、人员姓名。" + }, + "商务评分": { "主要监理岗位的职责": [ { "评分": "4分", - "要求": "1、总监理工程师的职责全面、清晰、合理得 1.2-2分;一般的1.2分。2、其他主要监理人员及岗位的职责全面、清晰、合理得 1.2-2分;一般的 1.2分。" + "要求": "1、总监理工程师的职责全面、清晰、合理得 2 分;一般的 1 分。2、其他主要监理人员及岗位的职责全面、清晰、合理得 2 分;一般的 1 分。" } ], - "备注": "技术标采用定性方式评审的, “不合格”仅限于投标文件出现违反国家强制性条文标准的情况,否则技术标评审结论为“合格” 。" - }, - "商务评分": { - "控制系统内主板": [ - { - "评分": "10分", - "要求": "所投电梯控制系统内主板为制造商原厂原品牌制造生产且为进口部件得 10分。(提供进口部件报关单及原产地证明扫描件加盖公章,否则不得分)" - } - ], - "制造商技术实力": [ + "制造商实力": [ { "评分": "3分", "要求": "一级证书得3分,二级证书得1分,其他不得分" }, { "评分": "2分", - "要求": "行业销量排名连续前 2 名,得 2 分,第 4-6 名得 0.5 分,其他不得分" + "要求": "行业销量排名连续前 2 名,得 2 分,第 3-6 名得 0.5 分,其他不得分" } ] }, @@ -227,10 +248,20 @@ def combine_evaluation_standards(evaluation_method_path,invalid_path,zb_type): """ 你是一个对招投标业务非常熟悉的专家。根据该文档中的评标办法表格,请你列出该文件的技术评分,商务评分,投标报价评分以及它们对应的具体评分要求,请以JSON格式返回结果。 格式要求: -请以 JSON 格式返回结果,最外层键名为 '技术评分'、'商务评分' 和 '投标报价评分'。在每大项下,用键值对表示具体评分项,键为具体的评审因素,若评审因素存在嵌套(表格中存在层级),请使用嵌套键值对表示,外层键名为主评审因素,嵌套的子评审因素作为内层键名,最内键值为列表,列表中包含描述评分及要求的字典。每个字典的键包括: - '评分':具体得分或定性指标(如 '合格制'),无评分时可删去'评分'键值对。 - '要求':说明评分标准。 -若这三大项评分中存在额外信息(不属于某个评审因素,即该大项评分的整体要求),在该评分项内部新增键名为'备注',值为该要求。 +1.总体结构: + -JSON 的最外层包含三个键:技术评分、商务评分 和 投标报价评分。 + -每个大项(如技术评分、商务评分)下包含具体的评分项,评分项按以下规则表示。 +2.评分项表示规则: + -层级嵌套规则: + 若评分因素存在嵌套关系:主评分因素需附加括号,括号中注明该主评分项的总分。例如:产品技术响应(8分);子评分因素作为嵌套键,列在主评分因素之下,无需再附加括号表示评分。 + 若评分因素不存在嵌套关系:键名直接为评分因素,无需附加括号表示总分。 + -评分项内容: + -每个评分项最内层值都是一个列表,列表中包含一个或多个描述评分标准的字典。 + -字典结构如下: + 评分(可选):具体得分(如 8分),若为定性指标(如“合格制”),可标明“合格制”。 + 要求:详细描述评分标准及要求。 +3.备注信息: + -若评分部分包含附加信息(如大项评分的整体要求,未直接归属于具体评分项),需添加一个 备注 键,值为该附加信息。 要求与指南: 1. 请首先定位评分细则的表格,不要回答有关资格审查的内容,也不要从评标办法正文中提取回答 @@ -250,29 +281,43 @@ def combine_evaluation_standards(evaluation_method_path,invalid_path,zb_type): { "一包": { "技术评分": { + "产品技术响应(8分)":{ + "常规参数符合":[ + { + "评分":"4分", + "要求":"未标★项为常规参数每条负偏离扣1分,本项满分4分。" + } + ], + "摄影机":[ + { + "评分":"4分", + "要求":"支持1路H.265编码、25fps、32MP分辨率的拼接摄像机视频实时预览功能,满分4分" + } + ] + }, + "实施方案": [ + { + "评分": "10分", + "要求": "实施方案清晰、完整、合理、可行的得 10 分。" + } + ], + "备注": "注:若不满足“与公安部、省公安厅、随州市公安局高清视频会议系统无缝对接互联互通”的要求,则本项技术部分不得分。" + }, + "商务评分": { "主要监理岗位的职责": [ { "评分": "4分", - "要求": "1、总监理工程师的职责全面、清晰、合理得 1.2-2分;一般的1.2分。2、其他主要监理人员及岗位的职责全面、清晰、合理得 1.2-2分;一般的 1.2分。" + "要求": "1、总监理工程师的职责全面、清晰、合理得 2 分;一般的 1 分。2、其他主要监理人员及岗位的职责全面、清晰、合理得 2 分;一般的 1 分。" } ], - "备注": "注:若不满足“与公安部、省公安厅、随州市公安局高清视频会议系统无缝对接互联互通”的要求,则本项技术部分(50分)不得分。" - }, - "商务评分": { - "控制系统内主板": [ - { - "评分": "10分", - "要求": "所投电梯控制系统内主板为制造商原厂原品牌制造生产且为进口部件得 10分。(提供进口部件报关单及原产地证明扫描件加盖公章,否则不得分)" - } - ], - "制造商技术实力": [ + "制造商实力": [ { "评分": "3分", "要求": "一级证书得3分,二级证书得1分,其他不得分" }, { "评分": "2分", - "要求": "行业销量排名连续前 2 名,得 2 分,第 4-6 名得 0.5 分,其他不得分" + "要求": "行业销量排名连续前 2 名,得 2 分,第 3-6 名得 0.5 分,其他不得分" } ] }, @@ -325,23 +370,32 @@ def combine_evaluation_standards(evaluation_method_path,invalid_path,zb_type): updated_jsons = combine_technical_and_business(result_data, target_values) final_res = reorganize_data(updated_jsons, include) # 重新组织字典,尤其是分包的情况 return final_res + try: judge_res,file_id = run_first_query(evaluation_method_path) # 检查 judge_res 的内容 + def get_default_result(): + return { + '技术评分': '本招标文件没有技术评分!', + '商务评分': '本招标文件没有商务评分!' + } + # 如果 judge_res 包含 '是',直接运行第二步查询 if '是' in judge_res: - # 执行 user_query 相关的逻辑 return run_second_qeury(file_id) - else: - judge_res,file_id=run_first_query(invalid_path) #调用invalid_path看看有没有评分项 - if '是' in judge_res: - # 执行 user_query 相关的逻辑 - return run_second_qeury(file_id) - else: - # 如果 judge 是 False,直接返回默认的技术标和商务标的结构 - result_data = {} - result_data['技术评分'] = '本招标文件没有技术评分!' - result_data['商务评分'] = '本招标文件没有商务评分!' - return result_data + # 标准化路径,避免多种表示形式造成的误判 + eval_path = os.path.abspath(evaluation_method_path) + invalid_eval_path = os.path.abspath(invalid_path) + # 判断路径是否一致 + if eval_path == invalid_eval_path: + # 如果路径一致,直接返回默认结果 + return get_default_result() + # 路径不一致,尝试运行第一次查询 + judge_res, file_id = run_first_query(invalid_path) + # 如果 judge_res 包含 '是',运行第二步查询 + if '是' in judge_res: + return run_second_qeury(file_id) + # 默认返回结果 + return get_default_result() except Exception as e: print(f"Error in combine_evaluation_standards: {e}") # 在出错时返回默认的包含空字符串的字典 @@ -350,13 +404,13 @@ def combine_evaluation_standards(evaluation_method_path,invalid_path,zb_type): if __name__ == "__main__": start_time=time.time() # truncate_file=r"C:\Users\Administrator\Desktop\招标文件-采购类\tmp2\2024-新疆-塔城地区公安局食药环分局快检实验室项目_evaluation_method.pdf" - evaluation_method_path = r'C:\Users\Administrator\Desktop\文件解析问题\文件解析问题\be901ea0-adc9-47b8-9ada-5c3bc0dd9434\ztbfile_evaluation_method.pdf' + evaluation_method_path = r'C:\Users\Administrator\Desktop\招标文件\招标test文件夹\招标04.pdf' invalid_path=r'C:\Users\Administrator\Desktop\文件解析问题\文件解析问题\be901ea0-adc9-47b8-9ada-5c3bc0dd9434\ztbfile.docx' # truncate_file = "C:\\Users\\Administrator\\Desktop\\货物标\\output2\\2-招标文件(统计局智能终端二次招标)_evaluation_method.pdf" # truncate_file="C:\\Users\\Administrator\\Desktop\\货物标\\output2\\广水市妇幼招标文件最新(W改)_evaluation_method.pdf" # truncate_file = "C:\\Users\\Administrator\\Desktop\\fsdownload\\2d481945-1f82-45a5-8e56-7fafea4a7793\\ztbfile_evaluation_method.pdf" # truncate_file="C:\\Users\\Administrator\\Desktop\\fsdownload\\ztbfile_evaluation_method.pdf" - res = combine_evaluation_standards(evaluation_method_path,invalid_path,2) + res = combine_evaluation_standards(evaluation_method_path,invalid_path,1) print(json.dumps(res, ensure_ascii=False, indent=4)) end_time=time.time() print("elapsed time:"+str(end_time-start_time)) \ No newline at end of file diff --git a/flask_app/general/截取pdf通用函数.py b/flask_app/general/截取pdf通用函数.py index c577f9f..cbe4fc2 100644 --- a/flask_app/general/截取pdf通用函数.py +++ b/flask_app/general/截取pdf通用函数.py @@ -147,7 +147,7 @@ def get_invalid_file(file_path, output_folder, common_header,begin_page): # 定义结束模式 end_patterns = [ regex.compile( - r'第[一二三四五六七八九十]+章\s*合同|[::]清标报告', + r'第[一二三四五六七八九十]+(?:章|部分).*?合同|[::]清标报告', regex.MULTILINE ), regex.compile( diff --git a/flask_app/general/投标人须知正文提取指定内容.py b/flask_app/general/投标人须知正文提取指定内容.py index b025712..d9750d3 100644 --- a/flask_app/general/投标人须知正文提取指定内容.py +++ b/flask_app/general/投标人须知正文提取指定内容.py @@ -299,6 +299,7 @@ def extract_between_sections(data, target_values): section_pattern = re.compile(r'^[一二三四五六七八九十]+$') # 匹配 "一", "二", "三" 等大标题 current_block = {} + file_pattern = re.compile(r'文\s*件') # 遍历所有键值对 for key, value in data.items(): # 只匹配形如 "一": "竞争性磋商响应文件" 的章节标题 @@ -312,7 +313,7 @@ def extract_between_sections(data, target_values): target_found = False # 检查当前标题是否包含 target_values 中的任意关键词 - if any(tv in value for tv in target_values): + if any(tv in value for tv in target_values) and not file_pattern.search(value): target_found = True # 找到了目标章节,开始捕获后续内容 current_section_title = value # 保存章节标题内容 diff --git a/flask_app/test_case/test_qianwen_long.py b/flask_app/test_case/test_qianwen_long.py index cf3e0a0..fd7439f 100644 --- a/flask_app/test_case/test_qianwen_long.py +++ b/flask_app/test_case/test_qianwen_long.py @@ -1,6 +1,4 @@ import concurrent.futures -import os - from flask_app.general.通义千问long import qianwen_long, upload_file diff --git a/flask_app/工程标/投标人须知正文提取指定内容工程标.py b/flask_app/工程标/投标人须知正文提取指定内容工程标.py index 06674db..957bd9b 100644 --- a/flask_app/工程标/投标人须知正文提取指定内容工程标.py +++ b/flask_app/工程标/投标人须知正文提取指定内容工程标.py @@ -90,7 +90,7 @@ def extract_from_notice(merged_baseinfo_path, clause_path, type): # 映射 type 到 target_values type_target_map = { 1: ["投标", "投标文件", "响应文件"], - 2: ["开标", "评标", "定标", "评审", "成交", "合同", "磋商程序", "中标", "程序", "步骤"], + 2: ["开标", "评标", "定标", "评审", "成交", "合同", "磋商","谈判","中标", "程序", "步骤"], 3: ["重新招标、不再招标和终止招标", "重新招标", "重新采购", "不再招标", "不再采购", "终止招标", "终止采购"], 4: ["评标"] # 测试 } diff --git a/flask_app/货物标/截取pdf货物标版.py b/flask_app/货物标/截取pdf货物标版.py index 6fbdcc1..9c44319 100644 --- a/flask_app/货物标/截取pdf货物标版.py +++ b/flask_app/货物标/截取pdf货物标版.py @@ -94,15 +94,12 @@ def extract_pages(pdf_path, output_folder, begin_pattern, begin_page, end_patter def get_patterns_for_procurement(): - # begin_pattern = regex.compile( - # r'^第[一二三四五六七八九十百千]+(?:章|部分).*?(?:服务|项目|商务|技术).*?要求|^第[一二三四五六七八九十1-9]+(?:章|部分).*(?:采购|需求).*', - # regex.MULTILINE) begin_pattern = regex.compile( r'(?