Forráskód Böngészése

用户与账号同步接口及文档

liuq 1 hónapja
szülő
commit
d6407c3194

+ 30 - 18
backend/app/api/v1/endpoints/apps.py

@@ -1205,13 +1205,26 @@ def sync_mapping(
     if not user:
         # Create New User
         
-        # Auto-generate English name if missing but Chinese name is present
-        if in_name and not in_english_name:
-             in_english_name = generate_english_name(in_name)
-
-        # Validation: Name and English Name are required for new users
-        if not in_name or not in_english_name:
-            raise HTTPException(status_code=400, detail="新建用户必须提供姓名和英文名称")
+        # Validation: Name is required for new users
+        if not in_name:
+            raise HTTPException(status_code=400, detail="新建用户必须提供姓名")
+        
+        # Auto-generate English name if missing
+        if not in_english_name:
+            in_english_name = generate_english_name(in_name)
+            
+            # Check uniqueness for auto-generated English name
+            if in_english_name:
+                original_base = in_english_name
+                counter = 1
+                
+                # Check if the generated name already exists
+                while db.query(User).filter(
+                    User.english_name == in_english_name,
+                    User.is_deleted == 0
+                ).first():
+                    in_english_name = f"{original_base}{counter}"
+                    counter += 1
 
         # Auto create user
         password = security.generate_alphanumeric_password(8) # Random password letters+digits
@@ -1230,20 +1243,19 @@ def sync_mapping(
         new_user_created = True
         logger.info(f"M2M 自动创建用户: {sync_in.mobile}")
     else:
-        # Update Existing User (if fields provided)
-        updated = False
+        # Update Existing User - 已有用户不允许修改 name、mobile、english_name
+        # Check if trying to modify restricted fields
+        if sync_in.mobile != user.mobile:
+            raise HTTPException(status_code=400, detail="已有用户不允许修改手机号")
+        
         if in_name is not None and user.name != in_name:
-            user.name = in_name
-            updated = True
+            raise HTTPException(status_code=400, detail="已有用户不允许修改姓名")
         
         if in_english_name is not None and user.english_name != in_english_name:
-            user.english_name = in_english_name
-            updated = True
-            
-        if updated:
-            db.add(user)
-            db.commit()
-            db.refresh(user)
+            raise HTTPException(status_code=400, detail="已有用户不允许修改英文名")
+        
+        # 已有用户的其他字段(如status等)可以更新,但当前M2M接口不涉及
+        # 这里只处理映射关系的更新
 
     # 2. Handle Mapping
     mapping = db.query(AppUserMapping).filter(

+ 31 - 12
frontend/public/docs/account_sync.md

@@ -19,9 +19,9 @@
 ### 逻辑
 1. **增改模式 (UPSERT)**:
    - 根据 `mobile` 查找用户。
-   - **新建用户**: 若用户不存在,必须提供 `name` 和 `english_name`,否则报错
-   - **已有用户**: 若提供了 `name` 或 `english_name` 且不为空,则更新用户信息;否则保留原值
-   - 建立或更新该用户与当前应用的映射 (`mapped_key`, `mapped_email`)。
+   - **新建用户**: 若用户不存在,必须提供 `name`(姓名)。`english_name`(英文名)可选,如未提供会自动生成并确保唯一性
+   - **已有用户**: **不允许修改** `name`、`mobile`、`english_name` 等用户基本信息。但可以修改映射信息(`mapped_key`、`mapped_email`、`is_active`)
+   - 建立或更新该用户与当前应用的映射 (`mapped_key`, `mapped_email`, `is_active`)。
 2. **删除模式 (DELETE)**:
    - 仅删除该用户在当前应用下的映射关系。
    - **不删除**平台上的用户账号。
@@ -30,14 +30,14 @@
 | Field | Type | Required | Description |
 |---|---|---|---|
 | `mobile` | string | Yes | 用户手机号 (平台唯一标识) |
-| `name` | string | Conditional | 用户姓名 (新建用户必填,已有用户选填) |
-| `english_name` | string | Conditional | 英文名/拼音 (新建用户必填,全局唯一) |
-| `mapped_key` | string | No | 外部系统用户ID |
-| `mapped_email` | string | No | 外部系统邮箱 |
-| `is_active` | boolean | No | 映射状态 (默认 true) |
+| `name` | string | Conditional | 用户姓名 (新建用户必填,已有用户不允许修改) |
+| `english_name` | string | Optional | 英文名/拼音 (新建用户可选,如未提供会自动生成;已有用户不允许修改) |
+| `mapped_key` | string | No | 外部系统用户ID (可修改) |
+| `mapped_email` | string | No | 外部系统邮箱 (可修改) |
+| `is_active` | boolean | No | 映射状态 (默认 true,可修改) |
 | `sync_action` | string | No | 操作类型: `UPSERT` (增改, 默认) 或 `DELETE` (删除映射) |
 
-### 示例 1: 新增或更新用户 (UPSERT)
+### 示例 1: 新增用户 (UPSERT)
 ```bash
 curl -X POST "{{API_BASE_URL}}/apps/mapping/sync" \
      -H "Content-Type: application/json" \
@@ -45,14 +45,29 @@ curl -X POST "{{API_BASE_URL}}/apps/mapping/sync" \
      -d '{
            "mobile": "13800138000",
            "name": "张三",
-           "english_name": "zhangsan",
            "mapped_key": "user_1001",
            "mapped_email": "zhangsan@example.com",
            "sync_action": "UPSERT"
          }'
 ```
+注意:`english_name` 可以不提供,系统会自动生成。
 
-### 示例 2: 删除映射 (DELETE)
+### 示例 2: 更新已有用户的映射信息 (UPSERT)
+```bash
+curl -X POST "{{API_BASE_URL}}/apps/mapping/sync" \
+     -H "Content-Type: application/json" \
+     -H "X-App-Access-Token: eyJhbGci..." \
+     -d '{
+           "mobile": "13800138000",
+           "mapped_key": "user_1001_updated",
+           "mapped_email": "zhangsan_new@example.com",
+           "is_active": true,
+           "sync_action": "UPSERT"
+         }'
+```
+注意:已有用户不能修改 `name`、`mobile`、`english_name`,只能修改映射信息。
+
+### 示例 3: 删除映射 (DELETE)
 ```bash
 curl -X POST "{{API_BASE_URL}}/apps/mapping/sync" \
      -H "Content-Type: application/json" \
@@ -75,6 +90,10 @@ curl -X POST "{{API_BASE_URL}}/apps/mapping/sync" \
 ```
 
 ## 4. 错误码
-- `400 Bad Request`: 参数错误、姓名/英文名已存在、映射关系冲突。
+- `400 Bad Request`: 
+  - 参数错误(如新建用户未提供 `name`)
+  - 已有用户尝试修改 `name`、`mobile` 或 `english_name`
+  - 姓名/英文名已存在(新建用户时)
+  - 映射关系冲突(`mapped_key` 或 `mapped_email` 已被占用)
 - `403 Forbidden`: Token 无效。
 

+ 45 - 12
frontend/src/views/help/AccountSync.vue

@@ -21,9 +21,19 @@
         <h4>🛠️ 接口逻辑 (UPSERT 模式)</h4>
         <ol>
           <li>根据 <code>mobile</code> 查找用户。</li>
-          <li><strong>新建用户</strong>:若用户不存在,必须提供 <code>name</code> 和 <code>english_name</code>,否则报错。</li>
-          <li><strong>已有用户</strong>:若提供了 <code>name</code> 或 <code>english_name</code> 且不为空,则更新用户信息;否则保留原值。</li>
-          <li>将该用户与当前应用建立映射关系(绑定 <code>mapped_key</code> 和 <code>mapped_email</code>)。</li>
+          <li><strong>新建用户</strong>:
+            <ul>
+              <li>必须提供 <code>name</code>(姓名)。</li>
+              <li><code>english_name</code>(英文名)可选,如未提供会自动生成并确保唯一性。</li>
+            </ul>
+          </li>
+          <li><strong>已有用户</strong>:
+            <ul>
+              <li><strong>不允许修改</strong>:<code>name</code>、<code>mobile</code>、<code>english_name</code> 等用户基本信息。</li>
+              <li><strong>可以修改</strong>:映射信息(<code>mapped_key</code>、<code>mapped_email</code>、<code>is_active</code>)。</li>
+            </ul>
+          </li>
+          <li>将该用户与当前应用建立或更新映射关系(绑定 <code>mapped_key</code> 和 <code>mapped_email</code>)。</li>
         </ol>
       </div>
 
@@ -44,16 +54,16 @@
         </thead>
         <tbody>
           <tr><td><code>mobile</code></td><td>string</td><td><span class="tag-required">是</span></td><td>用户手机号(平台唯一标识)</td></tr>
-          <tr><td><code>name</code></td><td>string</td><td><span class="tag-conditional">条件</span></td><td>姓名(新建用户必填)</td></tr>
-          <tr><td><code>english_name</code></td><td>string</td><td><span class="tag-conditional">条件</span></td><td>英文名(新建用户必填,全局唯一)</td></tr>
-          <tr><td><code>mapped_key</code></td><td>string</td><td><span class="tag-optional">否</span></td><td>外部系统中的用户ID(在该应用下唯一)</td></tr>
-          <tr><td><code>mapped_email</code></td><td>string</td><td><span class="tag-optional">否</span></td><td>外部系统中的邮箱(在该应用下唯一)</td></tr>
-          <tr><td><code>is_active</code></td><td>boolean</td><td><span class="tag-optional">否</span></td><td>映射关系状态(<code>true</code>启用,<code>false</code>禁用)</td></tr>
+          <tr><td><code>name</code></td><td>string</td><td><span class="tag-conditional">条件</span></td><td>姓名(新建用户必填,已有用户不允许修改)</td></tr>
+          <tr><td><code>english_name</code></td><td>string</td><td><span class="tag-optional">否</span></td><td>英文名(新建用户可选,如未提供会自动生成;已有用户不允许修改)</td></tr>
+          <tr><td><code>mapped_key</code></td><td>string</td><td><span class="tag-optional">否</span></td><td>外部系统中的用户ID(在该应用下唯一,可修改)</td></tr>
+          <tr><td><code>mapped_email</code></td><td>string</td><td><span class="tag-optional">否</span></td><td>外部系统中的邮箱(在该应用下唯一,可修改)</td></tr>
+          <tr><td><code>is_active</code></td><td>boolean</td><td><span class="tag-optional">否</span></td><td>映射关系状态(<code>true</code>启用,<code>false</code>禁用,可修改)</td></tr>
           <tr><td><code>sync_action</code></td><td>string</td><td><span class="tag-optional">否</span></td><td><code>UPSERT</code> (默认) 或 <code>DELETE</code></td></tr>
         </tbody>
       </table>
 
-      <p><strong>请求示例 (UPSERT):</strong></p>
+      <p><strong>请求示例 1: 新建用户 (UPSERT):</strong></p>
       <div class="code-block">
         <pre>
 curl -X POST "http://your-uap-domain/api/v1/apps/mapping/sync" \
@@ -62,15 +72,32 @@ curl -X POST "http://your-uap-domain/api/v1/apps/mapping/sync" \
      -d '{
            "mobile": "13800138000",
            "name": "张三",
-           "english_name": "zhangsan",
            "mapped_key": "user_1001",
            "mapped_email": "zhangsan@example.com",
            "sync_action": "UPSERT"
          }'
         </pre>
       </div>
+      <p class="note">注意:<code>english_name</code> 可以不提供,系统会自动生成。</p>
 
-      <p><strong>请求示例 (DELETE):</strong></p>
+      <p><strong>请求示例 2: 更新已有用户的映射信息 (UPSERT):</strong></p>
+      <div class="code-block">
+        <pre>
+curl -X POST "http://your-uap-domain/api/v1/apps/mapping/sync" \
+     -H "Content-Type: application/json" \
+     -H "X-App-Access-Token: YOUR_APP_ACCESS_TOKEN" \
+     -d '{
+           "mobile": "13800138000",
+           "mapped_key": "user_1001_updated",
+           "mapped_email": "zhangsan_new@example.com",
+           "is_active": true,
+           "sync_action": "UPSERT"
+         }'
+        </pre>
+      </div>
+      <p class="note">注意:已有用户不能修改 <code>name</code>、<code>mobile</code>、<code>english_name</code>,只能修改映射信息。</p>
+
+      <p><strong>请求示例 3: 删除映射 (DELETE):</strong></p>
       <div class="code-block">
         <pre>
 curl -X POST "http://your-uap-domain/api/v1/apps/mapping/sync" \
@@ -104,7 +131,13 @@ curl -X POST "http://your-uap-domain/api/v1/apps/mapping/sync" \
 
       <p><strong>响应失败:</strong></p>
       <ul>
-        <li><code>400 Bad Request</code>: <code>mapped_key</code> 或 <code>mapped_email</code> 已被其他用户占用。</li>
+        <li><code>400 Bad Request</code>: 
+          <ul>
+            <li>新建用户未提供 <code>name</code></li>
+            <li>已有用户尝试修改 <code>name</code>、<code>mobile</code> 或 <code>english_name</code></li>
+            <li><code>mapped_key</code> 或 <code>mapped_email</code> 已被其他用户占用</li>
+          </ul>
+        </li>
         <li><code>403 Forbidden</code>: Access Token 无效或过期。</li>
       </ul>
     </div>

+ 10 - 0
frontend/src/views/help/help.css

@@ -66,6 +66,16 @@ li {
   border-left: 5px solid #909399;
 }
 
+.note {
+  font-size: 14px;
+  color: #909399;
+  font-style: italic;
+  margin-top: 8px;
+  margin-bottom: 15px;
+  padding-left: 10px;
+  border-left: 3px solid #e6a23c;
+}
+
 .code-block {
   background: #282c34;
   color: #abb2bf;