app-cloudep-member-server/pkg/usecase/member.go

390 lines
11 KiB
Go
Raw Permalink Normal View History

2024-12-30 03:58:14 +00:00
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
}