All checks were successful
Build docker and publish / build (20.15.1) (push) Successful in 4m57s
- 新增数据库迁移文件添加last_login_time字段 - 在登录逻辑中更新最后登录时间 - 添加FindActiveSubscribesByUserIds方法查询用户订阅状态 - 在用户列表接口中聚合最后登录时间和会员状态信息 - 更新相关API定义和模型结构 - 修复迁移文件版本号冲突问题 - 移除omitempty标签确保字段始终返回
94 lines
2.6 KiB
Go
94 lines
2.6 KiB
Go
package user
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/perfect-panel/server/internal/model/user"
|
|
"github.com/perfect-panel/server/internal/svc"
|
|
"github.com/perfect-panel/server/internal/types"
|
|
"github.com/perfect-panel/server/pkg/logger"
|
|
"github.com/perfect-panel/server/pkg/phone"
|
|
"github.com/perfect-panel/server/pkg/tool"
|
|
"github.com/perfect-panel/server/pkg/xerr"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
type GetUserListLogic struct {
|
|
ctx context.Context
|
|
svcCtx *svc.ServiceContext
|
|
logger.Logger
|
|
}
|
|
|
|
func NewGetUserListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetUserListLogic {
|
|
return &GetUserListLogic{
|
|
ctx: ctx,
|
|
svcCtx: svcCtx,
|
|
Logger: logger.WithContext(ctx),
|
|
}
|
|
}
|
|
func (l *GetUserListLogic) GetUserList(req *types.GetUserListRequest) (*types.GetUserListResponse, error) {
|
|
list, total, err := l.svcCtx.UserModel.QueryPageList(l.ctx, req.Page, req.Size, &user.UserFilterParams{
|
|
UserId: req.UserId,
|
|
Search: req.Search,
|
|
SubscribeId: req.SubscribeId,
|
|
UserSubscribeId: req.UserSubscribeId,
|
|
DeviceId: req.DeviceId,
|
|
Order: "DESC",
|
|
})
|
|
if err != nil {
|
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "GetUserListLogic failed: %v", err.Error())
|
|
}
|
|
|
|
// Batch fetch active subscriptions
|
|
userIds := make([]int64, 0, len(list))
|
|
for _, u := range list {
|
|
userIds = append(userIds, u.Id)
|
|
}
|
|
activeSubs, err := l.svcCtx.UserModel.FindActiveSubscribesByUserIds(l.ctx, userIds)
|
|
if err != nil {
|
|
// Log error but continue
|
|
l.Logger.Error("FindActiveSubscribesByUserIds failed", logger.Field("error", err.Error()))
|
|
}
|
|
|
|
userRespList := make([]types.User, 0, len(list))
|
|
|
|
for _, item := range list {
|
|
var u types.User
|
|
tool.DeepCopy(&u, item)
|
|
|
|
// Set LastLoginTime
|
|
if item.LastLoginTime != nil {
|
|
u.LastLoginTime = item.LastLoginTime.Unix()
|
|
}
|
|
|
|
// Set MemberStatus and update LastLoginTime from traffic
|
|
if info, ok := activeSubs[item.Id]; ok {
|
|
u.MemberStatus = info.MemberStatus
|
|
|
|
if info.LastTrafficAt != nil {
|
|
trafficTime := info.LastTrafficAt.Unix()
|
|
if trafficTime > u.LastLoginTime {
|
|
u.LastLoginTime = trafficTime
|
|
}
|
|
}
|
|
}
|
|
|
|
// 处理 AuthMethods
|
|
authMethods := make([]types.UserAuthMethod, len(u.AuthMethods)) // 直接创建目标 slice
|
|
for i, method := range u.AuthMethods {
|
|
tool.DeepCopy(&authMethods[i], method)
|
|
if method.AuthType == "mobile" {
|
|
authMethods[i].AuthIdentifier = phone.FormatToInternational(method.AuthIdentifier)
|
|
}
|
|
}
|
|
u.AuthMethods = authMethods
|
|
|
|
userRespList = append(userRespList, u)
|
|
}
|
|
|
|
return &types.GetUserListResponse{
|
|
Total: total,
|
|
List: userRespList,
|
|
}, nil
|
|
}
|