user.go 14.5 KB
Newer Older
hujiebin's avatar
hujiebin committed
1 2 3 4
package rpc

import (
	"encoding/json"
hujiebin's avatar
hujiebin committed
5
	"errors"
hujiebin's avatar
hujiebin committed
6
	"fmt"
hujiebin's avatar
hujiebin committed
7
	"git.hilo.cn/hilo-common/_const/common"
hujiebin's avatar
hujiebin committed
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
	"git.hilo.cn/hilo-common/domain"
	"git.hilo.cn/hilo-common/mylogrus"
	"git.hilo.cn/hilo-common/resource/consul"
	"git.hilo.cn/hilo-common/resource/mysql"
	"math/rand"
)

const (
	defaultUserConsulName   = "hiloUser"
	defaultUserServerScheme = "http"
	defaultUserServerAddr   = "127.0.0.1:9040" // 默认内网转发,本地回环
)

var UserServerHost = []string{defaultUserServerAddr}

func init() {
	go func() {
hujiebin's avatar
hujiebin committed
25 26 27
		consul.RegisterWatcher(defaultUserConsulName, func(addr []string) {
			if len(addr) > 0 {
				UserServerHost = addr
hujiebin's avatar
hujiebin committed
28
			}
hujiebin's avatar
hujiebin committed
29
		})
hujiebin's avatar
hujiebin committed
30 31 32 33 34 35 36
	}()
}

type CvUserLevel struct {
	UserId          mysql.ID `json:"userId"`          // 用户id
	WealthUserGrade uint32   `json:"wealthUserGrade"` //财富等级
	CharmUserGrade  uint32   `json:"charmUserGrade"`  //魅力等级
hujiebin's avatar
hujiebin committed
37 38
	ActiveUserGrade uint32   `json:"activeUserGrade"` // 活跃等级
	NobleLevel      uint16   `json:"nobleLevel"`      // 贵族等级
hujiebin's avatar
hujiebin committed
39 40 41 42 43 44 45 46 47 48 49 50 51 52
}

// 获取用户等级
func GetUserLevel(model *domain.Model, userId mysql.ID) (CvUserLevel, error) {
	level, err := MGetUserLevel(model, []mysql.ID{userId})
	if err != nil {
		return CvUserLevel{}, nil
	}
	return level[userId], nil
}

// 批量获取用户等级
func MGetUserLevel(model *domain.Model, userIds []mysql.ID) (map[mysql.ID]CvUserLevel, error) {
	type Response struct {
hujiebin's avatar
hujiebin committed
53 54 55
		Code    int                      `json:"code"`
		Message string                   `json:"message"`
		Data    map[mysql.ID]CvUserLevel `json:"data"`
hujiebin's avatar
hujiebin committed
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
	}
	var res = make(map[mysql.ID]CvUserLevel)
	if len(userIds) <= 0 {
		return res, nil
	}
	var userIdsStr []string
	for _, userId := range userIds {
		userIdsStr = append(userIdsStr, fmt.Sprintf("%d", userId))
	}
	_url := fmt.Sprintf("%v://%v/inner/user/levels", defaultUserServerScheme, getUserHost())
	resp, err := HttpGet(model, _url, nil, map[string][]string{
		"ids": userIdsStr,
	})
	if err != nil {
		model.Log.Errorf("MGetUserLevel fail:%v", err)
		return res, err
	}
	response := new(Response)
	if err = json.Unmarshal(resp, response); err != nil {
		model.Log.Errorf("MGetUserLevel json fail:%v", err)
		return res, err
	}
	for userId, level := range response.Data {
		res[userId] = CvUserLevel{
			UserId:          level.UserId,
			WealthUserGrade: level.WealthUserGrade,
			CharmUserGrade:  level.CharmUserGrade,
hujiebin's avatar
hujiebin committed
83 84
			ActiveUserGrade: level.ActiveUserGrade,
			NobleLevel:      level.NobleLevel,
hujiebin's avatar
hujiebin committed
85 86 87 88 89
		}
	}
	return res, nil
}

