Fix client friend status mapping

- Add explicit client friend status constants and resolver
- Return dynamic friend status from profileInfo and friend/search
- Accept invite_code when loading profileInfo targets
- Align live support friend status values with client expectations

Signed-off-by: Sean Du <do4suki@gmail.com>
This commit is contained in:
2026-06-05 22:55:00 +08:00
parent bac2335f14
commit 45eef9566a
5 changed files with 68 additions and 5 deletions
+15 -2
View File
@@ -48,6 +48,11 @@ func profileInfo(ctx *gin.Context, targetUserID int) (res any, err error) {
return nil, err return nil, err
} }
friendStatus, err := usermodel.ResolveClientFriendStatus(ss.UserEng, ss.UserID, targetUserID)
if err != nil {
return nil, err
}
if naviRaw != nil { if naviRaw != nil {
centerUnitInfo.Costume = profileapischema.Costume{ centerUnitInfo.Costume = profileapischema.Costume{
UnitID: naviRaw.UnitID, UnitID: naviRaw.UnitID,
@@ -80,7 +85,7 @@ func profileInfo(ctx *gin.Context, targetUserID int) (res any, err error) {
CenterUnitInfo: centerUnitInfo, CenterUnitInfo: centerUnitInfo,
NaviUnitInfo: naviUnitInfo, NaviUnitInfo: naviUnitInfo,
IsAlliance: false, IsAlliance: false,
FriendStatus: 0, FriendStatus: friendStatus,
SettingAwardID: targetPref.AwardID, SettingAwardID: targetPref.AwardID,
SettingBackgroundID: targetPref.BackgroundID, SettingBackgroundID: targetPref.BackgroundID,
}, },
@@ -104,13 +109,21 @@ func getTargetUserPref(ss *session.Session, targetUserID int) (usermodel.UserPre
if err != nil { if err != nil {
return usermodel.UserPref{}, err return usermodel.UserPref{}, err
} }
if !has {
has, err = ss.UserEng.Table(new(usermodel.UserPref)).
Where("invite_code = ?", strconv.Itoa(targetUserID)).
Get(&pref)
if err != nil {
return usermodel.UserPref{}, err
}
}
if !has { if !has {
return usermodel.UserPref{}, errors.New("user not found") return usermodel.UserPref{}, errors.New("user not found")
} }
if pref.NeedsProfileMigration() { if pref.NeedsProfileMigration() {
pref.ApplyProfileDefaults() pref.ApplyProfileDefaults()
_, err = ss.UserEng.Table(new(usermodel.UserPref)). _, err = ss.UserEng.Table(new(usermodel.UserPref)).
Where("user_id = ?", targetUserID). Where("user_id = ?", pref.UserID).
Cols(usermodel.UserPrefProfileColumns()...). Cols(usermodel.UserPrefProfileColumns()...).
Update(&pref) Update(&pref)
if err != nil { if err != nil {
+6 -1
View File
@@ -86,6 +86,11 @@ func search(ctx *gin.Context) {
return return
} }
friendStatus, err := usermodel.ResolveClientFriendStatus(ss.UserEng, ss.UserID, targetUserID)
if ss.CheckErr(err) {
return
}
ss.Respond(friendschema.SearchResp{ ss.Respond(friendschema.SearchResp{
ResponseData: friendschema.SearchData{ ResponseData: friendschema.SearchData{
UserInfo: friendschema.SearchUserInfo{ UserInfo: friendschema.SearchUserInfo{
@@ -103,7 +108,7 @@ func search(ctx *gin.Context) {
CenterUnitInfo: toSearchCenterUnitInfo(centerUnitInfo, costume), CenterUnitInfo: toSearchCenterUnitInfo(centerUnitInfo, costume),
SettingAwardID: row.AwardID, SettingAwardID: row.AwardID,
IsAlliance: false, IsAlliance: false,
FriendStatus: 0, FriendStatus: friendStatus,
ServerTimestamp: time.Now().Unix(), ServerTimestamp: time.Now().Unix(),
}, },
ReleaseInfo: []any{}, ReleaseInfo: []any{},
+1 -1
View File
@@ -39,7 +39,7 @@ func partyList(ctx *gin.Context) {
selfParty := liveschema.PartyList{ selfParty := liveschema.PartyList{
UserInfo: ss.GetUserInfo(), UserInfo: ss.GetUserInfo(),
SettingAwardID: pref.AwardID, SettingAwardID: pref.AwardID,
FriendStatus: 0, FriendStatus: usermodel.ClientFriendStatusNone,
} }
selfParty.AvailableSocialPoint = 10 selfParty.AvailableSocialPoint = 10
selfParty.CenterUnitInfo, err = mustFindCenterUnitInfo(ss, ss.UserID, pref.UnitOwningUserID) selfParty.CenterUnitInfo, err = mustFindCenterUnitInfo(ss, ss.UserID, pref.UnitOwningUserID)
+1 -1
View File
@@ -51,7 +51,7 @@ func buildLiveSupportParty(ss *session.Session, row liveSupportRow) (liveschema.
CenterUnitInfo: centerUnitInfo, CenterUnitInfo: centerUnitInfo,
SettingAwardID: row.AwardID, SettingAwardID: row.AwardID,
AvailableSocialPoint: 10, AvailableSocialPoint: 10,
FriendStatus: 0, FriendStatus: usermodel.ClientFriendStatusApproved,
}, nil }, nil
} }
+45
View File
@@ -16,6 +16,13 @@ const (
FriendListPageSize = 40 FriendListPageSize = 40
) )
const (
ClientFriendStatusNone = iota
ClientFriendStatusApproved
ClientFriendStatusPending
ClientFriendStatusAwaitingApproval
)
type UserFriend struct { type UserFriend struct {
ID int `xorm:"id pk autoincr"` ID int `xorm:"id pk autoincr"`
UserID int `xorm:"user_id unique(friend_pair) index"` UserID int `xorm:"user_id unique(friend_pair) index"`
@@ -86,6 +93,44 @@ func EnsureMutualFriendWithIsNew(dbSession *xorm.Session, userID, friendUserID,
return EnsureFriendLink(dbSession, friendUserID, userID, status, friendIsNew) return EnsureFriendLink(dbSession, friendUserID, userID, status, friendIsNew)
} }
func ResolveClientFriendStatus(dbSession *xorm.Session, userID, targetUserID int) (int, error) {
if dbSession == nil || userID <= 0 || targetUserID <= 0 || userID == targetUserID {
return ClientFriendStatusNone, nil
}
link := UserFriend{}
has, err := dbSession.Table(new(UserFriend)).
Where("user_id = ? AND friend_user_id = ?", userID, targetUserID).
Cols("status").
Get(&link)
if err != nil {
return ClientFriendStatusNone, err
}
if !has {
return ClientFriendStatusNone, nil
}
switch link.Status {
case FriendStatusApproved:
isMutual, err := dbSession.Table(new(UserFriend)).
Where("user_id = ? AND friend_user_id = ?", targetUserID, userID).
Where("status = ?", FriendStatusApproved).
Exist()
if err != nil {
return ClientFriendStatusNone, err
}
if isMutual {
return ClientFriendStatusApproved, nil
}
case FriendStatusPending:
return ClientFriendStatusPending, nil
case FriendStatusAwaitingApproval:
return ClientFriendStatusAwaitingApproval, nil
}
return ClientFriendStatusNone, nil
}
func EnsureDefaultFriendship(dbSession *xorm.Session, userID int) error { func EnsureDefaultFriendship(dbSession *xorm.Session, userID int) error {
if dbSession == nil || userID <= 0 { if dbSession == nil || userID <= 0 {
return nil return nil