浏览代码

表格提取新增服务期限,同一电话连接多个公司删除

znj 9 月之前
父节点
当前提交
45db31e7c1
共有 2 个文件被更改,包括 61 次插入9 次删除
  1. 28 1
      BiddingKG/dl/interface/getAttributes.py
  2. 33 8
      BiddingKG/dl/interface/predictor.py

+ 28 - 1
BiddingKG/dl/interface/getAttributes.py

@@ -943,7 +943,7 @@ def findAttributeAfterEntity(PackDict,roleSet,PackageList,PackageSet,list_senten
                 packDict[packageName]["roleList"][i].ratio = ratio.ratio_value
     def addServiceTimeByEntity(packDict,packageName,entity,serviceTime):
         for i in range(len(packDict[packageName]["roleList"])):
-            if packDict[packageName]["roleList"][i].entity_text==entity:
+            if packDict[packageName]["roleList"][i].entity_text==entity and not packDict[packageName]["roleList"][i].serviceTime:
                 # packDict[packageName]["roleList"][i].serviceTime = serviceTime.entity_text
                 packDict[packageName]["roleList"][i].serviceTime = extract_serviceTime(serviceTime.entity_text,"")
 
@@ -2913,6 +2913,29 @@ def findAttributeAfterEntity(PackDict,roleSet,PackageList,PackageSet,list_senten
                             if get_tenderee_contacts:
                                 break
 
+    # 如果同一个电话连到了不同的单位就直接去掉(2024-09-03 新增)
+    get_phone_dict = dict()
+    for k in PackDict.keys():
+        for i in range(len(PackDict[k]["roleList"])):
+            for item in PackDict[k]["roleList"][i].linklist:
+                if item[1]:
+                    if item[1] not in get_phone_dict:
+                        get_phone_dict[item[1]] = set()
+                    get_phone_dict[item[1]].add(PackDict[k]["roleList"][i].entity_text)
+    # print(get_phone_dict)
+    remove_phone = []
+    for phone,role_list in get_phone_dict.items():
+        if len(role_list)>1:
+            remove_phone.append(phone)
+    for k in PackDict.keys():
+        for i in range(len(PackDict[k]["roleList"])):
+            remove_list = []
+            for item in PackDict[k]["roleList"][i].linklist:
+                if item[1] and item[1] in remove_phone:
+                    remove_list.append(item)
+            for _item in remove_list:
+                PackDict[k]["roleList"][i].linklist.remove(_item)
+
     for pack in PackDict.keys():
         for i in range(len(PackDict[pack]["roleList"])):
             PackDict[pack]["roleList"][i] = PackDict[pack]["roleList"][i].getString()
@@ -4548,6 +4571,8 @@ def update_prem(old_prem, new_prem, in_attachment=False):
                                 tmp_l.append(d2)
                                 if d2['role_text'] != "":
                                     d['role_text'] = d2['role_text']
+                                if d2['serviceTime'] != "":
+                                    d['serviceTime'] = d2['serviceTime']
                                 if float(d2['role_money']['money']) != 0:  # 如果表格提取的金额不为0才替换
                                     d['role_money']['money'] = d2['role_money']['money']
                                     d['role_money']['money_unit'] = d2['role_money']['money_unit']
@@ -4581,6 +4606,8 @@ def update_prem(old_prem, new_prem, in_attachment=False):
                                 tmp_l.append(d2)
                                 if d2['role_text'] != "":
                                     d['role_text'] = d2['role_text']
+                                if d2['serviceTime'] != "":
+                                    d['serviceTime'] = d2['serviceTime']
                                 if float(d2['role_money']['money']) != 0: # 如果表格提取的金额不为0才替换
                                     d['role_money']['money'] = d2['role_money']['money']
                                     d['role_money']['money_unit'] = d2['role_money']['money_unit']

+ 33 - 8
BiddingKG/dl/interface/predictor.py

@@ -28,7 +28,8 @@ import calendar
 import datetime
 from BiddingKG.dl.entityLink.entityLink import get_business_data
 from BiddingKG.dl.proposed_building.pb_extract import PBPredictor
-from BiddingKG.dl.interface.getAttributes import turnMoneySource
+from BiddingKG.dl.interface.getAttributes import turnMoneySource, extract_serviceTime
+from BiddingKG.dl.time.re_servicetime import extract_servicetime
 # import fool   # 统一用 selffool ,阿里云上只有selffool 包
 
 cpu_num = int(os.environ.get("CPU_NUM",0))
@@ -6360,6 +6361,18 @@ class TablePremExtractor(object):
             "tenderee": "(项目|采购|招标|遴选|寻源|竞价|议价|比选|委托|询比?价|比价|评选|谈判|邀标|邀请|洽谈|约谈|选取|抽取|抽选)(人|公司|单位|组织|用户|业主|主体|方|部门)(名称|$)",
             "budget": "最高(投标)?限价|总价限价|控制(价格?|金额|总价)|(总价|采购)限价|上限价|拦标价|(采购|招标|项目)?预算|(预算|招标|采购|计划)金额|挂牌价",
             "bid_amount": "投标[报总]?价|报价(总?金额|总价|总额)|总报价|^\w{,5}报价(([\w、/]{1,15}))?$|(中标|成交|合同))?总?(金?额|[报均总]价|价[格款]?)|承包价|含税价|经评审的价格|中标存款金?额|中标资金|存放金额",
+            "serviceTime": '合同期限|工期/交货期/服务期|工期\(交货期\)|合格工期|服务期限|工期' \
+                 '|工期要求|项目周期|工期\(交货期\)|计划工期\(服务期限\)|服务时限|履行期限|服务周期|供货期限' \
+                 '|合格工期|计划工期\(服务期\)|服务期|服务,期|交货\(完工\)时间|交付\(服务、完工\)时间' \
+                 '|交货时间|保洁期限|维保期|管理年限|工期承诺|(服务|合同|施工|实施|工程|设计)的?(年限|期限|周期|期:)' \
+                 '|计划工期|工期要求|服务期限?' \
+                 '|投标工期|设计工期|合格服务周期|总工期|服务时间(范围)?|流转期限|维护期限|服务时限|交货期' \
+                 '|完成时间|中标工期|项目周期|期限要求|周期|供货期|合同的?履行日期|计划周期' \
+                 '|履约期限|合同的?约定完成时限|合同的?完成日期|承诺完成日期' \
+                 '|合同起始日起|合同的?履约期|履约截止日期|承包期限|合同的?完成日期|特许经营期限' \
+                 '|服务期间|服务履行期|委托(管理)?期限|经营期限|数量' \
+                 '|(工期|服务期限?|交货期限?|服务履行期|合同期限?|履[行约]期限?)说明|存款期限?|(存款|存放|定存)(期|年)限' \
+                 '|服务(有效期|年限)|本?合同有效期|协议有效期|项目期限'
         }
 
         with open(os.path.dirname(__file__)+'/header_set.pkl', 'rb') as f:
@@ -6439,6 +6452,8 @@ class TablePremExtractor(object):
                 return flag,contain_header, header_dic
             elif 'tenderer' in header_dic and re.search('(中标|中选|中价|成交|竞得)(人|单位|供应商|公司|企业|厂家|商家?|客户|供?方|银行)',header_dic['tenderer'][1]): # 有中标人,且有明确中标关键词的进行提取
                 return flag, contain_header, header_dic
+            elif 'tenderer' in header_dic and 'serviceTime' in header_dic:
+                return flag, contain_header, header_dic
         elif len(set(fix_td_list) & self.headerset) >= 2 or (len(set(fix_td_list)) == 2 and len(set(td_list) & self.headerset) >= 1): # 如果包含两个表头以上或 只有两列且包含一个表头
             contain_header = True
         return flag, contain_header, dict()
@@ -6479,6 +6494,7 @@ class TablePremExtractor(object):
         package_fix2raw = dict()  # 处理后包号:处理前包号 字典
         link_set = set()
         tenderer_list = [] # 保存所有中标人
+        serviceTime_list = []
         not_package = True if 'project_name' in headers and re.search('(货物|商品|产品|通用|主要标的)(名称?|内容)', headers['project_name'][1]) and \
                           'package_code' not in headers and 'budget' not in headers and "bid_amount" not in headers else False
 
@@ -6498,6 +6514,7 @@ class TablePremExtractor(object):
             bid_amount_ = df.loc[i, headers['bid_amount'][0]].strip() if "bid_amount" in headers else ""
             win_sort = df.loc[i, headers['win_sort'][0]].strip() if "win_sort" in headers else ""
             win_or_not = df.loc[i, headers['win_or_not'][0]].strip() if "win_or_not" in headers else ""
+            serviceTime = df.loc[i, headers['serviceTime'][0]].strip() if "serviceTime" in headers else ""
 
             if set([project_code, package_code_raw, project_name,tenderee,tenderer,budget_,bid_amount_]) & self.headerset != set(): # 只要有一项为表头 停止匹配
                 # print('只要有一项为表头 停止匹配', set([project_code, package_code_raw, project_name,tenderee,tenderer,budget_,bid_amount_,win_sort]) & self.headerset)
@@ -6507,7 +6524,7 @@ class TablePremExtractor(object):
                 break
             if re.search('详见', project_name):  # 去除某些表达: 详见招标文件
                 project_name = ""
-            if package_code_raw == "" and re.search('第?[0-9一二三四五六七八九十a-zZ-Z]{1,4}(标[段号的包项]|([分子]?包|包[组件号]))$|^(标[段号的包项]|([分子]?包|包[组件号]))号?:?[0-9一二三四五六七八九十a-zZ-Z]{1,4}$', project_name):
+            if package_code_raw == "" and re.search('第?[0-9一二三四五六七八九十a-zA-Z]{1,4}(标[段号的包项]|([分子]?包|包[组件号]))$|^(标[段号的包项]|([分子]?包|包[组件号]))号?:?[0-9一二三四五六七八九十a-zA-Z]{1,4}$', project_name):
                 package_code_raw = project_name
                 project_name = ""
 
@@ -6633,6 +6650,13 @@ class TablePremExtractor(object):
                 if (re.search('费率|下浮率|[%%‰折]',
                               bid_amount_header + bid_amount_) and bid_amount < 100) or bid_amount > 50000000000:  # 如果是费率或大于500亿的金额改为0
                     bid_amount = 0
+                if serviceTime:
+                    serviceTime_text = headers['serviceTime'][1] + serviceTime if headers['serviceTime'][1][-1] in [':',':'] else headers['serviceTime'][1] + ':' + serviceTime
+                    # print('serviceTime_text',serviceTime_text)
+                    serviceTime = extract_servicetime(serviceTime_text)
+                    serviceTime.sort(key=lambda x:x.get('begin_index',0))
+                    serviceTime = extract_serviceTime(serviceTime[0]['body'],"") if serviceTime else ""
+                    # print(serviceTime)
                 if not same_package or len(prem_dic[package]['roleList'])==0:
                     prem_dic[package]['roleList'].append({
                             "address": "",
@@ -6646,7 +6670,7 @@ class TablePremExtractor(object):
                             },
                             "role_name": "win_tenderer",
                             "role_text": tenderer,
-                            "serviceTime": ""
+                            "serviceTime": serviceTime
                     })
                 elif prem_dic[package]['roleList'] and prem_dic[package]['roleList'][-1].get('role_name', '')=='win_tenderer':
                     if 'multi_winner' not in prem_dic[package]['roleList'][-1]:
