fix: 优化群成员分页并补齐头像资料
This commit is contained in:
@@ -3340,8 +3340,11 @@ func (a *adapter) UsersForTopic(topic string, keepDeleted bool, opts *t.QueryOpt
|
||||
|
||||
// Fetch all subscribed users. The number of users is not large.
|
||||
q := `SELECT s.createdat,s.updatedat,s.deletedat,s.userid,s.topic,s.delid,s.recvseqid,
|
||||
s.readseqid,s.modewant,s.modegiven,u.public,u.trusted,u.lastseen,u.useragent,s.private
|
||||
s.readseqid,s.modewant,s.modegiven,u.public,u.trusted,u.lastseen,u.useragent,s.private,
|
||||
p.nickname AS profile_nickname,p.avatar_file_id AS profile_avatar_file_id,p.signature AS profile_signature,
|
||||
p.gender AS profile_gender,p.region AS profile_region,p.public_account AS profile_public_account
|
||||
FROM im_subscriptions AS s JOIN im_users AS u ON s.userid=u.id
|
||||
LEFT JOIN im_user_profiles AS p ON p.user_id=s.userid
|
||||
WHERE s.topic=?`
|
||||
args := []any{topic}
|
||||
if !keepDeleted {
|
||||
@@ -3394,18 +3397,21 @@ func (a *adapter) UsersForTopic(topic string, keepDeleted bool, opts *t.QueryOpt
|
||||
var lastSeen sql.NullTime
|
||||
var userAgent string
|
||||
var public, trusted any
|
||||
var profileNickname, profileAvatarFileID, profileSignature, profileGender, profileRegion, profilePublicAccount sql.NullString
|
||||
for rows.Next() {
|
||||
if err = rows.Scan(
|
||||
&sub.CreatedAt, &sub.UpdatedAt, &sub.DeletedAt,
|
||||
&sub.User, &sub.Topic, &sub.DelId, &sub.RecvSeqId,
|
||||
&sub.ReadSeqId, &sub.ModeWant, &sub.ModeGiven,
|
||||
&public, &trusted, &lastSeen, &userAgent, &sub.Private); err != nil {
|
||||
&public, &trusted, &lastSeen, &userAgent, &sub.Private,
|
||||
&profileNickname, &profileAvatarFileID, &profileSignature,
|
||||
&profileGender, &profileRegion, &profilePublicAccount); err != nil {
|
||||
break
|
||||
}
|
||||
|
||||
sub.User = common.EncodeUidString(sub.User).String()
|
||||
sub.Private = common.FromJSON(sub.Private)
|
||||
sub.SetPublic(common.FromJSON(public))
|
||||
sub.SetPublic(profilePublicFromFields(common.FromJSON(public), profileNickname, profileAvatarFileID, profileSignature, profileGender, profileRegion, profilePublicAccount))
|
||||
sub.SetTrusted(common.FromJSON(trusted))
|
||||
sub.SetLastSeenAndUA(&lastSeen.Time, userAgent)
|
||||
subs = append(subs, sub)
|
||||
|
||||
@@ -1077,8 +1077,11 @@ func (a *adapter) TenantUsersForTopic(id t.TenantID, topic string, keepDeleted b
|
||||
}
|
||||
tcat := t.GetTopicCat(topic)
|
||||
q := `SELECT s.tenant_id,s.createdat,s.updatedat,s.deletedat,s.userid,s.topic,s.delid,s.recvseqid,
|
||||
s.readseqid,s.modewant,s.modegiven,u.public,u.trusted,u.lastseen,u.useragent,s.private
|
||||
s.readseqid,s.modewant,s.modegiven,u.public,u.trusted,u.lastseen,u.useragent,s.private,
|
||||
p.nickname AS profile_nickname,p.avatar_file_id AS profile_avatar_file_id,p.signature AS profile_signature,
|
||||
p.gender AS profile_gender,p.region AS profile_region,p.public_account AS profile_public_account
|
||||
FROM im_subscriptions AS s JOIN im_users AS u ON s.tenant_id=u.tenant_id AND s.userid=u.id
|
||||
LEFT JOIN im_user_profiles AS p ON p.tenant_id=s.tenant_id AND p.user_id=s.userid
|
||||
WHERE s.tenant_id=? AND s.topic=?`
|
||||
args := []any{id, topic}
|
||||
if !keepDeleted {
|
||||
@@ -1119,14 +1122,17 @@ func (a *adapter) TenantUsersForTopic(id t.TenantID, topic string, keepDeleted b
|
||||
var sub t.Subscription
|
||||
var lastSeen sql.NullTime
|
||||
var public, trusted any
|
||||
var profileNickname, profileAvatarFileID, profileSignature, profileGender, profileRegion, profilePublicAccount sql.NullString
|
||||
if err = rows.Scan(&sub.TenantID, &sub.CreatedAt, &sub.UpdatedAt, &sub.DeletedAt,
|
||||
&sub.User, &sub.Topic, &sub.DelId, &sub.RecvSeqId, &sub.ReadSeqId, &sub.ModeWant, &sub.ModeGiven,
|
||||
&public, &trusted, &lastSeen, &userAgent, &sub.Private); err != nil {
|
||||
&public, &trusted, &lastSeen, &userAgent, &sub.Private,
|
||||
&profileNickname, &profileAvatarFileID, &profileSignature,
|
||||
&profileGender, &profileRegion, &profilePublicAccount); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sub.User = common.EncodeUidString(sub.User).String()
|
||||
sub.Private = common.FromJSON(sub.Private)
|
||||
sub.SetPublic(common.FromJSON(public))
|
||||
sub.SetPublic(profilePublicFromFields(common.FromJSON(public), profileNickname, profileAvatarFileID, profileSignature, profileGender, profileRegion, profilePublicAccount))
|
||||
sub.SetTrusted(common.FromJSON(trusted))
|
||||
sub.SetLastSeenAndUA(&lastSeen.Time, userAgent)
|
||||
subs = append(subs, sub)
|
||||
|
||||
@@ -248,30 +248,49 @@ func (a *adapter) TenantGroupMemberList(id t.TenantID, topic string, opts t.Grou
|
||||
if opts.Limit <= 0 || opts.Limit > 100 {
|
||||
opts.Limit = 30
|
||||
}
|
||||
where := []string{"topic=?", "member_status=?"}
|
||||
memberIndex := "idx_im_group_members_topic_status"
|
||||
where := []string{"gm.topic=?", "gm.member_status=?"}
|
||||
args := []any{topic, t.GroupMemberStatusActive}
|
||||
if opts.Role != "" {
|
||||
where = append(where, "role=?")
|
||||
memberIndex = "idx_im_group_members_topic_role"
|
||||
where = append(where, "gm.role=?")
|
||||
args = append(args, opts.Role)
|
||||
}
|
||||
if opts.Query != "" {
|
||||
where = append(where, "nickname LIKE ?")
|
||||
args = append(args, "%"+opts.Query+"%")
|
||||
like := "%" + opts.Query + "%"
|
||||
where = append(where, `(gm.nickname LIKE ? OR p.nickname LIKE ? OR p.public_account LIKE ?
|
||||
OR JSON_UNQUOTE(JSON_EXTRACT(u.public,'$.fn')) LIKE ?
|
||||
OR JSON_UNQUOTE(JSON_EXTRACT(u.public,'$.name')) LIKE ?
|
||||
OR JSON_UNQUOTE(JSON_EXTRACT(u.public,'$.display_name')) LIKE ?
|
||||
OR u.username LIKE ?)`)
|
||||
args = append(args, like, like, like, like, like, like, like)
|
||||
}
|
||||
if opts.Cursor != "" {
|
||||
parsed, err := strconv.ParseInt(opts.Cursor, 10, 64)
|
||||
if err != nil || parsed <= 0 {
|
||||
if err != nil || parsed < 0 {
|
||||
return nil, "", t.ErrMalformed
|
||||
}
|
||||
where = append(where, "id>?")
|
||||
args = append(args, parsed)
|
||||
if parsed > 0 {
|
||||
where = append(where, "gm.id>?")
|
||||
args = append(args, parsed)
|
||||
}
|
||||
}
|
||||
if opts.Mentionable {
|
||||
where = append(where, "INSTR(s.modewant,'J')>0 AND INSTR(s.modegiven,'J')>0")
|
||||
}
|
||||
args = append(args, opts.Limit+1)
|
||||
ctx, cancel := a.getContext()
|
||||
if cancel != nil {
|
||||
defer cancel()
|
||||
}
|
||||
rows, err := a.db.QueryxContext(ctx, "SELECT * FROM im_group_members WHERE "+strings.Join(where, " AND ")+" ORDER BY id LIMIT ?", args...)
|
||||
rows, err := a.db.QueryxContext(ctx, `SELECT STRAIGHT_JOIN gm.*,s.modewant,s.modegiven,u.public,u.trusted,
|
||||
p.nickname AS profile_nickname,p.avatar_file_id AS profile_avatar_file_id,p.signature AS profile_signature,
|
||||
p.gender AS profile_gender,p.region AS profile_region,p.public_account AS profile_public_account
|
||||
FROM im_group_members AS gm FORCE INDEX (`+memberIndex+`)
|
||||
JOIN im_subscriptions AS s ON s.topic=gm.topic AND s.userid=gm.user_id AND s.deletedat IS NULL
|
||||
JOIN im_users AS u ON u.id=gm.user_id AND u.state!=?
|
||||
LEFT JOIN im_user_profiles AS p ON p.user_id=gm.user_id
|
||||
WHERE `+strings.Join(where, " AND ")+` ORDER BY gm.id LIMIT ?`, append([]any{t.StateDeleted}, args...)...)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
@@ -279,15 +298,30 @@ func (a *adapter) TenantGroupMemberList(id t.TenantID, topic string, opts t.Grou
|
||||
items := make([]t.GroupMember, 0, opts.Limit)
|
||||
next := ""
|
||||
for rows.Next() {
|
||||
var item t.GroupMember
|
||||
if err = rows.StructScan(&item); err != nil {
|
||||
row := struct {
|
||||
t.GroupMember
|
||||
Public any
|
||||
Trusted any
|
||||
ProfileNickname sql.NullString `db:"profile_nickname"`
|
||||
ProfileAvatarFileID sql.NullString `db:"profile_avatar_file_id"`
|
||||
ProfileSignature sql.NullString `db:"profile_signature"`
|
||||
ProfileGender sql.NullString `db:"profile_gender"`
|
||||
ProfileRegion sql.NullString `db:"profile_region"`
|
||||
ProfilePublicAccount sql.NullString `db:"profile_public_account"`
|
||||
}{}
|
||||
if err = rows.StructScan(&row); err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
item := row.GroupMember
|
||||
scanGroupMember(&item)
|
||||
if len(items) == opts.Limit {
|
||||
next = strconv.FormatInt(item.ID, 10)
|
||||
if len(items) > 0 {
|
||||
next = strconv.FormatInt(items[len(items)-1].ID, 10)
|
||||
}
|
||||
continue
|
||||
}
|
||||
item.Public = profilePublicFromFields(common.FromJSON(row.Public), row.ProfileNickname, row.ProfileAvatarFileID, row.ProfileSignature, row.ProfileGender, row.ProfileRegion, row.ProfilePublicAccount)
|
||||
item.Trusted = common.FromJSON(row.Trusted)
|
||||
items = append(items, item)
|
||||
}
|
||||
return items, next, rows.Err()
|
||||
|
||||
Reference in New Issue
Block a user