Selaa lähdekoodia

微信注册接口修改
修复微信注册接口返回用户已存在时返回错误信息的问题
名片解析功能修复

maxiaolong 1 kuukausi sitten
vanhempi
commit
05c9ad0bf1

+ 51 - 18
app/core/data_parse/calendar.py

@@ -888,7 +888,9 @@ class WechatUserService:
     
     def register_user_by_code(self, wechat_code: str, phone_number: Optional[str] = None, id_card_number: Optional[str] = None, platform: str = 'miniprogram') -> tuple[bool, Optional[WechatUser], Optional[str]]:
         """
-        通过微信授权码注册新用户
+        通过微信授权码注册新用户或返回已存在用户
+        
+        如果用户已存在,则返回现有用户信息;如果用户不存在,则创建新用户。
         
         Args:
             wechat_code (str): 微信授权码(15分钟有效期)
@@ -898,7 +900,10 @@ class WechatUserService:
             
         Returns:
             tuple[bool, Optional[WechatUser], Optional[str]]: 
-            (是否成功, 用户对象, 错误信息)
+            (是否成功, 用户对象, 状态信息)
+            - 新用户: (True, user, None)
+            - 已存在用户: (True, user, "用户已存在")
+            - 失败: (False, None, 错误信息)
         """
         try:
             # 使用微信code换取openid
@@ -913,7 +918,8 @@ class WechatUserService:
             # 检查用户是否已存在
             existing_user = self.get_user_by_openid(openid)
             if existing_user:
