package user import ( "bytes" "context" "errors" "github.com/saas-mingyang/mingyang-admin-common/i18n" "mingyang-admin-app-api/internal/svc" "mingyang-admin-app-api/internal/types" "mingyang-admin-app-rpc/types/app" "mingyang-admin-app-rpc/utils" "runtime" "strconv" "time" "github.com/zeromicro/go-zero/core/logx" ) type LogoutLogic struct { logx.Logger ctx context.Context svcCtx *svc.ServiceContext } func NewLogoutLogic(ctx context.Context, svcCtx *svc.ServiceContext) *LogoutLogic { return &LogoutLogic{ Logger: logx.WithContext(ctx), ctx: ctx, svcCtx: svcCtx, } } // Logout 在API层添加调用栈信息 func (l *LogoutLogic) Logout() (resp *types.BaseMsgResp, err error) { // 打印调用栈 buf := make([]byte, 1024) n := runtime.Stack(buf, false) l.Logger.Infof("Logout call stack:\n%s", buf[:n]) userContent, err := l.getTokenFromContext() if err != nil { return nil, err } l.Info("UserContent: %v", userContent) l.Infof("Starting Logout RPC call at: %v", time.Now()) // 记录goroutine ID goID := getGoroutineID() l.Logger.Infof("Goroutine ID: %d", goID) _, err = l.svcCtx.AppRpc.LogoutUser(l.ctx, &app.UserToken{ AccessToken: userContent.Token, UserId: userContent.UserID, }) l.Logger.Infof("Finished Logout RPC call at: %v", time.Now()) if err != nil { return nil, err } return &types.BaseMsgResp{Msg: l.svcCtx.Trans.Trans(l.ctx, i18n.Success)}, nil } // 获取goroutine ID func getGoroutineID() uint64 { b := make([]byte, 64) b = b[:runtime.Stack(b, false)] b = bytes.TrimPrefix(b, []byte("goroutine ")) b = b[:bytes.IndexByte(b, ' ')] n, _ := strconv.ParseUint(string(b), 10, 64) return n } // 从上下文中获取 Token func (l *LogoutLogic) getTokenFromContext() (*utils.UserContext, error) { requestContext := utils.GetRequestContext(l.ctx) if requestContext == nil { return nil, errors.New("invalid request context") } return requestContext, nil } // 获取 Token 过期时间 func (l *LogoutLogic) getTokenExpireTime(token string) (time.Time, error) { // 使用 JWTManager 验证并获取 Claims claims, err := l.svcCtx.AppRpc.AuthToken(l.ctx, &app.AuthReq{Token: token}) if err != nil { return time.Time{}, err } return claims.Claims.ExpiresAt.Timestamp.AsTime(), nil }