fix: 优化群成员分页并补齐头像资料
This commit is contained in:
+53
-29
@@ -4807,8 +4807,14 @@ func serveIMGroupMembers(wrt http.ResponseWriter, req *http.Request, topic strin
|
||||
return
|
||||
}
|
||||
limit := parseIMLimit(req.URL.Query().Get("limit"), 30, 100)
|
||||
cursor, err := parseIMNonNegativeCursor(req.URL.Query().Get("cursor"))
|
||||
if err != nil {
|
||||
cursor := strings.TrimSpace(req.URL.Query().Get("cursor"))
|
||||
if cursor != "" {
|
||||
if _, err := strconv.ParseInt(cursor, 10, 64); err != nil {
|
||||
writeIMError(wrt, req, http.StatusBadRequest, 30000, imReasonMalformedRequest, "malformed request", map[string]any{"field": "cursor"})
|
||||
return
|
||||
}
|
||||
}
|
||||
if parsed, err := parseIMNonNegativeCursor(cursor); err != nil || parsed < 0 {
|
||||
writeIMError(wrt, req, http.StatusBadRequest, 30000, imReasonMalformedRequest, "malformed request", map[string]any{"field": "cursor"})
|
||||
return
|
||||
}
|
||||
@@ -4822,25 +4828,22 @@ func serveIMGroupMembers(wrt http.ResponseWriter, req *http.Request, topic strin
|
||||
writeIMSuccess(wrt, req, cached)
|
||||
return
|
||||
}
|
||||
members, err := store.Topics.GetUsers(principal.TenantID, topic, &types.QueryOpt{Limit: 1000})
|
||||
members, nextCursor, err := store.GroupBusiness.ListMembers(principal.TenantID, topic, types.GroupMemberListOptions{
|
||||
Role: roleFilter,
|
||||
EligibleRole: eligibleRole,
|
||||
Query: query,
|
||||
Cursor: cursor,
|
||||
Limit: limit,
|
||||
Mentionable: mentionableOnly,
|
||||
})
|
||||
if err != nil {
|
||||
writeIMError(wrt, req, http.StatusInternalServerError, 90000, imReasonInternal, "internal error", nil)
|
||||
return
|
||||
}
|
||||
items := make([]map[string]any, 0, limit)
|
||||
seen := 0
|
||||
nextCursor := ""
|
||||
for _, member := range members {
|
||||
access := member.ModeGiven & member.ModeWant
|
||||
mentionable := access.IsJoiner() && access.IsReader()
|
||||
role := groupMemberRole(access)
|
||||
if roleFilter != "" && role != roleFilter {
|
||||
continue
|
||||
}
|
||||
if mentionableOnly && !mentionable {
|
||||
continue
|
||||
}
|
||||
item := groupMemberPayload(member, mentionable)
|
||||
access := groupMemberAccess(member)
|
||||
item := groupBusinessMemberPayload(member)
|
||||
if eligibleRole != "" {
|
||||
eligible, reason := groupRoleEligibility(selfAccess, access, eligibleRole)
|
||||
item["eligible"] = eligible
|
||||
@@ -4855,19 +4858,7 @@ func serveIMGroupMembers(wrt http.ResponseWriter, req *http.Request, topic strin
|
||||
item["ineligible_reason"] = reason
|
||||
}
|
||||
}
|
||||
if query != "" && !groupMemberMatches(item, query) {
|
||||
continue
|
||||
}
|
||||
if seen < cursor {
|
||||
seen++
|
||||
continue
|
||||
}
|
||||
if len(items) == limit {
|
||||
nextCursor = strconv.Itoa(seen)
|
||||
break
|
||||
}
|
||||
items = append(items, item)
|
||||
seen++
|
||||
}
|
||||
permissions := map[string]any{
|
||||
"can_mention_all": selfAccess.IsAdmin(),
|
||||
@@ -7320,6 +7311,38 @@ func groupMemberPayload(sub types.Subscription, mentionable bool) map[string]any
|
||||
return data
|
||||
}
|
||||
|
||||
func groupBusinessMemberPayload(member types.GroupMember) map[string]any {
|
||||
access := groupMemberAccess(member)
|
||||
user := &types.User{ObjHeader: types.ObjHeader{Id: member.UserID.String()}, Public: member.Public, Trusted: member.Trusted}
|
||||
data := userSummaryPayload(user, "")
|
||||
if nickname := strings.TrimSpace(member.Nickname); nickname != "" {
|
||||
data["group_nickname"] = nickname
|
||||
}
|
||||
data["role"] = groupMemberRole(access)
|
||||
data["mentionable"] = access.IsJoiner() && access.IsReader()
|
||||
data["acs"] = map[string]any{
|
||||
"mode": access.String(),
|
||||
"want": member.ModeWant.String(),
|
||||
"given": member.ModeGiven.String(),
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
func groupMemberAccess(member types.GroupMember) types.AccessMode {
|
||||
access := member.ModeGiven & member.ModeWant
|
||||
if access != types.ModeNone {
|
||||
return access
|
||||
}
|
||||
switch member.Role {
|
||||
case types.GroupMemberRoleOwner:
|
||||
return types.ModeCFull
|
||||
case types.GroupMemberRoleAdmin:
|
||||
return types.ModeCPublic | types.ModeApprove
|
||||
default:
|
||||
return types.ModeCPublic
|
||||
}
|
||||
}
|
||||
|
||||
func groupMemberProfilePayload(topic string, sub *types.Subscription, user *types.User, ctx *types.RelationshipContext) map[string]any {
|
||||
data := groupMemberPayload(*sub, true)
|
||||
data["topic"] = topic
|
||||
@@ -7771,16 +7794,17 @@ func groupMemberMatches(item map[string]any, query string) bool {
|
||||
}
|
||||
|
||||
func groupMemberPageCacheKey(topic string, uid types.Uid, access types.AccessMode, query, roleFilter, eligibleRole string,
|
||||
limit, cursor int, mentionableOnly, muteEligible bool) string {
|
||||
limit int, cursor string, mentionableOnly, muteEligible bool) string {
|
||||
return strings.Join([]string{
|
||||
topic,
|
||||
"v3",
|
||||
uid.UserId(),
|
||||
access.String(),
|
||||
strings.ToLower(strings.TrimSpace(query)),
|
||||
strings.TrimSpace(roleFilter),
|
||||
strings.TrimSpace(eligibleRole),
|
||||
strconv.Itoa(limit),
|
||||
strconv.Itoa(cursor),
|
||||
strings.TrimSpace(cursor),
|
||||
strconv.FormatBool(mentionableOnly),
|
||||
strconv.FormatBool(muteEligible),
|
||||
}, "|")
|
||||
|
||||
Reference in New Issue
Block a user