复制项目

This commit is contained in:
kim.dev.6789
2026-01-14 22:35:45 +08:00
parent 305d526110
commit b7f8db7d08
297 changed files with 81784 additions and 0 deletions

202
internal/rpc/chat/utils.go Normal file
View File

@@ -0,0 +1,202 @@
package chat
import (
"context"
"regexp"
"strconv"
"strings"
"git.imall.cloud/openim/chat/pkg/common/db/dbutil"
table "git.imall.cloud/openim/chat/pkg/common/db/table/chat"
"git.imall.cloud/openim/chat/pkg/eerrs"
"git.imall.cloud/openim/chat/pkg/protocol/chat"
"git.imall.cloud/openim/chat/pkg/protocol/common"
"github.com/openimsdk/tools/errs"
"github.com/openimsdk/tools/utils/datautil"
"github.com/openimsdk/tools/utils/stringutil"
)
func DbToPbAttribute(attribute *table.Attribute) *common.UserPublicInfo {
if attribute == nil {
return nil
}
return &common.UserPublicInfo{
UserID: attribute.UserID,
Account: attribute.Account,
Email: attribute.Email,
Nickname: attribute.Nickname,
FaceURL: attribute.FaceURL,
Gender: attribute.Gender,
Level: attribute.Level,
UserType: attribute.UserType,
}
}
func DbToPbAttributes(attributes []*table.Attribute) []*common.UserPublicInfo {
return datautil.Slice(attributes, DbToPbAttribute)
}
func DbToPbUserFullInfo(attribute *table.Attribute) *common.UserFullInfo {
return &common.UserFullInfo{
UserID: attribute.UserID,
Password: "",
Account: attribute.Account,
PhoneNumber: attribute.PhoneNumber,
AreaCode: attribute.AreaCode,
Email: attribute.Email,
Nickname: attribute.Nickname,
FaceURL: attribute.FaceURL,
Gender: attribute.Gender,
Level: attribute.Level,
UserType: attribute.UserType,
Birth: attribute.BirthTime.UnixMilli(),
AllowAddFriend: attribute.AllowAddFriend,
AllowBeep: attribute.AllowBeep,
AllowVibration: attribute.AllowVibration,
GlobalRecvMsgOpt: attribute.GlobalRecvMsgOpt,
RegisterType: attribute.RegisterType,
UserFlag: attribute.UserFlag,
CreateTime: attribute.CreateTime.UnixMilli(),
Ip: "", // 默认空字符串
}
}
func DbToPbUserFullInfos(attributes []*table.Attribute) []*common.UserFullInfo {
return datautil.Slice(attributes, DbToPbUserFullInfo)
}
func DbToPbUserFullInfoWithIP(attribute *table.Attribute, ip string) *common.UserFullInfo {
return &common.UserFullInfo{
UserID: attribute.UserID,
Password: "",
Account: attribute.Account,
PhoneNumber: attribute.PhoneNumber,
AreaCode: attribute.AreaCode,
Email: attribute.Email,
Nickname: attribute.Nickname,
FaceURL: attribute.FaceURL,
Gender: attribute.Gender,
Level: attribute.Level,
UserType: attribute.UserType,
Birth: attribute.BirthTime.UnixMilli(),
AllowAddFriend: attribute.AllowAddFriend,
AllowBeep: attribute.AllowBeep,
AllowVibration: attribute.AllowVibration,
GlobalRecvMsgOpt: attribute.GlobalRecvMsgOpt,
RegisterType: attribute.RegisterType,
UserFlag: attribute.UserFlag,
CreateTime: attribute.CreateTime.UnixMilli(),
Ip: ip,
}
}
func DbToPbUserFullInfosWithIP(attributes []*table.Attribute, userIPMap map[string]string) []*common.UserFullInfo {
result := make([]*common.UserFullInfo, 0, len(attributes))
for _, attr := range attributes {
ip := userIPMap[attr.UserID]
result = append(result, DbToPbUserFullInfoWithIP(attr, ip))
}
return result
}
// DbToPbUserFullInfosWithRealNameAuth 转换用户信息(包含实名认证信息)
func DbToPbUserFullInfosWithRealNameAuth(attributes []*table.Attribute, walletMap map[string]*table.Wallet) []*common.UserFullInfo {
result := make([]*common.UserFullInfo, 0, len(attributes))
for _, attr := range attributes {
userInfo := DbToPbUserFullInfo(attr)
// 填充实名认证信息
if wallet, ok := walletMap[attr.UserID]; ok {
userInfo.IdCard = wallet.RealNameAuth.IDCard
userInfo.RealName = wallet.RealNameAuth.Name
userInfo.IdCardPhotoFront = wallet.RealNameAuth.IDCardPhotoFront
userInfo.IdCardPhotoBack = wallet.RealNameAuth.IDCardPhotoBack
userInfo.AuditStatus = wallet.RealNameAuth.AuditStatus
}
result = append(result, userInfo)
}
return result
}
// DbToPbUserFullInfosWithRealNameAuthAndIP 转换用户信息包含实名认证信息和IP
func DbToPbUserFullInfosWithRealNameAuthAndIP(attributes []*table.Attribute, walletMap map[string]*table.Wallet, userIPMap map[string]string) []*common.UserFullInfo {
result := make([]*common.UserFullInfo, 0, len(attributes))
for _, attr := range attributes {
ip := userIPMap[attr.UserID]
userInfo := DbToPbUserFullInfoWithIP(attr, ip)
// 填充实名认证信息
if wallet, ok := walletMap[attr.UserID]; ok {
userInfo.IdCard = wallet.RealNameAuth.IDCard
userInfo.RealName = wallet.RealNameAuth.Name
userInfo.IdCardPhotoFront = wallet.RealNameAuth.IDCardPhotoFront
userInfo.IdCardPhotoBack = wallet.RealNameAuth.IDCardPhotoBack
userInfo.AuditStatus = wallet.RealNameAuth.AuditStatus
}
result = append(result, userInfo)
}
return result
}
func BuildCredentialPhone(areaCode, phone string) string {
return areaCode + " " + phone
}
func (o *chatSvr) checkRegisterInfo(ctx context.Context, user *chat.RegisterUserInfo, isAdmin bool) error {
if user == nil {
return errs.ErrArgs.WrapMsg("user is nil")
}
user.Account = strings.TrimSpace(user.Account)
// 如果提供了account则不需要验证phone和email
if user.Account != "" {
// account验证逻辑在后面这里直接跳过"至少需要一个账号"的检查
} else if user.Email == "" && !(user.PhoneNumber != "" && user.AreaCode != "") && !isAdmin {
// 如果没有account也没有email也没有完整的phonephoneNumber和areaCode都提供且不是管理员则报错
return errs.ErrArgs.WrapMsg("at least one valid account is required")
}
if user.PhoneNumber != "" {
if !strings.HasPrefix(user.AreaCode, "+") {
user.AreaCode = "+" + user.AreaCode
}
if _, err := strconv.ParseUint(user.AreaCode[1:], 10, 64); err != nil {
return errs.ErrArgs.WrapMsg("area code must be number")
}
if _, err := strconv.ParseUint(user.PhoneNumber, 10, 64); err != nil {
return errs.ErrArgs.WrapMsg("phone number must be number")
}
_, err := o.Database.TakeAttributeByPhone(ctx, user.AreaCode, user.PhoneNumber)
if err == nil {
return eerrs.ErrPhoneAlreadyRegister.Wrap()
} else if !dbutil.IsDBNotFound(err) {
return err
}
}
if user.Account != "" {
// 验证长度6到20位
if len(user.Account) < 6 || len(user.Account) > 20 {
return errs.ErrArgs.WrapMsg("account must be between 6 and 20 characters")
}
// 验证格式:只能包含数字、字母、下划线(_)、横线(-)
pattern := `^[a-zA-Z0-9_-]+$`
matched, err := regexp.MatchString(pattern, user.Account)
if err != nil || !matched {
return errs.ErrArgs.WrapMsg("account must contain only letters, numbers, underscores, and hyphens")
}
_, err = o.Database.TakeAttributeByAccount(ctx, user.Account)
if err == nil {
return eerrs.ErrAccountAlreadyRegister.Wrap()
} else if !dbutil.IsDBNotFound(err) {
return err
}
}
if user.Email != "" {
if !stringutil.IsValidEmail(user.Email) {
return errs.ErrArgs.WrapMsg("invalid email")
}
_, err := o.Database.TakeAttributeByAccount(ctx, user.Email)
if err == nil {
return eerrs.ErrEmailAlreadyRegister.Wrap()
} else if !dbutil.IsDBNotFound(err) {
return err
}
}
return nil
}