优化利益检索

This commit is contained in:
27942
2026-02-06 01:26:00 +08:00
parent 9203b17f2b
commit 52be5caa7f

View File

@@ -109,8 +109,8 @@ def get_team_name_from_responsiblefor(responsiblefor):
def search_related_records(client_info, party_info, exclude_project_id=None):
"""
根据委托人和相对方信息检索预立案、投标、立项三个表的冲突记录
只返回委托人和相对方匹配的记录(冲突数据)
根据委托人和相对方信息检索预立案、投标、立项三个表的冲突记录
冲突规则:当前委托人只与历史「委托人」匹配,当前相对方只与历史「相对方匹配,任一匹配即视为冲突。
Args:
client_info: 委托人身份信息(字符串)
@@ -147,37 +147,14 @@ def search_related_records(client_info, party_info, exclude_project_id=None):
party_id_number = party_parsed['id_number']
party_original = party_parsed['original']
# 检索预立案表 - 查找委托人和相对方都匹配的记录(冲突数据)
# 注意:预立案和立项是完全独立的,没有关联关系,只根据委托人和相对方信息匹配
# 预立案表字段client_username/party_usernameJSON数组格式字符串[{"index":1,"name":"张三","idNumber":"110101199001011234"}]
# 立项表字段client_info/party_info完整身份信息如"张三身份证号110101199001011234"
#
# 冲突判断逻辑:
# 1. 委托人和相对方都匹配(顺序相同或相反)
# 2. 预立案中委托人和相对方是同一个人,且这个人在立项的委托人或相对方中
# 3. 立项中委托人和相对方是同一个人,且这个人在预立案的委托人或相对方中
if (client_info or client_name) and (party_info or party_name):
# 检索预立案表 - 冲突规则:当前委托人只与历史「委托人」匹配,当前相对方只与历史「相对方」匹配,任一匹配即冲突
# 预立案表字段client_username/party_usernameJSON 数组)
if (client_info or client_name) or (party_info or party_name):
matched_prefilings = []
# 检查立项中委托人和相对方是否是同一个人
is_same_person_in_project = False
if client_name and party_name and client_name.strip() == party_name.strip():
is_same_person_in_project = True
elif client_id_number and party_id_number and client_id_number == party_id_number:
# 通过身份证号判断是否为同一人
is_same_person_in_project = True
# 遍历预立案记录解析JSON格式并匹配
prefiling_all = PreFiling.objects.filter(is_deleted=False)
for pf in prefiling_all[:100]: # 限制查询数量以提高性能
for pf in prefiling_all[:100]:
if len(matched_prefilings) >= 10:
break
if not pf.client_username or not pf.party_username:
continue
# 解析预立案的client_usernameJSON数组格式
pf_client_names = []
try:
client_data = json.loads(pf.client_username) if isinstance(pf.client_username, str) else pf.client_username
@@ -188,10 +165,7 @@ def search_related_records(client_info, party_info, exclude_project_id=None):
elif isinstance(client_data, dict) and 'name' in client_data:
pf_client_names.append(client_data['name'].strip())
except (json.JSONDecodeError, TypeError, AttributeError):
# 如果不是JSON格式尝试直接使用字符串兼容旧数据
pf_client_names = [pf.client_username.strip()]
# 解析预立案的party_usernameJSON数组格式
pf_client_names = [pf.client_username.strip()] if pf.client_username else []
pf_party_names = []
try:
party_data = json.loads(pf.party_username) if isinstance(pf.party_username, str) else pf.party_username
@@ -202,86 +176,20 @@ def search_related_records(client_info, party_info, exclude_project_id=None):
elif isinstance(party_data, dict) and 'name' in party_data:
pf_party_names.append(party_data['name'].strip())
except (json.JSONDecodeError, TypeError, AttributeError):
# 如果不是JSON格式尝试直接使用字符串兼容旧数据
pf_party_names = [pf.party_username.strip()]
if not pf_client_names or not pf_party_names:
continue
# 检查预立案中委托人和相对方是否是同一个人(所有委托人和所有相对方中有相同的名字)
is_same_person_in_prefiling = bool(set(pf_client_names) & set(pf_party_names))
# 对每个委托人名字和相对方名字进行匹配
pf_party_names = [pf.party_username.strip()] if pf.party_username else []
client_match = False
party_match = False
reverse_client_match = False
reverse_party_match = False
# 检查正向匹配:预立案的委托人是否在立项的委托人信息中,预立案的相对方是否在立项的相对方信息中
for pf_client in pf_client_names:
if client_name and pf_client in client_name:
client_match = True
break
elif client_original and pf_client in client_original:
client_match = True
break
for pf_party in pf_party_names:
if party_name and pf_party in party_name:
party_match = True
break
elif party_original and pf_party in party_original:
party_match = True
break
# 检查反向匹配:预立案的委托人是否在立项的相对方信息中,预立案的相对方是否在立项的委托人信息中
for pf_client in pf_client_names:
if party_name and pf_client in party_name:
reverse_client_match = True
break
elif party_original and pf_client in party_original:
reverse_client_match = True
break
for pf_party in pf_party_names:
if client_name and pf_party in client_name:
reverse_party_match = True
break
elif client_original and pf_party in client_original:
reverse_party_match = True
break
# 判断是否冲突:
# 1. 正向匹配或反向匹配都成功
# 2. 预立案中委托人和相对方是同一个人,且这个人在立项的委托人或相对方信息中
# 3. 立项中委托人和相对方是同一个人,且这个人在预立案的委托人或相对方信息中
is_conflict = False
if (client_match and party_match) or (reverse_client_match and reverse_party_match):
is_conflict = True
elif is_same_person_in_prefiling:
# 预立案中委托人和相对方是同一个人,检查这个共同的名字是否在立项信息中
common_names = set(pf_client_names) & set(pf_party_names)
for common_name in common_names:
if (client_name and common_name in client_name) or (party_name and common_name in party_name) or \
(client_original and common_name in client_original) or (party_original and common_name in party_original):
is_conflict = True
break
elif is_same_person_in_project:
# 立项中委托人和相对方是同一个人,检查这个共同的名字是否在预立案信息中
if (client_info or client_name) and pf_client_names:
for pf_client in pf_client_names:
if (client_name and pf_client in client_name) or (party_name and pf_client in party_name) or \
(client_original and pf_client in client_original) or (party_original and pf_client in party_original):
is_conflict = True
if (client_name and pf_client in client_name) or (client_original and pf_client in client_original):
client_match = True
break
if not is_conflict:
for pf_party in pf_party_names:
if (client_name and pf_party in client_name) or (party_name and pf_party in party_name) or \
(client_original and pf_party in client_original) or (party_original and pf_party in party_original):
is_conflict = True
break
if is_conflict:
party_match = False
if (party_info or party_name) and pf_party_names:
for pf_party in pf_party_names:
if (party_name and pf_party in party_name) or (party_original and pf_party in party_original):
party_match = True
break
if client_match or party_match:
matched_prefilings.append({
'id': pf.id,
'times': pf.times,
@@ -289,35 +197,32 @@ def search_related_records(client_info, party_info, exclude_project_id=None):
'party_username': pf.party_username,
'description': pf.description
})
result['prefiling_conflicts'] = matched_prefilings
# 检索立项表(排除当前正在创建的记录)- 只查找委托人和相对方匹配的记录(冲突数据)
if client_info and party_info:
project_records = ProjectRegistration.objects.filter(is_deleted=False)
if exclude_project_id:
project_records = project_records.exclude(id=exclude_project_id)
# 委托人和相对方都匹配,或者相对方和委托人都匹配(可能是顺序相反)
# 支持姓名和完整信息匹配
project_q = Q()
if client_name and party_name:
project_q |= (Q(client_info__icontains=client_name) & Q(party_info__icontains=party_name))
project_q |= (Q(client_info__icontains=party_name) & Q(party_info__icontains=client_name))
if client_original and party_original:
project_q |= (Q(client_info__icontains=client_original[:50]) & Q(party_info__icontains=party_original[:50]))
project_q |= (Q(client_info__icontains=party_original[:50]) & Q(party_info__icontains=client_original[:50]))
if client_id_number and party_id_number:
project_q |= (Q(client_info__icontains=client_id_number) & Q(party_info__icontains=party_id_number))
project_q |= (Q(client_info__icontains=party_id_number) & Q(party_info__icontains=client_id_number))
if project_q:
project_records = project_records.filter(project_q)
# 获取项目列表最多10条
# 检索立项表 - 冲突规则:当前委托人只匹配历史 client_info当前相对方匹配历史 party_info任一匹配即冲突
project_records = ProjectRegistration.objects.filter(is_deleted=False)
if exclude_project_id:
project_records = project_records.exclude(id=exclude_project_id)
project_q = Q()
if client_info or client_name:
if client_name:
project_q |= Q(client_info__icontains=client_name)
if client_original:
project_q |= Q(client_info__icontains=client_original[:50])
if client_id_number:
project_q |= Q(client_info__icontains=client_id_number)
if party_info or party_name:
if party_name:
project_q |= Q(party_info__icontains=party_name)
if party_original:
project_q |= Q(party_info__icontains=party_original[:50])
if party_id_number:
project_q |= Q(party_info__icontains=party_id_number)
if project_q:
project_records = project_records.filter(project_q)
project_list = list(project_records[:10].values('id', 'ContractNo', 'times', 'type', 'client_info', 'party_info'))
result['project_conflicts'] = project_list
# 检索投标表 - 投标表只有BiddingUnit字段需要检查是否包含委托人或相对方信息
# BiddingUnit可能同时包含委托人和相对方或者只包含其中一方
bid_records = Bid.objects.filter(is_deleted=False)
@@ -4366,57 +4271,32 @@ def conflict_search(client_info=None, party_info=None, undertaker=None, bidding_
except (json.JSONDecodeError, TypeError, AttributeError):
pf_party_names = [pf.party_username.strip()] if pf.party_username else []
# 检查委托人匹配(支持姓名和身份证号匹配
# 冲突规则:当前委托人只与历史「委托人」匹配,当前相对方只与历史「相对方」匹配
# 检查委托人匹配(仅匹配历史记录的委托人)
if client_info or client_name:
for pf_client in pf_client_names:
# 匹配姓名
if client_name and pf_client in client_name:
is_match = True
match_reason.append(f"委托人姓名匹配:{pf_client}")
break
# 匹配完整信息
if client_original and pf_client in client_original:
is_match = True
match_reason.append(f"委托人信息匹配:{pf_client}")
break
# 检查相对方是否匹配委托人
for pf_party in pf_party_names:
if client_name and pf_party in client_name:
is_match = True
match_reason.append(f"相对方与委托人姓名匹配:{pf_party}")
break
if client_original and pf_party in client_original:
is_match = True
match_reason.append(f"相对方与委托人信息匹配:{pf_party}")
break
# 检查相对方匹配(支持姓名和身份证号匹配)
# 检查相对方匹配(仅匹配历史记录的相对方)
if party_info or party_name:
for pf_party in pf_party_names:
# 匹配姓名
if party_name and pf_party in party_name:
is_match = True
match_reason.append(f"相对方姓名匹配:{pf_party}")
break
# 匹配完整信息
if party_original and pf_party in party_original:
is_match = True
match_reason.append(f"相对方信息匹配:{pf_party}")
break
# 检查委托人是否匹配相对方
for pf_client in pf_client_names:
if party_name and pf_client in party_name:
is_match = True
match_reason.append(f"委托人与相对方姓名匹配:{pf_client}")
break
if party_original and pf_client in party_original:
is_match = True
match_reason.append(f"委托人与相对方信息匹配:{pf_client}")
break
# 检查身份证号匹配(如果提供了身份证号)
# 检查身份证号匹配:委托人身份证只查历史委托人,相对方身份证只查历史相对方
if client_id_number:
# 检查预立案中的身份证号
try:
client_data = json.loads(pf.client_username) if isinstance(pf.client_username, str) else pf.client_username
if isinstance(client_data, list):
@@ -4434,9 +4314,7 @@ def conflict_search(client_info=None, party_info=None, undertaker=None, bidding_
match_reason.append(f"委托人身份证号匹配")
except (json.JSONDecodeError, TypeError, AttributeError):
pass
if party_id_number:
# 检查预立案中的身份证号
try:
party_data = json.loads(pf.party_username) if isinstance(pf.party_username, str) else pf.party_username
if isinstance(party_data, list):
@@ -4486,64 +4364,28 @@ def conflict_search(client_info=None, party_info=None, undertaker=None, bidding_
is_match = False
match_reason = []
# 检查委托人/相对方匹配(支持姓名和身份证号匹配)
if client_info or client_name:
if pro.client_info:
# 匹配姓名
if client_name and client_name in pro.client_info:
is_match = True
match_reason.append("委托人姓名匹配")
# 匹配完整信息
elif client_original and client_original in pro.client_info:
is_match = True
match_reason.append("委托人信息匹配")
# 匹配身份证号
elif client_id_number and client_id_number in pro.client_info:
is_match = True
match_reason.append("委托人身份证号匹配")
if pro.party_info:
# 匹配姓名
if client_name and client_name in pro.party_info:
is_match = True
match_reason.append("相对方与委托人姓名匹配")
# 匹配完整信息
elif client_original and client_original in pro.party_info:
is_match = True
match_reason.append("相对方与委托人信息匹配")
# 匹配身份证号
elif client_id_number and client_id_number in pro.party_info:
is_match = True
match_reason.append("相对方与委托人身份证号匹配")
# 冲突规则:当前委托人只与历史「委托人」匹配,当前相对方只与历史「相对方」匹配
if (client_info or client_name) and pro.client_info:
if client_name and client_name in pro.client_info:
is_match = True
match_reason.append("委托人姓名匹配")
elif client_original and client_original in pro.client_info:
is_match = True
match_reason.append("委托人信息匹配")
elif client_id_number and client_id_number in pro.client_info:
is_match = True
match_reason.append("委托人身份证号匹配")
if party_info or party_name:
if pro.party_info:
# 匹配姓名
if party_name and party_name in pro.party_info:
is_match = True
match_reason.append("相对方姓名匹配")
# 匹配完整信息
elif party_original and party_original in pro.party_info:
is_match = True
match_reason.append("相对方信息匹配")
# 匹配身份证号
elif party_id_number and party_id_number in pro.party_info:
is_match = True
match_reason.append("相对方身份证号匹配")
if pro.client_info:
# 匹配姓名
if party_name and party_name in pro.client_info:
is_match = True
match_reason.append("委托人与相对方姓名匹配")
# 匹配完整信息
elif party_original and party_original in pro.client_info:
is_match = True
match_reason.append("委托人与相对方信息匹配")
# 匹配身份证号
elif party_id_number and party_id_number in pro.client_info:
is_match = True
match_reason.append("委托人与相对方身份证号匹配")
# 检查负责人匹配
if undertaker and pro.responsiblefor: