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

209 lines
5.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 使用 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 字段可以存储任意扩展信息
-**兼容性**:不影响现有群组和功能
这个方案避免了修改服务端核心逻辑带来的风险,同时提供了足够的灵活性来满足不同的业务需求。