From 631597aeec736aa1434b6e7270376f6c97d88f11 Mon Sep 17 00:00:00 2001 From: hujiebin Date: Mon, 6 Mar 2023 09:29:19 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E5=85=88=E5=A4=84=E7=90=86=E5=9B=BD?= =?UTF-8?q?=E5=AE=B6=E5=8A=BF=E5=8A=9B=E7=9A=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _const/enum/group_e/enum.go | 2 + cv/user_cv/user.go | 177 ++++++++++++++++++++++--- domain/model/country_m/country_mgr.go | 40 ++++++ domain/model/user_m/oauth.go | 35 +++++ domain/model/user_m/phone.go | 38 ++++++ domain/service/group_s/welcome_text.go | 34 +++++ route/group_r/group_op.go | 14 +- route/router.go | 2 +- 8 files changed, 315 insertions(+), 27 deletions(-) create mode 100644 domain/model/country_m/country_mgr.go create mode 100644 domain/model/user_m/oauth.go create mode 100644 domain/model/user_m/phone.go create mode 100644 domain/service/group_s/welcome_text.go diff --git a/_const/enum/group_e/enum.go b/_const/enum/group_e/enum.go index 8d3c27c..e10a7f3 100644 --- a/_const/enum/group_e/enum.go +++ b/_const/enum/group_e/enum.go @@ -132,3 +132,5 @@ const ( SWITCH_ON = 1 SWITH_OFF = 0 ) + +var GROUP_ROLE_VIEW_LIMIT = 10 diff --git a/cv/user_cv/user.go b/cv/user_cv/user.go index a503a5f..df3cbb2 100644 --- a/cv/user_cv/user.go +++ b/cv/user_cv/user.go @@ -14,6 +14,7 @@ import ( "hilo-group/cv/medal_cv" "hilo-group/cv/noble_cv" "hilo-group/cv/property_cv" + "hilo-group/domain/model/country_m" "hilo-group/domain/model/groupPower_m" "hilo-group/domain/model/group_m" "hilo-group/domain/model/noble_m" @@ -49,20 +50,20 @@ type CvUserDetail struct { //是否可以免费通话,自己本人没有数据 //IsVideoFreeCan *bool `json:"isVideoCanFree"` //别人是否喜欢我,自己本人没有数据 (20210205 已废弃nil,产品说:可以自己喜欢自己) - IsLikeMe *bool `json:"isLikeMe"` - HeartValue uint32 `json:"heartValue"` // 与我之间永恒之心的值 - HeartValueMax uint32 `json:"heartValueMax"` // 与我之间永恒之心的最大值(0代表没有永恒之心,即没有相互关注) - MeetDays uint `json:"meetDays"` // 成长关系建立的时间(天数) - WealthUserGrade uint32 `json:"wealthUserGrade"` //财富等级 - CharmUserGrade uint32 `json:"charmUserGrade"` //魅力等级 - ActivityUserGrade uint32 `json:"activityUserGrade"` //活跃等级 - CurrentRoom string `json:"currentRoom"` // 当前用户所在房间(产品叫“群组”) - MyGroupPower uint64 `json:"myGroupPower"` // 当前用户所在势力 - MyGroupPowerName string `json:"myGroupPowerName"` // 当前用户所在势力绑定群组的名称 - GroupId string `json:"groupId"` // 当前用户拥有的群组id(产品叫“群组”),如果没有则为空,拥有多个,返回第一个 - //PhoneInfo *model.UserPhoneInfo `json:"phoneInfo"` // 用户绑定的手机信息 - ThirdList []int8 `json:"thirdList"` // 用户绑定的第三方平台列表;类型 1:phone, 2:google, 3:facebook 4:apple 5:wechat" Enums(1,2,3,4,5) - CountryManager *country_cv.CVCountryManager `json:"countryManager,omitempty"` // 国家管理员 + IsLikeMe *bool `json:"isLikeMe"` + HeartValue uint32 `json:"heartValue"` // 与我之间永恒之心的值 + HeartValueMax uint32 `json:"heartValueMax"` // 与我之间永恒之心的最大值(0代表没有永恒之心,即没有相互关注) + MeetDays uint `json:"meetDays"` // 成长关系建立的时间(天数) + WealthUserGrade uint32 `json:"wealthUserGrade"` //财富等级 + CharmUserGrade uint32 `json:"charmUserGrade"` //魅力等级 + ActivityUserGrade uint32 `json:"activityUserGrade"` //活跃等级 + CurrentRoom string `json:"currentRoom"` // 当前用户所在房间(产品叫“群组”) + MyGroupPower uint64 `json:"myGroupPower"` // 当前用户所在势力 + MyGroupPowerName string `json:"myGroupPowerName"` // 当前用户所在势力绑定群组的名称 + GroupId string `json:"groupId"` // 当前用户拥有的群组id(产品叫“群组”),如果没有则为空,拥有多个,返回第一个 + PhoneInfo *user_m.UserPhoneInfo `json:"phoneInfo"` // 用户绑定的手机信息 + ThirdList []int8 `json:"thirdList"` // 用户绑定的第三方平台列表;类型 1:phone, 2:google, 3:facebook 4:apple 5:wechat" Enums(1,2,3,4,5) + CountryManager *country_cv.CVCountryManager `json:"countryManager,omitempty"` // 国家管理员 } type CvUserTiny struct { @@ -713,12 +714,12 @@ func GetUserDetail(model *domain.Model, userId mysql.ID, myUserId mysql.ID) (*Cv // 手机绑定信息 // 第三方账号绑定信息 - phoneInfo := new(model2.UserPhoneInfo) + phoneInfo := new(user_m.UserPhoneInfo) var thirdList []int8 if userId == myUserId { thirdList = make([]int8, 0, 5) // 手机绑定信息 - bindInfo, err := dao.UserBindInfoDb.GetByUserId(userId) + bindInfo, err := user_m.GetUserBindInfoByUserId(model, userId) if err != nil && err != gorm.ErrRecordNotFound { return nil, err } @@ -732,7 +733,7 @@ func GetUserDetail(model *domain.Model, userId mysql.ID, myUserId mysql.ID) (*Cv thirdList = append(thirdList, 1) } // 第三方账号绑定信息 - thirdInfoList, err := dao.UserOauthDb.GetByUserId(userId, 0) + thirdInfoList, err := user_m.GetUserOauthByUserId(model, userId, 0) if err != nil { return nil, err } @@ -747,9 +748,9 @@ func GetUserDetail(model *domain.Model, userId mysql.ID, myUserId mysql.ID) (*Cv if err != nil { return nil, err } - var cvCountryManager *CVCountryManager + var cvCountryManager *country_cv.CVCountryManager if countryManager != nil { - cvCountryManager = &CVCountryManager{ + cvCountryManager = &country_cv.CVCountryManager{ Country: countryManager.Country, Role: countryManager.Role, } @@ -760,3 +761,141 @@ func GetUserDetail(model *domain.Model, userId mysql.ID, myUserId mysql.ID) (*Cv activityUserScore.Grade, medals[userId], medalInfo[userId], rooms[userId], powers[userId], powerNames[userId], noble, superManagerMap[userId], myGroups, phoneInfo, thirdList, cvCountryManager) } + +// 单用户版,简化参数 +func userToDetailOne(model *domain.Model, user *user_m.User, myUserId mysql.ID, userTradeUnion *user_m.UserTradeUnion, isLike bool, likeMe bool, hvMap map[mysql.ID]Relation, + isVip bool, vipExpireTime *int64, svip rpc.CvSvip, headwear *headwear_cv.CvHeadwear, ride property_cv.CvProperty, wealthGrade uint32, charmGrade uint32, activityGrade uint32, + medals []uint32, medalInfo []medal_cv.CvMedal, room string, power uint64, powerName string, noble *noble_m.UserNoble, isOfficialStaff bool, + myGroups []group_m.GroupInfo, phoneInfo *user_m.UserPhoneInfo, thirdList []int8, countryManager *country_cv.CVCountryManager) (*CvUserDetail, error) { + + room, err := group_m.ToTxGroupId(model, room) + if err != nil { + model.Log.Warnf("ToTxGroupId failed for %s, err:%v", room, err) + room = "" + } + + cvUserDetail := &CvUserDetail{ + CvUserBase: CvUserBase{ + Id: &user.ID, + Avatar: StrNil(IfLogoutStr(IfLogout(user.LogoutTime), "", user.Avatar)), + DefaultAvatar: &user.DefaultAvatar, + ExternalId: StrToString(&user.ExternalId), + Nick: StrNil(IfLogoutStr(IfLogout(user.LogoutTime), user.Code, user.Nick)), + Description: StrNil(IfLogoutStr(IfLogout(user.LogoutTime), "", user.Description)), + Sex: TypeToUint8(&user.Sex), + Country: StrNil(user.Country), + CountryIcon: StrNil(user.CountryIcon), + Code: StrToString(&user.Code), + IsPrettyCode: user.IsPrettyCode(), + IsVip: isVip, + IsOfficialStaff: isOfficialStaff, + VipExpireTime: vipExpireTime, + Svip: svip, + Medals: IfLogoutMedals(IfLogout(user.LogoutTime), []uint32{}, medals), + MedalInfo: IfLogoutMedalInfo(IfLogout(user.LogoutTime), []medal_cv.CvMedal{}, medalInfo), + Headwear: IfLogoutHeadwear(IfLogout(user.LogoutTime), nil, headwear), + Ride: IfLogoutRide(IfLogout(user.LogoutTime), property_cv.CvProperty{}, ride), + }, + IsPush: TypeToUint8(&user.IsPush), + IsLike: &isLike, + IsLikeMe: &likeMe, + WealthUserGrade: wealthGrade, + CharmUserGrade: charmGrade, + ActivityUserGrade: activityGrade, + CurrentRoom: room, + MyGroupPower: power, + MyGroupPowerName: powerName, + PhoneInfo: phoneInfo, + ThirdList: thirdList, + CountryManager: countryManager, + } + if noble != nil { + cvUserDetail.Noble = noble_cv.CvNoble{ + Level: noble.Level, + EndTime: noble.EndTime.Unix(), + } + } + + //本人,计算,喜欢统计,钻石数量 + if user.ID == myUserId { + cvUserDetail.IsShowAge = TypeToUint8((*mysql.Type)(&user.IsShowAge)) + cvUserDetail.Birthday = BirthdayToUint64(&user.Birthday) + + //喜欢统计 + var userCount user_m.UserCount + err := mysql.Db.Where(&user_m.UserCount{ + UserId: myUserId, + Type: user_e.CountTypeLikeMe, + }).First(&userCount).Error + if err != nil && err != gorm.ErrRecordNotFound { + return nil, myerr.WrapErr(err) + } + cvUserDetail.LikeCount = NumToUint32(&userCount.Num) + + //我喜欢统计 + var userILikeCount user_m.UserCount + err = mysql.Db.Where(&user_m.UserCount{ + UserId: myUserId, + Type: user_e.CountTypeLike, + }).First(&userILikeCount).Error + if err != nil && err != gorm.ErrRecordNotFound { + return nil, myerr.WrapErr(err) + } + cvUserDetail.ILikeCount = NumToUint32(&userILikeCount.Num) + + //访问统计 + var visitCount int64 + err = mysql.Db.Model(&visit_m.UserVisit{}).Where(&visit_m.UserVisit{ + VisitUserId: myUserId, + }).Count(&visitCount).Error + if err != nil && err != gorm.ErrRecordNotFound { + return nil, myerr.WrapErr(err) + } + vc := uint32(visitCount) + cvUserDetail.VisitCount = NumToUint32((*mysql.Num)(&vc)) + + //钻石数量 + cvDiamond, err := diamond_cv.GetDiamond(myUserId) + if err != nil { + return nil, err + } + cvUserDetail.DiamondNum = cvDiamond.DiamondNum + cvUserDetail.PinkDiamondNum = cvDiamond.PinkDiamondNum + + isAgent := user_m.IsAgent(myUserId) + cvUserDetail.IsAgentMgr = &isAgent + } else { + //不是本人 + if user.IsShowAge == mysql.OPEN { + cvUserDetail.Birthday = BirthdayToUint64(&user.Birthday) + } + } + + if userTradeUnion == nil { + isTradeUnionFlag := false + cvUserDetail.IsTradeUnion = &isTradeUnionFlag + cvUserDetail.IsTradeUnionMatchNotification = nil + } else { + isTradeUnionFlag := true + cvUserDetail.IsTradeUnion = &isTradeUnionFlag + isTradeUnionMatchNotificationFlag := userTradeUnion.MatchNotification == mysql.OPEN + cvUserDetail.IsTradeUnionMatchNotification = &isTradeUnionMatchNotificationFlag + } + + // 永恒之心的值 + hv, ok := hvMap[user.ID] + if ok { + cvUserDetail.HeartValue = hv.HeartValue + cvUserDetail.HeartValueMax = hv.HeartValueMax + cvUserDetail.MeetDays = hv.MeetDays + } else { + cvUserDetail.HeartValueMax = 0 + } + + // 拥有的群组id + if len(myGroups) > 0 { + cvUserDetail.GroupId = myGroups[0].TxGroupId + } + + return cvUserDetail, nil +} diff --git a/domain/model/country_m/country_mgr.go b/domain/model/country_m/country_mgr.go new file mode 100644 index 0000000..38dbd25 --- /dev/null +++ b/domain/model/country_m/country_mgr.go @@ -0,0 +1,40 @@ +package country_m + +import ( + "git.hilo.cn/hilo-common/domain" + "git.hilo.cn/hilo-common/resource/mysql" + "gorm.io/gorm" + "hilo-group/_const/enum/country_e" + "hilo-group/myerr" +) + +type CountryMgrUser struct { + mysql.Entity + Country string + UserId mysql.ID + Role country_e.CountryMgrRole +} + +// 获取国家管理人员 +func GetCountryMgr(model *domain.Model, userId mysql.ID) (*CountryMgrUser, error) { + cmu := new(CountryMgrUser) + if err := model.Db.WithContext(model.MyContext.Context).Where("user_id = ?", userId).First(&cmu).Error; err != nil { + if err == gorm.ErrRecordNotFound { + return nil, nil + } else { + return nil, myerr.WrapErr(err) + } + } + return cmu, nil +} + +// 更新国家管理人员 +func (cmu *CountryMgrUser) UpdateCountryMgr(userId mysql.ID, role country_e.CountryMgrRole, country string) *CountryMgrUser { + cmu.UserId, cmu.Role, cmu.Country = userId, role, country + return cmu +} + +// 删除国家管理人员 +func (cmu *CountryMgrUser) DeleteCountryMgr() { + cmu.SetDel() +} diff --git a/domain/model/user_m/oauth.go b/domain/model/user_m/oauth.go new file mode 100644 index 0000000..4ffaf06 --- /dev/null +++ b/domain/model/user_m/oauth.go @@ -0,0 +1,35 @@ +package user_m + +import ( + "git.hilo.cn/hilo-common/domain" + "git.hilo.cn/hilo-common/resource/mysql" + "gorm.io/gorm" + "hilo-group/myerr" +) + +type UserOauth struct { + UserId uint64 `json:"user_id"` + ThirdPartyId string `json:"third_party_id"` + ThirdPartyType int8 `json:"third_party_type"` +} + +func (p *UserOauth) TableName() string { + return "user_oauth" +} + +func GetUserOauthByUserId(model *domain.Model, userId uint64, thirdType uint8) ([]*UserOauth, error) { + res := make([]*UserOauth, 0) + db := mysql.Db.Where(&UserOauth{UserId: userId}) + if thirdType > 0 { + db = db.Where(&UserOauth{ThirdPartyType: int8(thirdType)}) + } + err := db.Find(&res).Error + if err != nil { + if err == gorm.ErrRecordNotFound { + return nil, nil + } else { + return nil, myerr.WrapErr(err) + } + } + return res, nil +} diff --git a/domain/model/user_m/phone.go b/domain/model/user_m/phone.go new file mode 100644 index 0000000..47cf919 --- /dev/null +++ b/domain/model/user_m/phone.go @@ -0,0 +1,38 @@ +package user_m + +import ( + "git.hilo.cn/hilo-common/domain" + "git.hilo.cn/hilo-common/resource/mysql" + "time" +) + +type UserBindInfo struct { + UserId uint64 `json:"user_id"` + Phone string `json:"phone"` + PhoneCountry string `json:"phone_country"` + Pwd string `json:"pwd"` + AreaCode string `json:"area_code"` + Icon string `json:"icon"` + CreateAt time.Time `json:"create_at"` + UpdateAt time.Time `json:"update_at"` +} + +func (p *UserBindInfo) TableName() string { + return "user_bind_info" +} + +type UserPhoneInfo struct { + Phone string `json:"phone"` + PhoneCountry string `json:"phoneCountry"` + AreaCode string `json:"areaCode"` + Icon string `json:"icon"` +} + +func GetUserBindInfoByUserId(model *domain.Model, userId uint64) (*UserBindInfo, error) { + res := new(UserBindInfo) + err := mysql.Db.Where(&UserBindInfo{UserId: userId}).First(&res).Error + if err != nil { + return nil, err + } + return res, nil +} diff --git a/domain/service/group_s/welcome_text.go b/domain/service/group_s/welcome_text.go new file mode 100644 index 0000000..1edf0e5 --- /dev/null +++ b/domain/service/group_s/welcome_text.go @@ -0,0 +1,34 @@ +package group_s + +import ( + "git.hilo.cn/hilo-common/domain" + "hilo-group/_const/enum/msg_e" + "hilo-group/domain/model/group_m" + "hilo-group/domain/model/res_m" +) + +func (s *GroupService) GetWelcomeText(groupInfo *group_m.GroupInfo) (string, uint64, bool, error) { + model := domain.CreateModelContext(s.svc.MyContext) + + g := group_m.GroupWelcomeText{GroupId: groupInfo.ImGroupId} + gwt, err := g.Get(model.Db) + if err != nil { + return "", 0, false, err + } + + if gwt == nil { + // 通过国家推断语言 + lang, err := res_m.GetLangeByCountry(model.Db, groupInfo.Country) + if err != nil { + return "", 0, false, err + } + + resMul, err := res_m.GetResMultiTextBy(model.Db, msg_e.MSG_ID_GROUP_WELCOME, lang) + if err != nil { + return "", 0, false, err + } + return resMul.Content, groupInfo.Owner, true, nil + } else { + return gwt.Text, gwt.UserId, false, nil + } +} diff --git a/route/group_r/group_op.go b/route/group_r/group_op.go index dee8674..cbb93a2 100644 --- a/route/group_r/group_op.go +++ b/route/group_r/group_op.go @@ -391,7 +391,7 @@ func GetGroupDetail(c *gin.Context) (*mycontext.MyContext, error) { } model.Log.Infof("GetGroupDetail, after GetGroupTop3Consume: +%v", result) - result.WelcomeText, _, _, err = myService.GetWelcomeText(groupInfo) + result.WelcomeText, _, _, err = group_s.NewGroupService(myContext).GetWelcomeText(groupInfo) if err != nil { return myContext, err } @@ -488,7 +488,7 @@ func GetGroupDetail(c *gin.Context) (*mycontext.MyContext, error) { return myContext, err } */ - superManagerMap, err := cv.GetSuperManagerMap(userIds) + superManagerMap, err := user_m.GetSuperManagerMap(userIds) if err != nil { return myContext, err } @@ -497,8 +497,8 @@ func GetGroupDetail(c *gin.Context) (*mycontext.MyContext, error) { for u, _ := range users { m := users[u] - result.RoleMembers = append(result.RoleMembers, cv.RoleMemberInfo{ - CvUserBase: cv.CvUserBase{ + result.RoleMembers = append(result.RoleMembers, group_cv.RoleMemberInfo{ + CvUserBase: user_cv.CvUserBase{ Avatar: &m.Avatar, ExternalId: &m.ExternalId, Nick: &m.Nick, @@ -530,20 +530,20 @@ func GetGroupDetail(c *gin.Context) (*mycontext.MyContext, error) { }) // 截取前N个 - endPos := common.GROUP_ROLE_VIEW_LIMIT + endPos := group_e.GROUP_ROLE_VIEW_LIMIT if endPos > len(result.RoleMembers) { endPos = len(result.RoleMembers) } result.RoleMembers = result.RoleMembers[0:endPos] // todo: 直接用全量接口,只为方便 - supportLevels, err := myService.GetWeekMaxSupportLevelMap() + supportLevels, err := group_s.NewGroupService(myContext).GetWeekMaxSupportLevelMap() if err != nil { return myContext, err } result.SupportLevel = supportLevels[groupId] - ResponseOk(c, result) + resp.ResponseOk(c, result) return myContext, nil } diff --git a/route/router.go b/route/router.go index 5fe09c3..ba730e3 100644 --- a/route/router.go +++ b/route/router.go @@ -25,7 +25,7 @@ func InitRouter() *gin.Engine { imGroup.POST("/group", wrapper(group_r.CreateGroup)) imGroup.DELETE("/group/:groupId", wrapper(group_r.DestroyGroup)) imGroup.GET("/group/:code", wrapper(group_r.GetGroupInfo)) - imGroup.GET("/detail/:groupId", wrapper(GetGroupDetail)) + imGroup.GET("/detail/:groupId", wrapper(group_r.GetGroupDetail)) //imGroup.PUT("/group/:groupId", wrapper(ModifyGroupInfo)) //imGroup.GET("/search/:code", wrapper(SearchGroup)) //imGroup.DELETE("/member/:groupId", wrapper(LeaveGroup)) -- 2.22.0