"""Rebuild the runtime whitelist from the final UI tags, never legacy names.""" import hashlib import json from pathlib import Path from openpyxl import load_workbook def build_taxonomy(source): source = Path(source) workbook = load_workbook(source, read_only=True, data_only=True) try: sheet = workbook['Sheet1'] rows = iter(sheet.values) header = next(rows) category_index = header.index('TAG_CATEGORY') tag_index = header.index('最终使用TAG') categories = {} count = 0 for row in rows: if not any(value is not None for value in row): continue category, tag = row[category_index], row[tag_index] if not all(isinstance(value, str) and value.strip() == value and value for value in (category, tag)): raise ValueError('invalid_final_tag_row') tags = categories.setdefault(category, []) if tag not in tags: tags.append(tag) count += 1 return {'source': source.as_posix(), 'sha256': hashlib.sha256(source.read_bytes()).hexdigest(), 'sheet': 'Sheet1', 'tag_column': '最终使用TAG', 'row_count': count, 'categories': categories} finally: workbook.close() if __name__ == '__main__': snapshot = build_taxonomy(Path('docs/法人标签表.xlsx')) Path(__file__).with_name('taxonomy.json').write_text( json.dumps(snapshot, ensure_ascii=False, indent=2) + '\n', encoding='utf-8')