#!/usr/bin/env python3 """ 互动组件类型匹配器 从剧本中的中文类型名 → cType 英文标识 """ import json # ============ 中互动组件类型映射(27种) ============ MID_INTERACTION_TYPES = { "对话互动": {"cType": "mid_sentence_dialogue", "bitable": "GH0hbBT0ZavkCesaVQ7c40Zfnub"}, "对话朗读": {"cType": "mid_dialog_repeat", "bitable": "MuwubKXoSaJe55sO4k9c63VSnmh"}, "对话表达": {"cType": "mid_dialog_express", "bitable": "IC2kbvgP0aLrj7sfzZicIozZn1e"}, "对话选读": {"cType": "mid_dialog_select", "bitable": "GsNEbjVVYarWqpsNanTcf8UnnPf"}, "对话选择": {"cType": "mid_dialog_choose", "bitable": "MsETbgiUAaG8h4sct0ycTOzGnfb"}, "对话挖空": {"cType": "mid_dialog_fillin", "bitable": "X6nHbUztFaGY5tsSHnKcmeJtnm5"}, "对话组句": {"cType": "mid_dialog_sentence", "bitable": "OfgZbhomiaYj2psBNhuc7THMnF9"}, "信息描写": {"cType": "mid_message_trace", "bitable": "Nd8cb0tnKankIHsVgw1caL1Xn3f"}, "信息拼词": {"cType": "mid_message_spell", "bitable": "X0sPb1KERarvocs4rb3cK35AnFg"}, "信息组句": {"cType": "mid_message_combine", "bitable": "TXYobOAuaakk6KslHp9caUB7nXa"}, "信息补词": {"cType": "mid_message_fillin", "bitable": "FxwMb8MJmarcRsso2tQcV8thn5g"}, "信息填词": {"cType": "mid_message_word", "bitable": "ElRebtQe3aeCyOsRjg6cEniznwg"}, "信息填句": {"cType": "mid_message_sentence", "bitable": "CNFgbIIszaPWXfsekt7cCZjHnVh"}, "物品互动": {"cType": "mid_vocab_item", "bitable": "BD9Wbi2l9akojasifEvcJG06n3g"}, "图片互动": {"cType": "mid_vocab_image", "bitable": "VJ1kb9xp8amX8PskntmcLhjpnQe"}, "图片单选": {"cType": "mid_image_choose", "bitable": "XyIVbYciraBkoasJtV1c3N5Gnhh"}, "图片多选": {"cType": "mid_image_multiple", "bitable": "XZo5bwagdau3VvsTDL9cJPrInQd"}, "图片有序": {"cType": "mid_image_sequence", "bitable": "BZWebQROpagkJ0sxArGcsBjwnCU"}, "图片拖拽": {"cType": "mid_image_drag", "bitable": "Qqq9bVv19aH6LisRrsVcvf6xnqe"}, "材料互动": {"cType": "mid_sentence_material", "bitable": "Yd84buD91aGxyqstpXqceftHnvM"}, "指令互动": {"cType": "mid_vocab_instruction", "bitable": "UorxbVCNYaqpx3sOUdTcF6bUnAh"}, "挖空互动": {"cType": "mid_grammar_cloze", "bitable": "TaU5baUEEagdlusiWXnc7nrGn5b"}, "组句互动": {"cType": "mid_grammar_sentence", "bitable": "X5w7bWQXGaWu3dsMEE1c3Tp8nBb"}, "填词互动": {"cType": "mid_vocab_fillBlank", "bitable": "TtjlbkLFgaDi6hsriHZcHBJnnRH"}, "语音互动": {"cType": "mid_sentence_voice", "bitable": "Qd2kbHD8has9mys3UhWcJbMznrf"}, "造句互动": {"cType": "mid_sentence_makeSentence", "bitable": "WfHMbzBYPau6hZsmFD0cBwWuncc"}, "发音互动": {"cType": "mid_pron_pron", "bitable": "CeH5bO3FhaG5cNsPZ4Xc72axnrb"}, } # ============ 核心互动组件类型映射(待完善cType) ============ CORE_INTERACTION_TYPES = { "合作阅读": {"cType": "core_reading_order", "bitable_wiki": "H6DJweNkpigCbak2Y5LcTZ8Vnfb"}, "看图选词": {"cType": "core_reading_imageDrag", "bitable_wiki": "MVo7wugWfimJPIkxhJCcqppFnyf", "db_table": "tblKl9CGmARjpw1O"}, "口语快答": {"cType": "core_speaking_reply", "bitable_wiki": "TSwcw0nFmi21khkpUndchNMsn6f", "db_table": "tbl4Qg8d45O58Cqf"}, "口语独白": {"cType": None, "bitable_wiki": "G20HwcF1uideNokLsHWcBs3znvg"}, "口语妙问": {"cType": "core_speaking_inquiry", "bitable_wiki": "GJUVwNSEkis3EXkrVj0ccbqdn8c", "db_table": "tbl1Q68oopST9Mel"}, "看图说话": {"cType": "core_speaking_image", "bitable_wiki": "KBOXwzVHfin6ORkKbA3c3eWEnoh", "db_table": "tblvi5HF0uSU2GNo"}, "口语探讨": {"cType": None, "bitable_wiki": "HoidwhEBWiWjaokQnz0cHbhTn6e"}, "合作听力": {"cType": "core_listening_order", "bitable_wiki": "FrxtwNRQDizqiikPkATcBzTCnYe", "db_table": "tblBuFU6wVKdBh8B"}, "听力拖拽": {"cType": "core_listening_drag", "bitable_wiki": "K3QrwQnWqiPBm1krhnNcWDTqnhe", "db_table": "tblOOAsgYoZWsTGJ"}, "听力选择": {"cType": "core_listening_choose", "bitable_wiki": "Kwrcw6A4jip2sxkdLn4czd1knvf", "db_table": "tblH4xNpAmKJ7gEq"}, "写作互动": {"cType": None, "bitable_wiki": "DVkcwVr2giswTckcgD0cpHwNnv2"}, "看图组句": {"cType": "core_writing_imgMakeSentence", "bitable_wiki": "BkmtwUBwMiHd5Ak7VS6ccE9SnHd", "db_table": "tblpILmFc9ec17DY"}, "看图撰写": {"cType": "core_writing_imgWrite", "bitable_wiki": "KwPHwnaqdiWlvNkDm5fcFreDnQh", "db_table": "tblAMaM3g7500Lmm"}, "邮件组句": {"cType": "core_writing_questionMakeSentence", "bitable_wiki": "M5oTwUP6wiImC4kVJU8cRYnfnyf", "db_table": "tblhS2nk05UsObPA"}, "邮件撰写": {"cType": "core_writing_questionWrite", "bitable_wiki": "Brn0wldKYizsLZkBqK6clp1tnKd", "db_table": "tblFWw079OkhVlvk"}, } def match_component_type(type_text: str) -> dict: """ 从剧本中的类型文本匹配组件类型。 Args: type_text: 剧本【类型】列的文本值,如 "对话朗读"、"对话挖空-配图" Returns: { "category": "mid" | "core", # 中互动 or 核心互动 "cType": "mid_dialog_repeat", # 英文类型标识 "type_name": "对话朗读", # 中文基础类型名 "has_image": False, # 是否为配图变体 "bitable": "MuwubKXoSaJe55sO4k9c63VSnmh", # 对应多维表格token "db_table": "middle_interaction_component", # 目标数据库表 } Raises: ValueError: 未知组件类型 """ text = type_text.strip() # 检查是否有配图后缀("-配图" 或 "+图片") has_image = False if text.endswith("-配图"): has_image = True text = text.replace("-配图", "").strip() elif text.endswith("+图片"): has_image = True text = text.replace("+图片", "").strip() # 优先匹配中互动 if text in MID_INTERACTION_TYPES: info = MID_INTERACTION_TYPES[text] return { "category": "mid", "cType": info["cType"], "type_name": text, "has_image": has_image, "bitable": info["bitable"], "db_table": "middle_interaction_component", } # 再匹配核心互动 if text in CORE_INTERACTION_TYPES: info = CORE_INTERACTION_TYPES[text] return { "category": "core", "cType": info["cType"], "type_name": text, "has_image": has_image, "bitable_wiki": info["bitable_wiki"], "db_table": "core_interaction_component", } raise ValueError(f"未知组件类型: '{type_text}' (清理后: '{text}')") def match_all(type_list: list) -> list: """批量匹配,返回结果列表,匹配失败的记录error""" results = [] for t in type_list: try: result = match_component_type(t) result["input"] = t results.append(result) except ValueError as e: results.append({"input": t, "error": str(e)}) return results # ============ 完整中英类型对照表 ============ def get_type_registry(): """ 返回完整的中互动组件中英类型对照表 Returns: list[dict]: [ { "type_name_cn": "对话朗读", "cType": "mid_dialog_repeat", "category": "mid", "bitable": "MuwubKXoSaJe55sO4k9c63VSnmh", "db_table": "middle_interaction_component", }, ... ] """ registry = [] for cn_name, info in MID_INTERACTION_TYPES.items(): registry.append({ "type_name_cn": cn_name, "cType": info["cType"], "category": "mid", "bitable": info["bitable"], "db_table": "middle_interaction_component", }) for cn_name, info in CORE_INTERACTION_TYPES.items(): registry.append({ "type_name_cn": cn_name, "cType": info.get("cType"), "category": "core", "bitable_wiki": info.get("bitable_wiki"), "db_table": "core_interaction_component", }) return registry def print_type_registry(): """打印完整的中英类型对照表""" print(f"{'中文类型名':<10} {'cType':<35} {'类别':<6} {'bitable_token'}") print("-" * 90) for entry in get_type_registry(): cat = "中互动" if entry["category"] == "mid" else "核心" bt = entry.get("bitable") or entry.get("bitable_wiki") or "" print(f"{entry['type_name_cn']:<10} {(entry['cType'] or 'TBD'):<35} {cat:<6} {bt}") # ============ CLI ============ if __name__ == "__main__": import sys if len(sys.argv) > 1: # 单个匹配 result = match_component_type(sys.argv[1]) print(json.dumps(result, ensure_ascii=False, indent=2)) else: # 测试:用剧本样例中的所有类型 test_types = [ "对话朗读", "对话挖空", "对话组句", "对话选择", "对话选读", "对话朗读-配图", "对话挖空-配图", "听力选择", "看图说话", "信息描写", "物品互动", "图片互动", "图片单选", ] print("=== 组件类型匹配测试 ===\n") results = match_all(test_types) for r in results: if "error" in r: print(f"❌ {r['input']}: {r['error']}") else: cat = "中互动" if r["category"] == "mid" else "核心互动" img = " [配图]" if r["has_image"] else "" print(f"✅ {r['input']}{img} → {cat} | {r['cType']}")