From 1225b6cbf0a028b765a0ab6d784bcb80459a67bb Mon Sep 17 00:00:00 2001
From: yj <2077506045@qq.com>
Date: 星期三, 23 七月 2025 17:59:54 +0800
Subject: [PATCH] 功能更新

---
 app/services/ecloud_client.py |  234 ++++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 203 insertions(+), 31 deletions(-)

diff --git a/app/services/ecloud_client.py b/app/services/ecloud_client.py
index 5a76116..42495c3 100644
--- a/app/services/ecloud_client.py
+++ b/app/services/ecloud_client.py
@@ -3,7 +3,7 @@
 """
 
 import requests
-from typing import Optional, Dict, Any
+from typing import Optional, Dict, Any, List
 from loguru import logger
 from config import settings
 
@@ -26,10 +26,12 @@
 
         Args:
             w_id: 鐧诲綍瀹炰緥鏍囪瘑
-            wc_id: 濂藉弸寰俊id/缇d
+            wc_id: 濂藉弸寰俊id/缇d锛屽涓娇鐢ㄨ嫳鏂囬�楀彿鍒嗛殧
 
         Returns:
-            鑱旂郴浜轰俊鎭瓧鍏革紝澶辫触杩斿洖None
+            鑱旂郴浜轰俊鎭瓧鍏告垨鍒楄〃锛屽け璐ヨ繑鍥濶one
+            - 鍗曚釜wcId鏃惰繑鍥炲瓧鍏�
+            - 澶氫釜wcId鏃惰繑鍥炲垪琛�
         """
         try:
             url = f"{self.base_url}/getContact"
@@ -45,8 +47,14 @@
             if result.get("code") == "1000":
                 contact_data = result.get("data", [])
                 if contact_data and len(contact_data) > 0:
-                    logger.info(f"鎴愬姛鑾峰彇鑱旂郴浜轰俊鎭�: wcId={wc_id}")
-                    return contact_data[0]  # 杩斿洖绗竴涓仈绯讳汉淇℃伅
+                    # 濡傛灉鏄崟涓獁cId锛岃繑鍥炵涓�涓仈绯讳汉淇℃伅
+                    if "," not in wc_id:
+                        logger.info(f"鎴愬姛鑾峰彇鑱旂郴浜轰俊鎭�: wcId={wc_id}")
+                        return contact_data[0]
+                    else:
+                        # 濡傛灉鏄涓獁cId锛岃繑鍥炲畬鏁村垪琛�
+                        logger.info(f"鎴愬姛鑾峰彇鎵归噺鑱旂郴浜轰俊鎭�: count={len(contact_data)}")
+                        return contact_data
                 else:
                     logger.warning(f"鑱旂郴浜轰俊鎭负绌�: wcId={wc_id}")
                     return None
@@ -63,7 +71,7 @@
             logger.error(f"鑾峰彇鑱旂郴浜轰俊鎭紓甯�: wcId={wc_id}, error={str(e)}")
             return None
 
-    def send_text_message(self, w_id: str, wc_id: str, content: str) -> bool:
+    def send_text_message(self, w_id: str, wc_id: str, content: str, max_retries: int = None) -> bool:
         """
         鍙戦�佹枃鏈秷鎭�
 
@@ -71,38 +79,55 @@
             w_id: 鐧诲綍瀹炰緥鏍囪瘑
             wc_id: 鎺ユ敹浜哄井淇d/缇d
             content: 鏂囨湰鍐呭娑堟伅
+            max_retries: 鏈�澶ч噸璇曟鏁�
 
         Returns:
             鍙戦�佹垚鍔熻繑鍥濼rue锛屽け璐ヨ繑鍥濬alse
         """
-        try:
-            url = f"{self.base_url}/sendText"
-            payload = {"wId": w_id, "wcId": wc_id, "content": content}
+        if max_retries is None:
+            from config import settings
+            max_retries = settings.max_retry_count
+            
+        retry_count = 0
+        while retry_count <= max_retries:
+            try:
+                url = f"{self.base_url}/sendText"
+                payload = {"wId": w_id, "wcId": wc_id, "content": content}
 
