Files
open-im-server-deploy/docs/使用Ex字段区分群类型方案.md
kim.dev.6789 e50142a3b9 复制项目
2026-01-14 22:16:44 +08:00

5.4 KiB
Raw Permalink Blame History

使用 Ex 字段区分群类型方案

一、方案概述

使用群组的 Ex 扩展字段来区分不同类型的群,在客户端根据 Ex 字段控制功能展示,服务端保持统一的验证逻辑。

二、Ex 字段格式建议

2.1 JSON 格式

{
  "groupCategory": "super",  // 群类型super(超级群)、normal(普通群)、work(工作群)
  "features": {
    "allowLink": true,        // 是否允许发送链接
    "allowQRCode": true,      // 是否允许发送二维码
    "showMemberList": true,   // 是否显示成员列表
    "showAdminPanel": false   // 是否显示管理面板
  },
  "custom": {}                // 其他自定义字段
}

2.2 简化格式(如果只需要区分类型)

{
  "type": "super"  // super, normal, work
}

三、实现方式

3.1 创建群组时设置 Ex

创建群组时,在 GroupInfo.Ex 中设置群类型:

// 创建超级群
groupInfo := &sdkws.GroupInfo{
    GroupName: "超级群",
    Ex: `{"type":"super"}`,
    // ... 其他字段
}

// 创建普通群
groupInfo := &sdkws.GroupInfo{
    GroupName: "普通群",
    Ex: `{"type":"normal"}`,
    // ... 其他字段
}

3.2 客户端解析 Ex 字段

客户端获取群信息后,解析 Ex 字段:

// 示例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 字段:

// 更新群扩展信息
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 服务端示例

// 创建群组时设置 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

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 字段可以存储任意扩展信息
  • 兼容性:不影响现有群组和功能

这个方案避免了修改服务端核心逻辑带来的风险,同时提供了足够的灵活性来满足不同的业务需求。