websource.py 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. # -*- coding: utf-8 -*-
  2. """站源招标人预测器。
  3. 按 ARCHITECTURE.md Phase 5 拆分建议,从 ``interface/predictor.py`` 迁出以下类:
  4. - ``WebsourceTenderee`` — 通过数据源唯一招标人召回调整 prem 中的招标人
  5. (原 predictor.py 第 9199-9296 行)
  6. 原 ``from common.Utils import *`` / ``from interface.modelFactory import *``
  7. 已替换为显式 import;``os.path.dirname(__file__)`` 路径引用替换为
  8. ``predictors._common.INTERFACE_DIR``。
  9. ``interface/predictor.py`` 仍保留原定义,老 import 不受影响。
  10. """
  11. from __future__ import absolute_import
  12. import re
  13. import json
  14. from BiddingKG.dl.common.logging import log
  15. from BiddingKG.dl.entityLink.entityLink import get_business_data
  16. from BiddingKG.dl.predictors._common import INTERFACE_DIR
  17. __all__ = ["WebsourceTenderee"]
  18. class WebsourceTenderee():
  19. def __init__(self):
  20. with open(INTERFACE_DIR+'/websource_tenderee.pkl', 'r', encoding='utf-8') as f:
  21. self.webno2ree = json.load(f)
  22. def get_websource_tenderee(self, docid, web_source_no, web_source_name, prem):
  23. '''
  24. 通过数据源唯一招标人召回调整prem中的招标人,
  25. :param web_source_no:
  26. :param prem:
  27. :return:
  28. '''
  29. p = '(医院|学院|学校|中学|小学|大学|幼儿园|保健院|党校|银行|研究院|血站|红十字会|防治院|研究所)'
  30. web_ree = self.webno2ree.get(web_source_no, '')
  31. if web_source_no.startswith('18591-') and web_ree == "":
  32. web_ree = '中国人民解放军总医院'
  33. elif web_source_no.startswith('Y00484-') and web_ree == "":
  34. web_ree = '航空总医院'
  35. elif web_source_no.startswith('DX015142-'):
  36. web_ree = '海尔集团'
  37. if web_source_name == '圣泉集团采购平台(新)':
  38. web_ree = '济南圣泉集团股份有限公司'
  39. elif web_source_name == '中信重工招标采购网':
  40. web_ree = '中信重工机械股份有限公司'
  41. elif web_source_name == '中国巨石采购管理平台':
  42. web_ree = '中国巨石股份有限公司'
  43. elif web_source_name == '卡奥斯模块商采购服务平台':
  44. web_ree = '卡奥斯数字科技(青岛)有限公司'
  45. elif web_source_name == '南山集团有限公司':
  46. web_ree = '南山集团有限公司'
  47. # elif web_source_name == '浪潮电子采购平台':
  48. # web_ree = '浪潮集团有限公司'
  49. if web_ree == "" and re.search('\w{2,8}(大学|医院|妇幼保健院)$', web_source_name): # 20240524 大学、医院类站源没唯一招标人默认为站源名称
  50. web_ree = web_source_name
  51. if web_source_no in ['DX013230-2', 'DX008427-1', 'DX001298', 'DX013230-3', 'DX003960-1', 'DX002797-1', 'DX010532',
  52. 'DX014075', 'DX002897', 'DX001242-1', 'DX000545', 'DX001069', 'DX009895', 'DX003270', 'DX006310-1',
  53. '02215-1', 'DX000820', 'DX002512-1', 'DX000443', 'DX008157', 'DX004927', 'DX005403', 'DX001425-1',
  54. 'DX000980', 'DX013748-1', 'DX002488', '07056-4', 'XX2102']: # 统计分析可能有问题的唯一招标人
  55. web_ree = ''
  56. if web_ree != '':
  57. flag = 0 # 是否被替换为站源招标人
  58. if 'Project' in prem[0]['prem']:
  59. find_tenderee = False
  60. for d in prem[0]['prem']['Project']['roleList']:
  61. if d['role_name'] == 'tenderee':
  62. find_tenderee = True
  63. if d['role_text'] == "":
  64. d['role_text'] = web_ree
  65. flag = 1
  66. elif re.search('大学$', web_ree) and re.search('学院$', d['role_text']) and web_ree not in d['role_text']:
  67. d['role_text'] = web_ree
  68. flag = 1
  69. elif d.get('role_prob', 0) < 0.8 and get_business_data(d['role_text'])[0] == False: # 20240201 概率低于0.8且没有工商数据的替换为站源招标人
  70. if re.search('银行', web_ree) and re.search('\w{2,}银行\w{2,}分行', d['role_text']): # 20251028 修复692502613 交通银行阜阳分行 被替换为 交通银行股份有限公司
  71. break
  72. d['role_text'] = web_ree
  73. flag = 1
  74. # elif re.search(p, web_ree) and (re.search(p, d['role_text'])==None and len(d['role_text'])<6): # 数据源唯一招标人以医院等结尾,角色中无相关关键词的,替换为数据源招标人
  75. # d['role_text'] = web_ree
  76. # elif re.search('有限(责任)?公司', web_ree) and (re.search('有限(责任)?公司', d['role_text'])==None and len(d['role_text'])<6):
  77. # d['role_text'] = web_ree
  78. break
  79. if not find_tenderee: # 没招标人的添加
  80. prem[0]['prem']['Project']['roleList'].append({'role_name': 'tenderee',
  81. 'role_text': '%s' % web_ree,
  82. 'role_money': {'money': 0, 'money_unit': '',
  83. 'floating_ratio': '',
  84. 'downward_floating_ratio': '',
  85. 'discount_ratio': ''},
  86. 'linklist': [],
  87. 'serviceTime': '',
  88. 'address': ''})
  89. flag = 1
  90. else:
  91. prem[0]['prem']['Project'] = {'code': '',
  92. 'tendereeMoney': 0,
  93. 'roleList': [
  94. {'role_name': 'tenderee',
  95. 'role_text': '%s' % web_ree,
  96. 'role_money': {'money': 0, 'money_unit': '', 'floating_ratio': '',
  97. 'downward_floating_ratio': '', 'discount_ratio': ''},
  98. 'linklist': [],
  99. 'serviceTime': '',
  100. 'address': ''}
  101. ]}
  102. flag = 1
  103. tenderee_l = [d2['role_text'] for v in prem[0]['prem'].values() for d2 in v['roleList'] if
  104. d2['role_name'] == 'tenderee']
  105. winner_l = [d2['role_text'] for v in prem[0]['prem'].values() for d2 in v['roleList'] if
  106. d2['role_name'] == 'win_tenderer']
  107. if set(tenderee_l) & set(winner_l) and web_ree in tenderee_l: # 删除与站源招标人冲突的中标人
  108. for k in prem[0]['prem']:
  109. prem[0]['prem'][k]['roleList'] = [d for d in prem[0]['prem'][k]['roleList'] if
  110. not (d['role_name'] == 'win_tenderer' and d['role_text'] in tenderee_l)]
  111. if flag == 1:
  112. log('规则补充站源招标人:%s,docid:%s'%(web_ree, docid))
  113. return prem