hujiebin's avatar
hujiebin committed
90 91 92 93 94 95 96 97 98 99 100 101
type CvUserBag struct {
	BagId      mysql.ID   `json:"bagId"`      // 背包id
	ResType    mysql.Type `json:"resType"`    // 道具类型 1:礼物道具
	ResId      mysql.ID   `json:"resId"`      // 道具资源id
	Name       string     `json:"name"`       // 资源名称
	DiamondNum mysql.Num  `json:"diamondNum"` // 钻石数量
	IconUrl    string     `json:"iconUrl"`    // icon url
	SvgaUrl    string     `json:"svgaUrl"`    // svga url
	Count      mysql.Num  `json:"count"`      // 拥有数量
	RemainDays int        `json:"remainDays"` // 有效天数
}

hujiebin's avatar
hujiebin committed
102 103
// 根据bagId获取用户背包
func GetUserBagId(model *domain.Model, bagId mysql.ID) (CvUserBag, error) {
hujiebin's avatar
hujiebin committed
104 105 106 107 108
	type Response struct {
		Code    int       `json:"code"`
		Message string    `json:"message"`
		Data    CvUserBag `json:"data"`
	}
hujiebin's avatar
hujiebin committed
109
	_url := fmt.Sprintf("%v://%v/inner/user/bag/id", defaultUserServerScheme, getUserHost())
hujiebin's avatar
hujiebin committed
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
	resp, err := HttpGet(model, _url, nil, map[string][]string{
		"bagId": {fmt.Sprintf("%d", bagId)},
	})
	if err != nil {
		model.Log.Errorf("GetUserBag fail:%v", err)
		return CvUserBag{}, err
	}
	response := new(Response)
	if err = json.Unmarshal(resp, response); err != nil {
		model.Log.Errorf("GetUserBag json fail:%v", err)
		return CvUserBag{}, err
	}
	return response.Data, nil
}

hujiebin's avatar
hujiebin committed
125
// 发送用户背包
hujiebin's avatar
hujiebin committed
126 127 128 129 130
// param resType 1:礼物
// param resId 礼物id
// param count 数量
// param day 天数
// param reason 原因
hujiebin's avatar
hujiebin committed
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244
func SendUserBag(model *domain.Model, userId mysql.ID, resType, resId mysql.ID, count, day mysql.Num, reason string) error {
	type Response struct {
		Code    int    `json:"code"`
		Message string `json:"message"`
	}
	_url := fmt.Sprintf("%v://%v/inner/prop/bag/send", defaultUserServerScheme, getUserHost())
	resp, err := HttpPostForm(model, _url, nil, map[string]string{
		"userId":  fmt.Sprintf("%d", userId),
		"resType": fmt.Sprintf("%d", resType),
		"resId":   fmt.Sprintf("%d", resId),
		"count":   fmt.Sprintf("%d", count),
		"day":     fmt.Sprintf("%d", day),
		"reason":  reason,
	})
	if err != nil {
		model.Log.Errorf("SendUserBag fail:%v", err)
		return err
	}
	response := new(Response)
	if err = json.Unmarshal(resp, response); err != nil {
		model.Log.Errorf("SendUserBag json fail:%v", err)
		return err
	}
	if response.Code != 200 {
		model.Log.Errorf("SendUserBag fail:%v", *response)
		return errors.New(response.Message)
	}
	return nil
}

// 发送用户贵族
func SendUserNoble(model *domain.Model, userId mysql.ID, level int, day mysql.Num) error {
	type Response struct {
		Code    int    `json:"code"`
		Message string `json:"message"`
	}
	_url := fmt.Sprintf("%v://%v/inner/prop/noble/send", defaultUserServerScheme, getUserHost())
	resp, err := HttpPostForm(model, _url, nil, map[string]string{
		"userId": fmt.Sprintf("%d", userId),
		"level":  fmt.Sprintf("%d", level),
		"day":    fmt.Sprintf("%d", day),
	})
	if err != nil {
		model.Log.Errorf("SendUserNoble fail:%v", err)
		return err
	}
	response := new(Response)
	if err = json.Unmarshal(resp, response); err != nil {
		model.Log.Errorf("SendUserNoble json fail:%v", err)
		return err
	}
	if response.Code != 200 {
		model.Log.Errorf("SendUserNoble fail:%v", *response)
		return errors.New(response.Message)
	}
	return nil
}

