This commit is contained in:
Marsway 2026-02-03 16:37:51 +08:00
parent 57d25c857e
commit 0d8304da2c
3 changed files with 83 additions and 36 deletions

View File

@ -15,6 +15,28 @@ huobanyun_service = HuobanyunService()
async def feishu_external_query( async def feishu_external_query(
req: FeishuExternalQueryRequest, x_feishu_token: str | None = Header(default=None) req: FeishuExternalQueryRequest, x_feishu_token: str | None = Header(default=None)
): ):
if not feishu_service.verify_token(x_feishu_token): if not feishu_service.verify_token(x_feishu_token or req.token):
raise HTTPException(status_code=403, detail="invalid token") raise HTTPException(status_code=403, detail="invalid token")
return await huobanyun_service.query(req) result = await huobanyun_service.query(req)
options = result.get("options", [])
texts = result.get("texts", {})
has_more = result.get("has_more", False)
next_page_token = result.get("next_page_token", "")
return {
"code": 0,
"msg": "success!",
"data": {
"result": {
"options": options,
"i18nResources": [
{
"locale": "zh_cn",
"isDefault": True,
"texts": texts,
}
],
"hasMore": has_more,
"nextPageToken": next_page_token if has_more else "",
}
},
}

View File

@ -14,6 +14,14 @@ class FeishuExternalQueryRequest(BaseModel):
keyword: Optional[str] = "" keyword: Optional[str] = ""
page: int = 1 page: int = 1
page_size: int = Field(default=20, alias="pageSize") page_size: int = Field(default=20, alias="pageSize")
key: Optional[str] = None
user_id: Optional[str] = None
employee_id: Optional[str] = None
token: Optional[str] = None
linkage_params: Dict[str, Any] = {}
page_token: Optional[str] = None
query: Optional[str] = None
locale: Optional[str] = None
filters: List[FeishuExternalQueryFilter] = [] filters: List[FeishuExternalQueryFilter] = []
raw: Dict[str, Any] = {} raw: Dict[str, Any] = {}

View File

@ -37,6 +37,17 @@ class HuobanyunService:
return self._extract_value(fields.get(key)) return self._extract_value(fields.get(key))
return "" return ""
def _resolve_field_key(self, key: str) -> str:
mapping = {
"项目单号": "2200000149785345",
"项目名称": "2200000150711223",
"订单状态": "2200000150497330",
"下单金额": "2200000149785349",
"是否已关联对公付款审批": "2200000589775224",
"是否已关联对私付款审批": "2200000589775228",
}
return mapping.get(key, key)
def _to_bool(self, value: Any) -> Optional[bool]: def _to_bool(self, value: Any) -> Optional[bool]:
if isinstance(value, bool): if isinstance(value, bool):
return value return value
@ -157,43 +168,49 @@ class HuobanyunService:
or raw.get("table") or raw.get("table")
or "2100000015544940" or "2100000015544940"
) )
limit = min(max(req.page_size, 1), 100) limit = 50
offset = max(req.page - 1, 0) * limit if req.page_token and str(req.page_token).isdigit():
offset = int(str(req.page_token))
else:
offset = 0
key = req.key or raw.get("key") or raw.get("field") or ""
key = self._resolve_field_key(str(key)) if key else ""
query_value = req.query or req.keyword or ""
payload: Dict[str, Any] = {"table_id": table_id, "limit": limit, "offset": offset} payload: Dict[str, Any] = {"table_id": table_id, "limit": limit, "offset": offset}
if raw.get("filter"): if key and query_value:
payload["filter"] = {"and": [{"field": key, "query": {"eqm": [query_value]}}]}
elif raw.get("filter"):
payload["filter"] = raw.get("filter") payload["filter"] = raw.get("filter")
elif req.keyword: elif query_value:
payload["filter"] = {"and": [{"field": "title", "query": {"eqm": [req.keyword]}}]} payload["filter"] = {"and": [{"field": "title", "query": {"eqm": [query_value]}}]}
if raw.get("order"): payload["order"] = {"field_id": "created_on", "type": "desc"}
payload["order"] = raw.get("order") payload["with_field_config"] = 0
if raw.get("with_field_config") is not None:
payload["with_field_config"] = raw.get("with_field_config")
data = await self.client.query(payload) data = await self.client.query(payload)
data_block = data.get("data", {}) if isinstance(data, dict) else {} data_block = data.get("data", {}) if isinstance(data, dict) else {}
items = data_block.get("items", []) if isinstance(data_block, dict) else [] items = data_block.get("items", []) if isinstance(data_block, dict) else []
total = data_block.get("filtered", data_block.get("total", len(items))) has_more = bool(data_block.get("has_more"))
parsed = HuobanyunQueryResponse( next_token = str(offset + limit) if has_more else ""
total=total,
items=[ options = []
{ texts = {}
"id": item.get("item_id", ""), for item in items:
"name": item.get("title", ""), fields = item.get("fields", {})
"value": item.get("title", ""), item_id = item.get("item_id", "")
"extra": item, if key:
} value = self._extract_value(fields.get(key, ""))
for item in items else:
], value = item.get("title", "")
) value_str = "" if value is None else str(value)
return FeishuExternalQueryResponse( i18n_key = f"@i18n@{item_id}" if item_id else f"@i18n@{value_str}"
total=parsed.total, options.append({"id": str(item_id), "value": i18n_key, "isDefault": False})
data=[ texts[i18n_key] = value_str
FeishuExternalItem(
id=item.id, return {
label=item.name, "options": options,
value=item.value, "texts": texts,
extra=item.extra, "has_more": has_more,
) "next_page_token": next_token,
for item in parsed.items }
],
)