package usecase import ( "app-cloudep-member-server/pkg/domain" "app-cloudep-member-server/pkg/domain/entity" "app-cloudep-member-server/pkg/domain/member" "app-cloudep-member-server/pkg/domain/repository" "app-cloudep-member-server/pkg/domain/usecase" "context" "errors" "fmt" "code.30cm.net/digimon/library-go/errs" "code.30cm.net/digimon/library-go/errs/code" "github.com/zeromicro/go-zero/core/logx" "github.com/zeromicro/go-zero/core/stores/mon" ) // HasPasswordFunc 這樣方便測試 var HasPasswordFunc = HashPassword func (use *MemberUseCase) CreateUserAccount(ctx context.Context, req usecase.CreateLoginUserRequest) error { token := "" if req.Platform == member.Digimon { var e error // 密碼加密 token, e = HasPasswordFunc(req.Token, use.Config.Bcrypt.Cost) if e != nil { return errs.NewError( code.CloudEPMember, code.CatSystem, domain.HashPasswordErrorCode, fmt.Sprintf("failed to encrypt err: %s", e.Error()), ) } } err := use.Account.Insert(ctx, &entity.Account{ LoginID: req.LoginID, Token: token, Platform: req.Platform, }) if err != nil { // 錯誤代碼 20-201-02 e := errs.DatabaseErrorWithScopeL( code.CloudEPMember, domain.InsertAccountErrorCode, logx.WithContext(ctx), []logx.LogField{ {Key: "req", Value: req}, {Key: "func", Value: "Account.Insert"}, {Key: "err", Value: err.Error()}, }, "account duplicate").Wrap(err) return e } return nil } func (use *MemberUseCase) GetUIDByAccount(ctx context.Context, req usecase.GetUIDByAccountRequest) (usecase.GetUIDByAccountResponse, error) { account, err := use.AccountUID.FindUIDByLoginID(ctx, req.Account) if err != nil { var e *errs.LibError switch { case errors.Is(err, mon.ErrNotFound): e = errs.ResourceNotFoundWithScope( code.CloudEPMember, domain.FailedFindUIDByLoginIDErrorCode, fmt.Sprintf("failed to insert account: %s", req.Account), ) default: // 錯誤代碼 20-201-07 e = errs.DatabaseErrorWithScopeL( code.CloudEPMember, domain.FailedFindUIDByLoginIDErrorCode, logx.WithContext(ctx), []logx.LogField{ {Key: "req", Value: req}, {Key: "func", Value: "AccountUID.FindUIDByLoginID"}, {Key: "err", Value: err.Error()}, }, "failed to find account").Wrap(err) } return usecase.GetUIDByAccountResponse{}, e } return usecase.GetUIDByAccountResponse{ UID: account.UID, Account: req.Account, }, nil } func (use *MemberUseCase) GetUserAccountInfo(ctx context.Context, req usecase.GetUIDByAccountRequest) (usecase.GetAccountInfoResponse, error) { account, err := use.Account.FindOneByAccount(ctx, req.Account) if err != nil { var e *errs.LibError switch { case errors.Is(err, mon.ErrNotFound): // 錯誤代碼 20-301-08 e = errs.ResourceNotFoundWithScope( code.CloudEPMember, domain.FailedFindOneByAccountErrorCode, fmt.Sprintf("failed to find account: %s", req.Account), ) default: // 錯誤代碼 20-201-08 e = errs.DatabaseErrorWithScopeL( code.CloudEPMember, domain.FailedFindOneByAccountErrorCode, logx.WithContext(ctx), []logx.LogField{ {Key: "req", Value: req}, {Key: "func", Value: "Account.FindOneByAccount"}, {Key: "err", Value: err.Error()}, }, "failed to find account").Wrap(err) } return usecase.GetAccountInfoResponse{}, e } return usecase.GetAccountInfoResponse{ Data: usecase.CreateLoginUserRequest{ LoginID: account.LoginID, Platform: account.Platform, Token: account.Token, }, }, nil } // =========================== func (use *MemberUseCase) GetUserInfo(ctx context.Context, req usecase.GetUserInfoRequest) (usecase.UserInfo, error) { var user *entity.User var err error switch { case req.UID != "": user, err = use.User.FindOneByUID(ctx, req.UID) case req.NickName != "": user, err = use.User.FindOneByNickName(ctx, req.NickName) default: // 驗證至少提供一個查詢參數 return usecase.UserInfo{}, errs.InvalidFormatWithScope( code.CloudEPMember, "UID or NickName must be provided", ) } // 查詢失敗時處理錯誤 if err != nil { return usecase.UserInfo{}, handleUserQueryError(ctx, err, req) } // 返回查詢結果 return mapUserEntityToUserInfo(user), nil } // 將查詢錯誤處理邏輯封裝為單獨的函數 func handleUserQueryError(ctx context.Context, err error, req usecase.GetUserInfoRequest) error { if errors.Is(err, mon.ErrNotFound) { return errs.ResourceNotFoundWithScope( code.CloudEPMember, domain.FailedToGetUserInfoErrorCode, fmt.Sprintf("user not found: %s", req.UID), ) } return errs.DatabaseErrorWithScopeL( code.CloudEPMember, domain.FailedToGetUserInfoErrorCode, logx.WithContext(ctx), []logx.LogField{ {Key: "req", Value: req}, {Key: "func", Value: "MemberUseCase.GetUserInfo"}, {Key: "err", Value: err.Error()}, }, "failed to query user info").Wrap(err) } // 將用戶實體轉換為業務層數據結構 func mapUserEntityToUserInfo(user *entity.User) usecase.UserInfo { return usecase.UserInfo{ CreateUserInfoRequest: usecase.CreateUserInfoRequest{ UID: user.UID, AlarmCategory: user.AlarmCategory, UserStatus: user.UserStatus, PreferredLanguage: user.PreferredLanguage, Currency: user.Currency, Nickname: user.Nickname, AvatarURL: user.AvatarURL, FullName: user.FullName, GenderCode: user.GenderCode, Birthdate: user.Birthdate, PhoneNumber: user.PhoneNumber, Address: user.Address, Email: user.Email, }, CreateTime: GetOriginalInt64(user.CreateAt), UpdateTime: GetOriginalInt64(user.UpdateAt), } } // =========================== func (use *MemberUseCase) UpdateUserToken(ctx context.Context, req usecase.UpdateTokenRequest) error { // 密碼加密 token, e := HasPasswordFunc(req.Token, use.Config.Bcrypt.Cost) if e != nil { return errs.NewError( code.CloudEPMember, code.CatSystem, domain.HashPasswordErrorCode, fmt.Sprintf("failed to encrypt err: %s", e.Error()), ) } err := use.Account.UpdateTokenByLoginID(ctx, req.Account, token) if err != nil { var e *errs.LibError switch { case errors.Is(err, mon.ErrNotFound): // 錯誤代碼 20-301-08 e = errs.ResourceNotFoundWithScope( code.CloudEPMember, domain.FailedToUpdatePasswordErrorCode, fmt.Sprintf("failed to upadte password since account not found: %s", req.Account), ) default: // 錯誤代碼 20-201-02 e = errs.DatabaseErrorWithScopeL( code.CloudEPMember, domain.FailedToUpdatePasswordErrorCode, logx.WithContext(ctx), []logx.LogField{ {Key: "req", Value: req}, {Key: "func", Value: "Account.UpdateTokenByLoginID"}, {Key: "err", Value: err.Error()}, }, "failed to update password").Wrap(err) } return e } return nil } func (use *MemberUseCase) UpdateUserInfo(ctx context.Context, req *usecase.UpdateUserInfoRequest) error { err := use.User.UpdateUserDetailsByUID(ctx, &repository.UpdateUserInfoRequest{ UID: req.UID, AvatarURL: req.AvatarURL, FullName: req.FullName, Nickname: req.Nickname, GenderCode: req.GenderCode, Birthdate: req.Birthdate, Address: req.Address, AlarmCategory: req.AlarmCategory, UserStatus: req.UserStatus, PreferredLanguage: req.PreferredLanguage, Currency: req.Currency, }) if err != nil { var e *errs.LibError switch { case errors.Is(err, mon.ErrNotFound): e = errs.ResourceNotFoundWithScope( code.CloudEPMember, domain.FailedToUpdateUserErrorCode, fmt.Sprintf("failed to upadte use info since account not found: %s", req.UID), ) default: e = errs.DatabaseErrorWithScopeL( code.CloudEPMember, domain.FailedToUpdateUserErrorCode, logx.WithContext(ctx), []logx.LogField{ {Key: "req", Value: req}, {Key: "func", Value: "User.UpdateUserDetailsByUid"}, {Key: "err", Value: err.Error()}, }, "failed to update user info").Wrap(err) } return e } return nil } func (use *MemberUseCase) UpdateStatus(ctx context.Context, req usecase.UpdateStatusRequest) error { err := use.User.UpdateStatus(ctx, req.UID, req.Status.ToInt32()) if err != nil { var e *errs.LibError switch { case errors.Is(err, mon.ErrNotFound): e = errs.ResourceNotFoundWithScope( code.CloudEPMember, domain.FailedToFindUserErrorCode, fmt.Sprintf("failed to upadte use info since account not found: %s", req.UID), ) default: e = errs.DatabaseErrorWithScopeL( code.CloudEPMember, domain.FailedToUpdateUserStatusErrorCode, logx.WithContext(ctx), []logx.LogField{ {Key: "req", Value: req}, {Key: "func", Value: "User.UpdateStatus"}, {Key: "err", Value: err.Error()}, }, "failed to update user info").Wrap(err) } return e } return nil } func (use *MemberUseCase) ListMember(ctx context.Context, req usecase.ListUserInfoRequest) (usecase.ListUserInfoResponse, error) { listMembers, total, err := use.User.ListMembers(ctx, &repository.UserQueryParams{ AlarmCategory: req.AlarmCategory, UserStatus: req.UserStatus, CreateStartTime: req.CreateStartTime, CreateEndTime: req.CreateEndTime, PageSize: req.PageSize, PageIndex: req.PageIndex, }) if err != nil { e := errs.DatabaseErrorWithScopeL( code.CloudEPMember, domain.FailedToGetUserInfoErrorCode, logx.WithContext(ctx), []logx.LogField{ {Key: "req", Value: req}, {Key: "func", Value: "User.ListMembers"}, {Key: "err", Value: err.Error()}, }, "failed to list members").Wrap(err) return usecase.ListUserInfoResponse{}, e } var data = make([]usecase.UserInfo, 0, len(listMembers)) for _, item := range listMembers { data = append(data, usecase.UserInfo{ CreateUserInfoRequest: usecase.CreateUserInfoRequest{ UID: item.UID, AlarmCategory: item.AlarmCategory, UserStatus: item.UserStatus, PreferredLanguage: item.PreferredLanguage, Currency: item.Currency, Nickname: item.Nickname, AvatarURL: item.AvatarURL, // 按照先前的命名 AvatarURL FullName: item.FullName, GenderCode: item.GenderCode, Birthdate: item.Birthdate, PhoneNumber: item.PhoneNumber, Address: item.Address, Email: item.Email, }, CreateTime: GetOriginalInt64(item.CreateAt), // 使用自定義指標轉換函數 UpdateTime: GetOriginalInt64(item.UpdateAt), }) } return usecase.ListUserInfoResponse{ Data: data, Page: usecase.Pager{ Total: total, Index: req.PageIndex, Size: req.PageSize, }, }, nil } // GetOriginalInt64 取得原始值的函數 func GetOriginalInt64(value *int64) int64 { if value == nil { return 0 // 處理 nil 的情況 } return *value }