// 发送用户头饰
func SendUserHeadwear(model *domain.Model, userId mysql.ID, headwearId mysql.ID, day mysql.Num) error {
	type Response struct {
		Code    int    `json:"code"`
		Message string `json:"message"`
	}
	_url := fmt.Sprintf("%v://%v/inner/prop/headwear/send", defaultUserServerScheme, getUserHost())
	resp, err := HttpPostForm(model, _url, nil, map[string]string{
		"userId":     fmt.Sprintf("%d", userId),
		"headwearId": fmt.Sprintf("%d", headwearId),
		"day":        fmt.Sprintf("%d", day),
	})
	if err != nil {
		model.Log.Errorf("SendUserHeadwear fail:%v", err)
		return err
	}
	response := new(Response)
	if err = json.Unmarshal(resp, response); err != nil {
		model.Log.Errorf("SendUserHeadwear json fail:%v", err)
		return err
	}
	if response.Code != 200 {
		model.Log.Errorf("SendUserHeadwear fail:%v", *response)
		return errors.New(response.Message)
	}
	return nil
}

// 发送用户座驾
func SendUserRide(model *domain.Model, userId mysql.ID, rideId mysql.ID, day mysql.Num) error {
	type Response struct {
		Code    int    `json:"code"`
		Message string `json:"message"`
	}
	_url := fmt.Sprintf("%v://%v/inner/prop/ride/send", defaultUserServerScheme, getUserHost())
	resp, err := HttpPostForm(model, _url, nil, map[string]string{
		"userId": fmt.Sprintf("%d", userId),
		"rideId": fmt.Sprintf("%d", rideId),
		"day":    fmt.Sprintf("%d", day),
	})
	if err != nil {
		model.Log.Errorf("SendUserRide fail:%v", err)
		return err
	}
	response := new(Response)
	if err = json.Unmarshal(resp, response); err != nil {
		model.Log.Errorf("SendUserRide json fail:%v", err)
		return err
	}
	if response.Code != 200 {
		model.Log.Errorf("SendUserRide fail:%v", *response)
		return errors.New(response.Message)
	}
	return nil
}

hujiebin's avatar
hujiebin committed
245
// 获取指定cp对
hujiebin's avatar
hujiebin committed
246
func MGetUserCpPairs(model *domain.Model, userIds []mysql.ID) ([][3]mysql.ID, error) {
hujiebin's avatar
hujiebin committed
247 248 249
	type Response struct {
		Code    int           `json:"code"`
		Message string        `json:"message"`
hujiebin's avatar
hujiebin committed
250
		Data    [][3]mysql.ID `json:"data"`
hujiebin's avatar
hujiebin committed
251
	}
hujiebin's avatar
hujiebin committed
252
	var res [][3]mysql.ID
hujiebin's avatar
hujiebin committed
253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277
	if len(userIds) <= 0 {
		return res, nil
	}
	var userIdsStr []string
	for _, userId := range userIds {
		userIdsStr = append(userIdsStr, fmt.Sprintf("%d", userId))
	}
	_url := fmt.Sprintf("%v://%v/inner/user/cp/pair", defaultUserServerScheme, getUserHost())
	resp, err := HttpGet(model, _url, nil, map[string][]string{
		"ids": userIdsStr,
	})
	if err != nil {
		model.Log.Errorf("MGetUserLevel fail:%v", err)
		return res, err
	}
	response := new(Response)
	if err = json.Unmarshal(resp, response); err != nil {
		model.Log.Errorf("MGetUserLevel json fail:%v", err)
		return res, err
	} else {
		res = response.Data
	}
	return res, nil
}