@@ -6656,8 +6680,9 @@ class TablePremExtractor(object):
                         prem_dic[package]['roleList'][-1]['multi_winner'] += ','+ tenderer
                     if 'other_winner_dic' not in prem_dic[package]['roleList'][-1]:
                         prem_dic[package]['roleList'][-1]['other_winner_dic'] = []
-                    prem_dic[package]['roleList'][-1]['other_winner_dic'].append({'role_text': tenderer, "money": bid_amount, "money_unit": money_unit})
+                    prem_dic[package]['roleList'][-1]['other_winner_dic'].append({'role_text': tenderer, "money": bid_amount, "money_unit": money_unit,"serviceTime":serviceTime})
                 tenderer_list.append(tenderer)
+                serviceTime_list.append(serviceTime)
             if len(prem_dic[package]['roleList']) == 0 and prem_dic[package]['tendereeMoney'] == 0:  # 只有项目编号和名称的 丢弃 并不再继续往下匹配
                 prem_dic.pop(package)
                 # break # 注释掉避免 400084571 某些包废标 中断匹配
@@ -6689,7 +6714,7 @@ class TablePremExtractor(object):
                         },
                         "role_name": "win_tenderer",
                         "role_text": tenderer_list[0],
-                        "serviceTime": ""
+                        "serviceTime": serviceTime_list[0]
                 }],
                 'tendereeMoney': 0,
                 'tendereeMoneyUnit': ""
