# -*- coding: utf-8 -*- """票 05 收尾:请求示例节残留占位标记处置 + 全量验证重跑(修 V7 路径/解析)。""" from __future__ import annotations import io import json import re import sys from pathlib import Path sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8') A4 = Path('D:/code/crm-api-docs/A4 客户管理') # ---------- 1) 请求示例标记行处置 ---------- FIX_TRUE = '// 请求参数(E2E 实测载荷)' # 原行含「E2E 实测值注入」:载荷本就是实测真值 FIX_SAMPLE = '// 请求参数示例' # 原行为编造示例值 fixed_t = fixed_s = 0 for p in sorted(A4.rglob('*.bru')): if p.name == 'folder.bru': continue txt = p.read_text(encoding='utf-8') if '非真实返回' not in txt: continue lines = txt.splitlines() hit = False for i, l in enumerate(lines): if '非真实返回' not in l: continue assert l.strip().startswith('// 示例数据'), f'非独立标记行 {p.relative_to(A4)}:{i+1}: {l}' if 'E2E 实测值注入' in l: lines[i] = l.replace(l.strip(), FIX_TRUE) fixed_t += 1 else: lines[i] = l.replace(l.strip(), FIX_SAMPLE) fixed_s += 1 hit = True if hit: p.write_text('\n'.join(lines) + ('\n' if txt.endswith('\n') else ''), encoding='utf-8', newline='') print(f'[F] 请求示例标记行处置:实测载荷版 {fixed_t} 行、编造示例版 {fixed_s} 行') # ---------- 2) 全量验证 ---------- print('== 验证 ==') all_files = [p for p in A4.rglob('*.bru') if p.name != 'folder.bru'] ph = [str(p.relative_to(A4)) for p in all_files if '非真实返回' in p.read_text(encoding='utf-8')] print(f'[V1] 「非真实返回」残留 = {len(ph)}(目标 0){ph if ph else ""}') sec_bad, tv = [], 0 for p in all_files: t = p.read_text(encoding='utf-8') n = len(re.findall(r'^\s*## 响应示例', t, re.M)) if n != 1: sec_bad.append(f'{p.relative_to(A4)} ×{n}') if 'E2E 实测真值' in t: tv += 1 print(f'[V2] 响应示例节≠1 = {len(sec_bad)}(目标 0){sec_bad if sec_bad else ""}') print(f'[V3] 含真值标记 = {tv}/{len(all_files)}') n_ec = sum(1 for p in all_files if '## 错误码' in p.read_text(encoding='utf-8')) print(f'[V4] 错误码节 = {n_ec}(基线 78)') keys_ok = sum(1 for p in all_files if re.search(r'^\s*`\s*(GET|POST)\s+(/[^\s`]+)\s*`', p.read_text(encoding='utf-8'), re.M)) print(f'[V5] 对账钥匙完好 = {keys_ok}/{len(all_files)}') bom = [str(p.relative_to(A4)) for p in all_files if p.read_bytes()[:3] == b'\xef\xbb\xbf'] print(f'[V6] BOM = {len(bom)}(目标 0){bom if bom else ""}') # V7 (b) 退化端点抽查:写回后 data 关键字段非空 SPOT = { '客户交割/客户分配.bru': 'failures', '客户公海/失败疑似重复明细.bru': 'data-list', '我的客户/客户导入/失败疑似重复明细.bru': 'data-list', '客户详情/联系人图谱/图谱全量读.bru': 'nodes', '客户详情/联系人/快速添加联系人.bru': 'failedRows', '我的客户/快速创建客户.bru': 'similarHits', '客户详情/联系人/页内批量编辑.bru': 'successCount', } for rel, field in SPOT.items(): t = (A4 / rel).read_text(encoding='utf-8') mm = re.search(r'## 响应示例\s*\n\s*\n\s*// 示例数据(E2E 实测真值)[^\n]*\n\s*```json\n(.*?)\n\s*```', t, re.S) ok = '?' if mm: try: payload = json.loads(mm.group(1)) d = payload.get('data') if field == 'data-list': ok = '非空' if isinstance(d, list) and len(d) >= 1 else f'退化:{str(d)[:50]}' elif isinstance(d, dict): v = d.get(field) ok = '非空' if v else f'空:{field}={v}' else: ok = f'形态异常:{str(d)[:50]}' except Exception as e: ok = f'解析失败:{e}' else: ok = '⚠ 未匹配响应示例块' print(f'[V7] {rel}: {field} {ok}') for rel in ['客户公海/下载导入模板.bru', '我的客户/客户导入/下载导入模板.bru', '客户详情/联系人导入/下载导入模板.bru']: t = (A4 / rel).read_text(encoding='utf-8') print(f'[V8] {rel}: 二进制说明 {"✓" if "二进制文件流" in t else "✗"}') for rel in ['客户总览/workspace 列表分页.bru', '我的客户/workspace 列表分页.bru', '客户公海/workspace 列表分页.bru']: t = (A4 / rel).read_text(encoding='utf-8') print(f'[V9] {rel}: total 注记 {"✓" if "实测 total=" in t else "✗"}') print('== 票 05 收尾完成 ==')