优化利益冲突

This commit is contained in:
ddrwode
2026-02-05 16:44:17 +08:00
parent 64483a8ec7
commit de2d87553d
2 changed files with 117 additions and 66 deletions

View File

@@ -1424,40 +1424,45 @@ class roxyExhibition(APIView):
exclude_project_id=project_id exclude_project_id=project_id
) )
# 处理冲突记录:将 client_info、party_info、BiddingUnit 字段从 JSON 字符串解析为列表 # 处理冲突记录:将 client_info、party_info、BiddingUnit、client_username、party_username 从 JSON 解析为列表
# 直接返回原始列表,不提取 name 字段 # 并归一化为前端期望的格式 [{ index, name, idNumber }, ...](兼容前端 isValidFormat 与查看冲突展示)
def _normalize_person_list(val):
"""将 JSON 字符串或列表归一化为 [{ index, name, idNumber }, ...],兼容前端;解析失败返回 None 以保留原值"""
if not val:
return []
try:
lst = json.loads(val) if isinstance(val, str) else val
if not isinstance(lst, list):
return None
out = []
for i, item in enumerate(lst):
if not isinstance(item, dict):
continue
name = item.get('name') or item.get('name_original') or ''
id_num = item.get('idNumber') or item.get('id_number') or ''
if not isinstance(name, str):
name = str(name) if name else ''
if not isinstance(id_num, str):
id_num = str(id_num) if id_num else ''
out.append({
'index': item.get('index') if isinstance(item.get('index'), (int, float)) else (i + 1),
'name': name,
'idNumber': id_num
})
return out
except (json.JSONDecodeError, TypeError, ValueError):
return None
def parse_json_fields(records): def parse_json_fields(records):
"""将记录中的 JSON 字符串字段解析为列表,不提取 name""" """将记录中的 JSON 字符串字段解析为列表,并归一化为前端格式"""
processed = [] processed = []
for record in records: for record in records:
new_record = dict(record) new_record = dict(record)
# 处理 client_info 字段:如果是 JSON 字符串,解析为列表 for key in ('client_info', 'party_info', 'BiddingUnit', 'client_username', 'party_username'):
if 'client_info' in new_record and new_record['client_info']: if key not in new_record or not new_record[key]:
try: continue
if isinstance(new_record['client_info'], str): normalized = _normalize_person_list(new_record[key])
parsed = json.loads(new_record['client_info']) if normalized is not None:
if isinstance(parsed, list): new_record[key] = normalized
new_record['client_info'] = parsed
except (json.JSONDecodeError, TypeError, ValueError):
pass # 解析失败,保持原值
# 处理 party_info 字段:如果是 JSON 字符串,解析为列表
if 'party_info' in new_record and new_record['party_info']:
try:
if isinstance(new_record['party_info'], str):
parsed = json.loads(new_record['party_info'])
if isinstance(parsed, list):
new_record['party_info'] = parsed
except (json.JSONDecodeError, TypeError, ValueError):
pass # 解析失败,保持原值
# 处理 BiddingUnit 字段:如果是 JSON 字符串,解析为列表
if 'BiddingUnit' in new_record and new_record['BiddingUnit']:
try:
if isinstance(new_record['BiddingUnit'], str):
parsed = json.loads(new_record['BiddingUnit'])
if isinstance(parsed, list):
new_record['BiddingUnit'] = parsed
except (json.JSONDecodeError, TypeError, ValueError):
pass # 解析失败,保持原值
processed.append(new_record) processed.append(new_record)
return processed return processed
@@ -1506,35 +1511,42 @@ class roxyExhibition(APIView):
itme["content"] = content_val.rstrip() + ",申请人:" + submitter itme["content"] = content_val.rstrip() + ",申请人:" + submitter
if bid and bid.BiddingUnit: if bid and bid.BiddingUnit:
conflict_result = conflict_search(bidding_unit=bid.BiddingUnit, exclude_bid_id=bid_id) conflict_result = conflict_search(bidding_unit=bid.BiddingUnit, exclude_bid_id=bid_id)
# 与立项登记共用同一套解析与归一化逻辑(预立案含 client_username/party_username立项/投标含 client_info/party_info/BiddingUnit
def _normalize_person_list_bid(val):
if not val:
return []
try:
lst = json.loads(val) if isinstance(val, str) else val
if not isinstance(lst, list):
return None
out = []
for i, item in enumerate(lst):
if not isinstance(item, dict):
continue
name = item.get('name') or item.get('name_original') or ''
id_num = item.get('idNumber') or item.get('id_number') or ''
if not isinstance(name, str):
name = str(name) if name else ''
if not isinstance(id_num, str):
id_num = str(id_num) if id_num else ''
out.append({
'index': item.get('index') if isinstance(item.get('index'), (int, float)) else (i + 1),
'name': name,
'idNumber': id_num
})
return out
except (json.JSONDecodeError, TypeError, ValueError):
return None
def parse_json_fields_bid(records): def parse_json_fields_bid(records):
"""将记录中的 JSON 字符串字段解析为列表,与立项展示逻辑一致"""
processed = [] processed = []
for record in records: for record in records:
new_record = dict(record) new_record = dict(record)
if 'client_info' in new_record and new_record['client_info']: for key in ('client_info', 'party_info', 'BiddingUnit', 'client_username', 'party_username'):
try: if key not in new_record or not new_record[key]:
if isinstance(new_record['client_info'], str): continue
parsed = json.loads(new_record['client_info']) normalized = _normalize_person_list_bid(new_record[key])
if isinstance(parsed, list): if normalized is not None:
new_record['client_info'] = parsed new_record[key] = normalized
except (json.JSONDecodeError, TypeError, ValueError):
pass
if 'party_info' in new_record and new_record['party_info']:
try:
if isinstance(new_record['party_info'], str):
parsed = json.loads(new_record['party_info'])
if isinstance(parsed, list):
new_record['party_info'] = parsed
except (json.JSONDecodeError, TypeError, ValueError):
pass
if 'BiddingUnit' in new_record and new_record['BiddingUnit']:
try:
if isinstance(new_record['BiddingUnit'], str):
parsed = json.loads(new_record['BiddingUnit'])
if isinstance(parsed, list):
new_record['BiddingUnit'] = parsed
except (json.JSONDecodeError, TypeError, ValueError):
pass
processed.append(new_record) processed.append(new_record)
return processed return processed
itme["prefiling_conflicts"] = parse_json_fields_bid(conflict_result.get('prefiling_conflicts', [])) itme["prefiling_conflicts"] = parse_json_fields_bid(conflict_result.get('prefiling_conflicts', []))