hujiebin's avatar
hujiebin committed
278 279 280 281 282 283
func getUserHost() string {
	l := len(UserServerHost)
	r := rand.Intn(l) // 随机一个
	mylogrus.MyLog.Infof("getHostUser:%v---%v", r, UserServerHost[r])
	return UserServerHost[r]
}
hujiebin's avatar
hujiebin committed
284 285 286 287 288 289 290 291 292 293 294 295

// cp关系
type CvCpRelation struct {
	CpId         uint64 `json:"cpId"`
	UserId       uint64 `json:"userId"`
	CpUserId     uint64 `json:"cpUserId"`
	CpUserAvatar string `json:"cpUserAvatar"`
}

// 批量获取用户cpRelation
func MGetUserCpRelations(model *domain.Model, userIds []mysql.ID) (map[mysql.ID]CvCpRelation, error) {
	type Response struct {
hujiebin's avatar
hujiebin committed
296 297 298
		Code    int                       `json:"code"`
		Message string                    `json:"message"`
		Data    map[mysql.ID]CvCpRelation `json:"data"`
hujiebin's avatar
hujiebin committed
299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320
	}
	var res = make(map[mysql.ID]CvCpRelation)
	if len(userIds) <= 0 {
		return res, nil
	}
	var userIdsStr []string
	for _, userId := range userIds {
		userIdsStr = append(userIdsStr, fmt.Sprintf("%d", userId))
	}
	_url := fmt.Sprintf("%v://%v/inner/user/cpRelations", defaultUserServerScheme, getUserHost())
	resp, err := HttpGet(model, _url, nil, map[string][]string{
		"ids": userIdsStr,
	})
	if err != nil {
		model.Log.Errorf("MGetUserSvip fail:%v", err)
		return res, err
	}
	response := new(Response)
	if err = json.Unmarshal(resp, response); err != nil {
		model.Log.Errorf("MGetUserSvip json fail:%v", err)
		return res, err
	}
hujiebin's avatar
hujiebin committed
321
	return response.Data, nil
hujiebin's avatar
hujiebin committed
322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455
}

// 获取用户cpRelation
func GetUserCpRelation(model *domain.Model, userId mysql.ID) (CvCpRelation, error) {
	res, err := MGetUserCpRelations(model, []uint64{userId})
	if err != nil {
		return CvCpRelation{}, err
	}
	return res[userId], nil
}

type CvCp struct {
	CpUserInfo      *CvUserBase   `json:"cpUserInfo"`      // cp用户信息
	CpLevel         CvCpLevel     `json:"cpLevel"`         // cp等级
	MyPrivilegeList []CvPrivilege `json:"myPrivilegeList"` // 等级特权
	CreatedUnix     int64         `json:"createdUnix"`     // cp创建时间
	CpDays          int           `json:"cpDays"`          // cp天数
}

// cp等级
type CvCpLevel struct {
	Level  int    `json:"level"`  // 等级 0:无称号 1:恋爱CP 2:甜蜜CP 3:忠诚CP 4:炽热CP 5:荣耀CP
	Points uint32 `json:"points"` // CP值
	Title  string `json:"title"`
}

// 特权信息
type CvPrivilege struct {
	Type int `json:"type"` // 特权id 1:空间 2:横幅 3:等级勋章 4:证书 5:进场特效 6:头像头饰 7:动态资料卡 8:麦位特效
}

