5.4 KiB
5.4 KiB
使用 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 服务端优势
- 统一验证逻辑:所有群组都使用
WorkingGroup的完整验证,安全可靠 - 无需修改代码:不需要修改服务端的验证、推送等逻辑
- 向后兼容:不影响现有群组,新群组通过 Ex 字段区分
- 灵活扩展:Ex 字段可以存储任意 JSON 数据,便于后续扩展
4.2 客户端优势
- 完全可控:客户端可以根据业务需求灵活控制功能展示
- 易于实现:只需要解析 JSON 并做条件判断
- 不影响现有功能:对没有 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 字段可以存储任意扩展信息
- ✅ 兼容性:不影响现有群组和功能
这个方案避免了修改服务端核心逻辑带来的风险,同时提供了足够的灵活性来满足不同的业务需求。