@@ -6727,7 +6752,7 @@ class TablePremExtractor(object):
 
             text = table.text.strip()
             previous = table.findPreviousSibling()
-            text2 = previous .text.strip() if previous else ""
+            text2 = previous.text.strip() if previous else ""
             # text2 = table.findPreviousSibling().text.strip() if table.findPreviousSibling() != None else ""
             if re.search('项目业主|业\s*主', text) and re.search('业\s*绩', text+text2): # 包含业绩的表格过滤掉,不进行处理
                 tb_ex = table.extract()
@@ -6770,7 +6795,7 @@ class TablePremExtractor(object):
             if table_prem and 'project_code' not in headers and 'package_code' not in headers and '自增1' in table_prem and table.find_previous_sibling(): # 表格内没有标段的,从上一个兄弟标签找标段
                 sib = table.find_previous_sibling()
                 sib_text = sib.get_text()
-                ser_sib = re.search('第?[0-9一二三四五六七八九十a-zZ-Z]{1,4}(标[段号的包项]|([分子]?包|包[组件号]))|(标[段号的包项]|([分子]?包|包[组件号]))号?:?[0-9一二三四五六七八九十a-zZ-Z]{1,4}|包名:[0-9一二三四五六七八九十]{1,4}', sib_text)
+                ser_sib = re.search('第?[0-9一二三四五六七八九十a-zA-Z]{1,4}(标[段号的包项]|([分子]?包|包[组件号]))|(标[段号的包项]|([分子]?包|包[组件号]))号?:?[0-9一二三四五六七八九十a-zA-Z]{1,4}|包名:[0-9一二三四五六七八九十]{1,4}', sib_text)
                 if sib.name in ['p','div','dl','ol','ul','h1','h2','h3','h4','h5','h6'] and len(sib_text)<100 and ser_sib:
                     package_sib = ser_sib.group(0)
                     package_sib = uniform_package_name(package_sib)
