From 6e6400ce34d345ef27c39d99cfcb91dafb7e6a7a Mon Sep 17 00:00:00 2001 From: zy123 <646228430@qq.com> Date: Thu, 7 Nov 2024 15:46:24 +0800 Subject: [PATCH] =?UTF-8?q?11.7=20=E8=B5=84=E6=A0=BC=E5=AE=A1=E6=9F=A5?= =?UTF-8?q?=E8=B4=A7=E7=89=A9=E6=A0=87=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- flask_app/general/读取文件/按页读取pdf.py | 2 +- flask_app/testdir/test3.py | 171 ++++++++--- .../投标人须知正文提取指定内容货物标版.py | 6 +- .../投标人须知正文条款提取成json文件货物标版.py | 35 ++- flask_app/货物标/货物标解析main.py | 2 +- flask_app/货物标/资格审查main.py | 267 +++++++++++++----- 6 files changed, 363 insertions(+), 120 deletions(-) diff --git a/flask_app/general/读取文件/按页读取pdf.py b/flask_app/general/读取文件/按页读取pdf.py index 1dff018..696ed1f 100644 --- a/flask_app/general/读取文件/按页读取pdf.py +++ b/flask_app/general/读取文件/按页读取pdf.py @@ -96,7 +96,7 @@ def extract_text_by_page(file_path): if __name__ == '__main__': # file_path='D:\\flask_project\\flask_app\\static\\output\\output1\\648e094b-e677-47ce-9073-09e0c82af210\\ztbfile_tobidders_notice_part2.pdf' - file_path = 'C:\\Users\\Administrator\\Desktop\\fsdownload\\54d7aa40-8b36-4803-b6f7-278356ff1381\\ztbfile_tobidders_notice_part2.pdf' + file_path = 'C:\\Users\\Administrator\\Desktop\\fsdownload\\a110ed59-00e8-47ec-873a-bd4579a6e628\\ztbfile_tobidders_notice_part2.pdf' # file_path = 'C:\\Users\\Administrator\\Desktop\\货物标\\output4\\磋商文件_tobidders_notice_part2.pdf' # file_path = 'C:\\Users\\Administrator\\Desktop\\货物标\\截取test\\交警支队机动车查验监管系统项目采购_tobidders_notice_part1.pdf' # file_path = "C:\\Users\\Administrator\\Desktop\\招标文件\\招标test文件夹\\zbtest8.pdf" diff --git a/flask_app/testdir/test3.py b/flask_app/testdir/test3.py index 9861a98..d813dc5 100644 --- a/flask_app/testdir/test3.py +++ b/flask_app/testdir/test3.py @@ -24,27 +24,6 @@ def contains_number_or_index(key, value): return False # 如果值是数字或包含数字,且不包含中文字符,或者键包含 "序号",返回 True return is_number or contains_index or contains_digit -def preprocess_dict(data): - if isinstance(data, dict): - if len(data) > 1: - # 检查是否所有值都是 "" 或 "/" - if all(v == "" or v == "/" or (isinstance(v, list) and not v) for v in data.values()): - return list(data.keys()) - else: - processed = {} - for k, v in data.items(): - if not contains_number_or_index(k, v): - processed_v = preprocess_dict(v) - if processed_v != "": # 只添加非空值 - processed[k] = processed_v - return processed - else: - return {k: preprocess_dict(v) for k, v in data.items()} - elif isinstance(data, list): - return [preprocess_dict(item) for item in data] - else: - return data - def process_dict(data): """ 递归处理字典,将符合条件的键值对进行转换。 @@ -81,7 +60,11 @@ def process_dict(data): elif re.match(r'^\d+\.\d+$', key): # 单层小数点 return (float(key),) else: # 多层序号,按字符串处理 - return tuple(map(int, key.split('.'))) + try: + return tuple(int(part) for part in key.split('.') if part.isdigit()) + except ValueError: + # 处理无法转换的部分,例如返回一个默认值或记录错误 + return () # 按键排序,确保顺序一致 numeric_keys_sorted = sorted(numeric_keys, key=sort_key) result['items'] = [process_dict(item[1]) for item in numeric_keys_sorted] @@ -124,21 +107,133 @@ def process_dict(data): return list(result.keys()) return result + +def preprocess_dict(data): + if isinstance(data, dict): + if len(data) > 1: + # 检查是否所有值都是 "" 或 "/" + if all(v == "" or v == "/" or (isinstance(v, list) and not v) for v in data.values()): + return list(data.keys()) + else: + processed = {} + for k, v in data.items(): + if not contains_number_or_index(k, v): + processed_v = preprocess_dict(v) + if processed_v != "": # 只添加非空值 + processed[k] = processed_v + return processed + else: + return {k: preprocess_dict(v) for k, v in data.items()} + elif isinstance(data, list): + return [preprocess_dict(item) for item in data] + else: + return data data={ - "资格性审查": { - "1": "供应商应具备《政府采购法》第二十二条规定的条件,提供相关材料。", - "2": "法人或者其他组织的营业执照等证明文件,自然人的身份证明;", - "3": "财务状况报告,依法缴纳税收和社会保障资金的声明函;", - "4": "具备履行合同所必需的设备和专业技术能力的证明材料;", - "5": "未被列入信用记录名单声明函;", - "6": "参加政府采购活动前 3年内在经营活动中没有重大违法记录的书面声明;", - "7": "具备法律、行政法规规定的其他条件的证明材料;", - "8": "招标文件第一章“投标人资格要求”中有特殊要求的,投标人应提供其符合特殊要求的证明材料或者情况说明;", - "9.1.1": "未被列入信用记录名单声明函;", - "10.1.1": "参加政府采购活动前 3年内在经营活动中没有重大违法记录的书面声明;", - "11": "具备法律、行政法规规定的其他条件的证明材料;", - "12": "招标文件第一章“投标人资格要求”中有特殊要求的,投标人应提供其符合特殊要求的证明材料或者情况说明;" - } + "符合性审查": { + "1": { + "投标报价": { + "审查内容": "(1)投标报价没有超过项目(采购包)预算金额或最高限价;\n(2)投标报价不存在缺项、漏项。" + } + }, + "2": { + "投标文件签署": { + "审查内容": "按照招标文件要求签署、盖章。" + } + }, + "3": { + "强制采购节能产品": { + "审查内容": "依据财库[2019]9号文的规定,如属于强制节能产品,须提供国家确定的认证机构出具的、处于有效期内的节能产品认证证书或中国政府采购网节能产品查询截图,未提供的视为无效响应(认证证书或查询截图的产品型号与所投产品不一致的,视为未提供)。" + } + }, + "4": { + "进口产品": { + "审查内容": "招标文件不接受进口产品投标时,投标人所投产品不是通过中国海关报关验放进入中国境内且产自关境外的。" + } + }, + "5": { + "实质性要求": { + "审查内容": "(1)满足招标文件第三章“项目采购需求”中要求的实质性条款;\n(2)投标有效期满足招标文件要求;\n(3)没有采购人不能接受的附加条件。" + } + }, + "6": { + "围标串标情形": { + "审查内容": "投标人不存在下列任一情形:\n(1)不同投标人的投标文件由同一单位或者个人编制;\n(2)不同投标人委托同一单位或者个人办理投标事宜;\n(3)不同投标人的投标文件载明的项目管理成员或者联系人员为同一人;\n(4)不同投标人的投标文件异常一致或者投标报价呈规律性差异;\n(5)不同投标人的投标文件相互混装;\n(6)不同投标人使用同一电脑(机器特征值一致:如 MAC地址等)或使用同一电子密钥,编制或上传电子投标文件。" + } + }, + "7": { + "其他无效情形": { + "审查内容": "不存在法律、法规和招标文件规定的其他无效投标情形。" + } + } + }, + "资格性审查": { + "1": { + "资格要求": "具有独立承担民事责任的能力", + "审查内容": "法人或者其他组织的营业执照等证明文件,自然人的身份证明。(1)企业应提供“营业执照”; (2)事业单位应提供“事业单位法人证书”; (3)非企业专业服务机构应提供执业许可证等证明文件; (4)个体工商户应提供“个体工商户营业执照”; (5)自然人应提供自然人身份证明。" + }, + "2": { + "资格要求": "具有良好的商业信誉和健全的财务会计制度", + "审查内容": "由投标人对以下内容提供书面承诺或声明,或提供相应证明材料。(1)投标人是法人的,应具有上一年度(__ 年度或_____年度)经审计的财务报告,或其基本开户银行出具的资信证明。其他组织和自然人,没有经审计的财务报告,应具有银行出具的资信证明。(2)有专业担保机构对投标人进行资信审查后出具投标担保函的,可以不用具备经审计的财务报告和银行资信证明文件。" + }, + "3": { + "资格要求": "具有履行合同所必需的设备和专业技术能力", + "审查内容": "由投标人提供书面承诺或声明,或提供相应证明材料。" + }, + "4": { + "资格要求": "有依法缴纳税收和社会保障资金的良好记录", + "审查内容": "由投标人对以下内容提供书面承诺或声明,或提供相应证明材料。(1)投标人依法缴纳税收:本项目公告发布时间前 12个月内(至少有 1个月)缴纳税收的凭据(完税证、缴款书、印花税票、银行代扣(代缴)转账凭证等均可); (2)投标人依法缴纳社会保障资金:本项目公告发布时间前 12个月内(至少有 1个月)缴纳社会保险的凭据(专用收据或社会保险交纳清单); (3)投标人为其他组织或自然人的,也应满足以上要求; (4)递交投标文件截止时间的当月成立但因税务机关原因导致其尚未依法缴纳税收的投标人,提供将依法缴纳税收承诺书原件(格式自拟),该承诺书视同税收缴纳凭据; (5)递交投标文件截止时间的当月成立但因社会保障资金管理机关原因导致其尚未依法缴纳社会保障资金的投标人,提供将依法缴纳社会保障资金承诺书原件(格式自拟),该承诺书视同社会保险凭据; (6)依法免税或不需要缴纳社会保障资金的投标人,具有相应文件证明其依法免税或不需要交纳社会保障资金。" + }, + "5": { + "资格要求": "参加政府采购活动前三年内,在经营活动中没有重大违法记录", + "审查内容": "由投标人提供书面承诺或声明,或提供相应证明材料。" + }, + "6": { + "资格要求": "法律、行政法规规定的其他条件", + "审查内容": "由投标人提供书面承诺或声明,或提供相应证明材料。" + }, + "7": { + "资格要求": "单位负责人为同一人或者存在直接控股、管理关系的不同投标人,不得参加本项目同一合同项下的政府采购活动", + "审查内容": "由投标人在《投标函》中声明" + }, + "8": { + "资格要求": "为本采购项目提供整体设计、规范编制或者项目管理、监理、检测等服务的,不得再参加本项目的其他招标采购活动。", + "审查内容": "由投标人在《投标函》中声明" + }, + "9": { + "资格要求": "未被列入失信被执行人、“重大税收违法失信主体”,未被列入政府采购严重违法失信行为记录名单。", + "审查内容": "以采购人和采购代理机构在投标截止日在 “信用中国”网站(www.creditchina.gov.cn) 及中国政府采购网(www.ccgp.gov.cn)查询的投标人参加政府采购活动前三年内的结果为准 (采购人和采购代理机构对信用信息查询记录和证据截图或下载存档)。" + }, + "10": { + "资格要求": "落实政府采购政策需满足的资格要求", + "审查内容": "☐支持中小企业发展资格要求:提供《中小企业声明函》,本项目投标人属于监狱企业或者残疾人福利性单位的,同时提供监狱企业证明材料或者《残疾人福利性单位声明函》; ☑其他政府采购政策需满足的资格要求:/" + }, + "11": { + "资格要求": "本项目的特定资格要求", + "审查内容": "详见第一章“投标邀请”投标人特定资格要求。" + } + }, + "申请人资格要求": [ + "1.满足《中华人民共和国政府采购法》第二十二条规定,即:", + "(1)具有独立承担民事责任的能力;", + "(2)具有良好的商业信誉和健全的财务会计制度;", + "(3)具有履行合同所必需的设备和专业技术能力;", + "(4)有依法缴纳税收和社会保障资金的良好记录;", + "(5)参加政府采购活动前三年内,在经营活动中没有重大违法记录;", + "2.未被列入失信被执行人、“重大税收违法失信主体”,未被列入政府采购严重违法失信行为记录名单。", + "3.落实政府采购政策需满足的资格要求:无", + "4.投标人特定资格要求:", + "(1)投标人须在中国工商行政管理机关注册登记并取得营业执照,具有独立承担民事责任的能力。", + "(2)投标人须提供近三年完整的财务审计报告(成立未满三年的,提供自成立之日起至今的财务审计报告;成立未满一年的,提供银行资信证明),以及近 6个月由税务部门出具的纳税证明材料(零申报提供零申报证明,如有减、免、缓交的须提供相应证明材料)和社保缴纳证明;", + "(3)投标人须出具在参加本项目投标活动前三年内,在经营活动中无重大违法记录,且遵守有关的国家法律、法令、条例和政府采购有关制度,一旦参加投标,则应承担相关法律责任的承诺函;", + "(4)投标截止时间前有相关任何一条以下不良记录及重大违法记录(政府采购法第二十二条第一款第五项所称重大违法记录,是指供应商因违法经营受到刑事处罚或责令停产停业、吊销许可证或执照、较大数额罚款等行政处罚。)的供应商将被拒绝:", + "①在信用中国网站(http://www.creditchina.gov.cn )查询“失信被执行人”和“重大税收违法失信主体”和“政府采购严重违法失信行为记录名单”的加盖公司公章的证明材料;", + "②中国政府采购网(http://www.ccgp.gov.cn/cr/list)查询“政府采购严重违法失信行为信息记录”的加盖公司公章的截图证明材料;", + "③国家企业信用信息公示系统 (http://www.gsxt.gov.cn/corp-query-homepage.html )查询“行政处罚信息”、“列入经营异常名录信息”、“列入严重违法失信企业名单(黑名单)信息”的加盖公司公章的证明材料;", + "(5)提供“中国裁判文书网”近三年内,参与投标的供应商企业、法定代表人在经营活动中没有行贿犯罪记录查询函;(公告发布起查询,网上自查加盖公章)" + ] } -res1=process_dict(preprocess_dict(data)) -print(json.dumps(res1,ensure_ascii=False,indent=4)) \ No newline at end of file +# print(json.dumps(data,ensure_ascii=False,indent=4)) +res1=preprocess_dict(data) +# print(json.dumps(res1,ensure_ascii=False,indent=4)) +res2=process_dict(res1) +print(json.dumps(res2,ensure_ascii=False,indent=4)) \ No newline at end of file diff --git a/flask_app/货物标/投标人须知正文提取指定内容货物标版.py b/flask_app/货物标/投标人须知正文提取指定内容货物标版.py index 84f99fd..593e541 100644 --- a/flask_app/货物标/投标人须知正文提取指定内容货物标版.py +++ b/flask_app/货物标/投标人须知正文提取指定内容货物标版.py @@ -109,7 +109,7 @@ def extract_from_notice(merged_baseinfo_path,clause_path, type): # print(json.dumps(extracted_data,ensure_ascii=False,indent=4)) extracted_data_concatenated = {section: concatenate_keys_values(content) #启用结构化就注释这三行 for section, content in extracted_data.items()} - + extracted_data_concatenated[data]=1 return extracted_data_concatenated # transformed_data = process_with_outer_key(extracted_data) #取消注释这三行 # final_result = process_nested_data(transformed_data) @@ -121,8 +121,8 @@ def extract_from_notice(merged_baseinfo_path,clause_path, type): return DEFAULT_RESULT if __name__ == "__main__": - clause_path = r'C:\Users\Administrator\Desktop\fsdownload\a110ed59-00e8-47ec-873a-bd4579a6e628\\clause1.json' - merged_baseinfo_path=r"C:\Users\Administrator\Desktop\fsdownload\a110ed59-00e8-47ec-873a-bd4579a6e628\ztbfile_merged_baseinfo.pdf" + clause_path = r'C:\Users\Administrator\Desktop\fsdownload\6b251074-bd29-4bd5-a776-3a11c20e6b11\\clause1.json' + merged_baseinfo_path=r"C:\Users\Administrator\Desktop\fsdownload\6b251074-bd29-4bd5-a776-3a11c20e6b11\ztbfile_merged_baseinfo.pdf" # file_path = 'D:\\flask_project\\flask_app\\static\\output\\fee18877-0c60-4c28-911f-9a5f7d1325a7\\clause1.json' try: res = extract_from_notice(merged_baseinfo_path,clause_path, 1) # 可以改变此处的 type 参数测试不同的场景 diff --git a/flask_app/货物标/投标人须知正文条款提取成json文件货物标版.py b/flask_app/货物标/投标人须知正文条款提取成json文件货物标版.py index 99355be..ffb11be 100644 --- a/flask_app/货物标/投标人须知正文条款提取成json文件货物标版.py +++ b/flask_app/货物标/投标人须知正文条款提取成json文件货物标版.py @@ -139,7 +139,7 @@ def parse_text_by_heading(text): pattern_numbered = re.compile(r'^\s*([一二三四五六七八九十]{1,2})\s*、\s*') pattern_parentheses = re.compile(r'^\s*[((]\s*([一二三四五六七八九十]{1,2})\s*[))]\s*') initial_heading_pattern = None - special_section_keywords = ['文件的组成', '文件的构成'] # 定义特殊章节关键词 + special_section_keywords = ['文件的组成', '文件的构成','文件包括:','文件包括:'] # 定义特殊章节关键词 in_special_section = False # 标志是否在特殊章节中 lines = text.split('\n') @@ -148,6 +148,19 @@ def parse_text_by_heading(text): line_no_spaces = line.replace(' ', '') return re.match(r'^\d{4}\s*年', line_no_spaces) is not None + def is_heading(line): + # 检查是否匹配任何标题模式 + patterns = [ + r'^(?1、满足《中华人民共和国政府采购法》第二十二条规定,即:
(1)具有独立承担 #TODO:资格审查默认加上第一章的内容, 资格审查章节不做跳转逻辑. -#TODO:开评定标那块,不做层次遍历 ing + #TODO:技术要求提取更全面一点 fsdownload\a110ed59-00e8-47ec-873a-bd4579a6e628 #good_list 金额 截取上下文 if __name__ == "__main__": diff --git a/flask_app/货物标/资格审查main.py b/flask_app/货物标/资格审查main.py index f5acfa2..6d25fa8 100644 --- a/flask_app/货物标/资格审查main.py +++ b/flask_app/货物标/资格审查main.py @@ -2,6 +2,9 @@ import json import os import re +import time +from concurrent.futures import ThreadPoolExecutor, as_completed + from flask_app.general.通义千问long import upload_file, qianwen_long from flask_app.general.多线程提问 import multi_threading from flask_app.general.json_utils import clean_json_string @@ -371,95 +374,229 @@ def process_additional_queries(combined_res, match_keys, output_folder, notice_p return final_result -def combine_qualification_review(invalid_path, output_folder, qualification_path, notice_path): - DEFAULT_QUALIFICATION_REVIEW = { - "资格审查": { - "资格审查": "", - "符合性审查": "" - } - } +def combine_qualification_review(invalid_path, qualification_path, notice_path): + detailed_res = {} - def process_file(file_path, invalid_path): - file_id = upload_file(file_path) + # 初始化无效文件ID + invalid_file_id = None + first_res = {} + if qualification_path: + # 上传资格文件并获取文件ID + qualification_file_id = upload_file(qualification_path) + # 定义第一个查询,用于检查资格性审查和符合性审查是否存在 first_query = """ - 该文档中是否有关于资格性审查标准的具体内容,是否有关于符合性审查标准的具体内容?请以json格式给出回答,外键分别为'资格性审查'和'符合性审查',键值仅限于'是','否',输出格式示例如下: - { - "资格性审查":"是", - "符合性审查":"是" - } - """ - qianwen_ans = clean_json_string(qianwen_long(file_id, first_query)) - user_queries = [ + 该文档中是否有关于资格性审查标准的具体内容,是否有关于符合性审查标准的具体内容?请以json格式给出回答,外键分别为'资格性审查'和'符合性审查',键值仅限于'是','否',输出格式示例如下: { - "key": "资格性审查", - "query": "该招标文件中规定的资格性审查标准是怎样的?请以json格式给出,外层为'资格性审查',你的回答要与原文完全一致,不可擅自总结删减,也不要回答有关符合性性审查的内容。" - }, - { - "key": "符合性审查", - "query": "该招标文件中规定的符合性审查标准是怎样的?请以json格式给出,外层为'符合性审查',你的回答要与原文完全一致,不可擅自总结删减,也不要回答有关资格性审查的内容。" + "资格性审查":"是", + "符合性审查":"是" } - ] - combined_res = {} - file_id2 = None # 延迟上传 invalid_path - def process_single_query(query_info): - nonlocal file_id2 + """ + + # 执行第一个查询并清洗返回的JSON字符串 + print("call first_query") + first_res = clean_json_string(qianwen_long(qualification_file_id, first_query)) + + # 判断是否存在资格性和符合性审查 + zige_file_id = qualification_file_id if first_res.get("资格性审查") == "是" else None + fuhe_file_id = qualification_file_id if first_res.get("符合性审查") == "是" else None + + # 如果需要,上传无效文件 + if zige_file_id is None or fuhe_file_id is None: + if invalid_file_id is None: + invalid_file_id = upload_file(invalid_path) + if zige_file_id is None: + zige_file_id = invalid_file_id + if fuhe_file_id is None: + fuhe_file_id = invalid_file_id + + else: + # 如果 qualification_path 为空,直接使用无效文件 + zige_file_id = fuhe_file_id = upload_file(invalid_path) + + # 定义第二组查询 + second_query = [ + { + "key": "资格性审查", + "query": "该招标文件中规定的资格性审查标准是怎样的?请以json格式给出,外层为'资格性审查',你的回答要与原文完全一致,不可擅自总结删减,也不要回答有关符合性审查的内容。" + }, + { + "key": "符合性审查", + "query": "该招标文件中规定的符合性审查标准是怎样的?请以json格式给出,外层为'符合性审查',你的回答要与原文完全一致,不可擅自总结删减,也不要回答有关资格性审查的内容。" + } + ] + + # 定义任务函数 + def process_second_query(key, query, file_id): + print("call second_query") + try: + res = qianwen_long(file_id, query) + cleaned_res = clean_json_string(res) + return key, cleaned_res.get(key, "未找到相关内容") + except Exception as e: + print(f"执行查询 '{key}' 时出错: {e}") + return key, "查询失败" + + def process_notice(notice_path): + print("call notice_path") + try: + # 上传通知文件并获取文件ID + file_id1 = upload_file(notice_path) + + # 定义用户查询,提取申请人资格要求 + user_query1 = """ + 该文档中说明的申请人资格要求是怎样的?请以json格式给出回答,外键为'申请人资格要求',键值为字符串列表,其中每个字符串对应原文中的一条要求,你的回答与原文内容一致,不要擅自总结删减。输出格式示例如下: + { + "申请人资格要求":[ + "1.满足《中华人民共和国政府采购法》第二十二条规定;", + "1.1 法人或者其他组织的营业执照等证明文件,如供应商是自然人的提供身份证明材料;", + "2.未被列入“信用中国”网站(www.creditchina.gov.cn)信用服务栏失信被执行人、重大税收违法案件当事人名单;" + ] + } + """ + + # 执行查询并清洗结果 + res1 = clean_json_string(qianwen_long(file_id1, user_query1)) + + # 提取申请人资格要求 + requirements = res1.get("申请人资格要求", "未找到相关内容") + return "申请人资格要求", requirements + except Exception as e: + print(f"处理申请人资格要求时出错: {e}") + return "申请人资格要求", "处理失败" + + # 初始化 ThreadPoolExecutor + with ThreadPoolExecutor(max_workers=3) as executor: + future_to_key = {} + + # 提交第二组查询 + for query_info in second_query: key = query_info["key"] query = query_info["query"] - # 根据键值决定使用哪个 file_id - if qianwen_ans.get(key) == "否": - print("no") - if not file_id2: - file_id2 = upload_file(invalid_path) - current_file_id = file_id2 - else: - current_file_id = file_id + current_file_id = zige_file_id if key == "资格性审查" else fuhe_file_id + future = executor.submit(process_second_query, key, query, current_file_id) + future_to_key[future] = key - # 调用大模型获取回答 - ans = qianwen_long(current_file_id, query) - cleaned_data = clean_json_string(ans) - processed = process_dict(preprocess_dict(cleaned_data)) - return processed + # 有条件地提交通知处理 + if qualification_path and notice_path and first_res.get("资格性审查") == "是": + future = executor.submit(process_notice, notice_path) + future_to_key[future] = "申请人资格要求" - # 使用线程池并行处理查询 - with concurrent.futures.ThreadPoolExecutor(max_workers=2) as executor: - futures = [executor.submit(process_single_query, q) for q in user_queries] - for future in concurrent.futures.as_completed(futures): - result = future.result() - combined_res.update(result) - return combined_res + # 收集结果(按完成顺序) + for future in as_completed(future_to_key): + key, result = future.result() + detailed_res[key] = result - try: - if not qualification_path: - file_to_process = invalid_path - else: - file_to_process = qualification_path + # 定义所需的顺序 + desired_order = ["申请人资格要求", "资格性审查", "符合性审查"] + # print(json.dumps(detailed_res,ensure_ascii=False,indent=4)) + # 创建一个新的有序字典 + ordered_res = {} + for key in desired_order: + if key in detailed_res: + ordered_res[key] = detailed_res[key] - combined_res = process_file(file_to_process,invalid_path) - match_keys = find_chapter_clause_references(combined_res) + # 将重新排序后的字典传递给处理函数 + processed_data = process_dict(preprocess_dict(ordered_res)) - if not match_keys: - return {"资格审查": combined_res} + # 最终处理结果,例如打印或保存 + return processed_data - return process_additional_queries(combined_res, match_keys, output_folder, notice_path,invalid_path) #还要跳转到第一章 - except Exception as e: - print(f"Error in combine_qualification_review: {e}") - return DEFAULT_QUALIFICATION_REVIEW.copy() +# def combine_qualification_review(invalid_path, output_folder, qualification_path, notice_path): +# DEFAULT_QUALIFICATION_REVIEW = { +# "资格审查": { +# "资格审查": "", +# "符合性审查": "" +# } +# } +# +# def process_file(file_path, invalid_path): +# file_id = upload_file(file_path) +# first_query = """ +# 该文档中是否有关于资格性审查标准的具体内容,是否有关于符合性审查标准的具体内容?请以json格式给出回答,外键分别为'资格性审查'和'符合性审查',键值仅限于'是','否',输出格式示例如下: +# { +# "资格性审查":"是", +# "符合性审查":"是" +# } +# """ +# qianwen_ans = clean_json_string(qianwen_long(file_id, first_query)) +# user_queries = [ +# { +# "key": "资格性审查", +# "query": "该招标文件中规定的资格性审查标准是怎样的?请以json格式给出,外层为'资格性审查',你的回答要与原文完全一致,不可擅自总结删减,也不要回答有关符合性性审查的内容。" +# }, +# { +# "key": "符合性审查", +# "query": "该招标文件中规定的符合性审查标准是怎样的?请以json格式给出,外层为'符合性审查',你的回答要与原文完全一致,不可擅自总结删减,也不要回答有关资格性审查的内容。" +# } +# ] +# combined_res = {} +# file_id2 = None # 延迟上传 invalid_path +# def process_single_query(query_info): +# nonlocal file_id2 +# key = query_info["key"] +# query = query_info["query"] +# # 根据键值决定使用哪个 file_id +# if qianwen_ans.get(key) == "否": +# print("no") +# if not file_id2: +# file_id2 = upload_file(invalid_path) +# current_file_id = file_id2 +# else: +# current_file_id = file_id +# +# # 调用大模型获取回答 +# ans = qianwen_long(current_file_id, query) +# cleaned_data = clean_json_string(ans) +# processed = process_dict(preprocess_dict(cleaned_data)) +# return processed +# +# # 使用线程池并行处理查询 +# with concurrent.futures.ThreadPoolExecutor(max_workers=2) as executor: +# futures = [executor.submit(process_single_query, q) for q in user_queries] +# for future in concurrent.futures.as_completed(futures): +# result = future.result() +# combined_res.update(result) +# return combined_res +# +# try: +# if not qualification_path: +# file_to_process = invalid_path +# else: +# file_to_process = qualification_path +# +# combined_res = process_file(file_to_process,invalid_path) +# match_keys = find_chapter_clause_references(combined_res) +# +# if not match_keys: +# return {"资格审查": combined_res} +# +# return process_additional_queries(combined_res, match_keys, output_folder, notice_path,invalid_path) #还要跳转到第一章 +# +# except Exception as e: +# print(f"Error in combine_qualification_review: {e}") +# return DEFAULT_QUALIFICATION_REVIEW.copy() # 整合基础信息核心代码 # [{'资格性审查.资格要求': '符合本采购文件第一章第二款要求,并提供合格有效的证明材料'}, {'资格性审查.没有重大违法记录的书面声明': '是否提交参加政府采购活动前三年内在经营活动中没有重大违法记录的书面承诺或声明(格式要求详见本项目采购文件第六章相关格式要求)'}] if __name__ == "__main__": + start_time=time.time() # qualification_path="C:\\Users\\Administrator\\Desktop\\货物标\\output3\\6.2定版视频会议磋商文件_qualification2.pdf" # output_folder = "D:\\flask_project\\flask_app\\static\\output\\output1\\e7dda5cb-10ba-47a8-b989-d2993d34bb89" output_folder="C:\\Users\\Administrator\\Desktop\\fsdownload\\52e54b20-c975-4cf3-a06b-6f146aaa93f5" - qualification_path = "C:\\Users\\Administrator\\Desktop\\fsdownload\\52e54b20-c975-4cf3-a06b-6f146aaa93f5\\ztbfile_qualification1.pdf" + # qualification_path = "C:\\Users\\Administrator\\Desktop\\fsdownload\\52e54b20-c975-4cf3-a06b-6f146aaa93f5\\ztbfile_qualification1.pdf" # qualification_path = "D:\\flask_project\\flask_app\\static\\output\\output1\\6558a50a-13ea-4279-a5db-684935481c39\\ztbfile_qualification2.pdf" + qualification_path="C:\\Users\\Administrator\\Desktop\\货物标\\output3\\6.2定版视频会议磋商文件_qualification2.pdf" # notice_path = "D:\\flask_project\\flask_app\\static\\output\\output1\\6558a50a-13ea-4279-a5db-684935481c39\\ztbfile_notice.pdf" - notice_path="C:\\Users\\Administrator\\Desktop\\fsdownload\\52e54b20-c975-4cf3-a06b-6f146aaa93f5\\ztbfile_notice.pdf" + # notice_path="C:\\Users\\Administrator\\Desktop\\fsdownload\\52e54b20-c975-4cf3-a06b-6f146aaa93f5\\ztbfile_notice.pdf" + notice_path="C:\\Users\\Administrator\\Desktop\\货物标\\output5\\6.2定版视频会议磋商文件_notice.pdf" # knowledge_name = "6.2视频会议docx" # invalid_path = "D:\\flask_project\\flask_app\\static\\output\\output1\\e7dda5cb-10ba-47a8-b989-d2993d34bb89\\ztbfile.pdf" - invalid_path="C:\\Users\\Administrator\\Desktop\\fsdownload\\52e54b20-c975-4cf3-a06b-6f146aaa93f5\\ztbfile.pdf" - res = combine_qualification_review(invalid_path,output_folder, qualification_path, notice_path) + # invalid_path="C:\\Users\\Administrator\\Desktop\\fsdownload\\52e54b20-c975-4cf3-a06b-6f146aaa93f5\\ztbfile.pdf" + invalid_path="C:\\Users\\Administrator\\Desktop\\货物标\\zbfiles\\6.2定版视频会议磋商文件.pdf" + res = combine_qualification_review(invalid_path, qualification_path, notice_path) print(json.dumps(res, ensure_ascii=False, indent=4)) + end_time=time.time() + print("耗时:"+str(end_time-start_time))