from __future__ import annotations from typing import Any try: import lark_oapi HAS_LARK_SDK = True except ImportError: HAS_LARK_SDK = False lark_oapi = None # type: ignore async def list_bitable_tables(client: Any, app_token: str) -> list[dict[str, Any]]: if not HAS_LARK_SDK or not client: return [] try: request = lark_oapi.api.bitable.v1.ListAppTableRequest.builder().app_token(app_token).build() resp = await client.bitable.v1.app_table.list(request) if not resp.success(): raise RuntimeError(f"获取多维表格列表失败: {resp.msg}") data = resp.data if hasattr(resp, "data") else {} items = data.get("items", []) return [ { "table_id": item.get("table_id", ""), "name": item.get("name", ""), "revision": item.get("revision", 0), } for item in items ] except Exception as e: raise RuntimeError(f"获取多维表格列表失败: {e}") from e async def get_bitable_fields(client: Any, app_token: str, table_id: str) -> list[dict[str, Any]]: if not HAS_LARK_SDK or not client: return [] try: request = ( lark_oapi.api.bitable.v1.ListAppTableFieldRequest.builder().app_token(app_token).table_id(table_id).build() ) resp = await client.bitable.v1.app_table_field.list(request) if not resp.success(): raise RuntimeError(f"获取字段列表失败: {resp.msg}") data = resp.data if hasattr(resp, "data") else {} items = data.get("items", []) return [ { "field_id": item.get("field_id", ""), "field_name": item.get("field_name", ""), "type": item.get("type", 0), "property": item.get("property", {}), "is_primary": item.get("is_primary", False), } for item in items ] except Exception as e: raise RuntimeError(f"获取字段列表失败: {e}") from e async def list_bitable_records( client: Any, app_token: str, table_id: str, page_size: int = 100, filter_formula: str = "", ) -> list[dict[str, Any]]: if not HAS_LARK_SDK or not client: return [] records: list[dict[str, Any]] = [] page_token = "" try: while True: request_builder = ( lark_oapi.api.bitable.v1.ListAppTableRecordRequest.builder() .app_token(app_token) .table_id(table_id) .page_size(page_size) .page_token(page_token) ) if filter_formula: request_builder.filter(filter_formula) request = request_builder.build() resp = await client.bitable.v1.app_table_record.list(request) if not resp.success(): break data = resp.data if hasattr(resp, "data") else {} items = data.get("items", []) for item in items: records.append( { "record_id": item.get("record_id", ""), "fields": item.get("fields", {}), "created_time": item.get("created_time", ""), "last_modified_time": item.get("last_modified_time", ""), } ) page_token = data.get("page_token", "") if not page_token or not items: break except Exception as e: raise RuntimeError(f"获取记录列表失败: {e}") from e return records async def create_bitable_record( client: Any, app_token: str, table_id: str, fields: dict[str, Any], ) -> dict[str, Any]: if not HAS_LARK_SDK or not client: raise RuntimeError("SDK 不可用") try: request_body = lark_oapi.api.bitable.v1.CreateAppTableRecordRequestBody.builder().fields(fields).build() request = ( lark_oapi.api.bitable.v1.CreateAppTableRecordRequest.builder() .app_token(app_token) .table_id(table_id) .request_body(request_body) .build() ) resp = await client.bitable.v1.app_table_record.create(request) if not resp.success(): raise RuntimeError(f"创建记录失败: {resp.msg}") data = resp.data if hasattr(resp, "data") else {} record = data.get("record", {}) or data return { "record_id": record.get("record_id", ""), "fields": record.get("fields", fields), } except Exception as e: raise RuntimeError(f"创建记录失败: {e}") from e