//用户基本信息
type CvUserBase struct {
	//不会有返回值
	Id *mysql.ID `json:"id,omitempty"`
	//头像,不存在为nil
	Avatar *string `json:"avatar"`
	//是否默认头像 true:是 false:不是
	DefaultAvatar *bool `json:"defaultAvatar"`
	//用户对外ID
	ExternalId *string `json:"externalId"`
	//昵称,不存在为nil
	Nick *string `json:"nick"`
	//签名,不存在为nil
	Description *string `json:"description"`
	//性别 1:男 2:女,不存在为nil
	Sex *uint8 `json:"sex"`
	//国家,不存在为nil
	Country *string `json:"country"`
	//国旗图标,不存在为nil
	CountryIcon *string `json:"countryIcon"`
	//邀请码
	Code         *string `json:"code"`
	IsPrettyCode bool    `json:"isPrettyCode"` // 是否靓号
	IsLogout     bool    `json:"isLogout"`     //是否注销
	//生日,如果是其它人用户信息,年龄则按照是否展示显示,如果是本人,年龄则按照是否存在展示
	Birthday *uint64 `json:"birthday"`
	//是否展示年龄, 是本人才有数据,看其他用户均为nil
	IsShowAge *uint8 `json:"isShowAge"`
	//是否工会成员, 只有是自己查自己,这个才有值,其它全为nil, 20220329 数据开放:原因:产品1对1视频聊天中,公会用户视频需要送礼物。改为: 全部人可以知道是否是公会用户。
	IsTradeUnion *bool `json:"isTradeUnion"`
	//是否代理管理员, 只有自己查自己的时候才有值,其他情况为nil
	IsAgentMgr *bool `json:"isAgentMgr"`
	//工会成员,是否开启了,匹配通知,只有 isTradeUnion值为true,这里才有值,
	IsTradeUnionMatchNotification *bool `json:"isTradeUnionMatchNotification"`
	//是否VIP用户
	IsVip bool `json:"isVip"`
	//是否是官方人员
	IsOfficialStaff bool `json:"isOfficialStaff"`
	//VIP用户过期时间(只有自己查询自己,才返回)
	VipExpireTime *int64               `json:"vipExpireTime"`
	Svip          CvSvip               `json:"svip"`      // svip结构,等级+权限
	Medals        []uint32             `json:"medals"`    // 勋章列表 TODO: 删除
	MedalInfo     []CvMedal            `json:"medalInfo"` // 勋章列表
	Headwear      *CvHeadwear          `json:"headwear"`  // 当前使用的头饰
	Ride          CvProperty           `json:"ride"`      // 当前使用的座驾
	Noble         CvNoble              `json:"noble"`     // 当前的
	GroupRole     common.GroupRoleType `json:"groupRole"` // 在群组的角色
}

type CvMedal struct {
	Id        uint32    `json:"id"`
	PicUrl    mysql.Str `json:"picUrl"`
	EffectUrl mysql.Str `json:"effectUrl"`
}

type CvHeadwear struct {
	Id        uint64    `json:"id"`
	Using     bool      `json:"using"`
	PicUrl    mysql.Str `json:"picUrl"`
	EffectUrl mysql.Str `json:"effectUrl"`
	TimeLeft  int64     `json:"timeLeft"` // 离到期还有多少秒(过期则是负数)
}

type CvProperty struct {
	Id             uint64    `json:"id"`
	PicUrl         mysql.Str `json:"picUrl"`
	EffectUrl      mysql.Str `json:"effectUrl"`
	Using          bool      `json:"using"`
	TimeLeft       int64     `json:"timeLeft"` // 离到期还有多少秒(过期则是负数)
	SenderAvatar   string    `json:"senderAvatar"`
	ReceiverAvatar string    `json:"receiverAvatar"`
}

type CvNoble struct {
	Level   uint16 `json:"level"`
	EndTime int64  `json:"endTime"`
}

// 获取用户cp
func GetUserCp(model *domain.Model, userId mysql.ID) (*CvCp, error) {
	type Response struct {
		Code    int    `json:"code"`
		Message string `json:"message"`
		Data    *CvCp  `json:"data"`
	}
	_url := fmt.Sprintf("%v://%v/inner/user/cp", defaultUserServerScheme, getUserHost())
	resp, err := HttpGet(model, _url, nil, map[string][]string{
		"id": {fmt.Sprintf("%d", userId)},
	})
	if err != nil {
		model.Log.Errorf("GetUserCp fail:%v", err)
		return nil, err
	}
	response := new(Response)
	if err = json.Unmarshal(resp, response); err != nil {
		model.Log.Errorf("GetUserCp json fail:%v", err)
		return nil, err
	}
	if response.Data != nil && response.Data.CpUserInfo != nil {
		return response.Data, nil
	}
	return nil, nil
}