-            logger.info(
-                f"鍙戦�佹枃鏈秷鎭�: wId={w_id}, wcId={wc_id}, content_length={len(content)}"
-            )
-
-            response = self.session.post(url, json=payload, timeout=30)
-            response.raise_for_status()
-
-            result = response.json()
-
-            if result.get("code") == "1000":
-                logger.info(f"鏂囨湰娑堟伅鍙戦�佹垚鍔�: wcId={wc_id}")
-                return True
-            else:
-                logger.error(
-                    f"鏂囨湰娑堟伅鍙戦�佸け璐�: wcId={wc_id}, code={result.get('code')}, message={result.get('message')}"
+                logger.info(
+                    f"鍙戦�佹枃鏈秷鎭�: wId={w_id}, wcId={wc_id}, content_length={len(content)}, retry={retry_count}"
                 )
-                return False
 
-        except requests.exceptions.RequestException as e:
-            logger.error(f"鍙戦�佹枃鏈秷鎭綉缁滈敊璇�: wcId={wc_id}, error={str(e)}")
-            return False
-        except Exception as e:
-            logger.error(f"鍙戦�佹枃鏈秷鎭紓甯�: wcId={wc_id}, error={str(e)}")
-            return False
+                response = self.session.post(url, json=payload, timeout=30)
+                response.raise_for_status()
+
+                result = response.json()
+
+                if result.get("code") == "1000":
+                    logger.info(f"鏂囨湰娑堟伅鍙戦�佹垚鍔�: wcId={wc_id}")
+                    return True
+                else:
+                    logger.error(
+                        f"鏂囨湰娑堟伅鍙戦�佸け璐�: wcId={wc_id}, code={result.get('code')}, message={result.get('message')}"
+                    )
+
+            except requests.exceptions.RequestException as e:
+                logger.error(f"鍙戦�佹枃鏈秷鎭綉缁滈敊璇�: wcId={wc_id}, retry={retry_count}, error={str(e)}")
+            except Exception as e:
+                logger.error(f"鍙戦�佹枃鏈秷鎭紓甯�: wcId={wc_id}, retry={retry_count}, error={str(e)}")
+            
+            retry_count += 1
+            if retry_count <= max_retries:
+                from config import settings
+                wait_time = settings.retry_delay * retry_count
+                logger.info(f"绛夊緟閲嶈瘯: wcId={wc_id}, wait_time={wait_time}s")
+                import time
+                time.sleep(wait_time)
+
+        logger.error(
+            f"鏂囨湰娑堟伅鍙戦�佸け璐ワ紝宸茶揪鏈�澶ч噸璇曟鏁�: wcId={wc_id}, max_retries={max_retries}"
+        )
+        return False
 
     def send_group_message(self, w_id: str, group_id: str, content: str) -> bool:
         """
@@ -118,6 +143,153 @@
         """
         return self.send_text_message(w_id, group_id, content)
 
+    def init_address_list(self, w_id: str) -> bool:
+        """
+        鍒濆鍖栭�氳褰曞垪琛�
+
+        Args:
+            w_id: 鐧诲綍瀹炰緥鏍囪瘑
+
+        Returns:
+            鍒濆鍖栨垚鍔熻繑鍥濼rue锛屽け璐ヨ繑鍥濬alse
+        """
+        try:
+            url = f"{self.base_url}/initAddressList"
+            payload = {"wId": w_id}
+
+            logger.info(f"鍒濆鍖栭�氳褰曞垪琛�: wId={w_id}")
+
+            response = self.session.post(url, json=payload, timeout=30)
+            response.raise_for_status()
+
+            result = response.json()
+
+            if result.get("code") == "1000":
+                logger.info(f"鍒濆鍖栭�氳褰曞垪琛ㄦ垚鍔�: wId={w_id}")
+                return True
+            else:
+                logger.error(
+                    f"鍒濆鍖栭�氳褰曞垪琛ㄥけ璐�: wId={w_id}, code={result.get('code')}, message={result.get('message')}"
+                )
+                return False
+
+        except requests.exceptions.RequestException as e:
+            logger.error(f"鍒濆鍖栭�氳褰曞垪琛ㄧ綉缁滈敊璇�: wId={w_id}, error={str(e)}")
+            return False
+        except Exception as e:
+            logger.error(f"鍒濆鍖栭�氳褰曞垪琛ㄥ紓甯�: wId={w_id}, error={str(e)}")
+            return False
+
+    def get_address_list(self, w_id: str) -> Optional[Dict[str, Any]]:
+        """
+        鑾峰彇閫氳褰曞垪琛�
+
+        Args:
+            w_id: 鐧诲綍瀹炰緥鏍囪瘑
+
+        Returns:
+            閫氳褰曟暟鎹瓧鍏革紝澶辫触杩斿洖None
+            杩斿洖鏍煎紡: {
+                "chatrooms": [...],  # 缇ょ粍鍒楄〃
+                "friends": [...],    # 濂藉弸鍒楄〃
+                "ghs": [...],        # 鍏紬鍙峰垪琛�
+                "others": [...]      # 鍏朵粬
+            }
+        """
+        try:
+            url = f"{self.base_url}/getAddressList"
+            payload = {"wId": w_id}
+
+            logger.info(f"鑾峰彇閫氳褰曞垪琛�: wId={w_id}")
+
+            response = self.session.post(url, json=payload, timeout=30)
+            response.raise_for_status()
+
+            result = response.json()
+
+            if result.get("code") == "1000":
+                address_data = result.get("data", {})
+                logger.info(f"鎴愬姛鑾峰彇閫氳褰曞垪琛�: wId={w_id}, friends_count={len(address_data.get('friends', []))}")
+                return address_data
+            else:
+                logger.error(
+                    f"鑾峰彇閫氳褰曞垪琛ㄥけ璐�: wId={w_id}, code={result.get('code')}, message={result.get('message')}"
+                )
+                return None
+
+        except requests.exceptions.RequestException as e:
+            logger.error(f"鑾峰彇閫氳褰曞垪琛ㄧ綉缁滈敊璇�: wId={w_id}, error={str(e)}")
+            return None
+        except Exception as e:
+            logger.error(f"鑾峰彇閫氳褰曞垪琛ㄥ紓甯�: wId={w_id}, error={str(e)}")
+            return None
+
+    def send_group_at_message(self, w_id: str, wc_id: str, content: str, at_wc_ids: List[str], max_retries: int = None) -> bool:
+        """
+        鍙戦�佺兢鑱夽娑堟伅
+
+        Args:
+            w_id: 鐧诲綍瀹炰緥鏍囪瘑
+            wc_id: 鎺ユ敹鏂圭兢id
+            content: 鏂囨湰鍐呭娑堟伅锛園鐨勫井淇℃樀绉伴渶瑕佽嚜宸辨嫾鎺ワ紝蹇呴』鎷兼帴鑹剧壒绗﹀彿锛屼笉鐒朵笉鐢熸晥锛�
+            at_wc_ids: 鑹剧壒鐨勫井淇d鍒楄〃
+            max_retries: 鏈�澶ч噸璇曟鏁�
+
+        Returns:
+            鍙戦�佹垚鍔熻繑鍥濼rue锛屽け璐ヨ繑鍥濬alse
+        """
+        if max_retries is None:
+            from config import settings
+            max_retries = settings.max_retry_count
+
+        retry_count = 0
+        while retry_count <= max_retries:
+            try:
+                url = f"{self.base_url}/sendText"
+                # 灏哸t_wc_ids鍒楄〃鐢ㄩ�楀彿鎷兼帴
+                at_str = ",".join(at_wc_ids)
+                payload = {
+                    "wId": w_id,
+                    "wcId": wc_id,
+                    "content": content,
+                    "at": at_str
+                }
+
+                logger.info(
+                    f"鍙戦�佺兢鑱夽娑堟伅: wId={w_id}, wcId={wc_id}, at={at_str}, content_length={len(content)}, retry={retry_count}"
+                )
+
+                response = self.session.post(url, json=payload, timeout=30)
+                response.raise_for_status()
+
+                result = response.json()
+
+                if result.get("code") == "1000":
+                    logger.info(f"缇よ亰@娑堟伅鍙戦�佹垚鍔�: wcId={wc_id}, at={at_str}")
+                    return True
+                else:
+                    logger.error(
+                        f"缇よ亰@娑堟伅鍙戦�佸け璐�: wcId={wc_id}, at={at_str}, code={result.get('code')}, message={result.get('message')}"
+                    )
+
+            except requests.exceptions.RequestException as e:
+                logger.error(f"鍙戦�佺兢鑱夽娑堟伅缃戠粶閿欒: wcId={wc_id}, at={at_str}, retry={retry_count}, error={str(e)}")
+            except Exception as e:
+                logger.error(f"鍙戦�佺兢鑱夽娑堟伅寮傚父: wcId={wc_id}, at={at_str}, retry={retry_count}, error={str(e)}")
+
+            retry_count += 1
+            if retry_count <= max_retries:
+                from config import settings
+                wait_time = settings.retry_delay * retry_count
+                logger.info(f"绛夊緟閲嶈瘯: wcId={wc_id}, wait_time={wait_time}s")
+                import time
+                time.sleep(wait_time)
+
+        logger.error(
+            f"缇よ亰@娑堟伅鍙戦�佸け璐ワ紝宸茶揪鏈�澶ч噸璇曟鏁�: wcId={wc_id}, at={at_str}, max_retries={max_retries}"
+        )
+        return False
+
 
 # 鍏ㄥ眬E浜戠瀹跺鎴风瀹炰緥
 ecloud_client = ECloudClient()

--
Gitblit v1.9.1