View File

@@ -4626,23 +4626,62 @@ class ConflictSearch(APIView):
exclude_project_id=exclude_project_id, exclude_project_id=exclude_project_id,
exclude_bid_id=exclude_bid_id exclude_bid_id=exclude_bid_id
) )
# 归一化冲突记录为前端期望格式 [{ index, name, idNumber }, ...](预立案用 client_username/party_username立项用 client_info/party_info投标用 BiddingUnit
def _normalize_person_list(val):
if not val:
return []
try:
lst = json.loads(val) if isinstance(val, str) else val
if not isinstance(lst, list):
return None
out = []
for i, item in enumerate(lst):
if not isinstance(item, dict):
continue
name = item.get('name') or item.get('name_original') or ''
id_num = item.get('idNumber') or item.get('id_number') or ''
if not isinstance(name, str):
name = str(name) if name else ''
if not isinstance(id_num, str):
id_num = str(id_num) if id_num else ''
out.append({
'index': item.get('index') if isinstance(item.get('index'), (int, float)) else (i + 1),
'name': name,
'idNumber': id_num
})
return out
except (json.JSONDecodeError, TypeError, ValueError):
return None
def _normalize_conflict_records(records):
processed = []
for record in records:
new_record = dict(record)
for key in ('client_info', 'party_info', 'BiddingUnit', 'client_username', 'party_username'):
if key not in new_record or not new_record[key]:
continue
normalized = _normalize_person_list(new_record[key])
if normalized is not None:
new_record[key] = normalized
processed.append(new_record)
return processed
prefiling = _normalize_conflict_records(conflict_result['prefiling_conflicts'])
project = _normalize_conflict_records(conflict_result['project_conflicts'])
bid = _normalize_conflict_records(conflict_result['bid_conflicts'])
# 统计冲突数量 # 统计冲突数量
total_conflicts = len(conflict_result['prefiling_conflicts']) + \ total_conflicts = len(prefiling) + len(project) + len(bid)
len(conflict_result['project_conflicts']) + \
len(conflict_result['bid_conflicts'])
return Response({ return Response({
'message': '检索成功', 'message': '检索成功',
'code': 0, 'code': 0,
'data': { 'data': {
'total_conflicts': total_conflicts, 'total_conflicts': total_conflicts,
'prefiling_conflicts_count': len(conflict_result['prefiling_conflicts']), 'prefiling_conflicts_count': len(prefiling),
'project_conflicts_count': len(conflict_result['project_conflicts']), 'project_conflicts_count': len(project),
'bid_conflicts_count': len(conflict_result['bid_conflicts']), 'bid_conflicts_count': len(bid),
'prefiling_conflicts': conflict_result['prefiling_conflicts'], 'prefiling_conflicts': prefiling,
'project_conflicts': conflict_result['project_conflicts'], 'project_conflicts': project,
'bid_conflicts': conflict_result['bid_conflicts'] 'bid_conflicts': bid
} }
}, status=status.HTTP_200_OK) }, status=status.HTTP_200_OK)