# 使用 Ex 字段区分群类型方案 ## 一、方案概述 使用群组的 `Ex` 扩展字段来区分不同类型的群,在客户端根据 `Ex` 字段控制功能展示,服务端保持统一的验证逻辑。 ## 二、Ex 字段格式建议 ### 2.1 JSON 格式 ```json { "groupCategory": "super", // 群类型:super(超级群)、normal(普通群)、work(工作群) "features": { "allowLink": true, // 是否允许发送链接 "allowQRCode": true, // 是否允许发送二维码 "showMemberList": true, // 是否显示成员列表 "showAdminPanel": false // 是否显示管理面板 }, "custom": {} // 其他自定义字段 } ``` ### 2.2 简化格式(如果只需要区分类型) ```json { "type": "super" // super, normal, work } ``` ## 三、实现方式 ### 3.1 创建群组时设置 Ex **创建群组时**,在 `GroupInfo.Ex` 中设置群类型: ```go // 创建超级群 groupInfo := &sdkws.GroupInfo{ GroupName: "超级群", Ex: `{"type":"super"}`, // ... 其他字段 } // 创建普通群 groupInfo := &sdkws.GroupInfo{ GroupName: "普通群", Ex: `{"type":"normal"}`, // ... 其他字段 } ``` ### 3.2 客户端解析 Ex 字段 **客户端获取群信息后**,解析 `Ex` 字段: ```javascript // 示例:JavaScript/TypeScript function getGroupType(groupInfo) { try { const ex = JSON.parse(groupInfo.Ex || '{}'); return ex.type || 'normal'; // 默认为普通群 } catch (e) { return 'normal'; } } // 根据群类型控制功能显示 function shouldShowFeature(groupInfo, feature) { const type = getGroupType(groupInfo); switch (feature) { case 'memberList': // 超级群可能不显示成员列表 return type !== 'super'; case 'adminPanel': // 只有工作群显示管理面板 return type === 'work'; case 'linkMessage': // 根据类型决定是否允许发送链接 return type !== 'super'; // 超级群不允许发送链接 default: return true; } } ``` ### 3.3 更新群信息时保持 Ex 字段 **使用 `SetGroupInfoEx` 接口更新群信息时**,可以更新 `Ex` 字段: ```go // 更新群扩展信息 req := &pbgroup.SetGroupInfoExReq{ GroupID: groupID, Ex: &wrapperspb.StringValue{ Value: `{"type":"super","features":{"allowLink":false}}`, }, } ``` ## 四、优势 ### 4.1 服务端优势 1. **统一验证逻辑**:所有群组都使用 `WorkingGroup` 的完整验证,安全可靠 2. **无需修改代码**:不需要修改服务端的验证、推送等逻辑 3. **向后兼容**:不影响现有群组,新群组通过 Ex 字段区分 4. **灵活扩展**:Ex 字段可以存储任意 JSON 数据,便于后续扩展 ### 4.2 客户端优势 1. **完全可控**:客户端可以根据业务需求灵活控制功能展示 2. **易于实现**:只需要解析 JSON 并做条件判断 3. **不影响现有功能**:对没有 Ex 字段或 Ex 字段格式不正确的群组,可以设置默认行为 ## 五、注意事项 ### 5.1 Ex 字段格式 - **建议使用 JSON 格式**:便于解析和扩展 - **字段命名规范**:使用小驼峰或下划线命名 - **版本兼容**:如果后续需要修改格式,考虑版本号字段 ### 5.2 默认值处理 - **客户端**:如果 Ex 字段为空或解析失败,应设置合理的默认值 - **服务端**:创建群组时,如果没有设置 Ex,可以设置默认值 ### 5.3 数据一致性 - **更新 Ex 字段时**:确保 JSON 格式正确 - **验证**:客户端解析 Ex 字段时,应该处理 JSON 解析错误 ## 六、示例代码 ### 6.1 Go 服务端示例 ```go // 创建群组时设置 Ex func createSuperGroup(req *pbgroup.CreateGroupReq) { req.GroupInfo.Ex = `{"type":"super","features":{"allowLink":false}}` // ... 创建群组 } // 解析 Ex 字段(如果需要) func parseGroupEx(ex string) map[string]interface{} { var result map[string]interface{} if err := json.Unmarshal([]byte(ex), &result); err != nil { return make(map[string]interface{}) } return result } ``` ### 6.2 客户端示例(React/TypeScript) ```typescript interface GroupEx { type?: 'super' | 'normal' | 'work'; features?: { allowLink?: boolean; allowQRCode?: boolean; showMemberList?: boolean; }; } function parseGroupEx(ex: string): GroupEx { try { return JSON.parse(ex || '{}') as GroupEx; } catch { return { type: 'normal' }; } } function useGroupFeatures(groupInfo: GroupInfo) { const ex = parseGroupEx(groupInfo.Ex); return { canSendLink: ex.features?.allowLink !== false, canSendQRCode: ex.features?.allowQRCode !== false, showMemberList: ex.features?.showMemberList !== false, isSuperGroup: ex.type === 'super', }; } ``` ## 七、总结 使用 `Ex` 字段区分群类型是一个**保守、安全、灵活**的方案: - ✅ **服务端**:保持统一逻辑,无需修改验证和推送代码 - ✅ **客户端**:完全可控,根据业务需求灵活展示功能 - ✅ **扩展性**:Ex 字段可以存储任意扩展信息 - ✅ **兼容性**:不影响现有群组和功能 这个方案避免了修改服务端核心逻辑带来的风险,同时提供了足够的灵活性来满足不同的业务需求。