390 lines
11 KiB
Go
390 lines
11 KiB
Go
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
|
|
}
|