| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869 |
- """Summarize exact product identity, observed likes and task-specific bills."""
- from collections import Counter
- import json
- from pathlib import Path
- import re
- PLACEHOLDER = re.compile(r'未填写评价|该用户觉得商品|此用户没有填写|系统默认')
- def payload(response):
- return response.get('structuredContent', {})
- def sample(folder):
- reservation = json.loads((folder / 'reservation.json').read_text(encoding='utf-8'))
- result_file = folder / 'mcp-result.json'
- if not result_file.is_file():
- return {'label': folder.name, 'status': 'pending', 'reservationCny': 0.30}
- result = payload(json.loads(result_file.read_text(encoding='utf-8'))['response'])
- family = reservation['endpoint'].split('.')[0]
- data = result.get('data', {}).get('result', {})
- rows = data.get('data', []) if family == 'jd' else data.get('comments', [])
- matched = []
- for index, row in enumerate(rows):
- iid = str(row.get('productId')) if family == 'jd' else str(row.get('auction', {}).get('aucNumId'))
- rid = str(row.get('commentId')) if family == 'jd' else str(row.get('rateId'))
- text = row.get('commentData', '') if family == 'jd' else row.get('content', '')
- likes = row.get('praiseCnt') if family == 'jd' else row.get('likeCount')
- matched.append({'itemId': iid, 'reviewId': rid, 'content': text, 'likes': likes,
- 'isPlaceholder': bool(PLACEHOLDER.search(text)), 'index': index,
- 'matchesRequestedProduct': iid == reservation['params']['itemId']})
- usages = []
- for file in sorted(folder.glob('usage-*.json')):
- data_usage = payload(json.loads(file.read_text(encoding='utf-8'))['response'])
- if data_usage.get('status') == 'ok':
- usages.append(data_usage)
- bill = usages[-1].get('summary') if usages else None
- billed = bool(bill and bill.get('billedCalls', 0))
- return {'label': folder.name, 'productId': family + ':' + reservation['params']['itemId'],
- 'page': reservation['params']['page'], 'order': reservation['params'].get('orderType', 'upstream_default'),
- 'status': result.get('status'), 'httpStatus': result.get('summary', {}).get('httpStatus'),
- 'sourceTime': result.get('summary', {}).get('recordTime'),
- 'historicalCountText': reservation.get('historicalCountDisplay'),
- 'upstreamCounts': data.get('pageInfo') if family == 'jd' else {k: data.get(k) for k in
- ('total', 'totalFuzzy', 'maxPage', 'hasNextPage')},
- 'returnedReviews': len(rows), 'matchingReviews': sum(r['matchesRequestedProduct'] for r in matched),
- 'meaningfulMatchingReviews': sum(r['matchesRequestedProduct'] and not r['isPlaceholder'] for r in matched),
- 'positiveLikeMatchingReviews': sum(r['matchesRequestedProduct'] and not r['isPlaceholder'] and
- type(r['likes']) is int and r['likes'] > 0 for r in matched),
- 'likeDistribution': dict(Counter(str(r['likes']) for r in matched)),
- 'maxObservedLikes': max((r['likes'] for r in matched if type(r['likes']) is int), default=None),
- 'billing': bill, 'confirmedCostCny': bill.get('costCny', 0) if bill else 0,
- 'unsettledReservationCny': 0 if billed else 0.30,
- 'usageTraceId': reservation['usageTraceId'], 'records': matched}
- def summarize(root):
- records = [sample(folder) for folder in sorted(Path(root).iterdir()) if (folder / 'reservation.json').is_file()]
- return {'collectionCalls': len(records), 'successfulCalls': sum(r['status'] == 'ok' for r in records),
- 'confirmedCostCny': round(sum(r.get('confirmedCostCny', 0) for r in records), 2),
- 'unsettledReservationCny': round(sum(r.get('unsettledReservationCny', r.get('reservationCny', 0)) for r in records), 2),
- 'records': records}
- if __name__ == '__main__':
- report = summarize('work/product-reviews/live-r1')
- print(json.dumps({**report, 'records': [{k: v for k, v in row.items() if k != 'records'} for row in report['records']]},
- ensure_ascii=False, indent=2))
|