From 0d8304da2c956f87288eaed0431de9f22b252ae5 Mon Sep 17 00:00:00 2001 From: Marsway Date: Tue, 3 Feb 2026 16:37:51 +0800 Subject: [PATCH] update --- app/api/feishu_external.py | 26 +++++++++- app/schemas/feishu_external.py | 8 +++ app/services/huobanyun_service.py | 85 ++++++++++++++++++------------- 3 files changed, 83 insertions(+), 36 deletions(-) diff --git a/app/api/feishu_external.py b/app/api/feishu_external.py index 81e0f10..95bc668 100644 --- a/app/api/feishu_external.py +++ b/app/api/feishu_external.py @@ -15,6 +15,28 @@ huobanyun_service = HuobanyunService() async def feishu_external_query( 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") - 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 "", + } + }, + } diff --git a/app/schemas/feishu_external.py b/app/schemas/feishu_external.py index 88a03ed..a01eaf7 100644 --- a/app/schemas/feishu_external.py +++ b/app/schemas/feishu_external.py @@ -14,6 +14,14 @@ class FeishuExternalQueryRequest(BaseModel): keyword: Optional[str] = "" page: int = 1 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] = [] raw: Dict[str, Any] = {} diff --git a/app/services/huobanyun_service.py b/app/services/huobanyun_service.py index b7e2787..8ccecd0 100644 --- a/app/services/huobanyun_service.py +++ b/app/services/huobanyun_service.py @@ -37,6 +37,17 @@ class HuobanyunService: return self._extract_value(fields.get(key)) 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]: if isinstance(value, bool): return value @@ -157,43 +168,49 @@ class HuobanyunService: or raw.get("table") or "2100000015544940" ) - limit = min(max(req.page_size, 1), 100) - offset = max(req.page - 1, 0) * limit + limit = 50 + 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} - 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") - elif req.keyword: - payload["filter"] = {"and": [{"field": "title", "query": {"eqm": [req.keyword]}}]} - if raw.get("order"): - payload["order"] = raw.get("order") - if raw.get("with_field_config") is not None: - payload["with_field_config"] = raw.get("with_field_config") + elif query_value: + payload["filter"] = {"and": [{"field": "title", "query": {"eqm": [query_value]}}]} + payload["order"] = {"field_id": "created_on", "type": "desc"} + payload["with_field_config"] = 0 data = await self.client.query(payload) data_block = data.get("data", {}) if isinstance(data, dict) else {} items = data_block.get("items", []) if isinstance(data_block, dict) else [] - total = data_block.get("filtered", data_block.get("total", len(items))) - parsed = HuobanyunQueryResponse( - total=total, - items=[ - { - "id": item.get("item_id", ""), - "name": item.get("title", ""), - "value": item.get("title", ""), - "extra": item, - } - for item in items - ], - ) - return FeishuExternalQueryResponse( - total=parsed.total, - data=[ - FeishuExternalItem( - id=item.id, - label=item.name, - value=item.value, - extra=item.extra, - ) - for item in parsed.items - ], - ) + has_more = bool(data_block.get("has_more")) + next_token = str(offset + limit) if has_more else "" + + options = [] + texts = {} + for item in items: + fields = item.get("fields", {}) + item_id = item.get("item_id", "") + if key: + value = self._extract_value(fields.get(key, "")) + else: + value = item.get("title", "") + value_str = "" if value is None else str(value) + i18n_key = f"@i18n@{item_id}" if item_id else f"@i18n@{value_str}" + options.append({"id": str(item_id), "value": i18n_key, "isDefault": False}) + texts[i18n_key] = value_str + + return { + "options": options, + "texts": texts, + "has_more": has_more, + "next_page_token": next_token, + }