-                return False, None, f"用户已存在,openid: {openid}"
+                # 用户已存在,返回现有用户信息
+                return True, existing_user, "用户已存在"
             
             # 创建用户数据
             user_data = {
@@ -1633,6 +1639,8 @@ def register_wechat_user(wechat_code: str, phone_number: Optional[str] = None, i
     """
     注册微信用户的便捷函数
     
+    如果用户已存在,则返回现有用户信息;如果用户不存在,则创建新用户。
+    
     Args:
         wechat_code (str): 微信授权码(15分钟有效期)
         phone_number (str, optional): 手机号码
@@ -1642,6 +1650,9 @@ def register_wechat_user(wechat_code: str, phone_number: Optional[str] = None, i
         
     Returns:
         dict: 包含注册结果的JSON格式数据
+        - 新用户注册成功: return_code=201, is_new_user=True
+        - 用户已存在: return_code=200, is_new_user=False
+        - 注册失败: return_code=400/500
     """
     try:
         # 验证必填参数
@@ -1660,26 +1671,48 @@ def register_wechat_user(wechat_code: str, phone_number: Optional[str] = None, i
         success, user, error_msg = service.register_user_by_code(wechat_code, phone_number, id_card_number, platform)
         
         if success and user:
-            # 注册成功
-            return {
-                "reason": "successed",
-                "return_code": 201,
-                "result": {
-                    "id": str(user.id),
-                    "openid": user.openid,
-                    "phone_number": user.phone_number,
-                    "id_card_number": user.id_card_number,
-                    "login_status": user.login_status,
-                    "user_status": user.user_status,
-                    "created_at": user.created_at.isoformat() if user.created_at is not None else None
+            # 检查是否为已存在用户
+            if error_msg == "用户已存在":
+                # 用户已存在,返回现有用户信息
+                return {
+                    "reason": "successed",
+                    "return_code": 200,
+                    "result": {
+                        "id": str(user.id),
+                        "openid": user.openid,
+                        "phone_number": user.phone_number,
+                        "id_card_number": user.id_card_number,
+                        "login_status": user.login_status,
+                        "user_status": user.user_status,
+                        "created_at": user.created_at.isoformat() if user.created_at is not None else None,
+                        "updated_at": user.updated_at.isoformat() if user.updated_at is not None else None,
+                        "is_new_user": False
+                    },
+                    "message": "用户已存在,返回现有用户信息"
+                }
+            else:
+                # 新用户注册成功
+                return {
+                    "reason": "successed",
+                    "return_code": 201,
+                    "result": {
+                        "id": str(user.id),
+                        "openid": user.openid,
+                        "phone_number": user.phone_number,
+                        "id_card_number": user.id_card_number,
+                        "login_status": user.login_status,
+                        "user_status": user.user_status,
+                        "created_at": user.created_at.isoformat() if user.created_at is not None else None,
+                        "updated_at": user.updated_at.isoformat() if user.updated_at is not None else None,
+                        "is_new_user": True
+                    },
+                    "message": "新用户注册成功"
                 }
-            }
         else:
             # 注册失败
-            error_code = 409 if "已存在" in (error_msg or "") else 400
             return {
                 "reason": "failed",
-                "return_code": error_code,
+                "return_code": 400,
                 "result": None,
                 "error": error_msg or "注册失败"
             }

+ 32 - 31
app/core/data_parse/parse_card.py

@@ -341,37 +341,36 @@ def add_business_card(card_data, image_file=None):
                     except (ValueError, TypeError):
                         age_value = None
                 
-                business_card = BusinessCard(
-                    name_zh=card_data.get('name_zh', ''),
-                    name_en=card_data.get('name_en', ''),
-                    title_zh=card_data.get('title_zh', ''),
-                    title_en=card_data.get('title_en', ''),
-                    mobile=normalize_mobile_numbers(card_data.get('mobile', '')),
-                    phone=card_data.get('phone', ''),
-                    email=card_data.get('email', ''),
-                    hotel_zh=card_data.get('hotel_zh', ''),
-                    hotel_en=card_data.get('hotel_en', ''),
-                    address_zh=card_data.get('address_zh', ''),
-                    address_en=card_data.get('address_en', ''),
-                    postal_code_zh=card_data.get('postal_code_zh', ''),
-                    postal_code_en=card_data.get('postal_code_en', ''),
-                    brand_zh=card_data.get('brand_zh', ''),
-                    brand_en=card_data.get('brand_en', ''),
-                    affiliation_zh=card_data.get('affiliation_zh', ''),
-                    affiliation_en=card_data.get('affiliation_en', ''),
-                    birthday=datetime.strptime(card_data.get('birthday'), '%Y-%m-%d').date() if card_data.get('birthday') else None,
-                    age=age_value,
-                    native_place=card_data.get('native_place', ''),
-                    gender=card_data.get('gender', ''),  # 新增性别字段
-                    residence=card_data.get('residence', ''),
-                    image_path=minio_path,  # 最新的图片路径
-                    career_path=career_path,  # 直接使用card_data中的career_path
-                    brand_group=card_data.get('brand_group', ''),
-                    origin_source=[create_origin_source_entry('business_card_creation', minio_path)],  # 原始资料记录
-                    talent_profile=card_data.get('talent_profile', ''),  # 人才档案
-                    status='active',
-                    updated_by='system'
-                )
+                business_card = BusinessCard()
+                business_card.name_zh = card_data.get('name_zh', '')
+                business_card.name_en = card_data.get('name_en', '')
+                business_card.title_zh = card_data.get('title_zh', '')
+                business_card.title_en = card_data.get('title_en', '')
+                business_card.mobile = normalize_mobile_numbers(card_data.get('mobile', ''))
+                business_card.phone = card_data.get('phone', '')
+                business_card.email = card_data.get('email', '')
+                business_card.hotel_zh = card_data.get('hotel_zh', '')
+                business_card.hotel_en = card_data.get('hotel_en', '')
+                business_card.address_zh = card_data.get('address_zh', '')
+                business_card.address_en = card_data.get('address_en', '')
+                business_card.postal_code_zh = card_data.get('postal_code_zh', '')
+                business_card.postal_code_en = card_data.get('postal_code_en', '')
+                business_card.brand_zh = card_data.get('brand_zh', '')
+                business_card.brand_en = card_data.get('brand_en', '')
+                business_card.affiliation_zh = card_data.get('affiliation_zh', '')
+                business_card.affiliation_en = card_data.get('affiliation_en', '')
+                business_card.birthday = datetime.strptime(card_data.get('birthday'), '%Y-%m-%d').date() if card_data.get('birthday') else None
+                business_card.age = age_value
+                business_card.native_place = card_data.get('native_place', '')
+                business_card.gender = card_data.get('gender', '')
+                business_card.residence = card_data.get('residence', '')
+                business_card.image_path = minio_path
+                business_card.career_path = career_path
+                business_card.brand_group = card_data.get('brand_group', '')
+                business_card.origin_source = [create_origin_source_entry('business_card_creation', minio_path)]
+                business_card.talent_profile = card_data.get('talent_profile', '')
+                business_card.status = 'active'
+                business_card.updated_by = 'system'
                 
                 db.session.add(business_card)
                 db.session.commit()
@@ -1049,6 +1048,8 @@ def parse_business_card_with_qwen(image_data):
         
         # 尝试从响应中提取 JSON
         try:
+            if response_content is None:
+                raise Exception("Qwen API 返回的内容为空")
             extracted_data = json.loads(response_content)
             logging.info("成功解析 Qwen 响应中的 JSON")
         except json.JSONDecodeError:

+ 11 - 6
app/core/data_parse/wechat_config.py

@@ -3,23 +3,22 @@
 用于配置微信小程序/公众号的API相关参数
 """
 
-import os
 from typing import Dict, Any
 
 # 微信API配置
 WECHAT_API_CONFIG: Dict[str, Any] = {
     # 微信小程序配置
     'miniprogram': {
-        'app_id': os.environ.get('WECHAT_MINIPROGRAM_APP_ID', ''),
-        'app_secret': os.environ.get('WECHAT_MINIPROGRAM_APP_SECRET', ''),
+        'app_id': 'wx6decdf12f9e7a061',
+        'app_secret': '6ba58fb365fd87036fe075bde65eade3',
         'code2session_url': 'https://api.weixin.qq.com/sns/jscode2session',
         'grant_type': 'authorization_code'
     },
     
     # 微信公众号配置(如果需要)
     'official_account': {
-        'app_id': os.environ.get('WECHAT_OFFICIAL_APP_ID', ''),
-        'app_secret': os.environ.get('WECHAT_OFFICIAL_APP_SECRET', ''),
+        'app_id': '',  # 如需要请填入公众号AppID
+        'app_secret': '',  # 如需要请填入公众号AppSecret
         'oauth2_url': 'https://api.weixin.qq.com/sns/oauth2/access_token',
         'grant_type': 'authorization_code'
     },
@@ -74,7 +73,13 @@ def validate_wechat_config(platform: str = 'miniprogram') -> bool:
     config = WECHAT_API_CONFIG.get(platform, {})
     required_keys = ['app_id', 'app_secret']
     
-    return all(config.get(key) for key in required_keys)
+    # 检查配置是否存在且不为空
+    for key in required_keys:
+        value = config.get(key, '')
+        if not value or value.strip() == '':
+            return False
+    
+    return True
 
 def get_error_message(error_code: int) -> str:
     """

+ 152 - 0
docs/wechat-config-setup-guide.md

@@ -0,0 +1,152 @@
+# 微信API配置设置指南
+
+## 问题描述
+
+如果您看到以下错误信息:
+```
+微信miniprogram配置不完整,请检查环境变量
+获取openid失败: 微信API配置不完整
+```
+
+这表示系统缺少微信小程序的 API 配置信息。
+
+## 解决方案
+
+### 方法一:使用自动配置脚本(推荐)
+
+#### 1. 交互式配置
+```bash
+python setup_wechat_config.py
+```
+
+按照提示输入您的微信小程序 AppID 和 AppSecret。
+
+#### 2. 快速配置
+```bash
+python setup_wechat_config.py <您的AppID> <您的AppSecret>
+```
+
+### 方法二:手动配置
+
+#### 1. 创建环境变量文件
+```bash
+cp env.example .env
+```
+
+#### 2. 编辑 .env 文件
+找到以下行并替换为您的实际配置:
+```bash
+WECHAT_MINIPROGRAM_APP_ID=your_miniprogram_app_id_here
+WECHAT_MINIPROGRAM_APP_SECRET=your_miniprogram_app_secret_here
+```
+
+替换为:
+```bash
+WECHAT_MINIPROGRAM_APP_ID=wx1234567890abcdef  # 您的实际AppID
+WECHAT_MINIPROGRAM_APP_SECRET=abcd1234567890abcd1234567890abcd  # 您的实际AppSecret
+```
+
+## 如何获取微信小程序凭证
+
+### 1. 登录微信公众平台
+访问:https://mp.weixin.qq.com/
+
+### 2. 进入小程序管理后台
+- 选择您的小程序项目
+- 点击左侧菜单中的 "开发"
+- 选择 "开发管理"
+
+### 3. 获取开发者ID
+在 "开发设置" 页面中:
+- **AppID**: 在 "开发者ID" 部分直接显示
+- **AppSecret**: 在 "开发者密码(AppSecret)" 部分,点击 "重置" 按钮获取
+
+⚠️ **重要提醒**:
+- AppSecret 只在重置时显示一次,请立即复制保存
+- 重置 AppSecret 会使之前的密钥失效
+- 请妥善保管 AppSecret,不要泄露给他人
+
+## 验证配置
+
+### 运行配置检查脚本
+```bash
+python check_wechat_config.py
+```
+
+如果配置正确,您将看到:
+```
+✅ WECHAT_MINIPROGRAM_APP_ID: wx1234...
+✅ WECHAT_MINIPROGRAM_APP_SECRET: abcd12...
+✅ 微信小程序配置验证通过
+🎉 微信API配置检查完成,一切正常!
+```
+
+### 重启应用
+配置完成后,请重启您的应用使配置生效。
+
+## 常见问题
+
+### Q: 提示 "AppID 格式不正确"
+**A**: 微信小程序 AppID 通常:
+- 以 "wx" 开头
+- 长度约为18位
+- 示例:`wx1234567890abcdef`
+
+### Q: 提示 "AppSecret 格式不正确"  
+**A**: 微信小程序 AppSecret 通常:
+- 长度为32位
+- 由字母和数字组成
+- 示例:`abcd1234567890abcd1234567890abcd`
+
+### Q: 配置后仍然报错
+**A**: 请检查:
+1. `.env` 文件是否在项目根目录
+2. 环境变量名称是否正确(区分大小写)
+3. 配置值中是否有多余的空格或引号
+4. 是否重启了应用
+
+### Q: 如何在生产环境配置
+**A**: 生产环境建议:
+1. 不使用 `.env` 文件
+2. 直接设置系统环境变量:
+   ```bash
+   export WECHAT_MINIPROGRAM_APP_ID=wx1234567890abcdef
+   export WECHAT_MINIPROGRAM_APP_SECRET=abcd1234567890abcd1234567890abcd
+   ```
+3. 或在容器/云服务中配置环境变量
+
+## 安全注意事项
+
+1. **不要提交 .env 文件到版本控制**
+   - `.env` 文件已被 `.gitignore` 忽略
+   - 确保不要手动添加到 git
+
+2. **保护 AppSecret**
+   - 不要在代码中硬编码
+   - 不要在日志中输出完整的 AppSecret
+   - 定期更换 AppSecret
+
+3. **环境隔离**
+   - 开发、测试、生产环境使用不同的小程序
+   - 每个环境有独立的 AppID 和 AppSecret
+
+## 相关文件
+
+- `env.example` - 环境变量配置模板
+- `setup_wechat_config.py` - 自动配置脚本
+- `check_wechat_config.py` - 配置检查脚本
+- `app/core/data_parse/wechat_config.py` - 微信API配置模块
+- `app/core/data_parse/wechat_api.py` - 微信API服务模块
+
+## 技术支持
+
+如果按照以上步骤操作后仍有问题,请检查:
+
+1. 网络连接是否正常
+2. 微信API服务是否可用
+3. 小程序是否已发布/审核通过
+4. 服务器IP是否在微信白名单中(如有限制)
+
+更多技术支持,请参考:
+- [微信小程序官方文档](https://developers.weixin.qq.com/miniprogram/dev/)
+- [微信登录API文档](https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/login/auth.code2Session.html)

+ 9 - 0
env.example

@@ -22,6 +22,15 @@ ACCESS_TOKEN_EXPIRE_MINUTES=30
 LOG_LEVEL=INFO
 LOG_FILE=logs/app.log
 
+# 微信小程序API配置
+# 请替换为您的实际微信小程序 APP_ID 和 APP_SECRET
+WECHAT_MINIPROGRAM_APP_ID=your_miniprogram_app_id_here
+WECHAT_MINIPROGRAM_APP_SECRET=your_miniprogram_app_secret_here
+
+# 微信公众号API配置(如果需要)
+WECHAT_OFFICIAL_APP_ID=your_official_account_app_id_here
+WECHAT_OFFICIAL_APP_SECRET=your_official_account_app_secret_here
+
 # 外部API配置
 EXTERNAL_API_URL=https://api.example.com
 API_KEY=your-api-key-here