From b94c62b7e64ce2cdb36d1240f025f8d8c0b7ed1a Mon Sep 17 00:00:00 2001
From: zy123 <646228430@qq.com>
Date: Sun, 17 Nov 2024 16:29:02 +0800
Subject: [PATCH] =?UTF-8?q?11.17=20=E4=BF=AE=E5=A4=8D=E4=BA=86=E6=8F=90?=
=?UTF-8?q?=E5=8F=96=E8=B4=A7=E7=89=A9=E6=A0=87=E7=9A=84Bug?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
flask_app/general/doubao.py | 7 +-
flask_app/general/file2markdown.py | 4 +-
flask_app/general/纯技术参数要求提取.py | 58 ++++-
flask_app/testdir/test3.py | 310 +-----------------------
flask_app/货物标/技术参数要求提取.py | 284 +++++++++++++---------
5 files changed, 231 insertions(+), 432 deletions(-)
diff --git a/flask_app/general/doubao.py b/flask_app/general/doubao.py
index 141e1cf..a00049b 100644
--- a/flask_app/general/doubao.py
+++ b/flask_app/general/doubao.py
@@ -77,7 +77,7 @@ def doubao_model(full_user_query):
"content": full_user_query
}
],
- "temperature":0.3
+ "temperature":0.2
}
response = requests.post(url, headers=headers, json=data)
@@ -158,8 +158,9 @@ if __name__ == "__main__":
2.如有任何疑问或不确定内容,请保留原文描述,必要时使用'未知'标注。
'''
# processed_filepath = convert_pdf_to_markdown(pdf_path_2) # 转markdown格式
- processed_filepath = pdf2txt(pdf_path_2) #纯文本提取
- user_query=generate_full_user_query(processed_filepath,prompt_template)
+ # processed_filepath = pdf2txt(pdf_path_2) #纯文本提取
+ # user_query=generate_full_user_query(processed_filepath,prompt_template)
+ user_query="一年有多少天?"
res=doubao_model(user_query)
print(res)
# print("--------------------")
diff --git a/flask_app/general/file2markdown.py b/flask_app/general/file2markdown.py
index fa2e169..6d636b8 100644
--- a/flask_app/general/file2markdown.py
+++ b/flask_app/general/file2markdown.py
@@ -60,7 +60,7 @@ def convert_pdf_to_markdown(file_path):
if 'result' in data and 'markdown' in data['result']:
markdown_content = data['result']['markdown']
# 定义输出文件名
- output_file = os.path.join(output_folder,"mdtext.text")
+ output_file = os.path.join(output_folder,"extract.txt")
try:
# 将 markdown 内容写入文件,使用 UTF-8 编码
with open(output_file, 'w', encoding='utf-8') as file:
@@ -72,6 +72,6 @@ def convert_pdf_to_markdown(file_path):
if __name__ == "__main__":
- file_path=r"C:\Users\Administrator\Desktop\货物标\output1\陕西省公安厅交通警察总队高速公路交通安全智能感知巡查系统项目 (1)_procurement.pdf"
+ file_path=r"C:\Users\Administrator\Desktop\货物标\output1\招标文件(107国道)_procurement.pdf"
res=convert_pdf_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 03babd8..ab8163b 100644
--- a/flask_app/general/纯技术参数要求提取.py
+++ b/flask_app/general/纯技术参数要求提取.py
@@ -1,5 +1,7 @@
import json
import logging
+import re
+import string
from flask_app.general.format_change import pdf2docx, docx2pdf
from flask_app.general.通义千问long import upload_file
@@ -14,10 +16,10 @@ def get_global_logger(unique_id):
logger = None
-
def extract_matching_keys(data_dict, good_list):
"""
- 递归遍历data_dict,查找good_list中存在的键,并将匹配的键及其值添加到结果字典中。
+ 递归遍历data_dict,查找good_list中存在的键(完全匹配或以good_list中的键开头,后跟“-数字”),并将匹配的键及其值添加到结果字典中。
+ 对于重复的键名,添加后缀 -a, -b, -c 等以确保唯一性。
参数:
- data_dict (dict): 要遍历的嵌套字典。
@@ -27,18 +29,64 @@ def extract_matching_keys(data_dict, good_list):
- dict: 包含所有匹配键及其值的字典。
"""
result = {}
+ key_count = {} # 用于统计每个匹配键的出现次数
+ # 预编译正则模式以提高效率
+ patterns = [re.compile(r'^' + re.escape(g) + r'(?:-\d+)?$') for g in good_list] #考虑同一系统下有同门设备,如交换机
+
+ def matches(key):
+ return any(pattern.match(key) for pattern in patterns)
+
+ # 第一次遍历:统计每个匹配键的出现次数
+ def first_pass(current_dict):
+ if isinstance(current_dict, dict):
+ for key, value in current_dict.items():
+ if matches(key):
+ key_count[key] = key_count.get(key, 0) + 1
+ first_pass(value)
+ elif isinstance(current_dict, list):
+ for item in current_dict:
+ first_pass(item)
+
+ first_pass(data_dict)
+
+ # 初始化用于跟踪每个重复键当前使用的后缀编号
+ suffix_map = {key: 0 for key, count in key_count.items() if count > 1}
+
+ def get_suffix(count):
+ """
+ 根据计数获取字母后缀,例如: 考虑不同系统下都有同门设备,如交换机
+ 1 -> '-a'
+ 2 -> '-b'
+ ...
+ 26 -> '-z'
+ 27 -> '-aa'
+ """
+ letters = string.ascii_lowercase
+ suffix = ''
+ while count > 0:
+ count, remainder = divmod(count - 1, 26)
+ suffix = letters[remainder] + suffix
+ return '-' + suffix
+
+ # 第二次遍历:添加后缀并构建结果字典
def recurse(current_dict):
if isinstance(current_dict, dict):
for key, value in current_dict.items():
- if key in good_list:
- result[key] = value
- # 递归遍历子字典
+ if matches(key):
+ if key_count.get(key, 0) > 1:
+ suffix_map[key] += 1
+ suffix = get_suffix(suffix_map[key])
+ new_key = f"{key}{suffix}"
+ else:
+ new_key = key
+ result[new_key] = value
recurse(value)
elif isinstance(current_dict, list):
for item in current_dict:
recurse(item)
# 如果current_dict不是dict或list,则无需进一步处理
+
recurse(data_dict)
return result
diff --git a/flask_app/testdir/test3.py b/flask_app/testdir/test3.py
index b9c4dd2..abed731 100644
--- a/flask_app/testdir/test3.py
+++ b/flask_app/testdir/test3.py
@@ -109,6 +109,8 @@ data={
"采购要求": {
"采购需求": {
"显示系统": {
+ "交换机-1":["111"],
+ "交换机-2":["222"],
"LED全彩显示屏": [
"1、显示尺寸:6m±0.3(W)× 1.5m±0.2(H),单屏分辨率≥3744 × 1040;",
"2 、像素间距≤1.53mm;",
@@ -177,6 +179,7 @@ data={
]
},
"摄像系统": {
+ "交换xx":["111111"],
"高清摄像机": [
"1 、成像器件: 1/2.8 Exmor CMOS;",
"2 、镜头: 30 倍光学(f=4.3mm to 129mm );",
@@ -212,6 +215,7 @@ data={
]
},
"视频处理系统": {
+ "交换xx":["xxxx"],
"高清视频拼控矩阵(16*16)": [
"1 、8U 切换主箱体, 支持输入 13 槽, 输出 4.5 槽, 支持 8 路高分采集, 支持冗余电源, 标配 1 个电源模块; 本项目配置输入接 口 16 路和 1 张字幕卡, 输出接口 16 路;",
"2 、设备应为纯硬件 FPGA 架构, CrossPoint 全总线交换技术, 背板 等效带宽;",
@@ -356,43 +360,7 @@ data={
"墙体拆除及修复": [
"对大屏安装区域墙体 、天花进行拆除及修复。"
]
- },
- "货物列表": [
- "LED全彩显示屏",
- "控制盒及电源",
- "大屏播控系统",
- "配电柜(含PLC)",
- "钢结构底座及铝型材支架",
- "电缆及信号线缆",
- "控制终端",
- "50寸液晶电视机",
- "50寸电视机地面推车",
- "高清监视器",
- "高清摄像机",
- "摄像机三角架",
- "摄像机壁装架",
- "摄像机控制键盘",
- "高清视频拼控矩阵(16*16)",
- "分量信号接口器",
- "高清四画面分割器",
- "数字会议发言主机",
- "方形短杆代表话筒",
- "专用连接线缆",
- "手持无线话筒",
- "多点控制器",
- "多串口控制服务器",
- "综合会议管理调度平台",
- "高清会议终端(主会场)",
- "高清会议终端(分会场)",
- "65寸电视机移动推车(9楼)",
- "65寸液晶电视机(分会场)",
- "控制平板及软件",
- "鹅颈话筒",
- "时序电源",
- "多媒体地插盒",
- "线材辅料",
- "墙体拆除及修复"
- ]
+ }
},
"技术要求": "未知",
"服务要求": "四 、其他要求
1 、售后服务要求:
1.1 、安装调试与人员培训, 中标人应及时安装调试设备, 安装调试期间采 购人的使用人员协助配合;安装调试完毕,中标人需组织采购人使用人员进行使 用及日常维护等的培训。
1.2 、免费质保期一年, 质保期从采购人签订验收合格报告之日开始计算, 免费质保期内中标人负责所有因设备质量问题而产生的费用, 所有服 务免费。
1.3 、投标人需承诺在保修期内, 向用户提供 7×24 小时技术支持与上门服 务。对系统故障的响应时间不超过 2 小时, 到达现场时 间不超过 24 小时,在 48 个小时内排除故障 。如果发生硬件故障, 在 4 8 小时后仍无法排除的, 投标人需 承诺提供性能档次不低于故障设备的备用设备供采购人使用, 直至故障设备修 复。
1.4 、保修期外要求: 中标人应提供长期技术支持的措施和质保期满后的服 务计划。",
@@ -436,271 +404,11 @@ data={
"投标预备会": "不召开",
"踏勘现场": "不组织"
}
- },
- "开评定标流程": {
- "磋商程序及步骤": [
- "23. 竞争性磋商小组",
- "23.1 采购人依照《中华人民共和国政府采购法》、《中华人民共和国政府采购法实施条例》、《政府采购竞争性磋商采购方式管理暂行办法》及现行法律规定组建磋商小组,磋商小组由采购人代表和评审专家共3人或5人以上单数组成。磋商小组人数详见《供应商须知前附表》。",
- "23.2 磋商小组中的评审专家人数不少于磋商小组成员总数的2。除本采购文件另有规定,评审专家将从湖北省政府采购专家库中随机抽取。",
- "23.3 磋商小组所有成员按事先抽取的磋商顺序,集中与磋商供应商分别进行磋商,并给予所有参加磋商的供应商平等的磋商机会。",
- "24. 磋商代表",
- "24.1 磋商供应商法定代表人或授权代表应携带本人身份证明参加磋商,授权代表参加磋商的,还应携带法定代表人授权书原件。磋商代表经磋商小组核对身份后,方可参加磋商。",
- "25. 资格审查和符合性审查",
- "25.1 在正式磋商前,本磋商文件第四章规定的程序和方法,对供应商进行资格性审查和符合性审查,通过资格性审查和符合性审查,实质性响应磋商文件的供应商方可进入磋商程序。",
- "26. 磋商",
- "26.1 磋商小组将根据本磋商文件第四章规定的程序和方法与进行磋商。在磋商中,磋商的任何一方不得透露与磋商有关的其他磋商供应商的技术资料、价格和其他信息。",
- "26.2 在磋商过程中,磋商小组可以根据磋商文件和磋商情况实质性变动采购需求中的技术、服务要求以及合同草案条款,但不得变动磋商文件中的其他内容。实质性变动的内容,须经采购人代表确认。对磋商文件作出的实质性变动是磋商文件的有效组成部分,磋商小组将以书面形式同时通知所有磋商供应商,并提供必要的修正时间。",
- "26.3 供应商应当按照磋商文件的变动情况和磋商小组的要求重新提交响应文件,对原响应文件进行技术、商务、价格修正,重新提交的响应文件应实质性响应本磋商文件及对磋商文件作出的实质性变动,并按本采购文件的规定进行签署。重新提交的响应文件与原响应文件不一致的,以重新提交的响应文件为准。不按要求签署或逾时不提交响应文件的,视同放弃磋商,放弃磋商的供应商的磋商保证金将在成交通知书发放后的五个工作日内退还。",
- "26.4 最后报价
采购代理机构将已确定条件的最后报价书发放至所有磋商供应商,要求磋商供应商在指定的时间内提交满足要求的最后报价,密封递交磋商小组。所有磋商供应商递交最后报价后,磋商小组将公布并记录所有磋商供应商的最终价格。最后报价为本次竞争性磋商不可变动的最终价格。磋商文件能够详细列明采购标的的技术、服务要求的,磋商结束后,磋商小组应当要求所有继续参加磋商的供应商在规定时间内提交最后报价,提交最后报价的供应商不得少于3家。磋商文件不能详细列明采购标的的技术、服务要求,需经磋商由供应商提供最终设计方案或解决方案的,磋商结束后,磋商小组应当按照少数服从多数的原则投票推荐3家以上供应商的设计方案或者解决方案,并要求其在规定时间内提交最后报价。本采购项目提交最后报价供应商的确定方式详见《供应商须知前附表》。",
- "26.5 如有需要,磋商小组可进行多轮磋商,直至最终确定竞争性磋商采购文件采购需求中的技术、服务要求以及合同草案条款。如竞争性磋商采购文件无需修改,可直接要求磋商供应商提交最后报价。",
- "26.6 磋商小组审核完最终报价后,根据竞争性磋商采购文件规定的评定办法推荐成交候选人或根据采购人的书面授权直接确定成交供应商。",
- "26.7 采购代理机构对磋商过程和重要磋商内容进行记录,磋商双方在记录上签字确认。、保密",
- "27.1 凡是属于审查、澄清、评价和比较的有关资料以及授标意向等,采购人、采购代理机构、监管人员、磋商小组及有关工作人员均不得向供应商或其它无关的人员透露。凡是属于审查、澄清、评价和比较的有关资料以及授标意向等,采购人、采购代理机构、监管人员、磋商小组及有关工作人员均不得向供应商或其它无关的人员透露。"
- ]
- },
- "投标文件要求": {
- "竞争性磋商响应文件": [
- "8. 语言和计量单位",
- "8.1 供应商提交的竞争性磋商响应文件以及供应商与采购代理机构或采购人就有关磋商的所有来往函电均应使用中文。供应商提交的支持文件或印刷的文献可以用另一种语言,但相应内容应附有中文翻译本,在解释竞争性磋商响应文件时以中文翻译本为准。",
- "8.2 除非竞争性磋商采购文件中另有规定,计量单位均采用中华人民共和国法定的计量单位。",
- "9. 竞争性磋商响应文件的构成",
- "9.1 供应商编制的竞争性磋商响应件应包括的内容详见本文件第六章要求。注:响应文件目录及内容每页须顺序编写页码。",
- "10. 竞争性磋商响应文件的编制",
- "10.1 供应商应当按照本采购文件的要求编制响应文件,并对其提交的响应文件及全部资料的真实性、合法性承担法律责任,并接受采购代理机构对其中任何资料进一步核实的要求。",
- "10.2 供应商应认真阅读本采购文件中的所有内容,并对本采购文件提出的要求和条件作出实质性响应。如供应商没有按照本采购文件的要求提交全部资料,或者没有对本采购文件在各方面都做出实质性响应的,其响应文件将被视为无效文件。",
- "10.3 供应商应完整地按本采购文件的要求提交所有资料并按要求的格式填写规定的所有内容,无相应内容可填项的,应填写“无”、“未测试”、“没有相应指标”等明确的回答文字。如未规定格式的,相关格式由供应商自定。",
- "10.4 供应商在编制响应文件时应注意本次采购对多包采购的规定,多包采购的规定见《供应商须知前附表》。",
- "10.5 本项目采购文件中★号条款不允许负偏离(或允许的负偏离项数及范围见第四章评标办法),非★号条款允许的负偏离项数及范围见第四章评标办法。",
- "11. 磋商报价",
- "11.1 磋商报价包括磋商供应商在首次提交的响应文件中的报价、磋商过程中的报价和最后报价。磋商供应商的报价均应以人民币报价。",
- "11.2 供应商应按照本采购文件规定的采购需求及合同条款进行报价,并按竞争性磋商采购文件确定的格式报出。报价中不得包含竞争性磋商采购文件要求以外的内容,否则,在评审时不予核减。报价中也不得缺漏竞争性磋商采购文件所要求的内容,否则,其响应文件将被视为无效文件。",
- "11.3 供应商应根据本磋商文件的规定和要求、市场价格水平及其走势、磋商供应商的管理水平、磋商供应商的方案和由这些因素决定的磋商供应商之于本项目的成本水平等提出自己的报价。报价应包含完成本采购文件采购需求全部内容的所有费用,所有根据本采购文件或其它原因应由磋商供应商支付的税款和其他应交纳的费用都应包括在报价中。但磋商供应商不得以低于其成本的价格进行报价。",
- "11.4 供应商在响应文件中注明免费的项目将视为包含在报价中。",
- "11.5 每一种采购内容只允许有一个报价,否则其响应文件将被视为无效文件。",
- "11.6 成交供应商的报价在合同执行过程中是固定不变的,不得以任何理由予以变更。",
- "12. 备选方案",
- "12.1 是否允许备选方案见《供应商须知前附表》。不允许有备选方案的,若在响应文件中提交了备选方案,其响应文件将被视为无效文件。",
- "13. 联合体",
- "13.1 本次采购是否允许联合体参加详见《供应商须知前附表》。",
- "13.2 本次采购允许联合体报价的,联合体各方不得再单独或者与其他供应商另外组成联合体参加本项目的报价。",
- "14. 供应商资格证明文件",
- "14.1 供应商应在响应文件提交证明其有资格参加磋商的证明文件,证明文件应包括下列文件:1)营业执照(复印件);2)采购文件要求供应商应提交的其它资格证明文件,应提交的其它资格证明文件见《供应商须知前附表》。",
- "14.2 除本须知14.1要求的资格证明文件外,如国家法律法规对市场准入有要求的还应提交相关资格证明文件。",
- "14.3 证明材料仅限于磋商供应商单位本身,母公司、股东单位和子公司的材料不能作为证明材料,但磋商供应商单位兼并的企业的材料可作为证明材料。采用复印件的必须加盖单位印章。",
- "15. 证明报价内容、服务合格性和符合竞争性磋商采购文件规定的文件",
- "15.1 证明报价内容符合竞争性磋商采购文件要求的文件和竞争性磋商采购文件规定的其他资料,具体要求见《供应商须知前附表》。",
- "16. 磋商保证金",
- "16.1 本采购文件是否要求递交磋商保证金及保证金金额、递交方式、递交时间、接受保证金的帐户信息等详见《供应商须知前附表》。",
- "16.2 本采购文件要求递交磋商保证金的,磋商保证金作为竞争性磋商响应文件的组成部分,以到账为准。凡未按规定递交磋商保证金的报价,其响应文件将被视为无效文件。",
- "16.3 磋商保证金有效时间:磋商保证金的有效期与本次磋商有效期一致。",
- "16.4 供应商为联合体的,应由联合体中牵头人交纳保证金,其交纳的保证金对联合体各方均具有约束力。",
- "16.5 保证金的退还:未成交的磋商供应商,其磋商保证金在成交通知书发出后5个工作日内不计利息原额退还,成交供应商的磋商保证金,在成交供应商与采购人签订合同后5个工作日内不计利息原额退还。",
- "16.6 有下列情形之一的,磋商保证金将不予退还:
1)供应商在提交响应文件截止时间后撤回响应文件的;2)供应商在响应文件中提供虚假材料的;3)除因不可抗力或磋商文件认可的情形以外,成交供应商不与采购人签订合同的;4)供应商与采购人、其他供应商或者采购代理机构恶意串通的;5)本采购文件规定的其他情形。",
- "17. 磋商有效期",
- "17.1 磋商有效期从磋商结束之日起计算,本次采购磋商有效期见《供应商须知前附表》,磋商供应商承诺的磋商有效期不足的,其响应文件将被视为无效文件。",
- "17.2 特殊情况下,在原磋商有效期截止之前,采购代理机构或采购人可要求供应商延长磋商有效期。需要延长磋商有效期时,采购代理机构或采购人将以书面形式通知所有磋商供应商,供应商应以书面形式答复是否同意延长磋商有效期。供应商同意延长的,其磋商保证金有效期相应延长,但不得要求或被允许修改或撤销其响应文件;供应商拒绝延长的,其响应文件在原磋商有效期满后将不再有效,供应商有权收回其投标保证金。",
- "17.3 供应商同意延长磋商有效期的,不得要求或被允许修改或撤销其竞争性磋商响应文件;供应商拒绝延长的,其响应文件失效,但供应商有权收回其磋商保证金。",
- "18. 竞争性磋商响应文件的装订、签署和数量",
- "18.1 供应商提交的响应文件应包括正本、副本、完整的电子文档及单独提供的法定代表人授权委托书(或法定代表人身份证明书)、报价一览表。本次磋商供应商提交响应文件正、副本和电子文档的数量见《供应商须知前附表》。每套响应文件须清楚地标明“正本”、“副本”,响应文件的副本可采用正本的复印件,若副本与正本不符,以正本为准;如单独提供的法定代表人授权委托书(或法定代表人身份证明书)、报价一览表、优惠声明(如有)与响应文件正本不符,以正本为准。电子文档与纸质文件不符,以纸质文件为准。",
- "18.2 正本需打印或用不褪色墨水书写,并由法定代表人或授权代表签字并加盖公章。由授权代表签字的,响应文件中应提交《法定代表人授权书》。供应商为自然人的,由供应商本人签字并附身份证明。",
- "18.3 竞争性磋商响应文件中的任何行间插字、涂改和增删,必须由法定代表人或授权代表在旁边签字才有效。",
- "18.4 响应文件应当采用不可拆卸的方法的装订,对未经装订的竞争性磋商响应文件可能发生的文件散落或缺损及由此产生的后果由磋商供应商承担。响应文件应当采用不可拆卸的方法的装订,对未经装订的竞争性磋商响应文件可能发生的文件散落或缺损及由此产生的后果由磋商供应商承担。"
- ],
- "竞争性磋商响应文件的递交": [
- "19. 竞争性磋商响应文件的密封和标记",
- "19.1 响应文件的正本、所有副本和电子文档必须密封和加盖供应商公章后递交,包装上应注明采购编号、项目名称、包号、供应商名称及“(磋商时间)前不得启封”的字样。",
- "19.2 为方便磋商记录,供应商还应将一份《报价一览表》(原件)与一份《法定代表人授权书》(原件)、单独密封提交,除需按上款要求注明外还应在信封上标明“报价一览表”字样。",
- "19.3 未按要求密封和加写标记的响应文件为无效文件,采购人、采购代理机构将拒收。",
- "19.4 要求在磋商时提交样品的,应在样品上标明磋商供应商名称。有关提交及退还样品的相关规定见《供应商须知前附表》。",
- "20. 竞争性磋商响应文件的送达地点及截止时间",
- "20.1 截止时间是竞争性磋商文件中规定的首次送达、提交响应文件的最后时间。本次磋商响应文件的送达地点及截止时间见《供应商须知前附表》。",
- "21. 迟交的竞争性磋商响应文件",
- "21.1 在本次磋商递交响应文件的截止时间以后送达的响应文件,不论何种原因,采购代理机构将拒收。",
- "22. 竞争性磋商响应文件的补充、修改或者撤回",
- "22.1 在提交响应文件截止时间前,供应商可以对已提交的响应文件进行补充、修改或者撤回。供应商需要补充、修改或者撤回响应文件时,应以书面形式通知采购人、采购代理机构。补充、修改的内容是响应文件的组成部分,补充、修改的内容与响应文件不一致的,以补充、修改的内容为准。",
- "22.2 从提交响应文件截止时间至磋商有效期期满这段时间,供应商不得修改或撤销其响应文件,否则其磋商保证金将不予以退还。",
- "22.3 供应商所提交的响应文件在磋商结束后,无论成交与否都不退还。供应商所提交的响应文件在磋商结束后,无论成交与否都不退还。"
- ]
- },
- "无效标与废标项": {
- "否决和无效投标情形": [
- "供应商应对采购文件第三章“采购需求”第一节“具体需求”、第二节“安装要求”及第二节“商务要求”,逐条说明所提供货物∕服务已对采购文件的技术规格做出了明确响应,并申明与技术规格条文的偏离和例外。特别对有具体参数要求的指标,供应商必须提供所投货物∕服务的具体参数值。如果仅注明“符合”,“满足”或简单复制采购文件要求,将可能导致竞标响应被拒绝。",
- "磋商有效期从磋商结束之日起计算,本次采购磋商有效期见《供应商须知前附表》,磋商供应商承诺的磋商有效期不足的,其响应文件将被视为无效文件。",
- "供应商应认真阅读本采购文件中的所有内容,并对本采购文件提出的要求和条件作出实质性响应。如供应商没有按照本采购文件的要求提交全部资料,或者没有对本采购文件在各方面都做出实质性响应的,其响应文件将被视为无效文件。",
- "供应商应按照本采购文件规定的采购需求及合同条款进行报价,并按竞争性磋商采购文件确定的格式报出。报价中不得包含竞争性磋商采购文件要求以外的内容,否则,在评审时不予核减。报价中也不得缺漏竞争性磋商采购文件所要求的内容,否则,其响应文件将被视为无效文件。",
- "是否允许备选方案见《供应商须知前附表》。不允许有备选方案的,若在响应文件中提交了备选方案,其响应文件将被视为无效文件。",
- "资格证明文件(未提供完整视为无效投标):",
- "本采购文件要求递交磋商保证金的,磋商保证金作为竞争性磋商响应文件的组成部分,以到账为准。凡未按规定递交磋商保证金的报价,其响应文件将被视为无效文件。",
- "每一种采购内容只允许有一个报价,否则其响应文件将被视为无效文件。",
- "未按要求密封和加写标记的响应文件为无效文件,采购人、采购代理机构将拒收。"
- ],
- "废标项": "",
- "不得存在的情形": [
- "成交供应商拒绝签订政府采购合同的,采购人可以按照《政府采购竞争性磋商采购方式管理暂行办法》第三十三条规定的原则确定其他供应商作为成交供应商并签订政府采购合同,也可以重新开展采购活动。拒绝签订政府采购合同的成交供应商不得参加对该项目重新开展的采购活动。",
- "响应文件的正本、所有副本和电子文档必须密封和加盖供应商公章后递交,包装上应注明采购编号、项目名称、包号、供应商名称及“(磋商时间)前不得启封”的字样。",
- "成交供应商的报价在合同执行过程中是固定不变的,不得以任何理由予以变更。",
- "磋商小组将根据本磋商文件第四章规定的程序和方法与进行磋商。在磋商中,磋商的任何一方不得透露与磋商有关的其他磋商供应商的技术资料、价格和其他信息。",
- "凡是属于审查、澄清、评价和比较的有关资料以及授标意向等,采购人、采购代理机构、监管人员、磋商小组及有关工作人员均不得向供应商或其它无关的人员透露。",
- "特殊情况下,在原磋商有效期截止之前,采购代理机构或采购人可要求供应商延长磋商有效期。需要延长磋商有效期时,采购代理机构或采购人将以书面形式通知所有磋商供应商,供应商应以书面形式答复是否同意延长磋商有效期。供应商同意延长的,其磋商保证金有效期相应延长,但不得要求或被允许修改或撤销其响应文件;供应商拒绝延长的,其响应文件在原磋商有效期满后将不再有效,供应商有权收回其投标保证金。",
- "供应商应按照本采购文件规定的采购需求及合同条款进行报价,并按竞争性磋商采购文件确定的格式报出。报价中不得包含竞争性磋商采购文件要求以外的内容,否则,在评审时不予核减。",
- "本次采购允许联合体报价的,联合体各方不得再单独或者与其他供应商另外组成联合体参加本项目的报价。",
- "磋商文件能够详细列明采购标的的技术、服务要求的,磋商结束后,磋商小组应当要求所有继续参加磋商的供应商在规定时间内提交最后报价,提交最后报价的供应商不得少于3家。",
- "采购代理机构将配合采购人与成交供应商签订政府采购合同。采购人与成交供应商应按竞争性磋商采购文件要求和成交供应商的竞争性磋商响应文件承诺订立书面合同,不得超出竞争性磋商采购文件和成交供应商竞争性磋商响应文件的范围,也不得再行订立背离合同实质性内容的其他协议。",
- "供应商同意延长磋商有效期的,不得要求或被允许修改或撤销其竞争性磋商响应文件;供应商拒绝延长的,其响应文件失效,但供应商有权收回其磋商保证金。",
- "单位负责人为同一人或者存在直接控股、管理关系的不同投标人,不得参加本项目同一合同项下的政府采购活动。",
- "为本采购项目提供整体设计、规范编制或者项目管理、监理、检测等服务的,不得再参加本项目的其他招标采购活动。",
- "在磋商过程中,磋商小组可以根据磋商文件和磋商情况实质性变动采购需求中的技术、服务要求以及合同草案条款,但不得变动磋商文件中的其他内容。",
- "供应商应根据本磋商文件的规定和要求、市场价格水平及其走势、磋商供应商的管理水平、磋商供应商的方案和由这些因素决定的磋商供应商之于本项目的成本水平等提出自己的报价。报价应包含完成本采购文件采购需求全部内容的所有费用,所有根据本采购文件或其它原因应由磋商供应商支付的税款和其他应交纳的费用都应包括在报价中。但磋商供应商不得以低于其成本的价格进行报价。",
- "从提交响应文件截止时间至磋商有效期期满这段时间,供应商不得修改或撤销其响应文件,否则其磋商保证金将不予以退还。"
- ]
- },
- "资格审查": {
- "申请人资格要求": [
- "1、满足《中华人民共和国政府采购法》第二十二条规定,即:",
- "(1)具有独立承担民事责任的能力;",
- "(2)具有良好的商业信誉和健全的财务会计制度;",
- "(3)具有履行合同所必需的设备和专业技术能力;",
- "(4)有依法缴纳税收和社会保障资金的良好记录;",
- "(5)参加政府采购活动前三年内,在经营活动中没有重大违法记录;",
- "(6)法律、行政法规规定的其他条件。",
- "2、单位负责人为同一人或者存在直接控股、管理关系的不同投标人,不得 参加本项目同一合同项下的政府采购活动。",
- "3、为本采购项目提供整体设计、规范编制或者项目管理、监理、检测等服5务的,不得再参加本项目的其他招标采购活动。",
- "4、未被列入失信被执行人、重大税收违法案件当事人名单,未被列入政府 采购严重违法失信行为记录名单。",
- "5、落实政府采购政策需满足的资格要求:本项目为非专门面向中小企业采 购。",
- "6、本项目的特定资格要求:",
- "6.1、未被列入“信用中国”网站(www.creditchina.gov.cn)信用服务栏失信被执 行人、重大税收违法案件当事人名单和“中国政府采购”网站(www.ccgp.gov.cn) 政府采购严重违法失信行为记录名单,并提供网页截图以证明;",
- "6.2、供应商提供有效的营业执照,涵盖相应的经营范围(与本项目相关内 容)。"
- ],
- "资格性审查": {
- "资格要求": "符合本采购文件第一章第二款要求,并提供合格有效的证明材料",
- "没有重大违法记录的书面声明": "是否提交参加政府采购活动前三年内在经营活动中没有重大违法记录的书面承诺或声明(格式要求详见本项目采购文件第六章相关格式要求)"
- },
- "符合性审查": {
- "磋商报价": [
- "每一种采购内容是否只有一个报价",
- "报价金额是否超过采购预算,采购人能否支付"
- ],
- "经营范围": "是否超出经营范围报价",
- "磋商书签字盖章": "是否有法定代表人或其委托代理人签字并加盖单位公章",
- "磋商结果有效期": "磋商有效期是否满足竞争性磋商采购文件要求",
- "信誉情况": "是否有不良经济纠纷记录和违法行为",
- "采购需求响应": [
- "是否实质性响应磋商文件",
- "是否有提出采购人不能接受的合同条件的"
- ],
- "其他要求": "是否符合竞争性磋商采购文件中的其他规定"
- }
- },
- "技术评分": {
- "技术响应情况": [
- {
- "评分": "30分",
- "要求": "技术参数全部满足招标文件要求的得满分,★产品的参数条款每负偏离 1条的扣 3分,其他参数条款每负偏离 1条扣 1分,扣完为止。(注:参数以提供官方证明材料、截图、检测报告等为准)"
- }
- ],
- "多点控制器(MCU)": [
- {
- "评分": "3分",
- "要求": "所投 MCU和会议终端等主要产品是同一品牌,高清视频会议终端与现有随州市局、省厅视频会议系统数字互通:MCU 通过数字线路接入现有随州市局、省厅视频会议系统,要求在高清视频会议终端上收听收看到现有随州市局、省厅视频系统广播的分会场图像和声音;同时随州市局、省厅视频系统会议终端上可收听、收看到主会场和任意分会场视频会议终端的图像和声音。提供相关证明文件得 3分,否则不得分。"
- },
- {
- "评分": "2分",
- "要求": "视频抗丢包能力:支持高至 60%丢包率情况下,图像流畅无马赛克;音频抗 IP网络丢包能力:支持高至 75%丢包率情况下,声音清晰流畅;会议抗 IP网络丢包能力:支持高至 70%丢包率情况下,会议可正常召开。(提供第三方检测机构检测报告);满足得 2分,否则不得分。"
- }
- ],
- "主会场高清会议终端": [
- {
- "评分": "2分",
- "要求": "支持抗丢包能力,视频抗丢包能力:支持 40%丢包率情况下,1080P图像流畅无马赛克,声音清晰流畅,会议可正常召开。满足得 2分,否则不得分(提供第三方检验报告)。"
- },
- {
- "评分": "2分",
- "要求": "投标主要软件具有自主知识产权,提供软件著作权证书每一项得 1分,最多得 2分(原件备查)。"
- }
- ],
- "高清摄像机": [
- {
- "评分": "2分",
- "要求": "具备 EMC防电磁干扰认证,产品拥有实用新型专利及软件著作权证书,有第三方专业检测机构的权威检验主证。满足得 2分,否则不得分。"
- }
- ],
- "项目团队": [
- {
- "评分": "2分",
- "要求": "根据投标人拟投入本次项目的管理人员及施工管理人员配备齐全,项目组成员有高级工程师、IT服务工程师、IT服务项目经理、智能楼宇管理师、中级工程师等证书,上述人员须为投标人本单位正式在岗职工,提供证书复印件及近 3个月社保证明得 2分,否则不得分。"
- },
- {
- "评分": "2分",
- "要求": "根据投标人拟投入本次项目的管理人员及施工管理人员配备齐全,技术负责人具有安全员 B证的建造师(机电)二级或以上并具有中级或以上职称,提供证书复印件及近 3个月社保证明得 2分,否则不得分。"
- }
- ],
- "实施技术方案": [
- {
- "评分": "2分",
- "要求": "根据投标供应商提供的实施技术方案、质量保障措施、项目进度计划等方面进行比较打分,最佳合理、可行得 2分,较合理、较可行得 1分,不合理、不可行得 0分。"
- }
- ],
- "售后服务": [
- {
- "评分": "2分",
- "要求": "投标人应对维护期给出合理、完善的运维服务方案。包括(1)售后服务团队管理方案(2)备件方案(3)运维服务流程。每个实施方案清晰、完整、合理、可行的得 2分。"
- },
- {
- "评分": "1分",
- "要求": "投标人具备诚信经营示范单位认证证书的得 1分,不满足得 0分。(原件备查)"
- }
- ],
- "备注": "注:若不满足“与公安部、省公安厅、随州市公安局高清视频会议系统无缝对接 互联互通”的要求,则本项技术部分(50分)不得分。"
- },
- "商务评分": {
- "商务评分": {
- "综合实力": [
- {
- "评分": "5分",
- "要求": "投标人具备有效期内的 ISO9001质量体系认证证书、具备有效期内的 OHSA18001职业健康安全体系认证证书、具备有效期内的 IS014001环境管理体系认证证书、具备有效期内的 ISO20000信息技术服务体系认证证书、具备有效期内的 ISO27001信息安全体系认证证书,全部满足得 5分,每缺一项扣 1分,(开标时需提供原件)。"
- },
- {
- "评分": "2分",
- "要求": "投标人具备电子与智能化工程专业承包二级资质及以上证书得 2分,不能够提供不得分(开标时需提供原件)。"
- },
- {
- "评分": "2分",
- "要求": "投标人具有建筑机电安装工程专业承包三级资质或以上资质得 2分,否则不得分。(证书开标原件备查)。"
- },
- {
- "评分": "3分",
- "要求": "投标人需具有健全的信息技术运维服务能力,通过 ITSS信息技术服务运维标准符合性认证得 3分,投标时需提供相关证书原件予以证明,否则不得分。"
- },
- {
- "评分": "2分",
- "要求": "投标人具备 CCRC信息安全服务安全集成三级及以上证书得 2分,不能够提供不得分(开标时需提供原件)。"
- }
- ],
- "类似业绩": [
- {
- "评分": "4分",
- "要求": "近三年(自投标截止时间前推 36个月,以合同签订日期为准)中标人作为独立承包人有已完成的类似业绩项目(建设内容含应包含会议系统设备采购项目及改造),每提供一份业绩得 2分,最多可得 4分。(业绩证明材料须提供中标公示截图、中标通知书、合同复印件,开标时备查,否则不得分。)"
- }
- ],
- "质量保证": [
- {
- "评分": "2分",
- "要求": "投标人所投的 MCU及视频会议终端设备产品,如果不是自己生产的,需提供制造商出具的授权及满足招标质保要求的售后服务承诺函,提供得 2分;(开标时提供授权书及售后服务承诺函原件予以证明,否则不得分。)"
- }
- ]
- },
- "投标报价评审": {
- "响应报价评分标准": [
- {
- "评分": "30分",
- "要求": "满足采购文件要求且响应报价综合单价(落实政府采购政策进行价格调整的,以调整后的价格计算)最低的响应报价为评标基准价,其价格分为满分。供应商的价格分统一按照下列公式计算:响应报价得分=(评标基准价/响应报价)×30。"
- }
- ]
- }
}
}
includes = ["基础信息", "资格审查", "商务评分", "技术评分", "无效标与废标项", "投标文件要求", "开评定标流程"]
-good_list=[
+good_list=[ "交换机",
+ "交换xx",
"LED全彩显示屏",
"控制盒及电源",
"大屏播控系统",
@@ -738,5 +446,5 @@ good_list=[
]
final_result, extracted_info, procurement_reqs=outer_post_processing(data,includes,good_list)
-# print(json.dumps(procurement_reqs,ensure_ascii=False,indent=4))
-print(json.dumps(final_result,ensure_ascii=False,indent=4))
\ No newline at end of file
+print(json.dumps(procurement_reqs,ensure_ascii=False,indent=4))
+# print(json.dumps(final_result,ensure_ascii=False,indent=4))
\ No newline at end of file
diff --git a/flask_app/货物标/技术参数要求提取.py b/flask_app/货物标/技术参数要求提取.py
index 5fa4846..4b19973 100644
--- a/flask_app/货物标/技术参数要求提取.py
+++ b/flask_app/货物标/技术参数要求提取.py
@@ -12,7 +12,7 @@ from flask_app.货物标.截取pdf货物标版 import truncate_pdf_main
from flask_app.general.doubao import doubao_model, generate_full_user_query, pdf2txt
-def generate_key_paths(data, parent_key=''):
+def generate_key_paths(data, parent_key='', good_list=None, seen=None):
"""
生成嵌套字典中的键路径,并提取最内层的键名。
同时,提取特定模式的键(如 '交换机-1', '交换机-2')的父路径。
@@ -20,13 +20,19 @@ def generate_key_paths(data, parent_key=''):
参数:
data (dict): 输入的字典数据
parent_key (str): 上级键路径,用于递归调用
+ good_list (list): 用于存储去重后的最内层键名
+ seen (set): 用于跟踪已添加到 good_list 的元素
返回:
tuple: 包含键路径列表、最内层键名列表、分组路径列表以及 no_keys_added 的元组
(key_paths, good_list, grouped_paths, no_keys_added)
"""
+ if good_list is None:
+ good_list = []
+ if seen is None:
+ seen = set()
+
key_paths = []
- good_list = []
grouped_paths = set() # 使用集合避免重复路径
no_keys_added = True # 默认假设没有添加任何键
@@ -37,16 +43,16 @@ def generate_key_paths(data, parent_key=''):
if isinstance(value, dict):
if value:
# 递归调用,并获取子路径、子 good_list、子分组路径以及子 no_keys_added
- sub_key_paths, sub_good_list, sub_grouped_paths, sub_no_keys_added = generate_key_paths(value, current_key)
+ sub_key_paths, _, sub_grouped_paths, sub_no_keys_added = generate_key_paths(
+ value, current_key, good_list, seen
+ )
key_paths.extend(sub_key_paths)
- good_list.extend(sub_good_list)
grouped_paths.update(sub_grouped_paths) # 合并子分组路径到当前分组路径
# 更新 no_keys_added
no_keys_added = no_keys_added and sub_no_keys_added
else:
# 空字典视为叶子节点
clean_key = key.replace(" ", "")
-
# 使用正则提取具有相同前缀的键
match = re.match(r'(.+)-\d+$', clean_key)
if match:
@@ -55,10 +61,18 @@ def generate_key_paths(data, parent_key=''):
goods_path = f"{parent_key}.{goods_name}" if parent_key else goods_name
goods_path = goods_path.replace(" ", "")
grouped_paths.add(goods_path) # 添加到集合中,不添加到key_paths
+
+ # **新增部分**:将匹配的键添加到 key_paths 和 good_list
+ key_paths.append(current_key.replace(" ", ""))
+ if goods_name not in seen:
+ good_list.append(goods_name)
+ seen.add(goods_name)
else:
# 非匹配项则直接添加到key_paths中
key_paths.append(current_key.replace(" ", ""))
- good_list.append(clean_key) # 去掉空格后添加
+ if clean_key not in seen:
+ good_list.append(clean_key) # 去掉空格后添加
+ seen.add(clean_key)
# 更新 no_keys_added
no_keys_added = False
@@ -66,29 +80,41 @@ def generate_key_paths(data, parent_key=''):
if value:
# 非空列表视为叶子节点
key_paths.append(current_key.replace(" ", ""))
- good_list.append(key.replace(" ", "")) # 去掉空格后添加
+ clean_key = key.replace(" ", "")
+ if clean_key not in seen:
+ good_list.append(clean_key) # 去掉空格后添加
+ seen.add(clean_key)
# 更新 no_keys_added
no_keys_added = False
else:
# 空列表也视为叶子节点(根据需求可以调整)
key_paths.append(current_key.replace(" ", ""))
- good_list.append(key.replace(" ", "")) # 去掉空格后添加
+ clean_key = key.replace(" ", "")
+ if clean_key not in seen:
+ good_list.append(clean_key) # 去掉空格后添加
+ seen.add(clean_key)
# 更新 no_keys_added
no_keys_added = False
elif value in {"未知", "", "/"}:
# 特定值视为叶子节点
key_paths.append(current_key.replace(" ", ""))
- good_list.append(key.replace(" ", "")) # 去掉空格后添加
+ clean_key = key.replace(" ", "")
+ if clean_key not in seen:
+ good_list.append(clean_key) # 去掉空格后添加
+ seen.add(clean_key)
# 更新 no_keys_added
no_keys_added = False
else:
# 其他情况视为叶子节点
key_paths.append(current_key.replace(" ", ""))
- good_list.append(key.replace(" ", "")) # 去掉空格后添加
+ clean_key = key.replace(" ", "")
+ if clean_key not in seen:
+ good_list.append(clean_key) # 去掉空格后添加
+ seen.add(clean_key)
# 更新 no_keys_added
no_keys_added = False
- return key_paths, good_list, grouped_paths, no_keys_added
+ return key_paths, good_list, grouped_paths, no_keys_added # xx_paths: 形如xx.xx,将嵌套键值对用'.'表示
def combine_and_update_results(original_data, updates):
def normalize_key(key):
@@ -190,54 +216,9 @@ def get_technical_requirements(file_path,invalid_path):
prompt_template1 = '''
任务:解析采购文件,提取采购需求,并以JSON格式返回。
- 要求与指南:
- 1. 精准定位:运用文档理解能力,找到文件中的采购需求部分。
- 2. 系统归属:若货物明确属于某个系统,则将其作为该系统的二级键。
- 3. 非清单形式处理:若未出现采购清单,则从表格或文字中摘取系统和货物信息。
- 4. 软件需求:对于软件应用需求,列出系统模块构成,并作为系统键值的一部分。
- 5. 系统功能:若文中提及系统功能,则在系统值中添加'系统功能'二级键,不展开具体内容。
- 6. 完整性:确保不遗漏系统内的货物,也不添加未提及的内容。
-
- 输出格式:
- 1.JSON格式,最外层键名为'采购需求'。
- 2.嵌套键名为系统或货物名称,与原文保持一致。
- 3.键值应为空对象({{}}),仅返回名称。
- 4.不包含'说明'、'规格'、'技术参数'等列内容。
- 5.层次关系用嵌套键值对表示。
- 6.最后一级键内值留空或填'未知'(如数量较多或未知内容)。
-
- 特殊情况处理:
- 1.同一层级下同名但采购要求不同的货物,以'货物名-编号'区分,编号从1递增。
- 2.对于工程施工、建设相关的采购需求,你无需提取,提取的范围仅限软件、硬件,。
-
- 示例输出结构:
- {{
- "采购需求": {{
- "交换机-1": {{}},
- "交换机-2": {{}},
- "门禁管理系统": {{
- // 可包含其他货物或模块
- }},
- "交通监控视频子系统": {{
- "系统功能": {{}},
- "高清视频抓拍像机": {{}},
- "补光灯": {{}}
- }},
- "LED全彩显示屏": {{}}
- // 其他系统和货物
- }}
- }}
-
- 注意事项:
- 1.严格按照上述要求执行,确保输出准确性和规范性。
- 2.如有任何疑问或不确定内容,请保留原文描述,必要时使用'未知'标注。
- '''
- prompt_template2 = '''
- 任务:解析采购文件,提取采购需求,并以JSON格式返回。
-
要求与指南:
- 1. 精准定位:文件内容以markdown格式组织,其中表格部分(若有)以html语法组织,请运用文档理解能力,找到文件中的采购需求部分,若有采购清单,请直接根据清单上的货物(或系统)名称给出结果。
- 2. 采购目标:采购目标通常有硬件(如设备、货物)和软件(如系统软件、应用APP),一次采购活动可能同时包含这两种。对于工程类的施工、建设采购需求,无需提取。
+ 1. 精准定位:请运用文档理解能力,找到文件中的采购需求部分,若有采购清单,请直接根据采购清单上的货物(或系统)名称给出结果。
+ 2. 采购目标:采购目标通常有硬件(如设备、货物)和软件(如系统软件、应用APP),一次采购活动可能同时包含这两种类型。对于工程类的施工、建设采购需求,无需提取。
3. 非清单形式处理:若未出现采购清单,则从表格或文字中摘取采购信息。
4. 系统归属:一些采购活动可能将采购目标划分为若干系统和货物,每个系统可能包含若干货物,则将这些货物名称作为该系统的二级键;系统可以只包含总体'系统功能'而无货物。
5. 软件需求:对于软件应用或系统软件需求,仅需列出系统模块构成(若有),并作为系统键值的一部分,无需在模块下再细分功能。
@@ -278,7 +259,69 @@ def get_technical_requirements(file_path,invalid_path):
"通用模块":{{}},
"用户管理":{{}}
}},
- "XX桌面应用": {{}},
+ "信息检索系统": {{
+ "系统功能":{{}},
+ "权限管理模块":{{}}
+ }},
+ "XX小程序":{{}},
+ "数据分析中心":{{}}
+ }}
+ }}
+
+ 注意事项:
+ 1.严格按照上述要求执行,确保输出准确性和规范性。
+ 2.如有任何疑问或不确定内容,请保留原文描述,必要时使用'未知'标注。
+ '''
+ prompt_template2 = '''
+ 任务:解析采购文件,提取采购需求,并以JSON格式返回。
+
+ 要求与指南:
+ 1. 精准定位:文件内容以markdown格式组织,请运用文档理解能力,找到文件中的采购需求部分,若有采购清单,请直接根据采购清单上的货物(或系统)名称给出结果。
+ 2. 采购目标:采购目标通常有硬件(如设备、货物)和软件(如系统软件、应用APP),一次采购活动可能同时包含这两种类型。对于工程类的施工、建设采购需求,无需提取。
+ 3. 非清单形式处理:若未出现采购清单,则从表格或文字中摘取采购信息。
+ 4. 系统归属:一些采购活动可能将采购目标划分为若干系统和货物,每个系统可能包含若干货物,则将这些货物名称作为该系统的二级键;系统可以只包含总体'系统功能'而无货物。
+ 5. 软件需求:对于软件应用或系统软件需求,仅需列出系统模块构成(若有),并作为系统键值的一部分,无需在模块下再细分功能。
+ 6. 系统功能:若采购的某系统提及总体系统功能,则在系统值中添加'系统功能'二级键,不展开具体内容。
+ 7. 完整性:确保不遗漏系统内的货物,也不添加未提及的内容。
+
+ 输出格式:
+ 1.JSON格式,最外层键名为'采购需求'。
+ 2.层次关系用嵌套键值对表示。
+ 3.嵌套键名为系统或货物或模块名称,与原文保持一致。
+ 4.最内层键值应为空对象({{}})。
+ 5.不包含'说明'、'规格'、'技术参数'等列内容,仅返回采购的货物或系统或模块名称。
+
+ 特殊情况处理:
+ 同一层级(如同一系统中)下同名但采购要求不同的货物,以'货物名-编号'区分,编号从1递增。
+
+ 示例输出1,普通系统、货物类采购:
+ {{
+ "采购需求": {{
+ "交换机-1": {{}},
+ "交换机-2": {{}},
+ "门禁管理系统": {{
+ "系统功能":{{}}
+ }},
+ "交通监控视频子系统": {{
+ "系统功能": {{}},
+ "高清视频抓拍像机": {{}},
+ "补光灯": {{}}
+ }},
+ "LED全彩显示屏": {{}}
+ // 其他系统和货物
+ }}
+ }}
+ 示例输出2,系统软件采购:
+ {{
+ "采购需求": {{
+ "信息管理系统": {{
+ "通用模块":{{}},
+ "用户管理":{{}}
+ }},
+ "信息检索系统": {{
+ "系统功能":{{}},
+ "权限管理模块":{{}}
+ }},
"XX小程序":{{}},
"数据分析中心":{{}}
}}
@@ -297,74 +340,73 @@ def get_technical_requirements(file_path,invalid_path):
print(model_res)
else:
# processed_filepath = convert_pdf_to_markdown(file_path) # 转markdown格式
- # processed_filepath=r"D:\flask_project\flask_app\general\陕西省公安厅交通警察总队高速公路交通安全智能感知巡查系统项目 (1)_procurement.txt"
+ # processed_filepath=r"C:\Users\Administrator\Desktop\货物标\extract_files\107国道.txt"
processed_filepath = pdf2txt(file_path) # 纯文本提取
user_query=generate_full_user_query(processed_filepath,prompt_template2)
model_res=doubao_model(user_query)
# model_res = qianwen_long(file_id,prompt_template1)
print(model_res)
-# cleaned_res = clean_json_string(model_res) #转字典
-# keys_list,good_list,grouped_paths,no_keys_added= generate_key_paths(cleaned_res['采购需求']) # 提取需要采购的货物清单 key_list:交通监控视频子系统.高清视频抓拍像机 ...
-# if no_keys_added:
-# final_res = postprocess(cleaned_res)
-# else:
-# # user_query_template = "请你根据该货物标中采购要求部分的内容,请你给出\"{}\"的技术参数(或采购要求),请以json格式返回结果,外层键名为\"{}\", 键值对中的键是你对该要求的总结,而值需要完全与原文保持一致,不可擅自总结删减。"
-# user_query_template = """
-# 请你根据该货物标中采购要求部分的内容,请你给出\"{}\"的技术参数(或采购要求),请以json格式返回结果,键名为\"{}\", 键值为一个列表,列表中包含若干描述\"{}\"的技术参数(或采购要求)的字符串,需与原文完全一致,即若技术参数前存在序号也要保留,但你不可擅自增添或删减。以下为需要考虑的特殊情况:如果该货物没有相关采购要求或技术参数要求,键值为空列表。示例输出格式如下:
-# {{
-# "摄像机控制键盘": [
-# "1、支持串行 RS232/RS422 和 IP 混合控制,允许在一个控制器上使用 RS232/RS422/IP 控制单个系统中的摄像机;",
-# "2、支持 2 组 RS422 串口 VISCA 协议菊花链控制 2x7 台摄像机。"
-# ]
-# }}
-# """
-# user_query_template_two="""
-# 请你根据该货物标中采购要求部分的内容,请你给出\"{}\"的技术参数(或采购要求),由于该货物存在多种不同的采购要求或技术参数,请你请逐一列出,请以json格式返回结果,请你以'货物名-编号'区分多种型号,编号为从 1 开始的自然数,依次递增,即第一个键名为\"{}-1\", 键值为一个列表,列表中包含若干描述\"{}\"的技术参数(或采购要求)的字符串,需与原文完全一致,即若技术参数前存在序号也要保留,但你不可擅自增添或删减。示例输出格式如下:
-# {{
-# "交换机-1": [
-# "1、支持固化千兆电口≥8 个,固化千兆光口≥2 个,桌面型设备;",
-# "2、支持静态链路聚合"
-# ]
-# "交换机-2":[
-# "1、交换容量≥52Gbps,包转发率≥38.69Mpps,",
-# "2、提供国家强制性产品认证证书及测试报告(3C)"
-# ]
-# }}
-# """
-# queries = []
-# for key in keys_list:
-# # 将键中的 '.' 替换为 '下的'
-# modified_key = key.replace('.', '下的')
-# # 使用修改后的键填充第一个占位符,原始键填充第二个占位符
-# new_query = user_query_template.format(modified_key, key, modified_key)
-# queries.append(new_query)
-#
-# # 处理 grouped_paths 中的项,应用 user_query_template_two
-# for grouped_key in grouped_paths:
-# # 将键中的 '.' 替换为 '下的'
-# modified_grouped_key = grouped_key.replace('.', '下的')
-# # 使用修改后的键填充第一个占位符,原始键填充第二个占位符
-# new_query = user_query_template_two.format(modified_grouped_key, grouped_key, modified_grouped_key)
-# queries.append(new_query)
-# results = multi_threading(queries, "", file_id, 2)
-# technical_requirements = []
-# if not results:
-# print("errror!未获得大模型的回答!")
-# else:
-# # 打印结果
-# for question, response in results:
-# technical_requirements.append(response)
-# technical_requirements_combined_res = combine_json_results(technical_requirements)
-#
-# """根据所有键是否已添加处理技术要求"""
-# # 更新原始采购需求字典
-# final_res=combine_and_update_results(cleaned_res['采购需求'], technical_requirements_combined_res)
-# # final_res = postprocess(cleaned_res)
-# final_res["货物列表"] = good_list
-#
-# # 输出最终的 JSON 字符串
-# return {"采购需求": final_res}
+ cleaned_res = clean_json_string(model_res) #转字典
+ normal_paths,good_list,grouped_paths,no_keys_added= generate_key_paths(cleaned_res['采购需求']) # 提取需要采购的货物清单 key_list:交通监控视频子系统.高清视频抓拍像机 ... grouped_paths是同一系统下同时有'交换机-1'和'交换机-2',提取'交换机' ,输出eg:{'交通标志.标志牌铝板', '交通信号灯.交换机'}
+ if no_keys_added:
+ final_res = postprocess(cleaned_res)
+ else:
+ # user_query_template = "请你根据该货物标中采购要求部分的内容,请你给出\"{}\"的技术参数(或采购要求),请以json格式返回结果,外层键名为\"{}\", 键值对中的键是你对该要求的总结,而值需要完全与原文保持一致,不可擅自总结删减。"
+ user_query_template = """
+请你根据该货物标中采购要求部分的内容,请你给出\"{}\"的技术参数(或采购要求),请以json格式返回结果,键名为\"{}\", 键值为一个列表,列表中包含若干描述\"{}\"的技术参数(或采购要求)的字符串,需与原文完全一致,即若技术参数前存在序号也要保留,但你不可擅自增添或删减。以下为需要考虑的特殊情况:如果该货物没有相关采购要求或技术参数要求,键值为空列表。示例输出格式如下:
+{{
+ "摄像机控制键盘": [
+ "1、支持串行 RS232/RS422 和 IP 混合控制,允许在一个控制器上使用 RS232/RS422/IP 控制单个系统中的摄像机;",
+ "2、支持 2 组 RS422 串口 VISCA 协议菊花链控制 2x7 台摄像机。"
+ ]
+}}
+ """
+ user_query_template_two="""请你根据该货物标中采购要求部分的内容,请你给出\"{}\"的技术参数(或采购要求),由于该货物存在多种不同的采购要求或技术参数,请你请逐一列出,请以json格式返回结果,请你以'货物名-编号'区分多种型号,编号为从 1 开始的自然数,依次递增,即第一个键名为\"{}-1\", 键值为一个列表,列表中包含若干描述\"{}\"的技术参数(或采购要求)的字符串,需与原文完全一致,即若技术参数前存在序号也要保留,但你不可擅自增添或删减。示例输出格式如下:
+{{
+ "交换机-1": [
+ "1、支持固化千兆电口≥8 个,固化千兆光口≥2 个,桌面型设备;",
+ "2、支持静态链路聚合"
+ ]
+ "交换机-2":[
+ "1、交换容量≥52Gbps,包转发率≥38.69Mpps,",
+ "2、提供国家强制性产品认证证书及测试报告(3C)"
+ ]
+}}
+ """
+ queries = []
+ for key in normal_paths:
+ # 将键中的 '.' 替换为 '下的'
+ modified_key = key.replace('.', '下的')
+ # 使用修改后的键填充第一个占位符,原始键填充第二个占位符
+ new_query = user_query_template.format(modified_key, key, modified_key)
+ queries.append(new_query)
+
+ # 处理 grouped_paths 中的项,应用 user_query_template_two
+ for grouped_key in grouped_paths:
+ # 将键中的 '.' 替换为 '下的'
+ modified_grouped_key = grouped_key.replace('.', '下的')
+ # 使用修改后的键填充第一个占位符,原始键填充第二个占位符
+ new_query = user_query_template_two.format(modified_grouped_key, grouped_key, modified_grouped_key)
+ queries.append(new_query)
+ results = multi_threading(queries, "", file_id, 2)
+ technical_requirements = []
+ if not results:
+ print("errror!未获得大模型的回答!")
+ else:
+ # 打印结果
+ for question, response in results:
+ technical_requirements.append(response)
+ technical_requirements_combined_res = combine_json_results(technical_requirements)
+
+ """根据所有键是否已添加处理技术要求"""
+ # 更新原始采购需求字典
+ final_res=combine_and_update_results(cleaned_res['采购需求'], technical_requirements_combined_res)
+ # final_res = postprocess(cleaned_res)
+ final_res["货物列表"] = good_list
+
+ # 输出最终的 JSON 字符串
+ return {"采购需求": final_res}
def test_all_files_in_folder(input_folder, output_folder):
# 确保输出文件夹存在