# -*- encoding:utf-8 -*- import json from flask_app.general.json_utils import clean_json_string from flask_app.general.通义千问long import upload_file, qianwen_long # def combine_technical_and_business(data, target_values1, target_values2): # extracted_data = {} # 根级别存储所有数据 # technical_found = False # business_found = False # # def extract_nested(data, parent_key='', is_technical=False, is_business=False): # nonlocal technical_found, business_found # if isinstance(data, dict): # for key, value in data.items(): # current_key = f"{parent_key}.{key}" if parent_key else key # # # 检查是否为技术标的内容 # if any(target in key for target in target_values1): # if not is_technical: # # 直接存储在根级别 # extracted_data[key] = value # technical_found = True # # 标记为技术标内容并停止进一步处理这个分支 # continue # # # 检查是否为商务标的内容 # elif any(target in key for target in target_values2): # if not is_business: # # 存储在'商务标'分类下 # if '商务标' not in extracted_data: # extracted_data['商务标'] = {} # extracted_data['商务标'][key] = value # business_found = True # # 标记为商务标内容并停止进一步处理这个分支 # continue # # # 如果当前值是字典或列表,且不在技术或商务分类下,继续递归搜索 # if isinstance(value, dict) or isinstance(value, list): # extract_nested(value, current_key, is_technical, is_business) # # elif isinstance(data, list): # for index, item in enumerate(data): # extract_nested(item, f"{parent_key}[{index}]", is_technical, is_business) # # # 开始从顶级递归搜索 # extract_nested(data) # # # 处理未找到匹配的情况 # if not technical_found: # extracted_data['技术标'] = '' # if not business_found: # extracted_data['商务标'] = '' # # return extracted_data def remove_unknown_scores(data): if isinstance(data, dict): return { k: remove_unknown_scores(v) for k, v in data.items() if not (k == "评分" and v in ["未知", "/", ""]) } elif isinstance(data, list): return [remove_unknown_scores(item) for item in data] else: return data def combine_technical_and_business(data, target_values): data=remove_unknown_scores(data) extracted_data = {} # 根级别存储所有数据 technical_found = False business_found = False def extract_nested(data, parent_key='', is_technical=False, is_business=False): nonlocal technical_found, business_found if isinstance(data, dict): for key, value in data.items(): current_key = f"{parent_key}.{key}" if parent_key else key # 检查是否为技术标的内容 if any(target in key for target in target_values): if not is_technical: extracted_data[key] = value technical_found = True continue # 默认其他所有内容都归为商务标 else: if not is_business: if '商务评分' not in extracted_data: extracted_data['商务评分'] = {} extracted_data['商务评分'][key] = value business_found = True continue if isinstance(value, dict) or isinstance(value, list): extract_nested(value, current_key, is_technical, is_business) elif isinstance(data, list): for index, item in enumerate(data): extract_nested(item, f"{parent_key}[{index}]", is_technical, is_business) extract_nested(data) if not technical_found: extracted_data['技术评分'] = '' if not business_found: extracted_data['商务评分'] = '' return extracted_data def combine_evaluation_standards(evaluation_method): # 商务标、技术标评分项:千问 file_id = upload_file(evaluation_method) # user_query_2 = ( # "根据该文档中的评标办法前附表,请你列出该文件的技术评分,商务评分,投标报价评审标准以及它们对应的具体评分要求,若对应内容中存在其他信息,在键名如'技术评分'中新增子键名'备注'存放该信息。如果评分内容(因素)不是这3个,则返回文档中给定的评分内容(因素)以及它的评分要求。请以json格式返回结果,不要回答有关形式、资格、响应性评审标准的内容") user_query_2 = ( """根据该文档中的评标办法表格,请你列出该文件的技术评分,商务评分,投标报价评审以及它们对应的具体评分要求,请以json格式返回结果,最外层键名分别是'技术评分','商务评分','投标报价评审',请在这三大项评分中分别用若干键值对表示具体评分项,外层键名为各评审因素,可能存在嵌套关系,但最内层键值为一个列表,列表中包含若干(可为一)描述该评审因素的评分及要求的字典,内层键名分别是'评分'和'要求',若无评分,可删去'评分'键值对,'要求'中说明了该评审因素的评分标准;若这三大项评分中存在其他信息,则在相应评分大块内部新增键名'备注'存放该信息,键值为具体的要求,否则不需要。如果评分内容(因素)不是这三大项,则返回文档中给定的评分内容(因素)以及它们的具体评分要求。 要求与指南: 1. 请首先定位评分细则的表格,不要回答有关资格审查的内容,也不要从评标办法正文中提取回答 2. 若大项的'xx评分'要求未在文中说明,则键名'xx评分'的键值设为'本项目无xx评分项',例如"技术评分":"本项目无技术评分项" 3. 如果该招标活动有多个包,则最外层键名为对应的包名,否则最外层键名为各大评分项 4. 你无需将表格的单元格内的内容进行拆分,需要将它视为一个整体 5. '评分'的键值不能是一个范围数字,如'0-5分',应该是一个具体数字,如'5分',或者是一个定性的指标如'合格制' 以下为示例输出,仅供格式参考: { "一包": { "技术评分": { "实施方案":{ "总体实施方案":[ { "评分":8, "要求":"根据投标人总体实施方案进行评分" } ], "项目实施要点":[ { "评分":8, "要求":"根据投标人对项目实施要点、难点进行评分" } ] }, "主要监理岗位的职责": [ { "评分": "4分", "要求": "1、总监理工程师的职责全面、清晰、合理得 1.2-2分;一般的1.2分。2、其他主要监理人员及岗位的职责全面、清晰、合理得 1.2-2分;一般的 1.2分。" } ], "备注": "注:若不满足“与公安部、省公安厅、随州市公安局高清视频会议系统无缝对接互联互通”的要求,则本项技术部分(50分)不得分。" }, "商务评分": { "控制系统内主板": [ { "评分": "10分", "要求": "所投电梯控制系统内主板为制造商原厂原品牌制造生产且为进口部件得 10分。(提供进口部件报关单及原产地证明扫描件加盖公章,否则不得分)" } ], "制造商技术实力": [ { "评分": "3分", "要求": "一级证书得3分,二级证书得1分,其他不得分" }, { "评分": "2分", "要求": "行业销量排名连续前 2 名,得 2 分,第 4-6 名得 0.5 分,其他不得分" } ] }, "投标报价评审": { "投标报价是否出现违反计价规范": [ { "评分": "合格制", "要求": "A:投标报价未违反计价规范的,评审意见为“合格”;B:投标报价违反计价规范的,评审意见为“不合格”" } ] } } } """ ) evaluation_res = qianwen_long(file_id, user_query_2) # print(evaluation_res) target_values1 = ['技术标','技术部分','设计', '实施',"技术评分"] # target_values2=['投标报价','商务标','商务部分','报价部分','业绩','信誉','分值','计算公式','信用','人员','资格','奖项','认证','荣誉'] # update_json=combine_technical_and_business(clean_json_string(evaluation_res),target_values1,target_values2) update_json = combine_technical_and_business(clean_json_string(evaluation_res), target_values1) return update_json #商务标技术标整合 if __name__ == "__main__": # evaluation_method="C:\\Users\\Administrator\\Desktop\\招标文件\\招标01_evaluation_method.pdf" evaluation_method= r"C:\Users\Administrator\Desktop\招标文件\招标04_evaluation_method.pdf" evaluation_standards_res=combine_evaluation_standards(evaluation_method) # 从结果中提取"商务标"和"技术标" technical_standards = {"技术评分": evaluation_standards_res.get("技术评分", {})} commercial_standards = {"商务评分": evaluation_standards_res.get("商务评分", {})} # 返回技术标和商务标 print(json.dumps(technical_standards,ensure_ascii=False,indent=4)) print(json.dumps(commercial_standards, ensure_ascii=False, indent=4))