@@ -7128,7 +7153,7 @@ class CandidateExtractor(object):
             if rs_dic and 'package_code' not in headers and 'Project' in rs_dic and table.find_previous_sibling(): # 一个表格只有两行且没有标段的,从上一个兄弟标签找标段
                 sib = table.find_previous_sibling()
                 sib_text = sib.get_text()
-                ser_sib = re.search('第?[0-9一二三四五六七八九十a-zZ-Z]{1,4}(标[段号的包项]|([分子]?包|包[组件号]))|(标[段号的包项]|([分子]?包|包[组件号]))号?:?[0-9一二三四五六七八九十a-zZ-Z]{1,4}|包名:[0-9一二三四五六七八九十]{1,4}', sib_text)
+                ser_sib = re.search('第?[0-9一二三四五六七八九十a-zA-Z]{1,4}(标[段号的包项]|([分子]?包|包[组件号]))|(标[段号的包项]|([分子]?包|包[组件号]))号?:?[0-9一二三四五六七八九十a-zA-Z]{1,4}|包名:[0-9一二三四五六七八九十]{1,4}', sib_text)
                 if sib.name in ['p', 'div'] and len(sib_text)<100 and ser_sib:
                     package_sib = ser_sib.group(0)
                     package_sib = uniform_package_name(package_sib)