diff --git a/User/views.py b/User/views.py index 812560f..628ca19 100644 --- a/User/views.py +++ b/User/views.py @@ -1424,40 +1424,45 @@ class roxyExhibition(APIView): exclude_project_id=project_id ) - # 处理冲突记录:将 client_info、party_info、BiddingUnit 字段从 JSON 字符串解析为列表 - # 直接返回原始列表,不提取 name 字段 + # 处理冲突记录:将 client_info、party_info、BiddingUnit、client_username、party_username 从 JSON 解析为列表, + # 并归一化为前端期望的格式 [{ 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): - """将记录中的 JSON 字符串字段解析为列表,不提取 name""" + """将记录中的 JSON 字符串字段解析为列表,并归一化为前端格式""" processed = [] for record in records: new_record = dict(record) - # 处理 client_info 字段:如果是 JSON 字符串,解析为列表 - if 'client_info' in new_record and new_record['client_info']: - try: - if isinstance(new_record['client_info'], str): - parsed = json.loads(new_record['client_info']) - if isinstance(parsed, list): - 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 # 解析失败,保持原值 + 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 @@ -1506,35 +1511,42 @@ class roxyExhibition(APIView): itme["content"] = content_val.rstrip() + ",申请人:" + submitter if bid and bid.BiddingUnit: 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): - """将记录中的 JSON 字符串字段解析为列表,与立项展示逻辑一致""" processed = [] for record in records: new_record = dict(record) - if 'client_info' in new_record and new_record['client_info']: - try: - if isinstance(new_record['client_info'], str): - parsed = json.loads(new_record['client_info']) - if isinstance(parsed, list): - new_record['client_info'] = parsed - 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 + 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_bid(new_record[key]) + if normalized is not None: + new_record[key] = normalized processed.append(new_record) return processed itme["prefiling_conflicts"] = parse_json_fields_bid(conflict_result.get('prefiling_conflicts', [])) diff --git a/business/views.py b/business/views.py index 70921c5..ff4fd77 100644 --- a/business/views.py +++ b/business/views.py @@ -4626,23 +4626,62 @@ class ConflictSearch(APIView): exclude_project_id=exclude_project_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']) + \ - len(conflict_result['project_conflicts']) + \ - len(conflict_result['bid_conflicts']) - + total_conflicts = len(prefiling) + len(project) + len(bid) return Response({ 'message': '检索成功', 'code': 0, 'data': { 'total_conflicts': total_conflicts, - 'prefiling_conflicts_count': len(conflict_result['prefiling_conflicts']), - 'project_conflicts_count': len(conflict_result['project_conflicts']), - 'bid_conflicts_count': len(conflict_result['bid_conflicts']), - 'prefiling_conflicts': conflict_result['prefiling_conflicts'], - 'project_conflicts': conflict_result['project_conflicts'], - 'bid_conflicts': conflict_result['bid_conflicts'] + 'prefiling_conflicts_count': len(prefiling), + 'project_conflicts_count': len(project), + 'bid_conflicts_count': len(bid), + 'prefiling_conflicts': prefiling, + 'project_conflicts': project, + 'bid_conflicts': bid } }, status=status.HTTP_200_OK)